Gaudi Framework, version v23r2

Home   Generated: Thu Jun 28 2012

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

Generated at Thu Jun 28 2012 23:27:18 for Gaudi Framework, version v23r2 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004