| # Gaudi Framework, version v23r0 |

Home |  | Generated: Mon Jan 30 2012

# 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 #include "GaudiKernel/Time.h"
    00009
    00010 #include <sstream>
    00011 #include <streambuf>
    00012 #include <algorithm>
    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     msg += " [" + Gaudi::Time::current().format(true, "%H:%M:%S %Y/%m/%d %Z") +"]";
    00256   }
    00257
    00258   if (lev >= m_traceLevel) {
    00259     std::string stack;
    00260     getTraceBack(stack);
    00261     msg += "\n" + stack;
    00262   }
    00263
    00264
    00265   m_log[lev](msg);
    00266
    00267
    00268 }
    00269
    00270
    00271 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00272
    00273
    00274 void
    00275 IssueLogger::report( const IssueSeverity &err ) {
    00276
    00277   report(err.getLevel(), err.getMsg(), err.getOrigin());
    00278
    00279 }
    00280
    00281 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00282
    00283 void
    00284 IssueLogger::setupLevels(Property& prop) {
    00285
    00286
    00287   StringProperty *sap = dynamic_cast<StringProperty*> (&prop);
    00288   if (sap == 0) {
    00289     MsgStream log ( msgSvc(), name() );
    00290     log << MSG::ERROR << "Could not convert " << prop.name()
    00291         << "to a StringProperty (which it should be!)" << endmsg;
    00292     return;
    00293   }
    00294
    00295   std::string val = sap->value();
    00296
    00297   if (prop.name() == "ReportLevel") {
    00298     if (m_levelSTrans.find(val) == m_levelSTrans.end()) {
    00299       MsgStream log ( msgSvc(), name() );
    00300       log << MSG::ERROR
    00301           << "Option ReportLevel: unknown Issue Severity level \""
    00302           << val << "\". Setting it WARNING" << endmsg;
    00303       m_reportLevel = IssueSeverity::WARNING;
    00304       return;
    00305     } else {
    00306       m_reportLevel = m_levelSTrans[m_reportLevelS];
    00307     }
    00308   } else if (prop.name() == "TracebackLevel") {
    00309     if (m_levelSTrans.find(val) == m_levelSTrans.end()) {
    00310       MsgStream log ( msgSvc(), name() );
    00311       log << MSG::ERROR
    00312           << "Option TracebackLevel: unknown Issue Severity level \""
    00313           << val << "\". Setting it to ERROR" << endmsg;
    00314       m_traceLevel = IssueSeverity::ERROR;
    00315       return;
    00316     } else {
    00317       m_traceLevel = m_levelSTrans[m_traceLevelS];
    00318     }
    00319   } else {
    00320       MsgStream log ( msgSvc(), name() );
    00321       log << MSG::ERROR << "setting up unknown property \"" << prop.name()
    00322           << "\"" << endmsg;
    00323       return;
    00324   }
    00325
    00326 }
    00327
    00328 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00329
    00330 void
    00331 IssueLogger::setupStreams(Property& prop) {
    00332
    00333   StringArrayProperty *sap = dynamic_cast<StringArrayProperty*>( &prop );
    00334   if (sap == 0) {
    00335     MsgStream log ( msgSvc(), name() );
    00336     log << MSG::ERROR << "Could not convert " << prop.name()
    00337         << "to a StringArrayProperty (which it should be!)" << endmsg;
    00338     return;
    00339   }
    00340
    00341   vector<string>::const_iterator itr;
    00342   for (itr = sap->value().begin(); itr != sap->value().end(); ++itr) {
    00343     if (connect(*itr).isFailure()) {
    00344       MsgStream log ( msgSvc(), name() );
    00345       log << MSG::ERROR << "Could not setup stream " << *itr << endmsg;
    00346     }
    00347   }
    00348
    00349   return;
    00350
    00351 }
    00352
    00353 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00354
    00355 void
    00356 IssueLogger::setupDefaultLogger() {
    00357   for (int i=1; i<IssueSeverity::NUM_LEVELS; ++i) {
    00358     if (m_logger[i] == 0) {
    00359       // default: dump to msgSvc
    00360       IssueSeverity::Level j = IssueSeverity::Level (i);
    00361
    00362       m_logger[j] = new StreamLogger(msgSvc(), m_sevMsgMap[j]);
    00363       m_log[j] = boost::bind(&StreamLogger::WriteToMsgSvc, m_logger[j],
    00364                              _1);
    00365
    00366       MsgStream log ( msgSvc(), name() );
    00367       log << MSG::DEBUG << "Writing " << m_levelTrans[j]
    00368           << " issues to " << m_logger[j]->name() << endmsg;
    00369
    00370     }
    00371   }
    00372 }

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines