30 template <
typename Container,
typename Iterator,
typename Predicate>
31 void erase_if( Container& c,
Iterator first,
Iterator last, Predicate pred ) {
32 while ( first != last ) {
34 first =
c.erase( first );
40 template <
typename Container,
typename Iterator,
typename Predicate>
41 void erase_if( Container& c, std::pair<Iterator, Iterator> range, Predicate pred ) {
42 return erase_if( c, std::move(
range.first ), std::move(
range.second ), std::forward<Predicate>( pred ) );
45 std::string colTrans( std::string_view col,
int offset ) {
55 return std::to_string( icol + offset );
61static const std::string levelNames[
MSG::NUM_LEVELS] = {
"NIL",
"VERBOSE",
"DEBUG",
"INFO",
62 "WARNING",
"ERROR",
"FATAL",
"ALWAYS" };
68 if ( app ) app->outputLevelUpdate();
108 const auto& pname = prop.
name();
116 : pname ==
"alwaysColorCode"
125 if ( col_desc.size() == 1 ) {
126 const std::string& desc = col_desc[0];
127 if ( desc.empty() ) {
129 }
else if ( desc[0] ==
'[' ) {
130 code =
"\033" + desc;
132 code =
"\033[" + colTrans( desc, 90 ) +
";1m";
134 }
else if ( col_desc.size() == 2 ) {
135 code =
"\033[" + colTrans( col_desc[0], 90 ) +
";" + colTrans( col_desc[1], 100 ) +
";1m";
143 if ( prop.
name() ==
"alwaysLimit" ) {
145 if ( p && p->
value() != 0 ) {
146 std::cout <<
"MessageSvc ERROR: cannot suppress ALWAYS messages" << std::endl;
149 }
else if ( prop.
name() ==
"defaultLimit" ) {
153 }
else if ( prop.
name() !=
"fatalLimit" && prop.
name() !=
"errorLimit" && prop.
name() !=
"warningLimit" &&
154 prop.
name() ==
"infoLimit" && prop.
name() ==
"debugLimit" && prop.
name() ==
"verboseLimit" ) {
155 std::cout <<
"MessageSvc ERROR: Unknown message limit parameter: " << prop.
name() << std::endl;
162 static const std::array<std::pair<const char*, MSG::Level>, 7> tbl{ { {
"setFatal",
MSG::FATAL },
170 auto i = std::find_if( std::begin( tbl ), std::end( tbl ),
171 [&](
const std::pair<const char*, MSG::Level>& t ) {
return prop.
name() == t.first; } );
172 if ( i == std::end( tbl ) ) {
173 std::cerr <<
"MessageSvc ERROR: Unknown message threshold parameter: " << prop.
name() << std::endl;
180 std::cerr <<
"could not dcast " << prop.
name()
181 <<
" to a Gaudi::Property<std::vector<std::string>> (which it should be!)" << std::endl;
191 if ( prop.
name() ==
"countInactive" ) {
202 std::ostringstream os;
205 os <<
"Summarizing all message counts" << std::endl;
207 os <<
"Listing sources of suppressed message: " << std::endl;
210 os <<
"=====================================================" << std::endl;
211 os <<
" Message Source | Level | Count" << std::endl;
212 os <<
"-----------------------------+---------+-------------" << std::endl;
222 os.setf( std::ios_base::left, std::ios_base::adjustfield );
227 os.setf( std::ios_base::right, std::ios_base::adjustfield );
228 os << levelNames[ic];
232 os << itr->second.msg[ic];
239 os <<
"=====================================================" << std::endl;
240 if ( found ||
m_stats ) std::cout << os.str() << std::flush;
246 std::ostringstream os;
247 os <<
"Listing sources of Unprotected and Unseen messages\n";
251 unsigned int ml( 0 );
254 if ( itr.second.msg[ic] != 0 && itr.first.length() > ml ) { ml = itr.first.length(); }
258 for (
unsigned int i = 0; i < ml + 25; ++i ) os <<
"=";
260 os << std::endl <<
" ";
262 os.setf( std::ios_base::left, std::ios_base::adjustfield );
263 os <<
"Message Source";
265 os <<
"| Level | Count" << std::endl;
267 for (
unsigned int i = 0; i < ml + 3; ++i ) os <<
"-";
268 os <<
"+---------+-----------" << std::endl;
272 if ( itr->second.msg[ic] != 0 ) {
275 os.setf( std::ios_base::left, std::ios_base::adjustfield );
281 os.setf( std::ios_base::right, std::ios_base::adjustfield );
282 os << levelNames[ic];
287 os << itr->second.msg[ic];
295 for (
unsigned int i = 0; i < ml + 25; ++i ) os <<
"=";
298 if ( found ) std::cout << os.str() << std::flush;
311 int key =
msg.getType();
320 if (
m_loggedStreams.end() != iLog ) { ( *iLog->second ) << *cmsg << std::endl; }
332 std::string txt = levelNames[key] +
" message limit (" + std::to_string(
m_msgLimit[key].value() ) +
333 ") reached for " +
msg.getSource() +
". Suppressing further output.";
342 std::for_each( range.first, range.second,
343 [&]( StreamMap::const_reference sm ) { *sm.second.second << *cmsg << std::endl; } );
348 ( *m_defaultStream ) << *cmsg << std::endl << std::flush;
350 ( *m_defaultStream ) <<
m_logColorCodes[key] << *cmsg <<
"\033[m" << std::endl << std::flush;
354 if ( cmsg != &
msg ) {
delete cmsg; }
370 auto report = [&](
Message mesg ) {
371 mesg.setSource( source );
372 Message stat_code( std::string{ source }, mesg.getType(),
"Status Code " + std::to_string( code.
getCode() ) );
379 std::for_each( range.first, range.second, [&]( MessageMap::const_reference sm ) { report( sm.second ); } );
396 [&]( StreamMap::const_reference j ) { return j.second.second == stream; } );
402 erase_if(
m_streamMap, [&]( StreamMap::const_reference j ) {
return j.second.second == stream; } );
425 [&]( MessageMap::const_reference j ) { return j.second == msg; } );
445 }
else if ( i->second != level ) {
459 ++entry->second.msg[level];
463 std::cout <<
"== inactive message detected from " << source <<
" ==\n";
466 std::cout << t << std::endl;
475 std::set<std::string_view> outFileNames;
477 std::inserter( outFileNames, outFileNames.end() ),
478 [](
const auto& p ) -> std::string_view { return p.second; } );
480 std::map<std::string_view, std::shared_ptr<std::ofstream>> outStreams;
481 std::transform( outFileNames.begin(), outFileNames.end(), std::inserter( outStreams, outStreams.end() ),
482 []( std::string_view fname ) {
483 return std::pair{ fname, std::make_shared<std::ofstream>(
484 std::string{ fname }, std::ios_base::out | std::ios_base::trunc ) };
487 for (
auto& iProp : m_loggedStreamsName ) {
488 auto& stream = outStreams.at( iProp.second );
489 if ( stream->good() ) m_loggedStreams.emplace( iProp.first, stream );
boost::spirit::classic::position_iterator2< ForwardIterator > Iterator
#define DECLARE_COMPONENT(type)
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
const std::string name() const
property name
Implementation of property with value of concrete type.
const ValueType & value() const
bool setValue(const ValueType &v)
Define general base for Gaudi exception.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
void setFormat(std::string msg) const
Set the format string.
Gaudi::Property< bool > m_color
void reportMessage(const Message &message) override
Gaudi::Property< std::string > m_defaultTimeFormat
std::recursive_mutex m_messageMapMutex
Mutex to synchronize multiple access to m_messageMap.
Message m_defaultMessage
Default Message.
MessageMap m_messageMap
Message map.
StatusCode reinitialize() override
StreamMap m_streamMap
Stream map.
std::map< std::string, MsgAry, std::less<> > m_sourceMap
ThresholdMap m_thresholdMap
Output level threshold map.
Gaudi::Property< bool > m_inactCount
std::map< std::string, std::shared_ptr< std::ostream >, std::less<> > m_loggedStreams
std::array< Gaudi::Property< int >, MSG::NUM_LEVELS > m_msgLimit
void setupInactCount(Gaudi::Details::PropertyBase &prop)
void setupThreshold(Gaudi::Details::PropertyBase &prop)
std::map< std::string, MsgAry, std::less<> > m_inactiveMap
std::array< int, MSG::NUM_LEVELS > m_msgCount
std::array< Gaudi::Property< std::vector< std::string > >, MSG::NUM_LEVELS > m_logColors
int outputLevel() const override
int messageCount(MSG::Level logLevel) const override
void setOutputLevel(int new_level) override
virtual void i_reportMessage(const Message &msg, int outputLevel)
Internal implementation of reportMessage(const Message&,int) without lock.
StatusCode initialize() override
void eraseStream() override
std::array< Gaudi::Property< std::vector< std::string > >, MSG::NUM_LEVELS > m_thresholdProp
void eraseMessage() override
void setupLimits(Gaudi::Details::PropertyBase &prop)
StatusCode finalize() override
Gaudi::Property< std::vector< std::string > > m_tracedInactiveSources
std::string getLogColor(int logLevel) const override
Gaudi::Property< unsigned int > m_statLevel
Gaudi::Property< bool > m_suppress
std::recursive_mutex m_thresholdMapMutex
Mutex to synchronize multiple access to m_thresholdMap (.
void setupColors(Gaudi::Details::PropertyBase &prop)
Gaudi::Property< bool > m_stats
std::recursive_mutex m_reportMutex
Mutex to synchronize multiple threads printing.
Gaudi::Property< std::string > m_defaultFormat
Gaudi::Property< std::map< std::string, std::string, std::less<> > > m_loggedStreamsName
std::pair< std::string, std::ostream * > NamedStream
void insertMessage(const StatusCode &code, Message message) override
void insertStream(int message_type, std::string name, std::ostream *stream) override
MessageSvc(const std::string &name, ISvcLocator *svcloc)
void incrInactiveCount(MSG::Level level, std::string_view src) override
std::string m_logColorCodes[MSG::NUM_LEVELS]
static GAUDI_API bool enableCountInactive(bool value=true)
Enable/disable the count of inactive messages.
Gaudi::Property< int > m_outputLevel
flag indicating whether ToolHandle tools have been added to m_tools
const std::string & name() const override
Retrieve name of the service.
Gaudi::StateMachine::State m_state
Service state.
StatusCode initialize() override
Small smart pointer class with automatic reference counting for IInterface.
This class is used for returning status codes from appropriate routines.
constexpr static const auto SUCCESS
constexpr static const auto FAILURE
code_t getCode() const
Retrieve value.
decltype(auto) range(Args &&... args)
Zips multiple containers together to form a single range.
GAUDI_API int backTrace(void **addresses, const int depth)
Private helper class to keep the count of messages of a type (MSG::LEVEL).