Gaudi Framework, version v22r0

Home   Generated: 9 Feb 2011

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

Generated at Wed Feb 9 16:25:02 2011 for Gaudi Framework, version v22r0 by Doxygen version 1.6.2 written by Dimitri van Heesch, © 1997-2004