31 template <
typename Container,
typename Iterator,
typename Predicate>
32 void erase_if( Container& c,
Iterator first,
Iterator last, Predicate pred ) {
33 while ( first != last ) {
35 first =
c.erase( first );
41 template <
typename Container,
typename Iterator,
typename Predicate>
42 void erase_if( Container& c, std::pair<Iterator, Iterator> range, Predicate pred ) {
43 return erase_if( c, std::move(
range.first ), std::move(
range.second ), std::forward<Predicate>( pred ) );
46 std::string colTrans( std::string_view col,
int offset ) {
56 return std::to_string( icol + offset );
62static const std::string levelNames[
MSG::NUM_LEVELS] = {
"NIL",
"VERBOSE",
"DEBUG",
"INFO",
63 "WARNING",
"ERROR",
"FATAL",
"ALWAYS" };
69 if ( app ) app->outputLevelUpdate();
109 const auto& pname = prop.
name();
117 : pname ==
"alwaysColorCode"
126 if ( col_desc.size() == 1 ) {
127 const std::string& desc = col_desc[0];
128 if ( desc.empty() ) {
130 }
else if ( desc[0] ==
'[' ) {
131 code =
"\033" + desc;
133 code =
"\033[" + colTrans( desc, 90 ) +
";1m";
135 }
else if ( col_desc.size() == 2 ) {
136 code =
"\033[" + colTrans( col_desc[0], 90 ) +
";" + colTrans( col_desc[1], 100 ) +
";1m";
144 if ( prop.
name() ==
"alwaysLimit" ) {
146 if ( p && p->
value() != 0 ) {
147 std::cout <<
"MessageSvc ERROR: cannot suppress ALWAYS messages" << std::endl;
150 }
else if ( prop.
name() ==
"defaultLimit" ) {
154 }
else if ( prop.
name() !=
"fatalLimit" && prop.
name() !=
"errorLimit" && prop.
name() !=
"warningLimit" &&
155 prop.
name() ==
"infoLimit" && prop.
name() ==
"debugLimit" && prop.
name() ==
"verboseLimit" ) {
156 std::cout <<
"MessageSvc ERROR: Unknown message limit parameter: " << prop.
name() << std::endl;
163 static const std::array<std::pair<const char*, MSG::Level>, 7> tbl{ { {
"setFatal",
MSG::FATAL },
171 auto i = std::find_if( std::begin( tbl ), std::end( tbl ),
172 [&](
const std::pair<const char*, MSG::Level>& t ) {
return prop.
name() == t.first; } );
173 if ( i == std::end( tbl ) ) {
174 std::cerr <<
"MessageSvc ERROR: Unknown message threshold parameter: " << prop.
name() << std::endl;
181 std::cerr <<
"could not dcast " << prop.
name()
182 <<
" to a Gaudi::Property<std::vector<std::string>> (which it should be!)" << std::endl;
192 if ( prop.
name() ==
"countInactive" ) {
203 std::ostringstream os;
206 os <<
"Summarizing all message counts" << std::endl;
208 os <<
"Listing sources of suppressed message: " << std::endl;
211 os <<
"=====================================================" << std::endl;
212 os <<
" Message Source | Level | Count" << std::endl;
213 os <<
"-----------------------------+---------+-------------" << std::endl;
223 os.setf( std::ios_base::left, std::ios_base::adjustfield );
228 os.setf( std::ios_base::right, std::ios_base::adjustfield );
229 os << levelNames[ic];
233 os << itr->second.msg[ic];
240 os <<
"=====================================================" << std::endl;
241 if ( found ||
m_stats ) std::cout << os.str() << std::flush;
247 std::ostringstream os;
248 os <<
"Listing sources of Unprotected and Unseen messages\n";
252 unsigned int ml( 0 );
255 if ( itr.second.msg[ic] != 0 && itr.first.length() > ml ) { ml = itr.first.length(); }
259 for (
unsigned int i = 0; i < ml + 25; ++i ) os <<
"=";
261 os << std::endl <<
" ";
263 os.setf( std::ios_base::left, std::ios_base::adjustfield );
264 os <<
"Message Source";
266 os <<
"| Level | Count" << std::endl;
268 for (
unsigned int i = 0; i < ml + 3; ++i ) os <<
"-";
269 os <<
"+---------+-----------" << std::endl;
273 if ( itr->second.msg[ic] != 0 ) {
276 os.setf( std::ios_base::left, std::ios_base::adjustfield );
282 os.setf( std::ios_base::right, std::ios_base::adjustfield );
283 os << levelNames[ic];
288 os << itr->second.msg[ic];
296 for (
unsigned int i = 0; i < ml + 25; ++i ) os <<
"=";
299 if ( found ) std::cout << os.str() << std::flush;
312 int key =
msg.getType();
321 if (
m_loggedStreams.end() != iLog ) { ( *iLog->second ) << *cmsg << std::endl; }
333 std::string txt = levelNames[key] +
" message limit (" + std::to_string(
m_msgLimit[key].value() ) +
334 ") reached for " +
msg.getSource() +
". Suppressing further output.";
343 std::for_each( range.first, range.second,
344 [&]( StreamMap::const_reference sm ) { *sm.second.second << *cmsg << std::endl; } );
349 ( *m_defaultStream ) << *cmsg << std::endl << std::flush;
351 ( *m_defaultStream ) <<
m_logColorCodes[key] << *cmsg <<
"\033[m" << std::endl << std::flush;
355 if ( cmsg != &
msg ) {
delete cmsg; }
376 auto report = [&](
Message mesg ) {
377 mesg.setSource( source );
378 Message stat_code( std::string{ source }, mesg.getType(),
"Status Code " + std::to_string( code.
getCode() ) );
385 std::for_each( range.first, range.second, [&]( MessageMap::const_reference sm ) { report( sm.second ); } );
402 [&]( StreamMap::const_reference j ) { return j.second.second == stream; } );
408 erase_if(
m_streamMap, [&]( StreamMap::const_reference j ) {
return j.second.second == stream; } );
431 [&]( MessageMap::const_reference j ) { return j.second == msg; } );
451 }
else if ( i->second != level ) {
465 ++entry->second.msg[level];
469 std::cout <<
"== inactive message detected from " << source <<
" ==\n";
472 std::cout << t << std::endl;
481 std::set<std::string_view> outFileNames;
483 std::inserter( outFileNames, outFileNames.end() ),
484 [](
const auto& p ) -> std::string_view { return p.second; } );
486 std::map<std::string_view, std::shared_ptr<std::ofstream>> outStreams;
487 std::transform( outFileNames.begin(), outFileNames.end(), std::inserter( outStreams, outStreams.end() ),
488 []( std::string_view fname ) {
489 return std::pair{ fname, std::make_shared<std::ofstream>(
490 std::string{ fname }, std::ios_base::out | std::ios_base::trunc ) };
493 for (
auto& iProp : m_loggedStreamsName ) {
494 auto& stream = outStreams.at( iProp.second );
495 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::string m_defaultFormat
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
StatusCode setPropertyRepr(const std::string &n, const std::string &r) override
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::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.
StatusCode setPropertyRepr(const std::string &n, const std::string &r) override
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).