CMS 3D CMS Logo

MessageSender.cc
Go to the documentation of this file.
6 
7 #include <algorithm>
8 #include <cassert>
9 #include <vector>
10 #include <limits>
11 #include <atomic>
12 
13 #include <functional>
14 #include "oneapi/tbb/concurrent_unordered_map.h"
15 
16 #define TRACE_DROP
17 #ifdef TRACE_DROP
18 #include <iostream>
19 #endif
20 
21 // Change log
22 //
23 // 1 mf 8/25/08 keeping the error summary information for
24 // LoggedErrorsSummary()
25 //
26 // 2 mf 11/2/10 Use new moduleContext method of MessageDrop:
27 // see MessageServer/src/MessageLogger.cc change 17.
28 //
29 
30 using namespace edm;
31 using namespace edm::messagelogger;
32 
33 namespace {
34  //Helper class used as 'key' to the thread safe map storing the
35  // per event log error and log warning messages
36  struct ErrorSummaryMapKey {
40 
41  bool operator<(ErrorSummaryMapKey const& iOther) const {
42  int comp = severity.getLevel() - iOther.severity.getLevel();
43  if (0 == comp) {
44  comp = category.compare(iOther.category);
45  if (comp == 0) {
46  comp = module.compare(iOther.module);
47  }
48  }
49  return comp < 0;
50  }
51 
52  bool operator==(ErrorSummaryMapKey const& iOther) const {
53  return ((iOther.category == category) and (iOther.module == module) and
54  (severity.getLevel() == iOther.severity.getLevel()));
55  }
56  size_t smallHash() const {
57  std::hash<std::string> h;
58 
59  return h(category + module + severity.getSymbol());
60  }
61 
62  struct key_hash {
63  std::size_t operator()(ErrorSummaryMapKey const& iKey) const { return iKey.smallHash(); }
64  };
65  };
66 
67  class AtomicUnsignedInt {
68  public:
69  AtomicUnsignedInt() : value_(0) {}
70  AtomicUnsignedInt(AtomicUnsignedInt const& r) : value_(r.value_.load(std::memory_order_acquire)) {}
71  std::atomic<unsigned int>& value() { return value_; }
72  std::atomic<unsigned int> const& value() const { return value_; }
73 
74  private:
75  std::atomic<unsigned int> value_;
76  };
77 
78 } // namespace
79 
80 CMS_THREAD_SAFE static std::atomic<bool> errorSummaryIsBeingKept{false};
81 //Each item in the vector is reserved for a different Stream
83  oneapi::tbb::concurrent_unordered_map<ErrorSummaryMapKey, AtomicUnsignedInt, ErrorSummaryMapKey::key_hash>>
85 
86 MessageSender::MessageSender(ELseverityLevel const& sev, std::string_view id, bool verbatim, bool suppressed)
87  : errorobj_p(suppressed ? nullptr : new ErrorObj(sev, id, verbatim), ErrorObjDeleter()) {
88  //std::cout << "MessageSender ctor; new ErrorObj at: " << errorobj_p << '\n';
89 }
90 
91 // This destructor must not be permitted to throw. A
92 // boost::thread_resoruce_error is thrown at static destruction time,
93 // if the MessageLogger library is loaded -- even if it is not used.
94 void MessageSender::ErrorObjDeleter::operator()(ErrorObj* errorObjPtr) {
95  if (errorObjPtr == nullptr) {
96  return;
97  }
98  try {
99  //std::cout << "MessageSender dtor; ErrorObj at: " << errorobj_p << '\n';
100 
101  // surrender ownership of our ErrorObj, transferring ownership
102  // (via the intermediate MessageLoggerQ) to the MessageLoggerScribe
103  // that will (a) route the message text to its destination(s)
104  // and will then (b) dispose of the ErrorObj
105 
107  if (drop) {
108  errorObjPtr->setModule(drop->moduleContext()); // change log
109  errorObjPtr->setContext(drop->runEvent);
110  }
111 #ifdef TRACE_DROP
112  if (!drop)
113  std::cerr << "MessageSender::~MessageSender() - Null drop pointer \n";
114 #endif
115  // change log 1
116  if (errorSummaryIsBeingKept.load(std::memory_order_acquire) && errorObjPtr->xid().severity >= ELwarning && drop &&
118  auto& errorSummaryMap = errorSummaryMaps[drop->streamID];
119 
120  ELextendedID const& xid = errorObjPtr->xid();
121  ErrorSummaryMapKey key{xid.id, xid.module, xid.severity};
122  auto i = errorSummaryMap.find(key);
123  if (i != errorSummaryMap.end()) {
124  i->second.value().fetch_add(1, std::memory_order_acq_rel); // same as ++errorSummaryMap[key]
125  } else {
126  errorSummaryMap[key].value().store(1, std::memory_order_release);
127  }
128  }
129 
130  MessageLoggerQ::MLqLOG(errorObjPtr);
131  } catch (...) {
132  // nothing to do
133 
134  // for test that removal of thread-involved static works,
135  // simply throw here, then run in trivial_main in totalview
136  // and Next or Step so that the exception would be detected.
137  // That test has been done 12/14/07.
138  }
139 }
141 
142 //The following functions are declared here rather than in
143 // LoggedErrorsSummary.cc because only MessageSender and these
144 // functions interact with the statics errorSummaryIsBeingKept and
145 // errorSummaryMaps. By putting them into the same .cc file the
146 // statics can be file scoped rather than class scoped and therefore
147 // better encapsulated.
148 namespace edm {
149  using namespace messagelogger;
150 
152  bool ret = errorSummaryIsBeingKept.exchange(true, std::memory_order_acq_rel);
153  return ret;
154  }
155 
157  bool ret = errorSummaryIsBeingKept.exchange(false, std::memory_order_acq_rel);
158  return ret;
159  }
160 
161  bool FreshErrorsExist(unsigned int iStreamID) {
162  assert(iStreamID < errorSummaryMaps.size());
163  return !errorSummaryMaps[iStreamID].empty();
164  }
165 
166  std::vector<ErrorSummaryEntry> LoggedErrorsSummary(unsigned int iStreamID) {
167  assert(iStreamID < errorSummaryMaps.size());
168  auto const& errorSummaryMap = errorSummaryMaps[iStreamID];
169  std::vector<ErrorSummaryEntry> v;
170  auto end = errorSummaryMap.end();
171  for (auto i = errorSummaryMap.begin(); i != end; ++i) {
172  auto const& key = i->first;
173  ErrorSummaryEntry e{key.category, key.module, key.severity};
174 
175  e.count = i->second.value().load(std::memory_order_acquire);
176  v.push_back(e);
177  }
178  std::sort(v.begin(), v.end());
179  return v;
180  }
181 
182  void clearLoggedErrorsSummary(unsigned int iStreamID) {
183  assert(iStreamID < errorSummaryMaps.size());
184  errorSummaryMaps[iStreamID].clear();
185  }
186 
187  void setMaxLoggedErrorsSummaryIndicies(unsigned int iMax) { errorSummaryMaps.resize(iMax); }
188 
189  std::vector<ErrorSummaryEntry> LoggedErrorsOnlySummary(unsigned int iStreamID) { // ChangeLog 2
190  std::vector<ErrorSummaryEntry> v;
191  assert(iStreamID < errorSummaryMaps.size());
192  auto const& errorSummaryMap = errorSummaryMaps[iStreamID];
193  auto end = errorSummaryMap.end();
194  for (auto i = errorSummaryMap.begin(); i != end; ++i) {
195  auto const& key = i->first;
196  if (key.severity >= edm::ELerror) {
197  ErrorSummaryEntry e{key.category, key.module, key.severity};
198  e.count = i->second.value().load(std::memory_order_acquire);
199  v.push_back(e);
200  }
201  }
202  std::sort(v.begin(), v.end());
203  return v;
204  }
205 
206 } // end namespace edm
messagelogger::ELseverityLevel severity
Definition: ELextendedID.h:30
constexpr const ELseverityLevel ELwarning
bool EnableLoggedErrorsSummary()
ret
prodAgent to be discontinued
static MessageDrop * instance()
Definition: MessageDrop.cc:33
void clearLoggedErrorsSummary(unsigned int iStreamID)
void setMaxLoggedErrorsSummaryIndicies(unsigned int iMax)
assert(be >=bs)
bool FreshErrorsExist(unsigned int iStreamID)
bool DisableLoggedErrorsSummary()
constexpr bool operator==(ELseverityLevel const &e1, ELseverityLevel const &e2) noexcept
std::string module
Definition: ELextendedID.h:31
key
prepare the HTCondor submission files and eventually submit them
#define CMS_THREAD_SAFE
virtual void setModule(std::string_view module)
Definition: ErrorObj.cc:175
const ELextendedID & xid() const
Definition: ErrorObj.cc:142
std::vector< messagelogger::ErrorSummaryEntry > LoggedErrorsOnlySummary(unsigned int iStreamID)
static std::vector< oneapi::tbb::concurrent_unordered_map< ErrorSummaryMapKey, AtomicUnsignedInt, ErrorSummaryMapKey::key_hash > > errorSummaryMaps
constexpr const ELseverityLevel ELerror
std::string id
Definition: ELextendedID.h:29
constexpr bool operator<(ELseverityLevel const &e1, ELseverityLevel const &e2) noexcept
static std::atomic< bool > errorSummaryIsBeingKept
virtual void setContext(std::string_view context)
Definition: ErrorObj.cc:177
MessageSender()=default
static void MLqLOG(ErrorObj *p)
HLT enums.
std::vector< messagelogger::ErrorSummaryEntry > LoggedErrorsSummary(unsigned int iStreamID)
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4