Gaudi Framework, version v20r2

Generated: 18 Jul 2008

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 }

Generated at Fri Jul 18 11:59:24 2008 for Gaudi Framework, version v20r2 by Doxygen version 1.5.1 written by Dimitri van Heesch, © 1997-2004