Gaudi Framework, version v20r3

Generated: 24 Nov 2008

MessageSvc.cpp

Go to the documentation of this file.
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 

Generated at Mon Nov 24 14:38:49 2008 for Gaudi Framework, version v20r3 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004