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