7 #include "GaudiKernel/Kernel.h"
8 #include "GaudiKernel/StatusCode.h"
9 #include "GaudiKernel/Message.h"
25 template <
typename Container,
typename Iterator,
typename Predicate >
27 while ( first!=last ) {
28 if ( pred(*first) ) first = c.erase(first);
33 template<
typename Container,
typename Predicate >
34 void erase_if( Container& c, Predicate pred ) {
36 std::forward<Predicate>(pred) );
39 template<
typename Container,
typename Iterator,
typename Predicate >
40 void erase_if( Container& c, std::pair<Iterator,Iterator>
range, Predicate pred ) {
41 return erase_if(c, std::move(range.first), std::move(range.second),
42 std::forward<Predicate>(pred) );
54 "NIL",
"VERBOSE",
"DEBUG",
"INFO",
55 "WARNING",
"ERROR",
"FATAL",
"ALWAYS"
64 declareProperty(
"showStats",
m_stats =
false );
78 declareProperty(
"fatalColorCode",
m_logColors[MSG::FATAL] );
79 declareProperty(
"errorColorCode",
m_logColors[MSG::ERROR] );
80 declareProperty(
"warningColorCode",
m_logColors[MSG::WARNING] );
81 declareProperty(
"infoColorCode",
m_logColors[MSG::INFO] );
82 declareProperty(
"debugColorCode",
m_logColors[MSG::DEBUG] );
83 declareProperty(
"verboseColorCode",
m_logColors[MSG::VERBOSE] );
84 declareProperty(
"alwaysColorCode",
m_logColors[MSG::ALWAYS] );
86 const int defaultLimit = 500;
87 declareProperty(
"fatalLimit",
m_msgLimit[MSG::FATAL] = defaultLimit );
88 declareProperty(
"errorLimit",
m_msgLimit[MSG::ERROR] = defaultLimit );
89 declareProperty(
"warningLimit",
m_msgLimit[MSG::WARNING] = defaultLimit );
90 declareProperty(
"infoLimit",
m_msgLimit[MSG::INFO] = defaultLimit );
91 declareProperty(
"debugLimit",
m_msgLimit[MSG::DEBUG] = defaultLimit );
92 declareProperty(
"verboseLimit",
m_msgLimit[MSG::VERBOSE] = defaultLimit );
93 declareProperty(
"alwaysLimit",
m_msgLimit[MSG::ALWAYS] = 0 );
97 declareProperty(
"enableSuppression",
m_suppress =
false );
104 declareProperty(
"loggedStreams",
106 "MessageStream sources we want to dump into a logfile" );
130 sc = setProperties();
170 static const std::array<std::pair<MSG::Level,std::vector<std::string>>,3> tbl{
175 for (
const auto& p : tbl ) {
177 if (lC.value().empty()) {
201 static const std::array<std::pair<const char*,MSG::Level>,7> tbl {
211 [&](
const std::pair<const char*,MSG::Level>& t) {
212 return prop.
name() == t.first;
215 cout <<
"ERROR: Unknown message color parameter: " << prop.
name()
228 }
else if (itr->compare(0,1,
"[") == 0) {
229 code =
"\033" + *itr;
231 code =
"\033[" +
colTrans(*itr, 90) +
";1m";
237 code =
"\033[" +
colTrans(*itr, 90) +
";"
249 if (prop.
name() ==
"alwaysLimit") {
251 if (p && p->
value() != 0) {
252 cout <<
"MessageSvc ERROR: cannot suppress ALWAYS messages" << endl;
255 }
else if (prop.
name() ==
"defaultLimit") {
261 }
else if (prop.
name() !=
"fatalLimit" &&
262 prop.
name() !=
"errorLimit" &&
263 prop.
name() !=
"warningLimit" &&
264 prop.
name() ==
"infoLimit" &&
265 prop.
name() ==
"debugLimit" &&
266 prop.
name() ==
"verboseLimit") {
267 cout <<
"MessageSvc ERROR: Unknown message limit parameter: "
268 << prop.
name() << endl;
276 static const std::array<std::pair<const char*,MSG::Level>,7> tbl{
286 [&](
const std::pair<const char*,MSG::Level>& t) {
287 return prop.
name() == t.first;
290 cerr <<
"MessageSvc ERROR: Unknown message threshold parameter: "
291 << prop.
name() << endl;
298 std::cerr <<
"could not dcast " << prop.
name()
299 <<
" to a StringArrayProperty (which it should be!)" << endl;
312 if (prop.
name() ==
"countInactive") {
328 std::ostringstream os;
331 os <<
"Summarizing all message counts" << endl;
333 os <<
"Listing sources of suppressed message: " << endl;
336 os <<
"=====================================================" << endl;
337 os <<
" Message Source | Level | Count" << endl;
338 os <<
"-----------------------------+---------+-------------" << endl;
349 os.setf(ios_base::left,ios_base::adjustfield);
354 os.setf(ios_base::right,ios_base::adjustfield);
355 os << levelNames[ic];
359 os << itr->second.msg[ic];
366 os <<
"=====================================================" << endl;
367 if (found ||
m_stats) cout << os.str();
373 std::ostringstream os;
374 os <<
"Listing sources of Unprotected and Unseen messages\n";
381 if (itr.second.msg[ic] != 0 && itr.first.length() > ml) {
382 ml = itr.first.length();
387 for (
unsigned int i=0;
i<ml+25; ++
i) os <<
"=";
389 os << std::endl <<
" ";
391 os.setf(ios_base::left,ios_base::adjustfield);
392 os <<
"Message Source";
394 os <<
"| Level | Count" << endl;
396 for (
unsigned int i=0;
i<ml+3; ++
i) os <<
"-";
397 os <<
"+---------+-----------" << endl;
400 for (
auto itr=m_inactiveMap.begin(); itr!=m_inactiveMap.end(); ++itr) {
402 if (itr->second.msg[ic] != 0) {
405 os.setf(ios_base::left,ios_base::adjustfield);
411 os.setf(ios_base::right,ios_base::adjustfield);
412 os << levelNames[ic];
417 os << itr->second.msg[ic];
425 for (
unsigned int i=0;
i<ml+25; ++
i) os <<
"=";
428 if (found) cout << os.str();
438 int icol = offset + ( (itr !=
m_colMap.end()) ? itr->second : 8 );
439 return std::to_string( icol );
462 (*iLog->second) << *cmsg << std::endl;
475 std::string txt = levelNames[key] +
" message limit ("
477 +
") reached for " + msg.
getSource() +
". Suppressing further output.";
486 std::for_each(
range.first,
range.second, [&](StreamMap::const_reference sm) {
487 *sm.second.second << *cmsg << std::endl;
489 }
else if ( key >= outputLevel ) {
493 (*m_defaultStream) << *cmsg << std::endl << std::flush;
496 << std::endl << std::flush;
500 if (cmsg != &msg) {
delete cmsg; }
522 const char* message) {
534 const std::string& message) {
546 const std::string& source)
550 auto report = [&](
Message mesg) {
551 mesg.setSource( source );
552 Message stat_code( source, mesg.getType(),
"Status Code " + std::to_string( key.
getCode() ) );
560 [&](MessageMap::const_reference sm) { report(sm.second); } );
574 const std::string&
name,
575 std::ostream *stream)
614 [&](StreamMap::const_reference j)
615 {
return j.second.second == stream; } );
628 erase_if(
m_streamMap, [&](StreamMap::const_reference j)
629 {
return j.second.second == stream; } );
684 [&](MessageMap::const_reference j) {
return j.second==
msg; } ) ;
690 return m_outputLevel;
698 return ( it !=
m_thresholdMap.end() ) ? it->second : m_outputLevel.value();
704 m_outputLevel = new_level;
744 std::set<std::string> outFileNames;
745 for (
auto& jProp : m_loggedStreamsName ) {
746 if ( jProp.first != iProp.first ) {
747 outFileNames.insert( jProp.second );
750 tee( iProp.first, iProp.second, outFileNames );
757 const std::string& outFileName,
758 const std::set<std::string>& outFileNames )
760 const std::ios_base::openmode openMode = std::ios_base::out |
761 std::ios_base::trunc;
771 if ( outFileNames.find( outFileName ) != outFileNames.end() ) {
772 m_loggedStreams[sourceName] = m_loggedStreams[iStream.first];
777 auto out = std::make_shared<std::ofstream>( outFileName, openMode );
778 if ( out->good() ) m_loggedStreams[sourceName] = std::move(out);
IntegerProperty m_msgLimit[MSG::NUM_LEVELS]
const std::string & getFormat() const
Get the format string.
std::string colTrans(std::string, int)
StatusCode initialize() override
GAUDI_API void fill(AIDA::IHistogram1D *histo, const double value, const double weight=1.0)
simple function to fill AIDA::IHistogram1D objects
std::ostream * m_defaultStream
Pointer to the output stream.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
StreamMap m_streamMap
Stream map.
std::array< int, MSG::NUM_LEVELS > m_msgCount
unsigned long getCode() const
Get the status code by value.
const std::string & name() const
property name
auto begin(reverse_wrapper< T > &w)
Message m_defaultMessage
Default Message.
MessageMap m_messageMap
Message map.
void setupLimits(Property &prop)
void setupInactCount(Property &prop)
bool setValue(const TYPE &value) override
implementation of PropertyWithValue::setValue
MessageSvc(const std::string &name, ISvcLocator *svcloc)
bool set(const TYPE &value)
update the value of the property/check the verifier
std::recursive_mutex m_messageMapMutex
Mutex to synchronize multiple access to m_messageMap.
int getType() const
Get the message type.
StatusCode reinitialize() override
Reinitialize Service.
std::pair< std::string, std::ostream * > NamedStream
void eraseMessage() override
bool isFailure() const
Test for a status code of FAILURE.
UnsignedIntegerProperty m_statLevel
void eraseStream() override
void incrInactiveCount(MSG::Level level, const std::string &src) override
std::map< std::string, std::shared_ptr< std::ostream > > m_loggedStreams
std::map< std::string, MsgAry > m_sourceMap
std::string getLogColor(int logLevel) const override
void setOutputLevel(int new_level) override
StatusCode initialize() override
Initialize Service.
NamedRange_< CONTAINER > range(const CONTAINER &cnt, std::string name)
simple function to create the named range form arbitrary container
ThresholdMap m_thresholdMap
Output level threshold map.
#define DECLARE_COMPONENT(type)
static const std::string getDefaultTimeFormat()
Get the default time format string.
auto end(reverse_wrapper< T > &w)
This class is used for returning status codes from appropriate routines.
static const std::string getDefaultFormat()
Get the default format string.
void reportMessage(const Message &message) override
std::recursive_mutex m_reportMutex
Mutex to synchronize multiple threads printing.
const TYPE & value() const
explicit conversion
StringArrayProperty m_thresholdProp[MSG::NUM_LEVELS]
Properties controlling.
void setFormat(std::string msg) const
Set the format string.
Property base class allowing Property* collections to be "homogeneous".
StatusCode finalize() override
Finalize Service.
boost::spirit::classic::position_iterator2< ForwardIterator > Iterator
Base class used to extend a class implementing other interfaces.
std::string m_defaultFormat
Default format for the messages.
Print levels enumeration.
void setTimeFormat(std::string timeFormat) const
Set the time format string.
void setupColors(Property &prop)
std::map< std::string, MsgAry > m_inactiveMap
virtual void declareUpdateHandler(std::function< void(Property &)> fun)
set new callback for update
void initColors(Property &prop)
std::string m_logColorCodes[MSG::NUM_LEVELS]
const std::string & getSource() const
Get the message source.
int messageCount(MSG::Level logLevel) const override
BooleanProperty m_inactCount
int outputLevel() const override
void tee(const std::string &sourceName, const std::string &logFileName, const std::set< std::string > &declaredOutFileNames)
std::map< std::string, std::string > m_loggedStreamsName
void insertMessage(const StatusCode &code, const Message &message) override
BooleanProperty m_suppress
void setupThreshold(Property &prop)
static GAUDI_API bool enableCountInactive(bool value=true)
Enable/disable the count of inactive messages.
std::string m_defaultTimeFormat
Default format for timestamps in the messages.
void insertStream(int message_type, const std::string &name, std::ostream *stream) override
StringArrayProperty m_logColors[MSG::NUM_LEVELS]
std::recursive_mutex m_thresholdMapMutex
Mutex to synchronize multiple access to m_thresholdMap (.