6#include "GaudiKernel/Kernel.h"
7#include "GaudiKernel/StatusCode.h"
8#include "GaudiKernel/Message.h"
20static const std::string
levelNames[MSG::NUM_LEVELS] = {
"NIL",
"VERBOSE",
"DEBUG",
"INFO",
21 "WARNING",
"ERROR",
"FATAL",
"ALWAYS"};
25 : base_class( name, svcloc ),
m_keysUsed(false)
28 m_outputLevel = MSG::INFO;
29 declareProperty(
"Format",
m_defaultFormat = Message::getDefaultFormat() );
31 declareProperty(
"showStats",
m_stats =
false );
43 declareProperty(
"useColors",
m_color=
false);
46 declareProperty(
"fatalColorCode",
m_logColors[MSG::FATAL] );
47 declareProperty(
"errorColorCode",
m_logColors[MSG::ERROR] );
48 declareProperty(
"warningColorCode",
m_logColors[MSG::WARNING] );
49 declareProperty(
"infoColorCode",
m_logColors[MSG::INFO] );
50 declareProperty(
"debugColorCode",
m_logColors[MSG::DEBUG] );
51 declareProperty(
"verboseColorCode",
m_logColors[MSG::VERBOSE] );
52 declareProperty(
"alwaysColorCode",
m_logColors[MSG::ALWAYS] );
54 const int defaultLimit = 500;
55 declareProperty(
"fatalLimit",
m_msgLimit[MSG::FATAL] = defaultLimit );
56 declareProperty(
"errorLimit",
m_msgLimit[MSG::ERROR] = defaultLimit );
57 declareProperty(
"warningLimit",
m_msgLimit[MSG::WARNING] = defaultLimit );
58 declareProperty(
"infoLimit",
m_msgLimit[MSG::INFO] = defaultLimit );
59 declareProperty(
"debugLimit",
m_msgLimit[MSG::DEBUG] = defaultLimit );
60 declareProperty(
"verboseLimit",
m_msgLimit[MSG::VERBOSE] = defaultLimit );
61 declareProperty(
"alwaysLimit",
m_msgLimit[MSG::ALWAYS] = 0 );
63 declareProperty(
"defaultLimit",
m_msgLimit[MSG::NIL] = defaultLimit );
65 declareProperty(
"enableSuppression",
m_suppress =
false );
72 declareProperty(
"loggingLevel",
m_logLevel = MSG::FATAL,
"Message level above which all messages are saved" );
75 declareProperty(
"keywords",
m_keywords,
"keywords to scan messages for and save");
78 declareProperty(
"loggedStreams",
80 "MessageStream sources we want to dump into a logfile" );
82 for (
int ic=0; ic<MSG::NUM_LEVELS; ++ic) {
88 for (
int i=0; i<MSG::NUM_LEVELS; ++i) {
101 for ( ; iStream != endStream; ++iStream ) {
102 delete iStream->second;
103 iStream->second =
nullptr;
112 sc = base_class::initialize();
113 if(
sc.isFailure() )
return sc;
116 SmartIF<IMessageSvc> &si
ATLAS_THREAD_SAFE =
const_cast<SmartIF<IMessageSvc>&
> (msgSvc());
139 return StatusCode::SUCCESS;
146 m_state = Gaudi::StateMachine::OFFLINE;
157 vector<string> fatDef;
158 fatDef.push_back(
"[94;101;1m" );
165 vector<string> errDef;
166 errDef.push_back(
"[97;101;1m" );
173 vector<string> warDef;
174 warDef.push_back(
"[93;1m" );
183 for (
int ic=0; ic<MSG::NUM_LEVELS; ++ic) {
199 if (prop.name() ==
"fatalColorCode") {
201 }
else if (prop.name() ==
"errorColorCode") {
203 }
else if (prop.name() ==
"warningColorCode") {
205 }
else if (prop.name() ==
"infoColorCode") {
207 }
else if (prop.name() ==
"debugColorCode") {
209 }
else if (prop.name() ==
"verboseColorCode") {
211 }
else if (prop.name() ==
"alwaysColorCode") {
214 std::println (
"ERROR: Unknown message color parameter: {}", prop.name());
219 vector<string>::const_iterator itr;
226 }
else if ((*itr)[0] ==
'[') {
227 code =
"\033" + *itr;
229 code =
"\033[" +
colTrans(*itr, 90) +
";1m";
233 vector<string>::const_iterator itr2 = itr + 1;
235 code =
"\033[" +
colTrans(*itr, 90) +
";"
248 if (prop.name() ==
"fatalLimit") {
250 }
else if (prop.name() ==
"errorLimit") {
252 }
else if (prop.name() ==
"warningLimit") {
254 }
else if (prop.name() ==
"infoLimit") {
256 }
else if (prop.name() ==
"debugLimit") {
258 }
else if (prop.name() ==
"verboseLimit") {
260 }
else if (prop.name() ==
"alwaysLimit") {
261 IntegerProperty *p =
dynamic_cast<IntegerProperty*
>(&prop);
262 if (p && p->value() != 0) {
263 std::println (
"LoggedMessageSvc ERROR: cannot suppress ALWAYS messages");
267 }
else if (prop.name() ==
"defaultLimit") {
268 for (
int i = MSG::VERBOSE; i< MSG::NUM_LEVELS; ++i) {
269 if (i != MSG::ALWAYS) {
274 std::println (
"LoggedMessageSvc ERROR: Unknown message limit parameter: {}",
285 if (prop.name() ==
"setFatal") {
287 }
else if (prop.name() ==
"setError") {
289 }
else if (prop.name() ==
"setWarning") {
291 }
else if (prop.name() ==
"setInfo") {
293 }
else if (prop.name() ==
"setDebug") {
295 }
else if (prop.name() ==
"setVerbose") {
297 }
else if (prop.name() ==
"setAlways") {
299 }
else if (prop.name() ==
"loggingLevel") {
300 IntegerProperty *iap =
dynamic_cast<IntegerProperty*
>( &prop );
304 }
else if (prop.name() ==
"keywords") {
305 StringArrayProperty *sap =
dynamic_cast<StringArrayProperty*
>( &prop );
306 if (sap!=
nullptr && sap->value().size() > 0) {
313 std::println (cerr,
"LoggedMessageSvc ERROR: Unknown message theshold parameter: {}",
318 StringArrayProperty *sap =
dynamic_cast<StringArrayProperty*
>( &prop);
319 if (sap ==
nullptr) {
320 std::println (std::cerr,
"could not dcast {} to a StringArrayProperty (which it should be!)",
324 std::vector<std::string>::const_iterator itr;
325 for ( itr = sap->value().begin();
326 itr != sap->value().end();
337 if (prop.name() ==
"countInactive") {
339 BooleanProperty *p =
dynamic_cast<BooleanProperty*
>(&prop);
341 MsgStream::enableCountInactive(p->value());
352#define PR(FMT, ...) std::println(os, FMT __VA_OPT__(,) __VA_ARGS__)
355 std::ostringstream os;
358 PR (
"Summarizing all message counts");
360 PR (
"Listing sources of suppressed message: ");
363 PR (
"=====================================================");
364 PR (
" Message Source | Level | Count");
365 PR (
"-----------------------------+---------+-------------");
371 std::map<std::string,MsgAry>::const_iterator itr;
373 for (
unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
376 PR (
" {:<28}|{:>8}|{:>9}",
377 itr->first,
levelNames[ic], itr->second.msg[ic]);
383 PR (
"=====================================================");
394 std::ostringstream os;
395 PR (
"Listing sources of Unprotected and Unseen messages");
400 std::map<std::string,MsgAry>::const_iterator itr;
402 for (
unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
403 if (itr->second.msg[ic] != 0) {
404 if (itr->first.length() > ml) { ml = itr->first.length(); }
409 for (
unsigned int i=0; i<ml+25; ++i) {
414 PR(
" {:<{}}| Level | Count",
"MessageSource", ml+2);
416 for (
unsigned int i=0; i<ml+3; ++i) {
419 PR (
"+---------+-----------");
423 for (
unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
424 if (itr->second.msg[ic] != 0) {
425 PR (
" {:<{}}|{:>8}|{:>9}",
426 itr->first, ml+2,
levelNames[ic], itr->second.msg[ic]);
431 for (
unsigned int i=0; i<ml+25; ++i) {
443 return StatusCode::SUCCESS;
448 ColorMap::const_iterator itr =
m_colMap.find(col);
451 icol = offset + itr->second;
455 return std::to_string (icol);
469 int key =
msg.getType();
479 if (
msg.getSource() !=
"AthenaSummarySvc") {
480 for (vector<string>::const_iterator itr=
m_keywords.value().begin(); itr!=
m_keywords.value().end(); ++itr) {
481 if (
msg.getMessage().find( *itr ) != string::npos) {
489 const Message *cmsg = &
msg;
490 std::unique_ptr<Message> suppressed_msg;
496 (*iLog->second) << *cmsg << std::endl;
502 std::map<std::string,MsgAry>::iterator itr =
505 itr->second.msg[key] += 1;
506 nmsg = itr->second.msg[key];
509 for (
int i=0; i<MSG::NUM_LEVELS; ++i) {
523 str +=
") reached for ";
524 str +=
msg.getSource() +
". Suppressing further output.";
525 suppressed_msg = std::make_unique<Message>(
msg.getSource(),MSG::WARNING,
str);
526 suppressed_msg->setFormat(
msg.getFormat());
527 cmsg = suppressed_msg.get();
536 StreamMap::const_iterator first =
m_streamMap.lower_bound( key );
538 StreamMap::const_iterator last =
m_streamMap.upper_bound( key );
539 while( first != last ) {
540 std::ostream& stream = *( (*first).second.second );
541 stream << *cmsg << std::endl;
549 (*m_defaultStream) << *cmsg << std::endl << std::flush;
552 << std::endl << std::flush;
575 std::string message) {
576 Message
msg( std::move(source),
type, std::move(message));
588 std::string_view source)
592 MessageMap::const_iterator first =
m_messageMap.lower_bound( key );
594 MessageMap::const_iterator last =
m_messageMap.upper_bound( key );
595 while( first != last ) {
596 Message
msg = (*first).second;
597 msg.setSource( source );
598 std::ostringstream os1;
599 os1 <<
"Status Code " << key.getCode() << std::ends;
600 Message stat_code1( std::string{source},
msg.getType(), os1.str() );
608 mesg.setSource( source );
609 std::ostringstream os2;
610 os2 <<
"Status Code " << key.getCode() << std::ends;
611 Message stat_code2( std::string{source}, mesg.getType(), os2.str() );
626 std::ostream *stream)
628 typedef StreamMap::value_type value_type;
664 if (
nullptr != stream ) {
668 StreamMap::iterator first =
m_streamMap.lower_bound( key );
669 StreamMap::iterator last =
m_streamMap.upper_bound( key );
670 while( first != last ) {
671 if ( (*first).second.second == stream ) {
689 if (
nullptr != stream ) {
695 if ( (*first).second.second == stream ) {
762 MessageMap::iterator first =
m_messageMap.lower_bound( key );
763 MessageMap::iterator last =
m_messageMap.upper_bound( key );
764 while( first != last ) {
765 const Message& message = (*first).second;
766 if ( message ==
msg ) {
778 return m_outputLevel;
786 return it !=
m_thresholdMap.end() ? it->second : m_outputLevel.value();
792 m_outputLevel = new_level;
804 }
else if ( i->second != level ) {
813 if (logLevel < MSG::NUM_LEVELS) {
835 ++entry->second.msg[level];
849 typedef std::map<std::string,std::string> StreamMap_t;
851 typedef StreamMap_t::const_iterator StreamMapIter;
853 for ( StreamMapIter iProp = streamMap.begin(), iEnd = streamMap.end();
857 const std::string sourceName = iProp->first;
858 const std::string outFileName = iProp->second;
860 std::set<std::string> outFileNames;
861 for ( StreamMapIter jProp = streamMap.begin();
864 if ( jProp->first != iProp->first ) {
865 outFileNames.insert( jProp->second );
869 tee( sourceName, outFileName, outFileNames );
878 const std::string& outFileName,
879 const std::set<std::string>& outFileNames )
881 const std::ios_base::openmode openMode = std::ios_base::out |
882 std::ios_base::trunc;
885 LoggedStreamsMap_t::iterator iStream =
m_loggedStreams.find( sourceName );
886 if ( iStream != iEnd ) {
887 delete iStream->second;
888 iStream->second =
nullptr;
895 for ( iStream =
m_loggedStreams.begin(); iStream != iEnd; ++iStream ) {
896 if ( outFileNames.find( outFileName ) != outFileNames.end() ) {
902 std::ofstream * out =
new std::ofstream( outFileName.c_str(), openMode );
904 if ( !out->good() ) {
922std::vector< std::pair<std::string, std::string> >
931 ->
std::vector< LoggedMessage >
static constexpr std::string levelNames[MSG::NUM_LEVELS]
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
size_t size() const
Number of registered mappings.
#define ATLAS_THREAD_SAFE
MessageMap m_messageMap
Message map.
void initColors(Gaudi::Details::PropertyBase &prop)
virtual void insertStream(int message_type, std::string name, std::ostream *stream) override
virtual int messageCount(MSG::Level logLevel) const override
LoggedStreamsMap_t m_loggedStreams
void setupLimits(Gaudi::Details::PropertyBase &prop)
virtual void eraseStream() override
LoggedMessageSvc(const std::string &name, ISvcLocator *svcloc)
StreamMap m_streamMap
Stream map.
void setupColors(Gaudi::Details::PropertyBase &prop)
UnsignedIntegerProperty m_statLevel
void tee(const std::string &sourceName, const std::string &logFileName, const std::set< std::string > &declaredOutFileNames)
virtual StatusCode initialize() override
Initialize Service.
std::mutex m_reportMutex
Mutex to synchronize multiple threads printing.
virtual void setOutputLevel(int new_level) override
std::vector< LoggedMessage > m_msgKeyLog
std::pair< std::string, std::ostream * > NamedStream
virtual std::string getLogColor(int logLevel) const override
IntegerProperty m_msgLimit[MSG::NUM_LEVELS]
virtual StatusCode reinitialize() override
Reinitialize Service.
std::vector< std::pair< std::string, std::string > > m_msgLog[MSG::NUM_LEVELS]
std::map< std::string, MsgAry, std::less<> > m_sourceMap
BooleanProperty m_inactCount
Message m_defaultMessage
Default Message.
virtual StatusCode finalize() override
Finalize Service.
ThresholdMap m_thresholdMap
Output level threshold map.
virtual std::vector< std::pair< std::string, std::string > > getMessages(MSG::Level level) const override
std::mutex m_thresholdMapMutex
Mutex to synchronize multiple access to m_thresholdMap (.
virtual ~LoggedMessageSvc()
int m_msgCount[MSG::NUM_LEVELS]
StringArrayProperty m_thresholdProp[MSG::NUM_LEVELS]
Properties controling.
std::string m_defaultTimeFormat
Default format for timestamps in the messages.
virtual void reportMessage(const Message &message) override
StringArrayProperty m_logColors[MSG::NUM_LEVELS]
std::string colTrans(const std::string &, int)
std::map< std::string, MsgAry, std::less<> > m_inactiveMap
virtual void insertMessage(const StatusCode &code, Message message) override
virtual int outputLevel() const override
std::ostream * m_defaultStream
Pointer to the output stream.
std::map< std::string, std::string > m_loggedStreamsName
IntegerProperty m_logLevel
void setupThreshold(Gaudi::Details::PropertyBase &prop)
void setupInactCount(Gaudi::Details::PropertyBase &prop)
virtual std::vector< LoggedMessage > getKeyMessages() const override
std::string m_logColorCodes[MSG::NUM_LEVELS]
std::string m_defaultFormat
Default format for the messages.
StringArrayProperty m_keywords
virtual void incrInactiveCount(MSG::Level level, std::string_view src) override
BooleanProperty m_suppress
std::recursive_mutex m_messageMapMutex
Mutex to synchronize multiple access to m_messageMap.
virtual void eraseMessage() override
hold the test vectors and ease the comparison
Private helper class to keep the count of messages of a type (MSG::LEVEL).