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