00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "EventFilter/Message2log4cplus/interface/ELlog4cplus.h"
00012
00013 #include "FWCore/MessageLogger/interface/ErrorObj.h"
00014 #include "FWCore/MessageService/interface/ELadministrator.h"
00015 #include "FWCore/MessageService/interface/ELcontextSupplier.h"
00016
00017 #include "log4cplus/logger.h"
00018 #include "log4cplus/fileappender.h"
00019 #include "log4cplus/loglevel.h"
00020
00021 #include "xdaq/Application.h"
00022
00023
00024
00025
00026
00027
00028 #include <iostream>
00029 #include <fstream>
00030
00031 namespace edm
00032 {
00033
00034 namespace {
00035 void makeFileAppender()
00036 {
00037 static bool iscalled = false;
00038 if(iscalled) return;
00039 iscalled=true;
00040
00041 using namespace log4cplus;
00042 using namespace log4cplus::helpers;
00043
00044 SharedAppenderPtr ap(new FileAppender("log4cplus.output"));
00045 ap->setName("Main");
00046 ap->setLayout(std::auto_ptr<Layout>(new log4cplus::TTCCLayout()) );
00047 Logger::getRoot().addAppender(ap);
00048 }
00049 }
00050
00051
00052
00053
00054
00055
00056 static char * formatTime( const time_t t ) {
00057
00058 static char ts[] = "dd-Mon-yyyy hh:mm:ss XYZ";
00059
00060
00061 #ifdef ANALTERNATIVE
00062 char * c = ctime( &t );
00063 strncpy( ts+ 0, c+ 8, 2 );
00064 strncpy( ts+ 3, c+ 4, 3 );
00065 strncpy( ts+ 7, c+20, 4 );
00066 strncpy( ts+12, c+11, 8 );
00067 strncpy( ts+21, tzname[localtime(&t)->tm_isdst], 3 );
00068 #endif
00069
00070 strftime( ts, strlen(ts)+1, "%d-%b-%Y %H:%M:%S %Z", localtime(&t) );
00071
00072
00073
00074 return ts;
00075
00076 }
00077
00078
00079
00080
00081
00082
00083 ELlog4cplus::ELlog4cplus()
00084 : ELdestination ( )
00085 , os ( &os_ )
00086 , osIsOwned ( false )
00087 , charsOnLine ( 0 )
00088 , xid ( )
00089 , wantTimestamp ( true )
00090 , wantModule ( true )
00091 , wantSubroutine ( true )
00092 , wantText ( true )
00093 , wantSomeContext ( true )
00094 , wantSerial ( false )
00095 , wantFullContext ( false )
00096 , wantTimeSeparate ( false )
00097 , wantEpilogueSeparate( false )
00098 , xxxxInt ( 0 )
00099 , appl_ ( 0 )
00100 {
00101
00102
00103 #ifdef ELlog4cplusCONSTRUCTOR_TRACE
00104 std::cerr << "Constructor for ELlog4cplus()\n";
00105 #endif
00106
00107 lineLength = 32000;
00108
00109 emit( "\n=======================================================", true );
00110 emit( "\nMessageLogger service established\n" );
00111 emit( formatTime(time(0)), true );
00112 emit( "\n=======================================================\n", true );
00113
00114 }
00115
00116
00117
00118 ELlog4cplus::ELlog4cplus( const ELlog4cplus & orig )
00119 : ELdestination ( )
00120 , os ( &os_ )
00121 , osIsOwned ( orig.osIsOwned )
00122 , charsOnLine ( orig.charsOnLine )
00123 , xid ( orig.xid )
00124 , wantTimestamp ( orig.wantTimestamp )
00125 , wantModule ( orig.wantModule )
00126 , wantSubroutine ( orig.wantSubroutine )
00127 , wantText ( orig.wantText )
00128 , wantSomeContext ( orig.wantSomeContext )
00129 , wantSerial ( orig.wantSerial )
00130 , wantFullContext ( orig.wantFullContext )
00131 , wantTimeSeparate ( orig.wantTimeSeparate )
00132 , wantEpilogueSeparate( orig.wantEpilogueSeparate )
00133 , xxxxInt ( orig.xxxxInt )
00134 , appl_ ( orig.appl_ )
00135 {
00136
00137 #ifdef ELlog4cplusCONSTRUCTOR_TRACE
00138 std::cerr << "Copy constructor for ELlog4cplus\n";
00139 #endif
00140
00141
00142 threshold = orig.threshold;
00143 traceThreshold = orig.traceThreshold;
00144
00145 limits = orig.limits;
00146 preamble = orig.preamble;
00147 newline = orig.newline;
00148 indent = orig.indent;
00149 lineLength = orig.lineLength;
00150
00151 ignoreMostModules = orig.ignoreMostModules;
00152 respondToThese = orig.respondToThese;
00153 respondToMostModules = orig.respondToMostModules;
00154 ignoreThese = orig.ignoreThese;
00155
00156
00157 const_cast<ELlog4cplus &>(orig).osIsOwned = false;
00158
00159 }
00160
00161
00162 ELlog4cplus::~ELlog4cplus() {
00163
00164 #ifdef ELlog4cplusCONSTRUCTOR_TRACE
00165 std::cerr << "Destructor for ELlog4cplus\n";
00166 #endif
00167
00168 if ( osIsOwned ) {
00169 ((std::ofstream*)os)->close();
00170 delete os;
00171 }
00172
00173 }
00174
00175
00176
00177
00178
00179
00180 ELlog4cplus *
00181 ELlog4cplus::clone() const {
00182
00183 return new ELlog4cplus( *this );
00184
00185 }
00186
00187
00188 bool ELlog4cplus::log( const ErrorObj & msg ) {
00189 os->str(std::string());
00190
00191 #ifdef ELlog4cplusTRACE_LOG
00192 std::cerr << " =:=:=: Log to an ELlog4cplus \n";
00193 #endif
00194
00195 xid = msg.xid();
00196
00197
00198
00199
00200 if ( msg.xid().severity < threshold ) return false;
00201 if ( thisShouldBeIgnored(xid.module) ) return false;
00202 if ( ! limits.add( msg.xid() ) ) return false;
00203
00204 #ifdef ELlog4cplusTRACE_LOG
00205 std::cerr << " =:=:=: Limits table work done \n";
00206 #endif
00207
00208
00209 bool mustPop = false;
00210
00211 log4cplus::Logger loghere = appl_ ? appl_->getApplicationLogger() :
00212 log4cplus::Logger::getInstance(msg.xid().module.c_str());
00213 LOG4CPLUS_DEBUG(loghere, "Message2log4cplus will use logger from appl_ ? "
00214 << (appl_ ? "yes" : "no"));
00215 if(appl_)
00216 {
00217 log4cplus::getNDC().push(msg.xid().module.c_str());
00218 mustPop = true;
00219 }
00220 log4cplus::getNDC().push(msg.context().c_str());
00221
00222
00223
00224 emit( preamble );
00225 emit( xid.severity.getSymbol() );
00226 emit( " " );
00227 emit( xid.id );
00228 emit( msg.idOverflow() );
00229 emit( ": " );
00230
00231 #ifdef ELlog4cplusTRACE_LOG
00232 std::cerr << " =:=:=: Prologue done \n";
00233 #endif
00234
00235
00236 if ( wantSerial ) {
00237 std::ostringstream s;
00238 s << msg.serial();
00239 emit( "[serial #" + s.str() + ELstring("] ") );
00240 }
00241
00242
00243
00244 if ( wantText ) {
00245 ELlist_string::const_iterator it;
00246 for ( it = msg.items().begin(); it != msg.items().end(); ++it ) {
00247 #ifdef ELlog4cplusTRACE_LOG
00248 std::cerr << " =:=:=: Item: " << *it << '\n';
00249 #endif
00250 emit( *it );
00251 }
00252 }
00253
00254
00255
00256 bool needAspace = true;
00257 if ( wantEpilogueSeparate ) {
00258 if ( xid.module.length() + xid.subroutine.length() > 0 ) {
00259 emit("\n");
00260 needAspace = false;
00261 }
00262 else if ( wantTimestamp && !wantTimeSeparate ) {
00263 emit("\n");
00264 needAspace = false;
00265 }
00266 }
00267 if ( wantModule && (xid.module.length() > 0) ) {
00268 if (needAspace) { emit(ELstring(" ")); needAspace = false; }
00269 emit( xid.module + ELstring(" ") );
00270 }
00271 if ( wantSubroutine && (xid.subroutine.length() > 0) ) {
00272 if (needAspace) { emit(ELstring(" ")); needAspace = false; }
00273 emit( xid.subroutine + "()" + ELstring(" ") );
00274 }
00275
00276 #ifdef ELlog4cplusTRACE_LOG
00277 std::cerr << " =:=:=: Module and Subroutine done \n";
00278 #endif
00279
00280
00281
00282 if ( wantTimestamp ) {
00283 if ( wantTimeSeparate ) {
00284 emit( ELstring("\n") );
00285 needAspace = false;
00286 }
00287 if (needAspace) { emit(ELstring(" ")); needAspace = false; }
00288 emit( formatTime(msg.timestamp()) + ELstring(" ") );
00289 }
00290
00291 #ifdef ELlog4cplusTRACE_LOG
00292 std::cerr << " =:=:=: TimeStamp done \n";
00293 #endif
00294
00295
00296
00297 if ( wantSomeContext )
00298 if (needAspace) { emit(ELstring(" ")); needAspace = false; }
00299 #ifdef ELlog4cplusTRACE_LOG
00300 std::cerr << " =:=:=:>> context supplier is at 0x"
00301 << std::hex
00302 << &service::ELadministrator::instance()->getContextSupplier() << '\n';
00303 std::cerr << " =:=:=:>> context is --- "
00304 << service::ELadministrator::instance()->getContextSupplier().context()
00305 << '\n';
00306 #endif
00307 if ( wantFullContext ) {
00308 emit( service::ELadministrator::instance()->getContextSupplier().fullContext());
00309 #ifdef ELlog4cplusTRACE_LOG
00310 std::cerr << " =:=:=: fullContext done: \n";
00311 #endif
00312 } else {
00313 emit( service::ELadministrator::instance()->getContextSupplier().context());
00314 #ifdef ELlog4cplusTRACE_LOG
00315 std::cerr << " =:=:=: Context done: \n";
00316 #endif
00317 }
00318
00319
00320
00321 if ( msg.xid().severity >= traceThreshold ) {
00322 emit( ELstring("\n")
00323 + service::ELadministrator::instance()->getContextSupplier().traceRoutine()
00324 , true );
00325 }
00326 else {
00327 emit ("", true);
00328 }
00329 #ifdef ELlog4cplusTRACE_LOG
00330 std::cerr << " =:=:=: Trace routine done: \n";
00331 #endif
00332
00333
00334
00335
00336 #ifdef ELlog4cplusTRACE_LOG
00337 std::cerr << " =:=:=: log(msg) done: \n";
00338 #endif
00339
00340
00341
00342 switch(msg.xid().severity.getLevel())
00343 {
00344 case edm::ELseverityLevel::ELsev_success:
00345 {
00346
00347 LOG4CPLUS_DEBUG(loghere,os->str());
00348 break;
00349 }
00350 case edm::ELseverityLevel::ELsev_info:
00351 {
00352 LOG4CPLUS_INFO(loghere,os->str());
00353 break;
00354 }
00355 case edm::ELseverityLevel::ELsev_warning:
00356 {
00357 LOG4CPLUS_WARN(loghere,os->str());
00358 break;
00359 }
00360 case edm::ELseverityLevel::ELsev_error:
00361 default:
00362 {
00363 LOG4CPLUS_ERROR(loghere,os->str());
00364 break;
00365 }
00366 }
00367 if(mustPop) log4cplus::getNDC().pop();
00368 log4cplus::getNDC().pop();
00369 return true;
00370
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 void ELlog4cplus::xxxxSet( int i ) {
00382 xxxxInt = i;
00383 }
00384
00385 void ELlog4cplus::xxxxShout() {
00386 std::cerr << "XXXX ELlog4cplus: " << xxxxInt << std::endl;
00387 }
00388
00389
00390
00391
00392
00393
00394 void ELlog4cplus::emit( const ELstring & s, bool nl ) {
00395
00396 #ifdef ELlog4cplus_EMIT_TRACE
00397 std::cerr << "[][][] in emit: charsOnLine is " << charsOnLine << '\n';
00398 std::cerr << "[][][] in emit: s.length() " << s.length() << '\n';
00399 std::cerr << "[][][] in emit: lineLength is " << lineLength << '\n';
00400 #endif
00401
00402 if (s.length() == 0) {
00403 if ( nl ) {
00404 (*os) << newline << std::flush;
00405 charsOnLine = 0;
00406 }
00407 return;
00408 }
00409
00410 char first = s[0];
00411 char second,
00412 last,
00413 last2;
00414 second = (s.length() < 2) ? '\0' : s[1];
00415 last = (s.length() < 2) ? '\0' : s[s.length()-1];
00416 last2 = (s.length() < 3) ? '\0' : s[s.length()-2];
00417
00418
00419
00420
00421 if ( first == '\n'
00422 || (charsOnLine + static_cast<int>(s.length())) > lineLength ) {
00423 #ifdef ELlog4cplus_EMIT_TRACE
00424 std::cerr << "[][][] in emit: about to << to *os \n";
00425 #endif
00426 (*os) << newline << indent;
00427 charsOnLine = indent.length();
00428 if (second != ' ') {
00429 (*os) << ' ';
00430 charsOnLine++;
00431 }
00432 if ( first == '\n' ) {
00433 (*os) << s.substr(1);
00434 }
00435 else {
00436 (*os) << s;
00437 }
00438 }
00439
00440 #ifdef ELlog4cplus_EMIT_TRACE
00441 std::cerr << "[][][] in emit: about to << s to *os: " << s << " \n";
00442 #endif
00443
00444 else {
00445 (*os) << s;
00446 }
00447
00448 if (last == '\n' || last2 == '\n') {
00449 (*os) << indent;
00450 if (last != ' ')
00451 (*os) << ' ';
00452 charsOnLine = indent.length() + 1;
00453 }
00454
00455 if ( nl ) { (*os) << newline << std::flush; charsOnLine = 0; }
00456 else { charsOnLine += s.length(); }
00457
00458 #ifdef ELlog4cplus_EMIT_TRACE
00459 std::cerr << "[][][] in emit: completed \n";
00460 #endif
00461
00462 }
00463
00464
00465
00466
00467
00468
00469 void ELlog4cplus::includeTime() { wantTimestamp = true; }
00470 void ELlog4cplus::suppressTime() { wantTimestamp = false; }
00471
00472 void ELlog4cplus::includeModule() { wantModule = true; }
00473 void ELlog4cplus::suppressModule() { wantModule = false; }
00474
00475 void ELlog4cplus::includeSubroutine() { wantSubroutine = true; }
00476 void ELlog4cplus::suppressSubroutine() { wantSubroutine = false; }
00477
00478 void ELlog4cplus::includeText() { wantText = true; }
00479 void ELlog4cplus::suppressText() { wantText = false; }
00480
00481 void ELlog4cplus::includeContext() { wantSomeContext = true; }
00482 void ELlog4cplus::suppressContext() { wantSomeContext = false; }
00483
00484 void ELlog4cplus::suppressSerial() { wantSerial = false; }
00485 void ELlog4cplus::includeSerial() { wantSerial = true; }
00486
00487 void ELlog4cplus::useFullContext() { wantFullContext = true; }
00488 void ELlog4cplus::useContext() { wantFullContext = false; }
00489
00490 void ELlog4cplus::separateTime() { wantTimeSeparate = true; }
00491 void ELlog4cplus::attachTime() { wantTimeSeparate = false; }
00492
00493 void ELlog4cplus::separateEpilogue() { wantEpilogueSeparate = true; }
00494 void ELlog4cplus::attachEpilogue() { wantEpilogueSeparate = false; }
00495
00496
00497
00498
00499
00500
00501 void ELlog4cplus::summarization(
00502 const ELstring & fullTitle
00503 , const ELstring & sumLines
00504 ) {
00505 const int titleMaxLength( 40 );
00506
00507
00508
00509 ELstring title( fullTitle, 0, titleMaxLength );
00510 int q = (lineLength - title.length() - 2) / 2;
00511 ELstring line(q, '=');
00512 emit( "", true );
00513 emit( line );
00514 emit( " " );
00515 emit( title );
00516 emit( " " );
00517 emit( line, true );
00518
00519
00520
00521 *os << sumLines;
00522
00523
00524
00525 emit( "", true );
00526 emit( ELstring(lineLength, '='), true );
00527
00528 }
00529
00530 void ELlog4cplus::setAppl(xdaq::Application *a)
00531 {
00532 std::cout << "setting application pointer in ELlog4cplus" << std::endl;
00533 appl_ = a;
00534 }
00535
00536
00537
00538
00539 }