Gaudi Framework, version v21r8

Home   Generated: 17 Mar 2010

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   : base_class(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 
00108 StatusCode
00109 IssueLogger::initialize() {
00110 
00111   StatusCode st = Service::initialize();
00112   if (st.isFailure()) { return st; }
00113 
00114   setupDefaultLogger();
00115 
00116   return st;
00117 
00118 }
00119 
00120 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00121 
00122 StatusCode
00123 IssueLogger::reinitialize() {
00124 
00125   MsgStream log ( msgSvc(), name() );
00126   log << MSG::WARNING << "reinitialize not implemented" << endmsg;
00127 
00128 
00129   return StatusCode::SUCCESS;
00130 
00131 }
00132 
00133 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00134 
00135 StatusCode
00136 IssueLogger::finalize() {
00137 
00138   MsgStream log ( msgSvc(), name() );
00139   log << MSG::DEBUG << "IssueLogger::finalize" << endmsg;
00140 
00141   for (int i=0; i<IssueSeverity::NUM_LEVELS; ++i) {
00142     IssueSeverity::Level j = IssueSeverity::Level (i);
00143     delete m_logger[j];
00144   }
00145 
00146   return Service::finalize();
00147 }
00148 
00149 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00150 
00151 void
00152 IssueLogger::getTraceBack(std::string& stack) {
00153   const int depth = 30;
00154   const int offset = 5;
00155   System::backTrace(stack, depth, offset);
00156 }
00157 
00158 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00159 
00160 StatusCode
00161 IssueLogger::connect(const std::string& ident) {
00162 
00163   MsgStream log ( msgSvc(), name() );
00164   Tokenizer tok(true);
00165 
00166   string::size_type loc = ident.find(" ");
00167   string stream = ident.substr(0,loc);
00168 //   typedef std::pair<std::string,std::string>      Prop;
00169 //   std::vector<Prop> props;
00170   string val,VAL,TAG,filename;
00171 
00172   tok.analyse(ident.substr(loc+1,ident.length()), " ", "", "", "=", "'", "'");
00173 
00174   for ( Tokenizer::Items::iterator i = tok.items().begin();
00175         i != tok.items().end(); i++)    {
00176     const std::string& tag = (*i).tag();
00177     TAG = tag;
00178     toupper(TAG);
00179 
00180     val = (*i).value();
00181     VAL = val;
00182     toupper(VAL);
00183 
00184     IssueSeverity::Level level;
00185 
00186     if (TAG == "DEBUG") {
00187       level = IssueSeverity::DEBUG;
00188     } else if ( TAG == "INFO") {
00189       level = IssueSeverity::INFO;
00190     } else if ( TAG == "WARNING") {
00191       level = IssueSeverity::WARNING;
00192     } else if ( TAG == "RECOVERABLE") {
00193       level = IssueSeverity::RECOVERABLE;
00194     } else if ( TAG == "ERROR") {
00195       level = IssueSeverity::ERROR;
00196     } else if ( TAG == "FATAL") {
00197       level = IssueSeverity::FATAL;
00198     } else {
00199       log << MSG::ERROR << "Unknown output level \"" << TAG << "\""
00200           << endmsg;
00201       continue;
00202     }
00203 
00204     if (m_logger[level] != 0) {
00205       log << MSG::INFO << "closing stream " << m_logger[level]->name()
00206           << endmsg;
00207       delete m_logger[level];
00208       m_logger[level] = 0;
00209     }
00210 
00211     if (val == "MsgSvc") {
00212       m_logger[level] = new StreamLogger(msgSvc(), m_sevMsgMap[level]);
00213       m_log[level] =
00214         boost::bind(&StreamLogger::WriteToMsgSvc, m_logger[level],
00215                     _1);
00216     } else if (val == "STDERR") {
00217       m_logger[level] = new StreamLogger(std::cerr);
00218       m_log[level] =
00219         boost::bind(&StreamLogger::WriteToStream, m_logger[level],
00220                     _1);
00221     } else if (val == "STDOUT") {
00222       m_logger[level] = new StreamLogger(std::cout);
00223       m_log[level] =
00224         boost::bind(&StreamLogger::WriteToStream, m_logger[level],
00225                     _1);
00226     } else { // A file
00227       try {
00228         m_logger[level] = new StreamLogger(val.c_str());
00229       }
00230       catch (std::exception&) {
00231         m_logger[level] = 0;
00232         log << MSG::ERROR << "Unable to open file \"" << VAL
00233             << "\" for writing issues at level " << TAG << endmsg;
00234         return StatusCode::FAILURE;
00235       }
00236       m_log[level] =
00237         boost::bind(&StreamLogger::WriteToStream, m_logger[level], _1);
00238     }
00239     log << MSG::DEBUG << "Writing " << m_levelTrans[level]
00240         << " issues to " << m_logger[level]->name() << endmsg;
00241 
00242   }
00243 
00244   return StatusCode::SUCCESS;
00245 }
00246 
00247 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00248 
00249 void
00250 IssueLogger::report(IssueSeverity::Level lev, const std::string& str,
00251                     const std::string& org) {
00252 
00253   if ( lev < m_reportLevel) return;
00254 
00255   std::string msg = m_levelTrans[lev] + "  " + org + "  \"" + str + "\"";
00256 
00257   if (m_showTime) {
00258     const time_t t = time( 0 );
00259     tm *tt = localtime( &t );
00260 
00261     ostringstream os;
00262     os << (tt->tm_hour < 10 ? "0" : "" ) << tt->tm_hour << ":"
00263        << (tt->tm_min < 10 ? "0" : "" )  << tt->tm_min << ":"
00264        << (tt->tm_sec < 10 ? "0" : "" )  << tt->tm_sec << " "
00265        << tt->tm_year + 1900 << "/"
00266        << (tt->tm_mon < 9 ? "0" : "" )   << tt->tm_mon+1 << "/"
00267        << (tt->tm_mday < 10 ? "0" : "" ) << tt->tm_mday << " "
00268 #ifdef __linux
00269        << tt->tm_zone;
00270 #else
00271        << " " ;
00272 #endif
00273 
00274     msg += " [" + os.str() +"]";
00275 
00276   }
00277 
00278   if (lev >= m_traceLevel) {
00279     std::string stack;
00280     getTraceBack(stack);
00281     msg += "\n" + stack;
00282   }
00283 
00284 
00285   m_log[lev](msg);
00286 
00287 
00288 }
00289 
00290 
00291 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00292 
00293 
00294 void
00295 IssueLogger::report( const IssueSeverity &err ) {
00296 
00297   report(err.getLevel(), err.getMsg(), err.getOrigin());
00298 
00299 }
00300 
00301 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00302 
00303 void
00304 IssueLogger::setupLevels(Property& prop) {
00305 
00306 
00307   StringProperty *sap = dynamic_cast<StringProperty*> (&prop);
00308   if (sap == 0) {
00309     MsgStream log ( msgSvc(), name() );
00310     log << MSG::ERROR << "Could not convert " << prop.name()
00311         << "to a StringProperty (which it should be!)" << endmsg;
00312     return;
00313   }
00314 
00315   std::string val = sap->value();
00316 
00317   if (prop.name() == "ReportLevel") {
00318     if (m_levelSTrans.find(val) == m_levelSTrans.end()) {
00319       MsgStream log ( msgSvc(), name() );
00320       log << MSG::ERROR
00321           << "Option ReportLevel: unknown Issue Severity level \""
00322           << val << "\". Setting it WARNING" << endmsg;
00323       m_reportLevel = IssueSeverity::WARNING;
00324       return;
00325     } else {
00326       m_reportLevel = m_levelSTrans[m_reportLevelS];
00327     }
00328   } else if (prop.name() == "TracebackLevel") {
00329     if (m_levelSTrans.find(val) == m_levelSTrans.end()) {
00330       MsgStream log ( msgSvc(), name() );
00331       log << MSG::ERROR
00332           << "Option TracebackLevel: unknown Issue Severity level \""
00333           << val << "\". Setting it to ERROR" << endmsg;
00334       m_traceLevel = IssueSeverity::ERROR;
00335       return;
00336     } else {
00337       m_traceLevel = m_levelSTrans[m_traceLevelS];
00338     }
00339   } else {
00340       MsgStream log ( msgSvc(), name() );
00341       log << MSG::ERROR << "setting up unknown property \"" << prop.name()
00342           << "\"" << endmsg;
00343       return;
00344   }
00345 
00346 }
00347 
00348 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00349 
00350 void
00351 IssueLogger::setupStreams(Property& prop) {
00352 
00353   StringArrayProperty *sap = dynamic_cast<StringArrayProperty*>( &prop );
00354   if (sap == 0) {
00355     MsgStream log ( msgSvc(), name() );
00356     log << MSG::ERROR << "Could not convert " << prop.name()
00357         << "to a StringArrayProperty (which it should be!)" << endmsg;
00358     return;
00359   }
00360 
00361   vector<string>::const_iterator itr;
00362   for (itr = sap->value().begin(); itr != sap->value().end(); ++itr) {
00363     if (connect(*itr).isFailure()) {
00364       MsgStream log ( msgSvc(), name() );
00365       log << MSG::ERROR << "Could not setup stream " << *itr << endmsg;
00366     }
00367   }
00368 
00369   return;
00370 
00371 }
00372 
00373 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00374 
00375 void
00376 IssueLogger::setupDefaultLogger() {
00377   for (int i=1; i<IssueSeverity::NUM_LEVELS; ++i) {
00378     if (m_logger[i] == 0) {
00379       // default: dump to msgSvc
00380       IssueSeverity::Level j = IssueSeverity::Level (i);
00381 
00382       m_logger[j] = new StreamLogger(msgSvc(), m_sevMsgMap[j]);
00383       m_log[j] = boost::bind(&StreamLogger::WriteToMsgSvc, m_logger[j],
00384                              _1);
00385 
00386       MsgStream log ( msgSvc(), name() );
00387       log << MSG::DEBUG << "Writing " << m_levelTrans[j]
00388           << " issues to " << m_logger[j]->name() << endmsg;
00389 
00390     }
00391   }
00392 }

Generated at Wed Mar 17 18:06:46 2010 for Gaudi Framework, version v21r8 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004