| # Gaudi Framework, version v20r2
Generated: 18 Jul 2008

- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages

- Search for |

- File List
- File Members

# MessageSvc.cpp

Go to the documentation of this file.

    00001 // $Id: MessageSvc.cpp,v 1.25 2008/06/02 14:21:35 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 )    {
    00399   boost::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(msg.getSource()) )   {
    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 char* source,
    00483                                 int type,
    00484                                 const char* message) {
    00485   Message msg( source, type, message);
    00486   reportMessage( msg );
    00487 }
    00488
    00489 //#############################################################################
    00490 // ---------------------------------------------------------------------------
    00491 // Routine: reportMessage
    00492 // Purpose: dispatches a message to the relevant streams.
    00493 // ---------------------------------------------------------------------------
    00494 //
    00495 void MessageSvc::reportMessage (const std::string& source,
    00496                                 int type,
    00497                                 const std::string& message) {
    00498   Message msg( source, type, message);
    00499   reportMessage( msg );
    00500 }
    00501
    00502 //#############################################################################
    00503 // ---------------------------------------------------------------------------
    00504 // Routine: sendMessage
    00505 // Purpose: finds a message for a given status code and dispatches it.
    00506 // ---------------------------------------------------------------------------
    00507 //
    00508
    00509 void MessageSvc::reportMessage (const StatusCode& key,
    00510                                 const std::string& source)
    00511 {
    00512   boost::mutex::scoped_lock lock(m_messageMapMutex);
    00513
    00514   MessageMap::const_iterator first = m_messageMap.lower_bound( key );
    00515   if ( first != m_messageMap.end() ) {
    00516     MessageMap::const_iterator last = m_messageMap.upper_bound( key );
    00517     while( first != last ) {
    00518       Message msg = (*first).second;
    00519       msg.setSource( source );
    00520       std::ostringstream os1;
    00521       os1 << "Status Code " << key.getCode() << std::ends;
    00522       Message stat_code1( source, msg.getType(), os1.str() );
    00523       reportMessage( stat_code1 );
    00524       reportMessage( msg );
    00525       first++;
    00526     }
    00527   }
    00528   else {
    00529     Message mesg = m_defaultMessage;
    00530     mesg.setSource( source );
    00531       std::ostringstream os2;
    00532     os2 << "Status Code " << key.getCode() << std::ends;
    00533     Message stat_code2( source,  mesg.getType(), os2.str() );
    00534     reportMessage( stat_code2 );
    00535     reportMessage( mesg );
    00536   }
    00537 }
    00538
    00539 //#############################################################################
    00540 // ---------------------------------------------------------------------------
    00541 // Routine: insertStream
    00542 // Purpose: inserts a stream for a message type.
    00543 // ---------------------------------------------------------------------------
    00544 //
    00545
    00546 void MessageSvc::insertStream (int key,
    00547                                const std::string& name,
    00548                                std::ostream *stream)
    00549 {
    00550   typedef StreamMap::value_type value_type;
    00551   m_streamMap.insert( value_type( key, NamedStream(name,stream) ) );
    00552 }
    00553
    00554 //#############################################################################
    00555 // ---------------------------------------------------------------------------
    00556 // Routine: eraseStream
    00557 // Purpose: erases all the streams for all the message types.
    00558 // ---------------------------------------------------------------------------
    00559 //
    00560
    00561 void MessageSvc::eraseStream()
    00562 {
    00563   m_streamMap.erase( m_streamMap.begin(), m_streamMap.end() );
    00564 }
    00565
    00566 //#############################################################################
    00567 // ---------------------------------------------------------------------------
    00568 // Routine: eraseStream
    00569 // Purpose: erases all the streams for a message type.
    00570 // ---------------------------------------------------------------------------
    00571 //
    00572
    00573 void MessageSvc::eraseStream( int message_type )
    00574 {
    00575   m_streamMap.erase( message_type );
    00576 }
    00577
    00578 //#############################################################################
    00579 // ---------------------------------------------------------------------------
    00580 // Routine: eraseStream
    00581 // Purpose: erases one stream for a message type.
    00582 // ---------------------------------------------------------------------------
    00583 //
    00584
    00585 void MessageSvc::eraseStream( int key, std::ostream* stream )   {
    00586   if ( 0 != stream )    {
    00587     bool changed = true;
    00588     while( changed ) {
    00589       changed = false;
    00590       StreamMap::iterator first = m_streamMap.lower_bound( key );
    00591       StreamMap::iterator last = m_streamMap.upper_bound( key );
    00592       while( first != last ) {
    00593         if ( (*first).second.second == stream ) {
    00594           m_streamMap.erase( first );
    00595           changed = true;
    00596           break;
    00597         }
    00598       }
    00599     }
    00600   }
    00601 }
    00602
    00603 //#############################################################################
    00604 // ---------------------------------------------------------------------------
    00605 // Routine: eraseStream
    00606 // Purpose: erases one stream for all message types.
    00607 // ---------------------------------------------------------------------------
    00608 //
    00609
    00610 void MessageSvc::eraseStream( std::ostream* stream )    {
    00611   if ( 0 != stream )    {
    00612     bool changed = true;
    00613     while( changed ) {
    00614       changed = false;
    00615       StreamMap::iterator first = m_streamMap.begin();
    00616       while( first != m_streamMap.end() ) {
    00617         if ( (*first).second.second == stream ) {
    00618           m_streamMap.erase( first );
    00619           changed = true;
    00620           break;
    00621         }
    00622       }
    00623     }
    00624   }
    00625 }
    00626
    00627
    00628 //#############################################################################
    00629 // ---------------------------------------------------------------------------
    00630 // Routine: insertMessage
    00631 // Purpose: inserts a message for a status code.
    00632 // ---------------------------------------------------------------------------
    00633 //
    00634
    00635 void MessageSvc::insertMessage( const StatusCode& key, const Message& msg )
    00636 {
    00637   boost::mutex::scoped_lock lock(m_messageMapMutex);
    00638
    00639   typedef MessageMap::value_type value_type;
    00640   m_messageMap.insert( value_type( key, msg ) );
    00641 }
    00642
    00643 //#############################################################################
    00644 // ---------------------------------------------------------------------------
    00645 // Routine: eraseMessage
    00646 // Purpose: erases all the messages for all the status codes.
    00647 // ---------------------------------------------------------------------------
    00648 //
    00649
    00650 void MessageSvc::eraseMessage()
    00651 {
    00652   boost::mutex::scoped_lock lock(m_messageMapMutex);
    00653
    00654   m_messageMap.erase( m_messageMap.begin(), m_messageMap.end() );
    00655 }
    00656
    00657 //#############################################################################
    00658 // ---------------------------------------------------------------------------
    00659 // Routine: eraseMessage
    00660 // Purpose: erases all the messages for a status code.
    00661 // ---------------------------------------------------------------------------
    00662 //
    00663
    00664 void MessageSvc::eraseMessage( const StatusCode& key )
    00665 {
    00666   boost::mutex::scoped_lock lock(m_messageMapMutex);
    00667
    00668   m_messageMap.erase( key );
    00669 }
    00670
    00671 //#############################################################################
    00672 // ---------------------------------------------------------------------------
    00673 // Routine: eraseMessage
    00674 // Purpose: erases one message for a status code.
    00675 // ---------------------------------------------------------------------------
    00676 //
    00677
    00678 void MessageSvc::eraseMessage( const StatusCode& key, const Message& msg )
    00679 {
    00680   boost::mutex::scoped_lock lock(m_messageMapMutex);
    00681
    00682   bool changed = true;
    00683   while( changed ) {
    00684     changed = false;
    00685     MessageMap::iterator first = m_messageMap.lower_bound( key );
    00686     MessageMap::iterator last = m_messageMap.upper_bound( key );
    00687     while( first != last ) {
    00688       const Message& message = (*first).second;
    00689       if ( message == msg ) {
    00690         m_messageMap.erase( first );
    00691         changed = true;
    00692         break;
    00693       }
    00694     }
    00695   }
    00696 }
    00697
    00698 // ---------------------------------------------------------------------------
    00699 StatusCode MessageSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) {
    00700 // ---------------------------------------------------------------------------
    00701   if ( IID_IMessageSvc == riid )  {
    00702     *ppvInterface = (IMessageSvc*)this;
    00703   }
    00704   else  {
    00705     return Service::queryInterface(riid, ppvInterface);
    00706   }
    00707   addRef();
    00708   return StatusCode::SUCCESS;
    00709 }
    00710
    00711 // ---------------------------------------------------------------------------
    00712 int MessageSvc::outputLevel()   const {
    00713 // ---------------------------------------------------------------------------
    00714   return m_outputLevel;
    00715 }
    00716 // ---------------------------------------------------------------------------
    00717 int MessageSvc::outputLevel( const std::string& source )   const {
    00718 // ---------------------------------------------------------------------------
    00719   boost::mutex::scoped_lock lock(m_thresholdMapMutex);
    00720
    00721   ThresholdMap::const_iterator it;
    00722
    00723   it = m_thresholdMap.find( source );
    00724   if( it != m_thresholdMap.end() ) {
    00725     return (*it).second;
    00726   }
    00727   else {
    00728     return m_outputLevel;
    00729   }
    00730 }
    00731
    00732 // ---------------------------------------------------------------------------
    00733 void MessageSvc::setOutputLevel(int new_level)    {
    00734 // ---------------------------------------------------------------------------
    00735   m_outputLevel = new_level;
    00736 }
    00737
    00738 // ---------------------------------------------------------------------------
    00739 void MessageSvc::setOutputLevel(const std::string& source, int level)    {
    00740 // ---------------------------------------------------------------------------
    00741   boost::mutex::scoped_lock lock(m_thresholdMapMutex);
    00742
    00743   /*
    00744   std::pair<ThresholdMap::iterator, bool> p;
    00745   p = m_thresholdMap.insert(ThresholdMap::value_type( source, level) );
    00746   if( p.second == false ) {
    00747     // Already esisting an output level for that source. Erase and enter it again
    00748     m_thresholdMap.erase ( p.first );
    00749     m_thresholdMap.insert(ThresholdMap::value_type( source, level) );
    00750   }
    00751   */
    00752   m_thresholdMap[source] = level;
    00753 }
    00754
    00755 // ---------------------------------------------------------------------------
    00756 std::string MessageSvc::getLogColor(int logLevel) const   {
    00757 // ---------------------------------------------------------------------------
    00758   if (logLevel < MSG::NUM_LEVELS) {
    00759     return m_logColorCodes[logLevel];
    00760   } else {
    00761     return "";
    00762   }
    00763 }
    00764
    00765 // ---------------------------------------------------------------------------
    00766 int MessageSvc::messageCount( MSG::Level level) const   {
    00767
    00768   return m_msgCount[level];
    00769
    00770 }
    00771
    00772 // ---------------------------------------------------------------------------
    00773 void MessageSvc::setupLogStreams()
    00774 {
    00775   // reset state
    00776   for ( LoggedStreamsMap_t::iterator iLog = m_loggedStreams.begin();
    00777         iLog != m_loggedStreams.end();
    00778         ++iLog ) {
    00779     delete iLog->second;
    00780   }
    00781   m_loggedStreams.clear();
    00782
    00783   typedef std::map<std::string,std::string> StreamMap_t;
    00784   const StreamMap_t& streamMap = m_loggedStreamsName;
    00785   typedef StreamMap_t::const_iterator StreamMapIter;
    00786
    00787   for ( StreamMapIter iProp = streamMap.begin(), iEnd = streamMap.end();
    00788         iProp != iEnd;
    00789         ++iProp ) {
    00790
    00791     const std::string sourceName  = iProp->first;
    00792     const std::string outFileName = iProp->second;
    00793
    00794     std::set<std::string> outFileNames;
    00795     for ( StreamMapIter jProp = streamMap.begin();
    00796           jProp != iEnd;
    00797           ++jProp ) {
    00798       if ( jProp->first != iProp->first ) {
    00799         outFileNames.insert( jProp->second );
    00800       }
    00801     }
    00802
    00803     tee( sourceName, outFileName, outFileNames );
    00804
    00805   }//> loop over property entries
    00806
    00807   return;
    00808 }
    00809
    00810 // ---------------------------------------------------------------------------
    00811 void MessageSvc::tee( const std::string& sourceName,
    00812                       const std::string& outFileName,
    00813                       const std::set<std::string>& outFileNames )
    00814 {
    00815   const std::ios_base::openmode openMode = std::ios_base::out |
    00816                                            std::ios_base::trunc;
    00817
    00818   LoggedStreamsMap_t::iterator iEnd    = m_loggedStreams.end();
    00819   LoggedStreamsMap_t::iterator iStream = m_loggedStreams.find( sourceName );
    00820   if ( iStream != iEnd ) {
    00821     delete iStream->second;
    00822     iStream->second = 0;
    00823     m_loggedStreams.erase( iStream );
    00824   }
    00825
    00826   // before creating a new ofstream, make sure there is no already existing
    00827   // one with the same file name...
    00828   iEnd = m_loggedStreams.end();
    00829   for ( iStream = m_loggedStreams.begin(); iStream != iEnd; ++iStream ) {
    00830     if ( outFileNames.find( outFileName ) != outFileNames.end() ) {
    00831       m_loggedStreams[sourceName] = m_loggedStreams[iStream->first];
    00832       return;
    00833     }
    00834   }
    00835
    00836   std::ofstream * out =  new std::ofstream( outFileName.c_str(), openMode );
    00837
    00838   if ( !out->good() ) {
    00839     out->close();
    00840     delete out;
    00841     return;
    00842   }
    00843
    00844   m_loggedStreams[sourceName] = out;
    00845
    00846   return;
    00847 }
    00848