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) );
52 "NIL",
"VERBOSE",
"DEBUG",
"INFO",
53 "WARNING",
"ERROR",
"FATAL",
"ALWAYS"
62 declareProperty(
"showStats",
m_stats =
false );
76 declareProperty(
"fatalColorCode",
m_logColors[MSG::FATAL] );
77 declareProperty(
"errorColorCode",
m_logColors[MSG::ERROR] );
78 declareProperty(
"warningColorCode",
m_logColors[MSG::WARNING] );
79 declareProperty(
"infoColorCode",
m_logColors[MSG::INFO] );
80 declareProperty(
"debugColorCode",
m_logColors[MSG::DEBUG] );
81 declareProperty(
"verboseColorCode",
m_logColors[MSG::VERBOSE] );
82 declareProperty(
"alwaysColorCode",
m_logColors[MSG::ALWAYS] );
84 const int defaultLimit = 500;
85 declareProperty(
"fatalLimit",
m_msgLimit[MSG::FATAL] = defaultLimit );
86 declareProperty(
"errorLimit",
m_msgLimit[MSG::ERROR] = defaultLimit );
87 declareProperty(
"warningLimit",
m_msgLimit[MSG::WARNING] = defaultLimit );
88 declareProperty(
"infoLimit",
m_msgLimit[MSG::INFO] = defaultLimit );
89 declareProperty(
"debugLimit",
m_msgLimit[MSG::DEBUG] = defaultLimit );
90 declareProperty(
"verboseLimit",
m_msgLimit[MSG::VERBOSE] = defaultLimit );
91 declareProperty(
"alwaysLimit",
m_msgLimit[MSG::ALWAYS] = 0 );
95 declareProperty(
"enableSuppression",
m_suppress =
false );
102 declareProperty(
"loggedStreams",
104 "MessageStream sources we want to dump into a logfile" );
124 sc = setProperties();
164 static const std::array<std::pair<MSG::Level,std::vector<std::string>>,3> tbl{
169 for (
const auto& p : tbl ) {
171 if (lC.value().empty()) {
195 static const std::array<std::pair<const char*,MSG::Level>,7> tbl {
205 [&](
const std::pair<const char*,MSG::Level>& t) {
206 return prop.
name() == t.first;
209 std::cout <<
"ERROR: Unknown message color parameter: " << prop.
name()
222 }
else if (itr->compare(0,1,
"[") == 0) {
223 code =
"\033" + *itr;
225 code =
"\033[" +
colTrans(*itr, 90) +
";1m";
231 code =
"\033[" +
colTrans(*itr, 90) +
";"
243 if (prop.
name() ==
"alwaysLimit") {
245 if (p && p->
value() != 0) {
246 std::cout <<
"MessageSvc ERROR: cannot suppress ALWAYS messages" << std::endl;
249 }
else if (prop.
name() ==
"defaultLimit") {
255 }
else if (prop.
name() !=
"fatalLimit" &&
256 prop.
name() !=
"errorLimit" &&
257 prop.
name() !=
"warningLimit" &&
258 prop.
name() ==
"infoLimit" &&
259 prop.
name() ==
"debugLimit" &&
260 prop.
name() ==
"verboseLimit") {
261 std::cout <<
"MessageSvc ERROR: Unknown message limit parameter: "
262 << prop.
name() << std::endl;
270 static const std::array<std::pair<const char*,MSG::Level>,7> tbl{
280 [&](
const std::pair<const char*,MSG::Level>& t) {
281 return prop.
name() == t.first;
284 std::cerr <<
"MessageSvc ERROR: Unknown message threshold parameter: "
285 << prop.
name() << std::endl;
292 std::cerr <<
"could not dcast " << prop.
name()
293 <<
" to a StringArrayProperty (which it should be!)" << std::endl;
306 if (prop.
name() ==
"countInactive") {
322 std::ostringstream os;
325 os <<
"Summarizing all message counts" << std::endl;
327 os <<
"Listing sources of suppressed message: " << std::endl;
330 os <<
"=====================================================" << std::endl;
331 os <<
" Message Source | Level | Count" << std::endl;
332 os <<
"-----------------------------+---------+-------------" << std::endl;
343 os.setf(std::ios_base::left,std::ios_base::adjustfield);
348 os.setf(std::ios_base::right,std::ios_base::adjustfield);
349 os << levelNames[ic];
353 os << itr->second.msg[ic];
360 os <<
"=====================================================" << std::endl;
361 if (found ||
m_stats) std::cout << os.str();
367 std::ostringstream os;
368 os <<
"Listing sources of Unprotected and Unseen messages\n";
375 if (itr.second.msg[ic] != 0 && itr.first.length() > ml) {
376 ml = itr.first.length();
381 for (
unsigned int i=0;
i<ml+25; ++
i) os <<
"=";
383 os << std::endl <<
" ";
385 os.setf(std::ios_base::left,std::ios_base::adjustfield);
386 os <<
"Message Source";
388 os <<
"| Level | Count" << std::endl;
390 for (
unsigned int i=0;
i<ml+3; ++
i) os <<
"-";
391 os <<
"+---------+-----------" << std::endl;
394 for (
auto itr=m_inactiveMap.begin(); itr!=m_inactiveMap.end(); ++itr) {
396 if (itr->second.msg[ic] != 0) {
399 os.setf(std::ios_base::left,std::ios_base::adjustfield);
405 os.setf(std::ios_base::right,std::ios_base::adjustfield);
406 os << levelNames[ic];
411 os << itr->second.msg[ic];
419 for (
unsigned int i=0;
i<ml+25; ++
i) os <<
"=";
422 if (found) std::cout << os.str();
432 int icol = offset + ( (itr !=
m_colMap.end()) ? itr->second : 8 );
458 (*iLog->second) << *cmsg << std::endl;
471 std::string txt = levelNames[key] +
" message limit ("
473 +
") reached for " + msg.
getSource() +
". Suppressing further output.";
482 std::for_each(
range.first,
range.second, [&](StreamMap::const_reference sm) {
483 *sm.second.second << *cmsg << std::endl;
485 }
else if ( key >= outputLevel ) {
489 (*m_defaultStream) << *cmsg << std::endl << std::flush;
492 << std::endl << std::flush;
496 if (cmsg != &msg) {
delete cmsg; }
518 const char* message) {
530 const std::string& message) {
541 const std::string& source)
548 const std::string& source)
551 auto report = [&](
Message mesg) {
552 mesg.setSource( source );
561 [&](MessageMap::const_reference sm) { report(sm.second); } );
575 const std::string&
name,
576 std::ostream *stream)
615 [&](StreamMap::const_reference j)
616 {
return j.second.second == stream; } );
629 erase_if(
m_streamMap, [&](StreamMap::const_reference j)
630 {
return j.second.second == stream; } );
685 [&](MessageMap::const_reference j) {
return j.second==
msg; } ) ;
691 return m_outputLevel;
699 return ( it !=
m_thresholdMap.end() ) ? it->second : m_outputLevel.value();
705 m_outputLevel = new_level;
745 std::set<std::string> outFileNames;
746 for (
auto& jProp : m_loggedStreamsName ) {
747 if ( jProp.first != iProp.first ) {
748 outFileNames.insert( jProp.second );
751 tee( iProp.first, iProp.second, outFileNames );
758 const std::string& outFileName,
759 const std::set<std::string>& outFileNames )
761 const std::ios_base::openmode openMode = std::ios_base::out |
762 std::ios_base::trunc;
772 if ( outFileNames.find( outFileName ) != outFileNames.end() ) {
773 m_loggedStreams[sourceName] = m_loggedStreams[iStream.first];
778 auto out = std::make_shared<std::ofstream>( outFileName, openMode );
779 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
string to_string(const T &value)
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.
virtual Property & declareUpdateHandler(std::function< void(Property &)> fun)
set new callback for update
const std::string & name() const
property name
virtual void i_reportMessage(const Message &msg, int outputLevel)
Internal implementation of reportMessage(const Message&,int) without lock.
Message m_defaultMessage
Default Message.
auto begin(reverse_wrapper< T > &w)
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.
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.
#define DECLARE_COMPONENT(type)
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
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 (.