| # Gaudi Framework, version v21r7p1 |

Home |  | Generated: 15 Feb 2010

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