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