00001 #ifdef _WIN32
00002
00003 #define NOMSG
00004 #define NOGDI
00005 #endif
00006
00007 #include "GaudiKernel/Kernel.h"
00008 #include "GaudiKernel/StatusCode.h"
00009 #include "GaudiKernel/SvcFactory.h"
00010 #include "GaudiKernel/Message.h"
00011 #include "GaudiKernel/xtoa.h"
00012 #include "MessageSvc.h"
00013
00014 #include <sstream>
00015 #include <iostream>
00016 #include <fstream>
00017
00018 using namespace std;
00019
00020
00021
00022 DECLARE_SERVICE_FACTORY(MessageSvc)
00023
00024 static std::string levelNames[MSG::NUM_LEVELS];
00025
00026
00027 MessageSvc::MessageSvc( const std::string& name, ISvcLocator* svcloc )
00028 : base_class( name, svcloc ) {
00029 m_defaultStream = &std::cout;
00030 m_outputLevel = MSG::NIL;
00031 declareProperty( "Format", m_defaultFormat = Message::getDefaultFormat() );
00032 declareProperty( "timeFormat", m_defaultTimeFormat = Message::getDefaultTimeFormat() );
00033 declareProperty( "showStats", m_stats = false );
00034 declareProperty( "statLevel", m_statLevel = 0 );
00035
00036
00037 declareProperty( "setVerbose", m_thresholdProp[MSG::VERBOSE] );
00038 declareProperty( "setDebug", m_thresholdProp[MSG::DEBUG] );
00039 declareProperty( "setInfo", m_thresholdProp[MSG::INFO] );
00040 declareProperty( "setWarning", m_thresholdProp[MSG::WARNING] );
00041 declareProperty( "setError", m_thresholdProp[MSG::ERROR] );
00042 declareProperty( "setFatal", m_thresholdProp[MSG::FATAL] );
00043 declareProperty( "setAlways", m_thresholdProp[MSG::ALWAYS] );
00044
00045 declareProperty( "useColors", m_color=false);
00046 m_color.declareUpdateHandler(&MessageSvc::initColors, this);
00047
00048 declareProperty( "fatalColorCode", m_logColors[MSG::FATAL] );
00049 declareProperty( "errorColorCode", m_logColors[MSG::ERROR] );
00050 declareProperty( "warningColorCode", m_logColors[MSG::WARNING] );
00051 declareProperty( "infoColorCode", m_logColors[MSG::INFO] );
00052 declareProperty( "debugColorCode", m_logColors[MSG::DEBUG] );
00053 declareProperty( "verboseColorCode", m_logColors[MSG::VERBOSE] );
00054 declareProperty( "alwaysColorCode", m_logColors[MSG::ALWAYS] );
00055
00056 const int defaultLimit = 500;
00057 declareProperty( "fatalLimit", m_msgLimit[MSG::FATAL] = defaultLimit );
00058 declareProperty( "errorLimit", m_msgLimit[MSG::ERROR] = defaultLimit );
00059 declareProperty( "warningLimit", m_msgLimit[MSG::WARNING] = defaultLimit );
00060 declareProperty( "infoLimit", m_msgLimit[MSG::INFO] = defaultLimit );
00061 declareProperty( "debugLimit", m_msgLimit[MSG::DEBUG] = defaultLimit );
00062 declareProperty( "verboseLimit", m_msgLimit[MSG::VERBOSE] = defaultLimit );
00063 declareProperty( "alwaysLimit", m_msgLimit[MSG::ALWAYS] = 0 );
00064
00065 declareProperty( "defaultLimit", m_msgLimit[MSG::NIL] = defaultLimit );
00066
00067 declareProperty( "enableSuppression", m_suppress = false );
00068 declareProperty( "countInactive", m_inactCount = false )->declareUpdateHandler( &MessageSvc::setupInactCount, this );
00069 #ifndef NDEBUG
00070
00071 MsgStream::enableCountInactive(m_inactCount);
00072 #endif
00073
00074 declareProperty( "loggedStreams",
00075 m_loggedStreamsName,
00076 "MessageStream sources we want to dump into a logfile" );
00077
00078 for (int ic=0; ic<MSG::NUM_LEVELS; ++ic) {
00079 m_logColors[ic].declareUpdateHandler(&MessageSvc::setupColors, this);
00080 m_msgLimit[ic].declareUpdateHandler(&MessageSvc::setupLimits, this);
00081 m_thresholdProp[ic].declareUpdateHandler(&MessageSvc::setupThreshold, this);
00082 }
00083
00084 levelNames[0] = "NIL";
00085 levelNames[1] = "VERBOSE";
00086 levelNames[2] = "DEBUG";
00087 levelNames[3] = "INFO";
00088 levelNames[4] = "WARNING";
00089 levelNames[5] = "ERROR";
00090 levelNames[6] = "FATAL";
00091 levelNames[7] = "ALWAYS";
00092
00093 for (int i=0; i<MSG::NUM_LEVELS; ++i) {
00094 m_msgCount[i] = 0;
00095 }
00096
00097 }
00098
00099
00100
00101 MessageSvc::~MessageSvc()
00102 {
00103
00104 LoggedStreamsMap_t::iterator iStream = m_loggedStreams.begin();
00105 LoggedStreamsMap_t::iterator endStream = m_loggedStreams.end();
00106 for ( ; iStream != endStream; ++iStream ) {
00107 delete iStream->second;
00108 iStream->second = 0;
00109 }
00110 }
00111
00112
00113
00115 StatusCode MessageSvc::initialize() {
00116 StatusCode sc;
00117 sc = Service::initialize();
00118 if( sc.isFailure() ) return sc;
00119
00120
00121
00122
00123
00124 sc = setProperties();
00125 if (sc.isFailure()) return sc;
00126
00127 #ifdef _WIN32
00128 m_color = false;
00129 #endif
00130
00131 m_colMap["black"] = MSG::BLACK;
00132 m_colMap["red"] = MSG::RED;
00133 m_colMap["green"] = MSG::GREEN;
00134 m_colMap["yellow"] = MSG::YELLOW;
00135 m_colMap["blue"] = MSG::BLUE;
00136 m_colMap["purple"] = MSG::PURPLE;
00137 m_colMap["cyan"] = MSG::CYAN;
00138 m_colMap["white"] = MSG::WHITE;
00139
00140
00141 setupLogStreams();
00142
00143 return StatusCode::SUCCESS;
00144 }
00145
00146
00147
00149 StatusCode MessageSvc::reinitialize() {
00150 m_state = Gaudi::StateMachine::OFFLINE;
00151 return initialize();
00152 }
00153
00154
00155
00156 void MessageSvc::initColors(Property& ) {
00157
00158 if (m_color == true) {
00159
00160 if (m_logColors[MSG::FATAL].value().size() == 0) {
00161 vector<string> fatDef;
00162 fatDef.push_back( "[94;101;1m" );
00163 m_logColors[MSG::FATAL].set( fatDef );
00164 } else {
00165 MessageSvc::setupColors( m_logColors[MSG::FATAL] );
00166 }
00167
00168 if (m_logColors[MSG::ERROR].value().size() == 0) {
00169 vector<string> errDef;
00170 errDef.push_back( "[97;101;1m" );
00171 m_logColors[MSG::ERROR].set( errDef );
00172 } else {
00173 MessageSvc::setupColors( m_logColors[MSG::ERROR] );
00174 }
00175
00176 if (m_logColors[MSG::WARNING].value().size() == 0) {
00177 vector<string> warDef;
00178 warDef.push_back( "[93;1m" );
00179 m_logColors[MSG::WARNING].set( warDef );
00180 } else {
00181 MessageSvc::setupColors( m_logColors[MSG::WARNING] );
00182 }
00183
00184 } else {
00185
00186
00187 for (int ic=0; ic<MSG::NUM_LEVELS; ++ic) {
00188 vector<string> def;
00189 m_logColors[ic].set( def );
00190 }
00191
00192 }
00193
00194 }
00195
00196
00197
00198 void MessageSvc::setupColors(Property& prop) {
00199
00200 if (! m_color) return;
00201
00202 int ic;
00203 if (prop.name() == "fatalColorCode") {
00204 ic = MSG::FATAL;
00205 } else if (prop.name() == "errorColorCode") {
00206 ic = MSG::ERROR;
00207 } else if (prop.name() == "warningColorCode") {
00208 ic = MSG::WARNING;
00209 } else if (prop.name() == "infoColorCode") {
00210 ic = MSG::INFO;
00211 } else if (prop.name() == "debugColorCode") {
00212 ic = MSG::DEBUG;
00213 } else if (prop.name() == "verboseColorCode") {
00214 ic = MSG::VERBOSE;
00215 } else if (prop.name() == "alwaysColorCode") {
00216 ic = MSG::ALWAYS;
00217 } else {
00218 cout << "ERROR: Unknown message color parameter: " << prop.name()
00219 << endl;
00220 return;
00221 }
00222
00223 string code;
00224 vector<string>::const_iterator itr;
00225 itr = m_logColors[ic].value().begin();
00226
00227 if ( m_logColors[ic].value().size() == 1 ) {
00228
00229 if (*itr == "") {
00230 code = "";
00231 } else if (itr->substr(0,1) == "[") {
00232 code = "\033" + *itr;
00233 } else {
00234 code = "\033[" + colTrans(*itr, 90) + ";1m";
00235 }
00236
00237 } else if (m_logColors[ic].value().size() == 2) {
00238 vector<string>::const_iterator itr2 = itr + 1;
00239
00240 code = "\033[" + colTrans(*itr, 90) + ";"
00241 + colTrans(*itr2, 100) + ";1m";
00242
00243 }
00244
00245 m_logColorCodes[ic] = code;
00246
00247 }
00248
00249
00250 void MessageSvc::setupLimits(Property& prop) {
00251
00252 if (prop.name() == "alwaysLimit") {
00253 IntegerProperty *p = dynamic_cast<IntegerProperty*>(&prop);
00254 if (p && p->value() != 0) {
00255 cout << "MessageSvc ERROR: cannot suppress ALWAYS messages" << endl;
00256 p->setValue(0);
00257 }
00258 } else if (prop.name() == "defaultLimit") {
00259 for (int i = MSG::VERBOSE; i< MSG::NUM_LEVELS; ++i) {
00260 if (i != MSG::ALWAYS) {
00261 m_msgLimit[i] = m_msgLimit[MSG::NIL].value();
00262 }
00263 }
00264 } else if (prop.name() != "fatalLimit" &&
00265 prop.name() != "errorLimit" &&
00266 prop.name() != "warningLimit" &&
00267 prop.name() == "infoLimit" &&
00268 prop.name() == "debugLimit" &&
00269 prop.name() == "verboseLimit") {
00270 cout << "MessageSvc ERROR: Unknown message limit parameter: "
00271 << prop.name() << endl;
00272 return;
00273 }
00274 }
00275
00276
00277 void MessageSvc::setupThreshold(Property& prop) {
00278
00279 int ic = 0;
00280 if (prop.name() == "setFatal") {
00281 ic = MSG::FATAL;
00282 } else if (prop.name() == "setError") {
00283 ic = MSG::ERROR;
00284 } else if (prop.name() == "setWarning") {
00285 ic = MSG::WARNING;
00286 } else if (prop.name() == "setInfo") {
00287 ic = MSG::INFO;
00288 } else if (prop.name() == "setDebug") {
00289 ic = MSG::DEBUG;
00290 } else if (prop.name() == "setVerbose") {
00291 ic = MSG::VERBOSE;
00292 } else if (prop.name() == "setAlways") {
00293 ic = MSG::ALWAYS;
00294 } else {
00295 cerr << "MessageSvc ERROR: Unknown message threshold parameter: "
00296 << prop.name() << endl;
00297 return;
00298 }
00299
00300 StringArrayProperty *sap = dynamic_cast<StringArrayProperty*>( &prop);
00301 if (sap == 0) {
00302 std::cerr << "could not dcast " << prop.name()
00303 << " to a StringArrayProperty (which it should be!)" << endl;
00304 return;
00305 } else {
00306 std::vector<std::string>::const_iterator itr;
00307 for ( itr = sap->value().begin();
00308 itr != sap->value().end();
00309 ++itr) {
00310 setOutputLevel( *itr, ic );
00311 }
00312 }
00313
00314 }
00315
00316
00317
00318 #ifdef NDEBUG
00319 void MessageSvc::setupInactCount(Property&) {}
00320 #else
00321 void MessageSvc::setupInactCount(Property&prop) {
00322 if (prop.name() == "countInactive") {
00323 BooleanProperty *p = dynamic_cast<BooleanProperty*>(&prop);
00324 if (p)
00325 MsgStream::enableCountInactive(p->value());
00326 }
00327 }
00328 #endif
00329
00330
00331
00333 StatusCode MessageSvc::finalize() {
00334
00335 m_suppress = false;
00336
00337 {
00338 std::ostringstream os;
00339
00340 if (m_stats) {
00341 os << "Summarizing all message counts" << endl;
00342 } else {
00343 os << "Listing sources of suppressed message: " << endl;
00344 }
00345
00346 os << "=====================================================" << endl;
00347 os << " Message Source | Level | Count" << endl;
00348 os << "-----------------------------+---------+-------------" << endl;
00349
00350
00351 bool found(false);
00352
00353 std::map<std::string,MsgAry>::const_iterator itr;
00354 for (itr=m_sourceMap.begin(); itr!=m_sourceMap.end(); ++itr) {
00355 for (unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
00356 if ( (itr->second.msg[ic] >= m_msgLimit[ic] && m_msgLimit[ic] != 0 ) ||
00357 (m_stats && itr->second.msg[ic] > 0 && ic >= m_statLevel.value()) ) {
00358 os << " ";
00359 os.width(28);
00360 os.setf(ios_base::left,ios_base::adjustfield);
00361 os << itr->first;
00362
00363 os << "|";
00364
00365 os.width(8);
00366 os.setf(ios_base::right,ios_base::adjustfield);
00367 os << levelNames[ic];
00368
00369 os << " |";
00370
00371 os.width(9);
00372 os << itr->second.msg[ic];
00373
00374 os << endl;
00375
00376 found = true;
00377 }
00378 }
00379 }
00380 os << "=====================================================" << endl;
00381
00382 if (found || m_stats) {
00383 cout << os.str();
00384 }
00385 }
00386
00387 #ifndef NDEBUG
00388 if (m_inactCount.value()) {
00389
00390 std::ostringstream os;
00391 os << "Listing sources of Unprotected and Unseen messages\n";
00392
00393 bool found(false);
00394
00395 unsigned int ml(0);
00396 std::map<std::string,MsgAry>::const_iterator itr;
00397 for (itr=m_inactiveMap.begin(); itr!=m_inactiveMap.end(); ++itr) {
00398 for (unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
00399 if (itr->second.msg[ic] != 0) {
00400 if (itr->first.length() > ml) { ml = itr->first.length(); }
00401 }
00402 }
00403 }
00404
00405 for (unsigned int i=0; i<ml+25; ++i) {
00406 os << "=";
00407 }
00408
00409 os << endl << " ";
00410 os.width(ml+2);
00411 os.setf(ios_base::left,ios_base::adjustfield);
00412 os << "Message Source";
00413 os.width(1);
00414 os << "| Level | Count" << endl;
00415
00416 for (unsigned int i=0; i<ml+3; ++i) {
00417 os << "-";
00418 }
00419 os << "+---------+-----------" << endl;
00420
00421
00422 for (itr=m_inactiveMap.begin(); itr!=m_inactiveMap.end(); ++itr) {
00423 for (unsigned int ic = 0; ic < MSG::NUM_LEVELS; ++ic) {
00424 if (itr->second.msg[ic] != 0) {
00425 os << " ";
00426 os.width(ml+2);
00427 os.setf(ios_base::left,ios_base::adjustfield);
00428 os << itr->first;
00429
00430 os << "|";
00431
00432 os.width(8);
00433 os.setf(ios_base::right,ios_base::adjustfield);
00434 os << levelNames[ic];
00435
00436 os << " |";
00437
00438 os.width(9);
00439 os << itr->second.msg[ic];
00440
00441 os << endl;
00442
00443 found = true;
00444 }
00445 }
00446 }
00447 for (unsigned int i=0; i<ml+25; ++i) {
00448 os << "=";
00449 }
00450 os << endl;
00451
00452 if (found) {
00453 cout << os.str();
00454 }
00455 }
00456 #endif
00457
00458 return StatusCode::SUCCESS;
00459 }
00460
00461
00462 std::string MessageSvc::colTrans(std::string col, int offset) {
00463 ColorMap::const_iterator itr = m_colMap.find(col);
00464 int icol;
00465 if (itr != m_colMap.end()) {
00466 icol = offset + itr->second;
00467 } else {
00468 icol = offset + 8;
00469 }
00470 std::ostringstream os1;
00471
00472 os1 << icol;
00473
00474 return os1.str();
00475
00476 }
00477
00478
00479
00480
00481
00482
00483
00484
00485 void MessageSvc::reportMessage( const Message& msg, int outputLevel ) {
00486 boost::recursive_mutex::scoped_lock lock(m_reportMutex);
00487
00488 int key = msg.getType();
00489
00490 m_msgCount[key] ++;
00491
00492 const Message *cmsg = &msg;
00493
00494
00495 if ( !m_loggedStreams.empty() ) {
00496 const LoggedStreamsMap_t::iterator iLog = m_loggedStreams.find( msg.getSource() );
00497 if ( m_loggedStreams.end() != iLog ) {
00498 (*iLog->second) << *cmsg << std::endl;
00499 }
00500 }
00501
00502 if ( m_suppress.value() || m_stats.value() ) {
00503
00504
00505
00506 const int nmsg = ++(m_sourceMap[msg.getSource()].msg[key]);
00507
00508 if (m_suppress.value()) {
00509
00510 if ( m_msgLimit[key] != 0 ) {
00511 if (nmsg == m_msgLimit[key]) {
00512 std::ostringstream txt;
00513 txt << levelNames[key] << " message limit ("
00514 << m_msgLimit[key].value()
00515 << ") reached for "
00516 << msg.getSource() + ". Suppressing further output.";
00517 cmsg = new Message(msg.getSource(), MSG::WARNING, txt.str());
00518 cmsg->setFormat(msg.getFormat());
00519 } else if (nmsg > m_msgLimit[key]) {
00520 return;
00521 }
00522 }
00523 }
00524
00525 }
00526
00527 StreamMap::const_iterator first = m_streamMap.lower_bound( key );
00528 if ( first != m_streamMap.end() ) {
00529 StreamMap::const_iterator last = m_streamMap.upper_bound( key );
00530 while( first != last ) {
00531 std::ostream& stream = *( (*first).second.second );
00532 stream << *cmsg << std::endl;
00533 first++;
00534 }
00535 }
00536 else if ( key >= outputLevel ) {
00537 msg.setFormat(m_defaultFormat);
00538 msg.setTimeFormat(m_defaultTimeFormat);
00539 if (!m_color) {
00540 (*m_defaultStream) << *cmsg << std::endl << std::flush;
00541 } else {
00542 (*m_defaultStream) << m_logColorCodes[key] << *cmsg << "\033[m"
00543 << std::endl << std::flush;
00544 }
00545 }
00546
00547 if (cmsg != &msg) { delete cmsg; }
00548
00549 }
00550
00551
00552
00553
00554
00555
00556
00557 void MessageSvc::reportMessage( const Message& msg ) {
00558 reportMessage(msg, outputLevel(msg.getSource()));
00559 }
00560
00561
00562
00563
00564
00565
00566
00567 void MessageSvc::reportMessage (const char* source,
00568 int type,
00569 const char* message) {
00570 Message msg( source, type, message);
00571 reportMessage( msg );
00572 }
00573
00574
00575
00576
00577
00578
00579
00580 void MessageSvc::reportMessage (const std::string& source,
00581 int type,
00582 const std::string& message) {
00583 Message msg( source, type, message);
00584 reportMessage( msg );
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594 void MessageSvc::reportMessage (const StatusCode& key,
00595 const std::string& source)
00596 {
00597 boost::recursive_mutex::scoped_lock lock(m_messageMapMutex);
00598
00599 MessageMap::const_iterator first = m_messageMap.lower_bound( key );
00600 if ( first != m_messageMap.end() ) {
00601 MessageMap::const_iterator last = m_messageMap.upper_bound( key );
00602 while( first != last ) {
00603 Message msg = (*first).second;
00604 msg.setSource( source );
00605 std::ostringstream os1;
00606 os1 << "Status Code " << key.getCode() << std::ends;
00607 Message stat_code1( source, msg.getType(), os1.str() );
00608 reportMessage( stat_code1 );
00609 reportMessage( msg );
00610 first++;
00611 }
00612 }
00613 else {
00614 Message mesg = m_defaultMessage;
00615 mesg.setSource( source );
00616 std::ostringstream os2;
00617 os2 << "Status Code " << key.getCode() << std::ends;
00618 Message stat_code2( source, mesg.getType(), os2.str() );
00619 reportMessage( stat_code2 );
00620 reportMessage( mesg );
00621 }
00622 }
00623
00624
00625
00626
00627
00628
00629
00630
00631 void MessageSvc::insertStream (int key,
00632 const std::string& name,
00633 std::ostream *stream)
00634 {
00635 typedef StreamMap::value_type value_type;
00636 m_streamMap.insert( value_type( key, NamedStream(name,stream) ) );
00637 }
00638
00639
00640
00641
00642
00643
00644
00645
00646 void MessageSvc::eraseStream()
00647 {
00648 m_streamMap.erase( m_streamMap.begin(), m_streamMap.end() );
00649 }
00650
00651
00652
00653
00654
00655
00656
00657
00658 void MessageSvc::eraseStream( int message_type )
00659 {
00660 m_streamMap.erase( message_type );
00661 }
00662
00663
00664
00665
00666
00667
00668
00669
00670 void MessageSvc::eraseStream( int key, std::ostream* stream ) {
00671 if ( 0 != stream ) {
00672 bool changed = true;
00673 while( changed ) {
00674 changed = false;
00675 StreamMap::iterator first = m_streamMap.lower_bound( key );
00676 StreamMap::iterator last = m_streamMap.upper_bound( key );
00677 while( first != last ) {
00678 if ( (*first).second.second == stream ) {
00679 m_streamMap.erase( first );
00680 changed = true;
00681 break;
00682 }
00683 }
00684 }
00685 }
00686 }
00687
00688
00689
00690
00691
00692
00693
00694
00695 void MessageSvc::eraseStream( std::ostream* stream ) {
00696 if ( 0 != stream ) {
00697 bool changed = true;
00698 while( changed ) {
00699 changed = false;
00700 StreamMap::iterator first = m_streamMap.begin();
00701 while( first != m_streamMap.end() ) {
00702 if ( (*first).second.second == stream ) {
00703 m_streamMap.erase( first );
00704 changed = true;
00705 break;
00706 }
00707 }
00708 }
00709 }
00710 }
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 void MessageSvc::insertMessage( const StatusCode& key, const Message& msg )
00721 {
00722 boost::recursive_mutex::scoped_lock lock(m_messageMapMutex);
00723
00724 typedef MessageMap::value_type value_type;
00725 m_messageMap.insert( value_type( key, msg ) );
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735 void MessageSvc::eraseMessage()
00736 {
00737 boost::recursive_mutex::scoped_lock lock(m_messageMapMutex);
00738
00739 m_messageMap.erase( m_messageMap.begin(), m_messageMap.end() );
00740 }
00741
00742
00743
00744
00745
00746
00747
00748
00749 void MessageSvc::eraseMessage( const StatusCode& key )
00750 {
00751 boost::recursive_mutex::scoped_lock lock(m_messageMapMutex);
00752
00753 m_messageMap.erase( key );
00754 }
00755
00756
00757
00758
00759
00760
00761
00762
00763 void MessageSvc::eraseMessage( const StatusCode& key, const Message& msg )
00764 {
00765 boost::recursive_mutex::scoped_lock lock(m_messageMapMutex);
00766
00767 bool changed = true;
00768 while( changed ) {
00769 changed = false;
00770 MessageMap::iterator first = m_messageMap.lower_bound( key );
00771 MessageMap::iterator last = m_messageMap.upper_bound( key );
00772 while( first != last ) {
00773 const Message& message = (*first).second;
00774 if ( message == msg ) {
00775 m_messageMap.erase( first );
00776 changed = true;
00777 break;
00778 }
00779 }
00780 }
00781 }
00782
00783
00784 int MessageSvc::outputLevel() const {
00785
00786 return m_outputLevel;
00787 }
00788
00789
00790 int MessageSvc::outputLevel( const std::string& source ) const {
00791
00792 boost::recursive_mutex::scoped_lock lock(m_thresholdMapMutex);
00793
00794 ThresholdMap::const_iterator it;
00795
00796 it = m_thresholdMap.find( source );
00797 if( it != m_thresholdMap.end() ) {
00798 return (*it).second;
00799 }
00800 else {
00801 return m_outputLevel;
00802 }
00803 }
00804
00805
00806 void MessageSvc::setOutputLevel(int new_level) {
00807
00808 m_outputLevel = new_level;
00809 }
00810
00811
00812 void MessageSvc::setOutputLevel(const std::string& source, int level) {
00813
00814 boost::recursive_mutex::scoped_lock lock(m_thresholdMapMutex);
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825 m_thresholdMap[source] = level;
00826 }
00827
00828
00829 std::string MessageSvc::getLogColor(int logLevel) const {
00830
00831 if (logLevel < MSG::NUM_LEVELS) {
00832 return m_logColorCodes[logLevel];
00833 } else {
00834 return "";
00835 }
00836 }
00837
00838
00839 int MessageSvc::messageCount( MSG::Level level) const {
00840
00841 return m_msgCount[level];
00842
00843 }
00844
00845
00846 void
00847 MessageSvc::incrInactiveCount(MSG::Level level, const std::string& source) {
00848
00849 ++(m_inactiveMap[source].msg[level]);
00850
00851 }
00852
00853
00854 void MessageSvc::setupLogStreams()
00855 {
00856
00857 for ( LoggedStreamsMap_t::iterator iLog = m_loggedStreams.begin();
00858 iLog != m_loggedStreams.end();
00859 ++iLog ) {
00860 delete iLog->second;
00861 }
00862 m_loggedStreams.clear();
00863
00864 typedef std::map<std::string,std::string> StreamMap_t;
00865 const StreamMap_t& streamMap = m_loggedStreamsName;
00866 typedef StreamMap_t::const_iterator StreamMapIter;
00867
00868 for ( StreamMapIter iProp = streamMap.begin(), iEnd = streamMap.end();
00869 iProp != iEnd;
00870 ++iProp ) {
00871
00872 const std::string sourceName = iProp->first;
00873 const std::string outFileName = iProp->second;
00874
00875 std::set<std::string> outFileNames;
00876 for ( StreamMapIter jProp = streamMap.begin();
00877 jProp != iEnd;
00878 ++jProp ) {
00879 if ( jProp->first != iProp->first ) {
00880 outFileNames.insert( jProp->second );
00881 }
00882 }
00883
00884 tee( sourceName, outFileName, outFileNames );
00885
00886 }
00887
00888 return;
00889 }
00890
00891
00892 void MessageSvc::tee( const std::string& sourceName,
00893 const std::string& outFileName,
00894 const std::set<std::string>& outFileNames )
00895 {
00896 const std::ios_base::openmode openMode = std::ios_base::out |
00897 std::ios_base::trunc;
00898
00899 LoggedStreamsMap_t::iterator iEnd = m_loggedStreams.end();
00900 LoggedStreamsMap_t::iterator iStream = m_loggedStreams.find( sourceName );
00901 if ( iStream != iEnd ) {
00902 delete iStream->second;
00903 iStream->second = 0;
00904 m_loggedStreams.erase( iStream );
00905 }
00906
00907
00908
00909 iEnd = m_loggedStreams.end();
00910 for ( iStream = m_loggedStreams.begin(); iStream != iEnd; ++iStream ) {
00911 if ( outFileNames.find( outFileName ) != outFileNames.end() ) {
00912 m_loggedStreams[sourceName] = m_loggedStreams[iStream->first];
00913 return;
00914 }
00915 }
00916
00917 std::ofstream * out = new std::ofstream( outFileName.c_str(), openMode );
00918
00919 if ( !out->good() ) {
00920 out->close();
00921 delete out;
00922 return;
00923 }
00924
00925 m_loggedStreams[sourceName] = out;
00926
00927 return;
00928 }
00929