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

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

- Search for |

- File List
- File Members

# IssueLogger.cpp

Go to the documentation of this file.

    00001 #include "IssueLogger.h"
    00002
    00003 #include "GaudiKernel/SvcFactory.h"
    00004 #include "GaudiKernel/ISvcLocator.h"
    00005 #include "GaudiKernel/MsgStream.h"
    00006 #include "GaudiKernel/Tokenizer.h"
    00007 #include "GaudiKernel/System.h"
    00008
    00009 #include <sstream>
    00010 #include <streambuf>
    00011 #include <time.h>
    00012
    00013 #include "boost/bind.hpp"
    00014
    00015 using namespace std;
    00016
    00017 DECLARE_SERVICE_FACTORY(IssueLogger)
    00018
    00019 //*************************************************************************//
    00020 inline void toupper(std::string &s)
    00021 {
    00022     std::string::iterator it=s.begin();
    00023     while(it != s.end())
    00024     {
    00025         *it = toupper(*it);
    00026         it++;
    00027     }
    00028 }
    00029
    00030 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00031
    00032 IssueLogger::IssueLogger( const std::string& name, ISvcLocator* svc )
    00033   : Service(name, svc) {
    00034
    00035   declareProperty ("Output", m_outputfile );
    00036   declareProperty ("ReportLevel", m_reportLevelS="WARNING");
    00037   declareProperty ("TracebackLevel", m_traceLevelS="ERROR");
    00038   declareProperty ("ShowTime", m_showTime=false);
    00039
    00040   m_reportLevelS.declareUpdateHandler(&IssueLogger::setupLevels,this);
    00041   m_traceLevelS.declareUpdateHandler(&IssueLogger::setupLevels,this);
    00042   m_outputfile.declareUpdateHandler(&IssueLogger::setupStreams,this);
    00043
    00044   m_reportLevel = IssueSeverity::WARNING;
    00045   m_traceLevel  = IssueSeverity::ERROR;
    00046
    00047   for (int i=0; i<IssueSeverity::NUM_LEVELS; ++i) {
    00048     m_logger[i] = 0;
    00049   }
    00050
    00051   m_msgSevMap[MSG::NIL]     = IssueSeverity::NIL;
    00052   m_msgSevMap[MSG::VERBOSE] = IssueSeverity::VERBOSE;
    00053   m_msgSevMap[MSG::DEBUG]   = IssueSeverity::DEBUG;
    00054   m_msgSevMap[MSG::INFO]    = IssueSeverity::INFO;
    00055   m_msgSevMap[MSG::WARNING] = IssueSeverity::WARNING;
    00056   m_msgSevMap[MSG::ERROR]   = IssueSeverity::ERROR;
    00057   m_msgSevMap[MSG::FATAL]   = IssueSeverity::FATAL;
    00058   m_msgSevMap[MSG::ALWAYS]  = IssueSeverity::ALWAYS;
    00059
    00060   m_sevMsgMap[IssueSeverity::NIL]           = MSG::NIL;
    00061   m_sevMsgMap[IssueSeverity::VERBOSE]       = MSG::VERBOSE;
    00062   m_sevMsgMap[IssueSeverity::DEBUG]         = MSG::DEBUG;
    00063   m_sevMsgMap[IssueSeverity::DEBUG1]        = MSG::DEBUG;
    00064   m_sevMsgMap[IssueSeverity::DEBUG2]        = MSG::DEBUG;
    00065   m_sevMsgMap[IssueSeverity::DEBUG3]        = MSG::DEBUG;
    00066   m_sevMsgMap[IssueSeverity::INFO]          = MSG::INFO;
    00067   m_sevMsgMap[IssueSeverity::WARNING]       = MSG::WARNING;
    00068   m_sevMsgMap[IssueSeverity::RECOVERABLE]   = MSG::ERROR;
    00069   m_sevMsgMap[IssueSeverity::ERROR]         = MSG::ERROR;
    00070   m_sevMsgMap[IssueSeverity::FATAL]         = MSG::FATAL;
    00071   m_sevMsgMap[IssueSeverity::ALWAYS]        = MSG::ALWAYS;
    00072
    00073   m_levelTrans[IssueSeverity::VERBOSE]     = "VERBOSE";
    00074   m_levelTrans[IssueSeverity::DEBUG]       = "DEBUG";
    00075   m_levelTrans[IssueSeverity::DEBUG1]      = "DEBUG1";
    00076   m_levelTrans[IssueSeverity::DEBUG2]      = "DEBUG2";
    00077   m_levelTrans[IssueSeverity::DEBUG3]      = "DEBUG3";
    00078   m_levelTrans[IssueSeverity::INFO]        = "INFO";
    00079   m_levelTrans[IssueSeverity::WARNING]     = "WARNING";
    00080   m_levelTrans[IssueSeverity::RECOVERABLE] = "RECOVERABLE";
    00081   m_levelTrans[IssueSeverity::ERROR]       = "ERROR";
    00082   m_levelTrans[IssueSeverity::FATAL]       = "FATAL";
    00083   m_levelTrans[IssueSeverity::ALWAYS]      = "ALWAYS";
    00084
    00085   m_levelSTrans["VERBOSE"]     = IssueSeverity::VERBOSE;
    00086   m_levelSTrans["DEBUG"]       = IssueSeverity::DEBUG;
    00087   m_levelSTrans["DEBUG1"]      = IssueSeverity::DEBUG1;
    00088   m_levelSTrans["DEBUG2"]      = IssueSeverity::DEBUG2;
    00089   m_levelSTrans["DEBUG3"]      = IssueSeverity::DEBUG3;
    00090   m_levelSTrans["INFO"]        = IssueSeverity::INFO;
    00091   m_levelSTrans["WARNING"]     = IssueSeverity::WARNING;
    00092   m_levelSTrans["RECOVERABLE"] = IssueSeverity::RECOVERABLE;
    00093   m_levelSTrans["ERROR"]       = IssueSeverity::ERROR;
    00094   m_levelSTrans["FATAL"]       = IssueSeverity::FATAL;
    00095   m_levelSTrans["ALWAYS"]      = IssueSeverity::ALWAYS;
    00096
    00097
    00098 }
    00099
    00100 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00101
    00102 IssueLogger::~IssueLogger() {
    00103
    00104 }
    00105 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00106
    00107 StatusCode IssueLogger::queryInterface( const InterfaceID& riid,
    00108                                         void** ppvInterface ) {
    00109   StatusCode sc = StatusCode::FAILURE;
    00110   if ( ppvInterface ) {
    00111     *ppvInterface = 0;
    00112
    00113     if ( IIssueLogger::interfaceID().versionMatch(riid) )    {
    00114       *ppvInterface = static_cast<IIssueLogger*>(this);
    00115       sc = StatusCode::SUCCESS;
    00116       addRef();
    00117     }
    00118     else
    00119       sc = Service::queryInterface( riid, ppvInterface );
    00120   }
    00121   return sc;
    00122 }
    00123
    00124 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00125
    00126 StatusCode
    00127 IssueLogger::initialize() {
    00128
    00129   StatusCode st = Service::initialize();
    00130   if (st.isFailure()) { return st; }
    00131
    00132   setupDefaultLogger();
    00133
    00134   return st;
    00135
    00136 }
    00137
    00138 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00139
    00140 StatusCode
    00141 IssueLogger::reinitialize() {
    00142
    00143   MsgStream log ( msgSvc(), name() );
    00144   log << MSG::WARNING << "reinitialize not implemented" << endreq;
    00145
    00146
    00147   return StatusCode::SUCCESS;
    00148
    00149 }
    00150
    00151 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00152
    00153 StatusCode
    00154 IssueLogger::finalize() {
    00155
    00156   MsgStream log ( msgSvc(), name() );
    00157   log << MSG::DEBUG << "IssueLogger::finalize" << endreq;
    00158
    00159   for (int i=0; i<IssueSeverity::NUM_LEVELS; ++i) {
    00160     IssueSeverity::Level j = IssueSeverity::Level (i);
    00161     delete m_logger[j];
    00162   }
    00163
    00164   return Service::finalize();
    00165 }
    00166
    00167 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00168
    00169 void
    00170 IssueLogger::getTraceBack(std::string& stack) {
    00171
    00172    size_t depth = 21;
    00173    void** addresses = 0 ;
    00174
    00175    addresses = (void**) malloc(depth*sizeof(void *));
    00176
    00177    std::string fnc, lib;
    00178    void *addr(0);
    00179
    00180    if ( (addresses != 0) && System::backTrace(addresses,depth)) {
    00181      for (size_t i=7; i<depth; ++i) {
    00182        addr = 0 ;
    00183
    00184        if (System::getStackLevel(addresses[i],addr,fnc,lib)) {
    00185          std::ostringstream ost;
    00186          ost << hex << addr << " " << fnc << "  [" << lib << "]\n";
    00187          stack += ost.str();
    00188        }
    00189      }
    00190      free(addresses);
    00191    }
    00192 }
    00193
    00194 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00195
    00196 StatusCode
    00197 IssueLogger::connect(const std::string& ident) {
    00198
    00199   MsgStream log ( msgSvc(), name() );
    00200   Tokenizer tok(true);
    00201
    00202   string::size_type loc = ident.find(" ");
    00203   string stream = ident.substr(0,loc);
    00204 //   typedef std::pair<std::string,std::string>      Prop;
    00205 //   std::vector<Prop> props;
    00206   string val,VAL,TAG,filename;
    00207
    00208   tok.analyse(ident.substr(loc+1,ident.length()), " ", "", "", "=", "'", "'");
    00209
    00210   for ( Tokenizer::Items::iterator i = tok.items().begin();
    00211         i != tok.items().end(); i++)    {
    00212     const std::string& tag = (*i).tag();
    00213     TAG = tag;
    00214     toupper(TAG);
    00215
    00216     val = (*i).value();
    00217     VAL = val;
    00218     toupper(VAL);
    00219
    00220     IssueSeverity::Level level;
    00221
    00222     if (TAG == "DEBUG") {
    00223       level = IssueSeverity::DEBUG;
    00224     } else if ( TAG == "INFO") {
    00225       level = IssueSeverity::INFO;
    00226     } else if ( TAG == "WARNING") {
    00227       level = IssueSeverity::WARNING;
    00228     } else if ( TAG == "RECOVERABLE") {
    00229       level = IssueSeverity::RECOVERABLE;
    00230     } else if ( TAG == "ERROR") {
    00231       level = IssueSeverity::ERROR;
    00232     } else if ( TAG == "FATAL") {
    00233       level = IssueSeverity::FATAL;
    00234     } else {
    00235       log << MSG::ERROR << "Unknown output level \"" << TAG << "\""
    00236           << endreq;
    00237       continue;
    00238     }
    00239
    00240     if (m_logger[level] != 0) {
    00241       log << MSG::INFO << "closing stream " << m_logger[level]->name()
    00242           << endreq;
    00243       delete m_logger[level];
    00244       m_logger[level] = 0;
    00245     }
    00246
    00247     if (val == "MsgSvc") {
    00248       m_logger[level] = new StreamLogger(msgSvc(), m_sevMsgMap[level]);
    00249       m_log[level] =
    00250         boost::bind(&StreamLogger::WriteToMsgSvc, m_logger[level],
    00251                     _1);
    00252     } else if (val == "STDERR") {
    00253       m_logger[level] = new StreamLogger(std::cerr);
    00254       m_log[level] =
    00255         boost::bind(&StreamLogger::WriteToStream, m_logger[level],
    00256                     _1);
    00257     } else if (val == "STDOUT") {
    00258       m_logger[level] = new StreamLogger(std::cout);
    00259       m_log[level] =
    00260         boost::bind(&StreamLogger::WriteToStream, m_logger[level],
    00261                     _1);
    00262     } else { // A file
    00263       try {
    00264         m_logger[level] = new StreamLogger(val.c_str());
    00265       }
    00266       catch (std::exception&) {
    00267         m_logger[level] = 0;
    00268         log << MSG::ERROR << "Unable to open file \"" << VAL
    00269             << "\" for writing issues at level " << TAG << endreq;
    00270         return StatusCode::FAILURE;
    00271       }
    00272       m_log[level] =
    00273         boost::bind(&StreamLogger::WriteToStream, m_logger[level], _1);
    00274     }
    00275     log << MSG::DEBUG << "Writing " << m_levelTrans[level]
    00276         << " issues to " << m_logger[level]->name() << endreq;
    00277
    00278   }
    00279
    00280   return StatusCode::SUCCESS;
    00281 }
    00282
    00283 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00284
    00285 void
    00286 IssueLogger::report(IssueSeverity::Level lev, const std::string& str,
    00287                     const std::string& org) {
    00288
    00289   if ( lev < m_reportLevel) return;
    00290
    00291   std::string msg = m_levelTrans[lev] + "  " + org + "  \"" + str + "\"";
    00292
    00293   if (m_showTime) {
    00294     const time_t t = time( 0 );
    00295     tm *tt = localtime( &t );
    00296
    00297     ostringstream os;
    00298     os << (tt->tm_hour < 10 ? "0" : "" ) << tt->tm_hour << ":"
    00299        << (tt->tm_min < 10 ? "0" : "" )  << tt->tm_min << ":"
    00300        << (tt->tm_sec < 10 ? "0" : "" )  << tt->tm_sec << " "
    00301        << tt->tm_year + 1900 << "/"
    00302        << (tt->tm_mon < 9 ? "0" : "" )   << tt->tm_mon+1 << "/"
    00303        << (tt->tm_mday < 10 ? "0" : "" ) << tt->tm_mday << " "
    00304 #ifdef __linux
    00305        << tt->tm_zone;
    00306 #else
    00307        << " " ;
    00308 #endif
    00309
    00310     msg += " [" + os.str() +"]";
    00311
    00312   }
    00313
    00314   if (lev >= m_traceLevel) {
    00315     std::string stack;
    00316     getTraceBack(stack);
    00317     msg += "\n" + stack;
    00318   }
    00319
    00320
    00321   m_log[lev](msg);
    00322
    00323
    00324 }
    00325
    00326
    00327 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00328
    00329
    00330 void
    00331 IssueLogger::report( const IssueSeverity &err ) {
    00332
    00333   report(err.getLevel(), err.getMsg(), err.getOrigin());
    00334
    00335 }
    00336
    00337 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00338
    00339 void
    00340 IssueLogger::setupLevels(Property& prop) {
    00341
    00342
    00343   StringProperty *sap = dynamic_cast<StringProperty*> (&prop);
    00344   if (sap == 0) {
    00345     MsgStream log ( msgSvc(), name() );
    00346     log << MSG::ERROR << "Could not convert " << prop.name()
    00347         << "to a StringProperty (which it should be!)" << endreq;
    00348     return;
    00349   }
    00350
    00351   std::string val = sap->value();
    00352
    00353   if (prop.name() == "ReportLevel") {
    00354     if (m_levelSTrans.find(val) == m_levelSTrans.end()) {
    00355       MsgStream log ( msgSvc(), name() );
    00356       log << MSG::ERROR
    00357           << "Option ReportLevel: unknown Issue Severity level \""
    00358           << val << "\". Setting it WARNING" << endreq;
    00359       m_reportLevel = IssueSeverity::WARNING;
    00360       return;
    00361     } else {
    00362       m_reportLevel = m_levelSTrans[m_reportLevelS];
    00363     }
    00364   } else if (prop.name() == "TracebackLevel") {
    00365     if (m_levelSTrans.find(val) == m_levelSTrans.end()) {
    00366       MsgStream log ( msgSvc(), name() );
    00367       log << MSG::ERROR
    00368           << "Option TracebackLevel: unknown Issue Severity level \""
    00369           << val << "\". Setting it to ERROR" << endreq;
    00370       m_traceLevel = IssueSeverity::ERROR;
    00371       return;
    00372     } else {
    00373       m_traceLevel = m_levelSTrans[m_traceLevelS];
    00374     }
    00375   } else {
    00376       MsgStream log ( msgSvc(), name() );
    00377       log << MSG::ERROR << "setting up unknown property \"" << prop.name()
    00378           << "\"" << endreq;
    00379       return;
    00380   }
    00381
    00382 }
    00383
    00384 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00385
    00386 void
    00387 IssueLogger::setupStreams(Property& prop) {
    00388
    00389   StringArrayProperty *sap = dynamic_cast<StringArrayProperty*>( &prop );
    00390   if (sap == 0) {
    00391     MsgStream log ( msgSvc(), name() );
    00392     log << MSG::ERROR << "Could not convert " << prop.name()
    00393         << "to a StringArrayProperty (which it should be!)" << endreq;
    00394     return;
    00395   }
    00396
    00397   vector<string>::const_iterator itr;
    00398   for (itr = sap->value().begin(); itr != sap->value().end(); ++itr) {
    00399     if (connect(*itr).isFailure()) {
    00400       MsgStream log ( msgSvc(), name() );
    00401       log << MSG::ERROR << "Could not setup stream " << *itr << endreq;
    00402     }
    00403   }
    00404
    00405   return;
    00406
    00407 }
    00408
    00409 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00410
    00411 void
    00412 IssueLogger::setupDefaultLogger() {
    00413   for (int i=1; i<IssueSeverity::NUM_LEVELS; ++i) {
    00414     if (m_logger[i] == 0) {
    00415       // default: dump to msgSvc
    00416       IssueSeverity::Level j = IssueSeverity::Level (i);
    00417
    00418       m_logger[j] = new StreamLogger(msgSvc(), m_sevMsgMap[j]);
    00419       m_log[j] = boost::bind(&StreamLogger::WriteToMsgSvc, m_logger[j],
    00420                              _1);
    00421
    00422       MsgStream log ( msgSvc(), name() );
    00423       log << MSG::DEBUG << "Writing " << m_levelTrans[j]
    00424           << " issues to " << m_logger[j]->name() << endreq;
    00425
    00426     }
    00427   }
    00428 }