6#include "GaudiKernel/Kernel.h"
7#include "GaudiKernel/StatusCode.h"
8#include "GaudiKernel/Message.h"
19static const std::string
levelNames[MSG::NUM_LEVELS] = {
"NIL",
"VERBOSE",
"DEBUG",
"INFO",
20 "WARNING",
"ERROR",
"FATAL",
"ALWAYS"};
24 : base_class( name, svcloc ),
m_keysUsed(false)
27 m_outputLevel = MSG::INFO;
28 declareProperty(
"Format",
m_defaultFormat = Message::getDefaultFormat() );
30 declareProperty(
"showStats",
m_stats =
false );
42 declareProperty(
"useColors",
m_color=
false);
45 declareProperty(
"fatalColorCode",
m_logColors[MSG::FATAL] );
46 declareProperty(
"errorColorCode",
m_logColors[MSG::ERROR] );
47 declareProperty(
"warningColorCode",
m_logColors[MSG::WARNING] );
48 declareProperty(
"infoColorCode",
m_logColors[MSG::INFO] );
49 declareProperty(
"debugColorCode",
m_logColors[MSG::DEBUG] );
50 declareProperty(
"verboseColorCode",
m_logColors[MSG::VERBOSE] );
51 declareProperty(
"alwaysColorCode",
m_logColors[MSG::ALWAYS] );
53 const int defaultLimit = 500;
54 declareProperty(
"fatalLimit",
m_msgLimit[MSG::FATAL] = defaultLimit );
55 declareProperty(
"errorLimit",
m_msgLimit[MSG::ERROR] = defaultLimit );
56 declareProperty(
"warningLimit",
m_msgLimit[MSG::WARNING] = defaultLimit );
57 declareProperty(
"infoLimit",
m_msgLimit[MSG::INFO] = defaultLimit );
58 declareProperty(
"debugLimit",
m_msgLimit[MSG::DEBUG] = defaultLimit );
59 declareProperty(
"verboseLimit",
m_msgLimit[MSG::VERBOSE] = defaultLimit );
60 declareProperty(
"alwaysLimit",
m_msgLimit[MSG::ALWAYS] = 0 );
62 declareProperty(
"defaultLimit",
m_msgLimit[MSG::NIL] = defaultLimit );
64 declareProperty(
"enableSuppression",
m_suppress =
false );
71 declareProperty(
"loggingLevel",
m_logLevel = MSG::FATAL,
"Message level above which all messages are saved" );
74 declareProperty(
"keywords",
m_keywords,
"keywords to scan messages for and save");
77 declareProperty(
"loggedStreams",
79 "MessageStream sources we want to dump into a logfile" );
81 for (
int ic=0; ic<MSG::NUM_LEVELS; ++ic) {
87 for (
int i=0; i<MSG::NUM_LEVELS; ++i) {
100 for ( ; iStream != endStream; ++iStream ) {
101 delete iStream->second;
102 iStream->second =
nullptr;
111 sc = base_class::initialize();
112 if(
sc.isFailure() )
return sc;
115 SmartIF<IMessageSvc> &si
ATLAS_THREAD_SAFE =
const_cast<SmartIF<IMessageSvc>&
> (msgSvc());
138 return StatusCode::SUCCESS;
145 m_state = Gaudi::StateMachine::OFFLINE;
156 vector<string> fatDef;
157 fatDef.push_back(
"[94;101;1m" );
164 vector<string> errDef;
165 errDef.push_back(
"[97;101;1m" );
171 if (
m_logColors[MSG::WARNING].value().size() == 0) {
172 vector<string> warDef;
173 warDef.push_back(
"[93;1m" );
182 for (
int ic=0; ic<MSG::NUM_LEVELS; ++ic) {
198 if (prop.name() ==
"fatalColorCode") {
200 }
else if (prop.name() ==
"errorColorCode") {
202 }
else if (prop.name() ==
"warningColorCode") {
204 }
else if (prop.name() ==
"infoColorCode") {
206 }
else if (prop.name() ==
"debugColorCode") {
208 }
else if (prop.name() ==
"verboseColorCode") {
210 }
else if (prop.name() ==
"alwaysColorCode") {
213 cout <<
"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 cout <<
"LoggedMessageSvc ERROR: cannot suppress ALWAYS messages" << endl;
267 }
else if (prop.name() ==
"defaultLimit") {
268 for (
int i = MSG::VERBOSE; i< MSG::NUM_LEVELS; ++i) {
269 if (i != MSG::ALWAYS) {
274 cout <<
"LoggedMessageSvc ERROR: Unknown message limit parameter: "
275 << prop.name() << endl;
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 cerr <<
"LoggedMessageSvc ERROR: Unknown message theshold parameter: "
314 << prop.name() << endl;
318 StringArrayProperty *sap =
dynamic_cast<StringArrayProperty*
>( &prop);
319 if (sap ==
nullptr) {
320 std::cerr <<
"could not dcast " << prop.name()
321 <<
" to a StringArrayProperty (which it should be!)" << endl;
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 std::ostringstream os;
355 os <<
"Summarizing all message counts" << endl;
357 os <<
"Listing sources of suppressed message: " << endl;
360 os <<
"=====================================================" << endl;
361 os <<
" Message Source | Level | Count" << endl;
362 os <<
"-----------------------------+---------+-------------" << endl;
368 std::map<std::string,MsgAry>::const_iterator itr;
370 for (
unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
375 os.setf(ios_base::left,ios_base::adjustfield);
381 os.setf(ios_base::right,ios_base::adjustfield);
387 os << itr->second.msg[ic];
395 os <<
"=====================================================" << endl;
405 std::ostringstream os;
406 os <<
"Listing sources of Unprotected and Unseen messages\n";
411 std::map<std::string,MsgAry>::const_iterator itr;
413 for (
unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
414 if (itr->second.msg[ic] != 0) {
415 if (itr->first.length() > ml) { ml = itr->first.length(); }
420 for (
unsigned int i=0; i<ml+25; ++i) {
426 os.setf(ios_base::left,ios_base::adjustfield);
427 os <<
"Message Source";
429 os <<
"| Level | Count" << endl;
431 for (
unsigned int i=0; i<ml+3; ++i) {
434 os <<
"+---------+-----------" << endl;
438 for (
unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
439 if (itr->second.msg[ic] != 0) {
442 os.setf(ios_base::left,ios_base::adjustfield);
448 os.setf(ios_base::right,ios_base::adjustfield);
454 os << itr->second.msg[ic];
462 for (
unsigned int i=0; i<ml+25; ++i) {
473 return StatusCode::SUCCESS;
478 ColorMap::const_iterator itr =
m_colMap.find(col);
481 icol = offset + itr->second;
485 std::ostringstream os1;
503 int key =
msg.getType();
513 if (
msg.getSource() !=
"AthenaSummarySvc") {
514 for (vector<string>::const_iterator itr=
m_keywords.value().begin(); itr!=
m_keywords.value().end(); ++itr) {
515 if (
msg.getMessage().find( *itr ) != string::npos) {
523 const Message *cmsg = &
msg;
524 std::unique_ptr<Message> suppressed_msg;
530 (*iLog->second) << *cmsg << std::endl;
536 std::map<std::string,MsgAry>::iterator itr =
539 itr->second.msg[key] += 1;
540 nmsg = itr->second.msg[key];
543 for (
int i=0; i<MSG::NUM_LEVELS; ++i) {
557 str +=
") reached for ";
558 str +=
msg.getSource() +
". Suppressing further output.";
559 suppressed_msg = std::make_unique<Message>(
msg.getSource(),MSG::WARNING,
str);
560 suppressed_msg->setFormat(
msg.getFormat());
561 cmsg = suppressed_msg.get();
570 StreamMap::const_iterator first =
m_streamMap.lower_bound( key );
572 StreamMap::const_iterator last =
m_streamMap.upper_bound( key );
573 while( first != last ) {
574 std::ostream& stream = *( (*first).second.second );
575 stream << *cmsg << std::endl;
583 (*m_defaultStream) << *cmsg << std::endl << std::flush;
586 << std::endl << std::flush;
609 std::string message) {
610 Message
msg( std::move(source),
type, std::move(message));
622 std::string_view source)
626 MessageMap::const_iterator first =
m_messageMap.lower_bound( key );
628 MessageMap::const_iterator last =
m_messageMap.upper_bound( key );
629 while( first != last ) {
630 Message
msg = (*first).second;
631 msg.setSource( source );
632 std::ostringstream os1;
633 os1 <<
"Status Code " << key.getCode() << std::ends;
634 Message stat_code1( std::string{source},
msg.getType(), os1.str() );
642 mesg.setSource( source );
643 std::ostringstream os2;
644 os2 <<
"Status Code " << key.getCode() << std::ends;
645 Message stat_code2( std::string{source}, mesg.getType(), os2.str() );
660 std::ostream *stream)
662 typedef StreamMap::value_type value_type;
698 if (
nullptr != stream ) {
702 StreamMap::iterator first =
m_streamMap.lower_bound( key );
703 StreamMap::iterator last =
m_streamMap.upper_bound( key );
704 while( first != last ) {
705 if ( (*first).second.second == stream ) {
723 if (
nullptr != stream ) {
729 if ( (*first).second.second == stream ) {
796 MessageMap::iterator first =
m_messageMap.lower_bound( key );
797 MessageMap::iterator last =
m_messageMap.upper_bound( key );
798 while( first != last ) {
799 const Message& message = (*first).second;
800 if ( message ==
msg ) {
812 return m_outputLevel;
820 return it !=
m_thresholdMap.end() ? it->second : m_outputLevel.value();
826 m_outputLevel = new_level;
838 }
else if ( i->second != level ) {
847 if (logLevel < MSG::NUM_LEVELS) {
869 ++entry->second.msg[level];
883 typedef std::map<std::string,std::string> StreamMap_t;
885 typedef StreamMap_t::const_iterator StreamMapIter;
887 for ( StreamMapIter iProp = streamMap.begin(), iEnd = streamMap.end();
891 const std::string sourceName = iProp->first;
892 const std::string outFileName = iProp->second;
894 std::set<std::string> outFileNames;
895 for ( StreamMapIter jProp = streamMap.begin();
898 if ( jProp->first != iProp->first ) {
899 outFileNames.insert( jProp->second );
903 tee( sourceName, outFileName, outFileNames );
912 const std::string& outFileName,
913 const std::set<std::string>& outFileNames )
915 const std::ios_base::openmode openMode = std::ios_base::out |
916 std::ios_base::trunc;
919 LoggedStreamsMap_t::iterator iStream =
m_loggedStreams.find( sourceName );
920 if ( iStream != iEnd ) {
921 delete iStream->second;
922 iStream->second =
nullptr;
929 for ( iStream =
m_loggedStreams.begin(); iStream != iEnd; ++iStream ) {
930 if ( outFileNames.find( outFileName ) != outFileNames.end() ) {
936 std::ofstream * out =
new std::ofstream( outFileName.c_str(), openMode );
938 if ( !out->good() ) {
956std::vector< std::pair<std::string, std::string> >
965 ->
std::vector< LoggedMessage >
static const std::string levelNames[MSG::NUM_LEVELS]
#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).