5#include "GaudiKernel/IAppMgrUI.h"
6#include "GaudiKernel/IIncidentSvc.h"
7#include "GaudiKernel/ITHistSvc.h"
8#include "GaudiKernel/Kernel.h"
9#include "GaudiKernel/Message.h"
10#include "GaudiKernel/StatusCode.h"
11#include "GaudiKernel/System.h"
26 "WARNING",
"ERROR",
"FATAL",
"ALWAYS"};
30 size_t msgHash(
const Message&
msg)
32 std::string
s =
msg.getSource() +
msg.getMessage();
33 s.erase(
std::remove_if(
s.begin(),
s.end(), [](
char c) { return std::isdigit(c); }),
s.end());
34 return std::hash<std::string>()(
s);
39 base_class(name, svcloc)
41 m_outputLevel.declareUpdateHandler([svcloc](Gaudi::Details::PropertyBase&) {
42 SmartIF<IAppMgrUI> app = svcloc;
43 if (app) app->outputLevelUpdate();
46 for (
int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
56 StatusCode
sc = Service::initialize();
57 if (
sc.isFailure())
return sc;
60 sc = incSvc.retrieve();
62 reportMessage(name(), MSG::WARNING,
"Cannot find IncidentSvc");
71 std::cout <<
"TrigMessageSvc WARNING: Colors are not supported by TrigMessageSvc" << std::endl;
73 return StatusCode::SUCCESS;
78 m_state = Gaudi::StateMachine::OFFLINE;
80 if (
sc.isSuccess() ) m_state = Gaudi::StateMachine::INITIALIZED;
89 return StatusCode::SUCCESS;
97 reportMessage(name(), MSG::INFO,
"Disabling asynchronous message reporting");
103 return StatusCode::SUCCESS;
109 reportMessage(name(), MSG::INFO,
"Enabling asynchronous message reporting");
117 if ( histSvc.retrieve().isFailure() ) {
118 reportMessage(name(), MSG::WARNING,
"Cannot find THistSvc. Message stats will not be published.");
124 const std::string path =
"/EXPERT/HLTFramework/" + name() +
"/";
126 m_msgCountHist =
new TH1I(
"MessageCount",
"Messages while RUNNING;Severity;Count",
127 nLevelBins, 0, nLevelBins);
129 const int nSrcBins = 1;
130 m_msgCountSrcHist =
new TH2I(
"MessageCountBySource",
"Messages while RUNNING;Severity;Source",
131 nLevelBins, 0, nLevelBins, nSrcBins, 0, nSrcBins);
139 reportMessage(name(), MSG::WARNING,
"Cannot register monitoring histogram 'MessageCount'");
142 reportMessage(name(), MSG::WARNING,
"Cannot register monitoring histogram 'MessageCountBySource'");
151 if (prop.name() ==
"alwaysLimit") {
152 Gaudi::Property<int>* p =
dynamic_cast<Gaudi::Property<int>*
>(&prop);
153 if (p && p->value() != 0) {
154 std::cout <<
"TrigMessageSvc ERROR: cannot suppress ALWAYS messages" << std::endl;
158 else if (prop.name() ==
"defaultLimit") {
159 for (
int i = MSG::VERBOSE; i < MSG::NUM_LEVELS; ++i) {
160 if (i != MSG::ALWAYS) {
165 else if (prop.name() !=
"fatalLimit" && prop.name() !=
"errorLimit" &&
166 prop.name() !=
"warningLimit" && prop.name() ==
"infoLimit" &&
167 prop.name() ==
"debugLimit" && prop.name() ==
"verboseLimit") {
168 std::cout <<
"TrigMessageSvc ERROR: Unknown message limit parameter: " << prop.name()
176 static const std::array<std::pair<const char*, MSG::Level>, 7> tbl{{{
"setFatal", MSG::FATAL},
177 {
"setError", MSG::ERROR},
178 {
"setWarning", MSG::WARNING},
179 {
"setInfo", MSG::INFO},
180 {
"setDebug", MSG::DEBUG},
181 {
"setVerbose", MSG::VERBOSE},
182 {
"setAlways", MSG::ALWAYS}}};
184 auto i = std::find_if(
185 std::begin(tbl), std::end(tbl),
186 [&](
const std::pair<const char*, MSG::Level>& t) {
return prop.name() == t.first; });
187 if (i == std::end(tbl)) {
188 std::cerr <<
"TrigMessageSvc ERROR: Unknown message threshold parameter: " << prop.name()
194 Gaudi::Property<std::vector<std::string>>* sap =
195 dynamic_cast<Gaudi::Property<std::vector<std::string>
>*>(&prop);
197 std::cerr <<
"could not dcast " << prop.name()
198 <<
" to a Gaudi::Property<std::vector<std::string>> (which it "
210 std::ostringstream os;
213 os <<
"Summarizing all message counts"
217 os <<
"Listing sources of suppressed message: " << std::endl;
220 os <<
"=====================================================" << std::endl;
221 os <<
" Message Source | Level | Count" << std::endl;
222 os <<
"-----------------------------+---------+-------------" << std::endl;
227 for (
unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
232 os.setf(std::ios_base::left, std::ios_base::adjustfield);
237 os.setf(std::ios_base::right, std::ios_base::adjustfield);
242 os << itr->second.msg[ic];
249 os <<
"=====================================================" << std::endl;
254 return StatusCode::SUCCESS;
272 std::function<void()> action;
285 const int key =
msg.getType();
288 const Message* cmsg = &
msg;
290 std::unique_ptr<Message> newMessage;
301 if (nmsg > msgLimit) doPrint =
false;
302 if (nmsg == msgLimit) {
303 std::string txt =
levelNames[key] +
" message limit (" + std::to_string(msgLimit) +
304 ") reached for " +
msg.getSource() +
". Suppressing further output.";
305 newMessage = std::make_unique<Message>(
msg.getSource(), MSG::WARNING, std::move(txt));
306 cmsg = newMessage.get();
310 else if (msgLimit < 0) {
312 const unsigned int mh = msgHash(*cmsg);
321 if (nmsg == abs(msgLimit)) {
322 std::ostringstream os;
323 os <<
msg.getMessage() <<
" [Message limit (" << abs(msgLimit)
324 <<
") reached. Log-suppression of further output.]";
325 newMessage = std::make_unique<Message>(
msg.getSource(),
msg.getType(), os.str());
326 cmsg = newMessage.get();
328 else if (nmsg > abs(msgLimit)) {
329 const int everyNth = (int)exp10((
int)log10(nmsg));
330 if ((nmsg % everyNth) == 0) {
331 std::ostringstream os;
332 os <<
msg.getMessage() <<
" [suppressed " << everyNth <<
" similar messages]";
333 newMessage = std::make_unique<Message>(
msg.getSource(),
msg.getType(), os.str());
334 cmsg = newMessage.get();
349 (*m_defaultStream) << *cmsg << std::endl << std::flush;
385 const char* filename =
msg.getSource().c_str();
386 const char* function_name =
"";
387 const int line_number = msgHash(
msg);
389 ers::LocalContext hlt_context_info(
package_name, filename, line_number, function_name);
399 std::ostringstream oss;
401 ers::HLTMessage ersMsg(hlt_context_info, oss.str());
402 ersMsg.add_qualifier(
"HLT");
405 switch (
msg.getType()) {
406 case MSG::NIL:
break;
407 case MSG::VERBOSE: ers::debug(ersMsg, 2);
break;
408 case MSG::DEBUG: ers::debug(ersMsg, 1);
break;
409 case MSG::INFO: ers::info(ersMsg);
break;
410 case MSG::WARNING: ers::warning(ersMsg);
break;
411 case MSG::ERROR: ers::error(ersMsg);
break;
412 case MSG::FATAL: ers::fatal(ersMsg);
break;
414 std::ostringstream oss;
415 oss <<
"Unknown message severity level: " <<
msg.getType() <<
" Original message was: " << m;
416 ers::error(ers::HLTMessage(ERS_HERE, oss.str()));
432 return m_outputLevel;
439 return it !=
m_thresholdMap.end() ? it->second : m_outputLevel.value();
444 m_outputLevel = new_level;
455 }
else if ( i->second != level ) {
466 const std::vector<std::string>& filter)
const
468 if (filter.empty())
return false;
469 auto it = filter.begin();
470 if (filter.size() == 1 && (*it) ==
"*")
return true;
473 for (; it != filter.end(); ++it) {
474 if ((*it) ==
"*") pass =
true;
475 if (source == (*it))
return true;
476 if (
"!" + source == (*it))
return false;
485 const EventContext::ContextID_t slot =
msg.getEventSlot();
486 const EventContext::ContextEvt_t evt =
msg.getEventNumber();
491 if ( itr->second.first != evt ) {
492 itr->second = {evt,
MsgAry()};
496 const int N = ++itr->second.second.msg[
msg.getType()];
static const std::string levelNames[MSG::NUM_LEVELS]
OH histogram lock header file.
static const std::string & type()
Incident type.
bool passErsFilter(const std::string &source, const std::vector< std::string > &filter) const
Gaudi::Property< std::string > m_ersFormat
tbb::concurrent_bounded_queue< std::function< void()> > m_messageActionsQueue
void setupLimits(Gaudi::Details::PropertyBase &prop)
virtual int outputLevel() const override
virtual StatusCode finalize() override
void i_reportMessage(const Message &msg, int outputLevel)
Internal implementation of reportMessage(const Message&,int) without lock.
bool passErsLimit(const Message &msg)
std::array< Gaudi::Property< int >, MSG::NUM_LEVELS > m_msgLimit
virtual StatusCode start() override
Gaudi::Property< std::string > m_defaultTimeFormat
std::map< std::string, MsgAry > m_sourceMap
counts per source
std::map< size_t, unsigned int > m_msgHashCount
counts per message hash
std::array< Gaudi::Property< std::vector< std::string > >, MSG::NUM_LEVELS > m_thresholdProp
std::unordered_map< EventContext::ContextID_t, std::pair< EventContext::ContextEvt_t, MsgAry > > m_slotMsgCount
counts per slot and level
std::array< Gaudi::Property< std::vector< std::string > >, MSG::NUM_LEVELS > m_useERS
Special properties to control output to ERS of individual sources.
Gaudi::Property< bool > m_color
std::recursive_mutex m_thresholdMapMutex
virtual void reportMessage(const Message &message) override
TH1I * m_msgCountHist
Message counting per level histogram.
void i_reportERS(const Message &msg) const
Report message to online messaging system (ERS)
bool m_doPublish
are we publishing message statistics?
Gaudi::Property< std::string > m_defaultFormat
ThresholdMap m_thresholdMap
Output level threshold map.
void setupThreshold(Gaudi::Details::PropertyBase &prop)
Gaudi::Property< bool > m_stats
virtual StatusCode stop() override
Gaudi::Property< bool > m_suppressRunningOnly
virtual int messageCount(MSG::Level logLevel) const override
bool m_doSuppress
is suppression currently enabled?
TH2I * m_msgCountSrcHist
Message counting per message source.
Gaudi::Property< int > m_ersEventLimit
Gaudi::Property< unsigned int > m_statLevel
virtual void setOutputLevel(int new_level) override
std::array< int, MSG::NUM_LEVELS > m_msgCount
counts per level
virtual StatusCode reinitialize() override
virtual void handle(const Incident &incident) override
Gaudi::Property< unsigned int > m_eventIDLevel
Gaudi::Property< bool > m_suppress
std::thread m_thread
Thread for asynchronous reporting.
Gaudi::Property< unsigned int > m_publishLevel
virtual StatusCode initialize() override
TrigMessageSvc(const std::string &name, ISvcLocator *svcloc)
Scoped lock to be used for threaded histogram operations.
static char * package_name
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.
Private helper class to keep the count of messages of a type (MSG::LEVEL).
ERS_DECLARE_ISSUE(offline_EventStorage_v5, CompressionIssue, ERS_EMPTY, ERS_EMPTY) ERS_DECLARE_ISSUE_BASE(offline_EventStorage_v5