File indexing completed on 2024-04-06 12:12:44
0001 #include "FWCore/MessageLogger/interface/ErrorSummaryEntry.h"
0002 #include "FWCore/MessageLogger/interface/MessageSender.h"
0003 #include "FWCore/MessageLogger/interface/MessageLoggerQ.h"
0004 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0005 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0006
0007 #include <algorithm>
0008 #include <cassert>
0009 #include <vector>
0010 #include <limits>
0011 #include <atomic>
0012
0013 #include <functional>
0014 #include "oneapi/tbb/concurrent_unordered_map.h"
0015
0016 #define TRACE_DROP
0017 #ifdef TRACE_DROP
0018 #include <iostream>
0019 #endif
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 using namespace edm;
0031 using namespace edm::messagelogger;
0032
0033 namespace {
0034
0035
0036 struct ErrorSummaryMapKey {
0037 std::string category;
0038 std::string module;
0039 ELseverityLevel severity;
0040
0041 bool operator<(ErrorSummaryMapKey const& iOther) const {
0042 int comp = severity.getLevel() - iOther.severity.getLevel();
0043 if (0 == comp) {
0044 comp = category.compare(iOther.category);
0045 if (comp == 0) {
0046 comp = module.compare(iOther.module);
0047 }
0048 }
0049 return comp < 0;
0050 }
0051
0052 bool operator==(ErrorSummaryMapKey const& iOther) const {
0053 return ((iOther.category == category) and (iOther.module == module) and
0054 (severity.getLevel() == iOther.severity.getLevel()));
0055 }
0056 size_t smallHash() const {
0057 std::hash<std::string> h;
0058
0059 return h(category + module + severity.getSymbol());
0060 }
0061
0062 struct key_hash {
0063 std::size_t operator()(ErrorSummaryMapKey const& iKey) const { return iKey.smallHash(); }
0064 };
0065 };
0066
0067 class AtomicUnsignedInt {
0068 public:
0069 AtomicUnsignedInt() : value_(0) {}
0070 AtomicUnsignedInt(AtomicUnsignedInt const& r) : value_(r.value_.load(std::memory_order_acquire)) {}
0071 std::atomic<unsigned int>& value() { return value_; }
0072 std::atomic<unsigned int> const& value() const { return value_; }
0073
0074 private:
0075 std::atomic<unsigned int> value_;
0076 };
0077
0078 }
0079
0080 CMS_THREAD_SAFE static std::atomic<bool> errorSummaryIsBeingKept{false};
0081
0082 CMS_THREAD_SAFE static std::vector<
0083 oneapi::tbb::concurrent_unordered_map<ErrorSummaryMapKey, AtomicUnsignedInt, ErrorSummaryMapKey::key_hash>>
0084 errorSummaryMaps;
0085
0086 MessageSender::MessageSender(ELseverityLevel const& sev, std::string_view id, bool verbatim, bool suppressed)
0087 : errorobj_p(suppressed ? nullptr : new ErrorObj(sev, id, verbatim), ErrorObjDeleter()) {
0088
0089 }
0090
0091
0092
0093
0094 void MessageSender::ErrorObjDeleter::operator()(ErrorObj* errorObjPtr) {
0095 if (errorObjPtr == nullptr) {
0096 return;
0097 }
0098 try {
0099
0100
0101
0102
0103
0104
0105
0106 MessageDrop* drop = MessageDrop::instance();
0107 if (drop) {
0108 errorObjPtr->setModule(drop->moduleContext());
0109 errorObjPtr->setContext(drop->runEvent);
0110 }
0111 #ifdef TRACE_DROP
0112 if (!drop)
0113 std::cerr << "MessageSender::~MessageSender() - Null drop pointer \n";
0114 #endif
0115
0116 if (errorSummaryIsBeingKept.load(std::memory_order_acquire) && errorObjPtr->xid().severity >= ELwarning && drop &&
0117 drop->streamID < std::numeric_limits<unsigned int>::max()) {
0118 auto& errorSummaryMap = errorSummaryMaps[drop->streamID];
0119
0120 ELextendedID const& xid = errorObjPtr->xid();
0121 ErrorSummaryMapKey key{xid.id, xid.module, xid.severity};
0122 auto i = errorSummaryMap.find(key);
0123 if (i != errorSummaryMap.end()) {
0124 i->second.value().fetch_add(1, std::memory_order_acq_rel);
0125 } else {
0126 errorSummaryMap[key].value().store(1, std::memory_order_release);
0127 }
0128 }
0129
0130 MessageLoggerQ::MLqLOG(errorObjPtr);
0131 } catch (...) {
0132
0133
0134
0135
0136
0137
0138 }
0139 }
0140 MessageSender::~MessageSender() {}
0141
0142
0143
0144
0145
0146
0147
0148 namespace edm {
0149 using namespace messagelogger;
0150
0151 bool EnableLoggedErrorsSummary() {
0152 bool ret = errorSummaryIsBeingKept.exchange(true, std::memory_order_acq_rel);
0153 return ret;
0154 }
0155
0156 bool DisableLoggedErrorsSummary() {
0157 bool ret = errorSummaryIsBeingKept.exchange(false, std::memory_order_acq_rel);
0158 return ret;
0159 }
0160
0161 bool FreshErrorsExist(unsigned int iStreamID) {
0162 assert(iStreamID < errorSummaryMaps.size());
0163 return !errorSummaryMaps[iStreamID].empty();
0164 }
0165
0166 std::vector<ErrorSummaryEntry> LoggedErrorsSummary(unsigned int iStreamID) {
0167 assert(iStreamID < errorSummaryMaps.size());
0168 auto const& errorSummaryMap = errorSummaryMaps[iStreamID];
0169 std::vector<ErrorSummaryEntry> v;
0170 auto end = errorSummaryMap.end();
0171 for (auto i = errorSummaryMap.begin(); i != end; ++i) {
0172 auto const& key = i->first;
0173 ErrorSummaryEntry e{key.category, key.module, key.severity};
0174
0175 e.count = i->second.value().load(std::memory_order_acquire);
0176 v.push_back(e);
0177 }
0178 std::sort(v.begin(), v.end());
0179 return v;
0180 }
0181
0182 void clearLoggedErrorsSummary(unsigned int iStreamID) {
0183 assert(iStreamID < errorSummaryMaps.size());
0184 errorSummaryMaps[iStreamID].clear();
0185 }
0186
0187 void setMaxLoggedErrorsSummaryIndicies(unsigned int iMax) { errorSummaryMaps.resize(iMax); }
0188
0189 std::vector<ErrorSummaryEntry> LoggedErrorsOnlySummary(unsigned int iStreamID) {
0190 std::vector<ErrorSummaryEntry> v;
0191 assert(iStreamID < errorSummaryMaps.size());
0192 auto const& errorSummaryMap = errorSummaryMaps[iStreamID];
0193 auto end = errorSummaryMap.end();
0194 for (auto i = errorSummaryMap.begin(); i != end; ++i) {
0195 auto const& key = i->first;
0196 if (key.severity >= edm::ELerror) {
0197 ErrorSummaryEntry e{key.category, key.module, key.severity};
0198 e.count = i->second.value().load(std::memory_order_acquire);
0199 v.push_back(e);
0200 }
0201 }
0202 std::sort(v.begin(), v.end());
0203 return v;
0204 }
0205
0206 }