| # Gaudi Framework, version v22r2 |

Home |  | Generated: Tue May 10 2011

# MessageSvc.cpp

Go to the documentation of this file.

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

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines