00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 #include "FWCore/MessageService/interface/ELoutput.h"
00068 #include "FWCore/MessageService/interface/ELadministrator.h"
00069 #include "FWCore/MessageService/interface/ELcontextSupplier.h"
00070
00071 #include "FWCore/MessageLogger/interface/ErrorObj.h"
00072
00073
00074
00075
00076
00077
00078 #include <iostream>
00079 #include <fstream>
00080
00081 namespace edm {
00082 namespace service {
00083
00084
00085
00086
00087
00088
00089 static char * formatTime( const time_t t ) {
00090
00091 static char ts[] = "dd-Mon-yyyy hh:mm:ss TZN ";
00092
00093
00094 #ifdef AN_ALTERNATIVE_FOR_TIMEZONE
00095 char * c = ctime( &t );
00096 strncpy( ts+ 0, c+ 8, 2 );
00097 strncpy( ts+ 3, c+ 4, 3 );
00098 strncpy( ts+ 7, c+20, 4 );
00099 strncpy( ts+12, c+11, 8 );
00100 strncpy( ts+21, tzname[localtime(&t)->tm_isdst], 8 );
00101 #endif
00102
00103 strftime( ts, strlen(ts)+1, "%d-%b-%Y %H:%M:%S %Z", localtime(&t) );
00104
00105
00106 #ifdef STRIP_TRAILING_BLANKS_IN_TIMEZONE
00107
00108
00109 unsigned int b = strlen(ts);
00110 while (ts[--b] == ' ') {ts[b] = 0;}
00111 #endif
00112
00113 return ts;
00114
00115 }
00116
00117
00118
00119
00120
00121
00122 ELoutput::ELoutput()
00123 : ELdestination ( )
00124 , os ( &std::cerr )
00125 , osIsOwned ( false )
00126 , charsOnLine ( 0 )
00127 , xid ( )
00128 , wantTimestamp ( true )
00129 , wantModule ( true )
00130 , wantSubroutine ( true )
00131 , wantText ( true )
00132 , wantSomeContext ( true )
00133 , wantSerial ( false )
00134 , wantFullContext ( false )
00135 , wantTimeSeparate ( false )
00136 , wantEpilogueSeparate( false )
00137 {
00138
00139 #ifdef ELoutputCONSTRUCTOR_TRACE
00140 std::cerr << "Constructor for ELoutput()\n";
00141 #endif
00142
00143 emit( "\n=================================================", true );
00144 emit( "\nMessage Log File written by MessageLogger service \n" );
00145 emit( "\n=================================================\n", true );
00146
00147 }
00148
00149
00150 ELoutput::ELoutput( std::ostream & os_ , bool emitAtStart )
00151 : ELdestination ( )
00152 , os ( &os_ )
00153 , osIsOwned ( false )
00154 , charsOnLine ( 0 )
00155 , xid ( )
00156 , wantTimestamp ( true )
00157 , wantModule ( true )
00158 , wantSubroutine ( true )
00159 , wantText ( true )
00160 , wantSomeContext ( true )
00161 , wantSerial ( false )
00162 , wantFullContext ( false )
00163 , wantTimeSeparate ( false )
00164 , wantEpilogueSeparate( false )
00165 {
00166
00167 #ifdef ELoutputCONSTRUCTOR_TRACE
00168 std::cerr << "Constructor for ELoutput( os )\n";
00169 #endif
00170
00171
00172 if (emitAtStart) {
00173 bool tprm = preambleMode;
00174 preambleMode = true;
00175 emit( "\n=================================================", true );
00176 emit( "\nMessage Log File written by MessageLogger service \n" );
00177 emit( "\n=================================================\n", true );
00178 preambleMode = tprm;
00179 }
00180
00181 }
00182
00183
00184 ELoutput::ELoutput( const ELstring & fileName, bool emitAtStart )
00185 : ELdestination ( )
00186 , os ( new std::ofstream( fileName.c_str()
00187 , std::ios::app
00188 )
00189 )
00190 , osIsOwned ( false )
00191 , charsOnLine ( 0 )
00192 , xid ( )
00193 , wantTimestamp ( true )
00194 , wantModule ( true )
00195 , wantSubroutine ( true )
00196 , wantText ( true )
00197 , wantSomeContext ( true )
00198 , wantSerial ( false )
00199 , wantFullContext ( false )
00200 , wantTimeSeparate ( false )
00201 , wantEpilogueSeparate( false )
00202 {
00203
00204 #ifdef ELoutputCONSTRUCTOR_TRACE
00205 std::cerr << "Constructor for ELoutput( " << fileName << " )\n";
00206 #endif
00207
00208 bool tprm = preambleMode;
00209 preambleMode = true;
00210 if ( os && *os ) {
00211 #ifdef ELoutputCONSTRUCTOR_TRACE
00212 std::cerr << " Testing if os is owned\n";
00213 #endif
00214 osIsOwned = true;
00215 #ifdef ELoutputCONSTRUCTOR_TRACE
00216 std::cerr << " About to do first emit\n";
00217 #endif
00218
00219 if (emitAtStart) {
00220 emit( "\n=======================================================",
00221 true );
00222 emit( "\nError Log File " );
00223 emit( fileName );
00224 emit( " \n" );
00225 }
00226 }
00227 else {
00228 #ifdef ELoutputCONSTRUCTOR_TRACE
00229 std::cerr << " Deleting os\n";
00230 #endif
00231 delete os;
00232 os = & std::cerr;
00233 #ifdef ELoutputCONSTRUCTOR_TRACE
00234 std::cerr << " about to emit to cerr\n";
00235 #endif
00236 if (emitAtStart) {
00237 emit( "\n=======================================================",
00238 true );
00239 emit( "\n%MSG** Logging to cerr is being substituted" );
00240 emit( " for specified log file \"" );
00241 emit( fileName );
00242 emit( "\" which could not be opened for write or append.\n" );
00243 }
00244 }
00245 if (emitAtStart) {
00246 emit( formatTime(time(0)), true );
00247 emit( "\n=======================================================\n",
00248 true );
00249 }
00250 preambleMode = tprm;
00251
00252 #ifdef ELoutputCONSTRUCTOR_TRACE
00253 std::cerr << "Constructor for ELoutput completed.\n";
00254 #endif
00255
00256 }
00257
00258
00259 ELoutput::ELoutput( const ELoutput & orig )
00260 : ELdestination ( )
00261 , os ( orig.os )
00262 , osIsOwned ( orig.osIsOwned )
00263 , charsOnLine ( orig.charsOnLine )
00264 , xid ( orig.xid )
00265 , wantTimestamp ( orig.wantTimestamp )
00266 , wantModule ( orig.wantModule )
00267 , wantSubroutine ( orig.wantSubroutine )
00268 , wantText ( orig.wantText )
00269 , wantSomeContext ( orig.wantSomeContext )
00270 , wantSerial ( orig.wantSerial )
00271 , wantFullContext ( orig.wantFullContext )
00272 , wantTimeSeparate ( orig.wantTimeSeparate )
00273 , wantEpilogueSeparate( orig.wantEpilogueSeparate )
00274 {
00275
00276 #ifdef ELoutputCONSTRUCTOR_TRACE
00277 std::cerr << "Copy constructor for ELoutput\n";
00278 #endif
00279
00280
00281 threshold = orig.threshold;
00282 traceThreshold = orig.traceThreshold;
00283 limits = orig.limits;
00284 preamble = orig.preamble;
00285 newline = orig.newline;
00286 indent = orig.indent;
00287 lineLength = orig.lineLength;
00288
00289 ignoreMostModules = orig.ignoreMostModules;
00290 respondToThese = orig.respondToThese;
00291 respondToMostModules = orig.respondToMostModules;
00292 ignoreThese = orig.ignoreThese;
00293
00294
00295 const_cast<ELoutput &>(orig).osIsOwned = false;
00296
00297 }
00298
00299
00300 ELoutput::~ELoutput() {
00301
00302 #ifdef ELoutputCONSTRUCTOR_TRACE
00303 std::cerr << "Destructor for ELoutput\n";
00304 #endif
00305
00306 if ( osIsOwned ) {
00307 ((std::ofstream*)os)->close();
00308 delete os;
00309 }
00310
00311 }
00312
00313
00314
00315
00316
00317
00318 ELoutput *
00319 ELoutput::clone() const {
00320
00321 return new ELoutput( *this );
00322
00323 }
00324
00325
00326 bool ELoutput::log( const edm::ErrorObj & msg ) {
00327
00328 #ifdef ELoutputTRACE_LOG
00329 std::cerr << " =:=:=: Log to an ELoutput \n";
00330 #endif
00331
00332 xid = msg.xid();
00333
00334
00335
00336
00337 if ( xid.severity < threshold ) return false;
00338 if ( thisShouldBeIgnored(xid.module)
00339 && (xid.severity < ELsevere) )
00340 return false;
00341 if ( ! limits.add( xid )
00342 && (xid.severity < ELsevere) )
00343 return false;
00344
00345 #ifdef ELoutputTRACE_LOG
00346 std::cerr << " =:=:=: Limits table work done \n";
00347 #endif
00348
00349
00350
00351 preambleMode = true;
00352
00353 if ( !msg.is_verbatim() ) {
00354 emit( preamble );
00355 emit( xid.severity.getSymbol() );
00356 emit( " " );
00357 emit( xid.id );
00358 emit( msg.idOverflow() );
00359 emit( ": " );
00360 }
00361
00362 #ifdef ELoutputTRACE_LOG
00363 std::cerr << " =:=:=: Prologue done \n";
00364 #endif
00365
00366
00367 if ( !msg.is_verbatim() )
00368 {
00369 if ( wantSerial ) {
00370 std::ostringstream s;
00371 s << msg.serial();
00372 emit( "[serial #" + s.str() + ELstring("] ") );
00373 }
00374 }
00375
00376 #ifdef OUTPUT_FORMATTED_ERROR_MESSAGES
00377
00378
00379 if ( wantText ) {
00380 ELlist_string::const_iterator it;
00381 for ( it = msg.items().begin(); it != msg.items().end(); ++it ) {
00382 #ifdef ELoutputTRACE_LOG
00383 std::cerr << " =:=:=: Item: " << *it << '\n';
00384 #endif
00385 emit( *it );
00386 }
00387 }
00388 #endif
00389
00390
00391
00392 bool needAspace = true;
00393 if ( !msg.is_verbatim() )
00394 {
00395 if ( wantEpilogueSeparate ) {
00396 if ( xid.module.length() + xid.subroutine.length() > 0 ) {
00397 emit("\n");
00398 needAspace = false;
00399 }
00400 else if ( wantTimestamp && !wantTimeSeparate ) {
00401 emit("\n");
00402 needAspace = false;
00403 }
00404 }
00405 if ( wantModule && (xid.module.length() > 0) ) {
00406 if (needAspace) { emit(ELstring(" ")); needAspace = false; }
00407 emit( xid.module + ELstring(" ") );
00408 }
00409 if ( wantSubroutine && (xid.subroutine.length() > 0) ) {
00410 if (needAspace) { emit(ELstring(" ")); needAspace = false; }
00411 emit( xid.subroutine + "()" + ELstring(" ") );
00412 }
00413 }
00414
00415 #ifdef ELoutputTRACE_LOG
00416 std::cerr << " =:=:=: Module and Subroutine done \n";
00417 #endif
00418
00419
00420
00421 if ( !msg.is_verbatim() )
00422 {
00423 if ( wantTimestamp ) {
00424 if ( wantTimeSeparate ) {
00425 emit( ELstring("\n") );
00426 needAspace = false;
00427 }
00428 if (needAspace) { emit(ELstring(" ")); needAspace = false; }
00429 emit( formatTime(msg.timestamp()) + ELstring(" ") );
00430 }
00431 }
00432
00433 #ifdef ELoutputTRACE_LOG
00434 std::cerr << " =:=:=: TimeStamp done \n";
00435 #endif
00436
00437
00438
00439 if ( !msg.is_verbatim() )
00440 {
00441 if ( wantSomeContext ) {
00442 if (needAspace) { emit(ELstring(" ")); needAspace = false; }
00443 #ifdef ELoutputTRACE_LOG
00444 std::cerr << " =:=:=:>> context supplier is at 0x"
00445 << std::hex
00446 << &ELadministrator::instance()->getContextSupplier() << '\n';
00447 std::cerr << " =:=:=:>> context is --- "
00448 << ELadministrator::instance()->getContextSupplier().context()
00449 << '\n';
00450 #endif
00451 if ( wantFullContext ) {
00452 emit( ELadministrator::instance()->getContextSupplier().fullContext());
00453 #ifdef ELoutputTRACE_LOG
00454 std::cerr << " =:=:=: fullContext done: \n";
00455 #endif
00456 } else {
00457 emit( ELadministrator::instance()->getContextSupplier().context());
00458 #ifdef ELoutputTRACE_LOG
00459 std::cerr << " =:=:=: Context done: \n";
00460 #endif
00461 }
00462 }
00463 }
00464
00465
00466
00467
00468 bool insertNewlineAfterHeader = ( msg.xid().severity != ELsuccess );
00469
00470
00471 if ( !msg.is_verbatim() )
00472 {
00473 if ( msg.xid().severity >= traceThreshold ) {
00474 emit( ELstring("\n")
00475 + ELadministrator::instance()->getContextSupplier().traceRoutine()
00476 , insertNewlineAfterHeader );
00477 }
00478 else {
00479 emit ("", insertNewlineAfterHeader);
00480 }
00481 }
00482 #ifdef ELoutputTRACE_LOG
00483 std::cerr << " =:=:=: Trace routine done: \n";
00484 #endif
00485
00486 #ifndef OUTPUT_FORMATTED_ERROR_MESSAGES
00487
00488
00489 preambleMode = false;
00490 if ( wantText ) {
00491 ELlist_string::const_iterator it;
00492 int item_count = 0;
00493 for ( it = msg.items().begin(); it != msg.items().end(); ++it ) {
00494 #ifdef ELoutputTRACE_LOG
00495 std::cerr << " =:=:=: Item: " << *it << '\n';
00496 #endif
00497 ++item_count;
00498 if ( !msg.is_verbatim() ) {
00499 if ( !insertNewlineAfterHeader && (item_count == 3) ) {
00500
00501 emit( *it, true );
00502 } else {
00503 emit( *it );
00504 }
00505 } else {
00506 emit( *it );
00507 }
00508 }
00509 }
00510 #endif
00511
00512
00513
00514
00515 if ( !msg.is_verbatim() )
00516 {
00517 emit ("\n%MSG");
00518 }
00519
00520
00521
00522
00523
00524 (*os) << newline;
00525 flush();
00526
00527
00528 #ifdef ELoutputTRACE_LOG
00529 std::cerr << " =:=:=: log(msg) done: \n";
00530 #endif
00531
00532 return true;
00533
00534 }
00535
00536
00537
00538
00539
00540
00541
00542
00543 void ELoutput::emit( const ELstring & s, bool nl ) {
00544
00545 #ifdef ELoutput_EMIT_TRACE
00546 std::cerr << "[][][] in emit: charsOnLine is " << charsOnLine << '\n';
00547 std::cerr << "[][][] in emit: s.length() " << s.length() << '\n';
00548 std::cerr << "[][][] in emit: lineLength is " << lineLength << '\n';
00549 #endif
00550
00551 if (s.length() == 0) {
00552 if ( nl ) {
00553 (*os) << newline << std::flush;
00554 charsOnLine = 0;
00555 }
00556 return;
00557 }
00558
00559 char first = s[0];
00560 char second,
00561 last,
00562 last2;
00563 second = (s.length() < 2) ? '\0' : s[1];
00564 last = (s.length() < 2) ? '\0' : s[s.length()-1];
00565 last2 = (s.length() < 3) ? '\0' : s[s.length()-2];
00566
00567
00568
00569 if (preambleMode) {
00570
00571 if ( first == '\n'
00572 || (charsOnLine + static_cast<int>(s.length())) > lineLength ) {
00573 #ifdef ELoutput_EMIT_TRACE
00574 std::cerr << "[][][] in emit: about to << to *os \n";
00575 #endif
00576 #ifdef HEADERS_BROKEN_INTO_LINES_AND_INDENTED
00577
00578 (*os) << newline << indent;
00579 charsOnLine = indent.length();
00580 #endif
00581 if (second != ' ') {
00582 (*os) << ' ';
00583 charsOnLine++;
00584 }
00585 if ( first == '\n' ) {
00586 (*os) << s.substr(1);
00587 }
00588 else {
00589 (*os) << s;
00590 }
00591 }
00592 #ifdef ELoutput_EMIT_TRACE
00593 std::cerr << "[][][] in emit: about to << s to *os: " << s << " \n";
00594 #endif
00595 else {
00596 (*os) << s;
00597 }
00598
00599 if (last == '\n' || last2 == '\n') {
00600 (*os) << indent;
00601 if (last != ' ')
00602 (*os) << ' ';
00603 charsOnLine = indent.length() + 1;
00604 }
00605
00606 if ( nl ) { (*os) << newline << std::flush; charsOnLine = 0; }
00607 else { charsOnLine += s.length(); }
00608 }
00609
00610 if (!preambleMode) {
00611 (*os) << s;
00612 }
00613
00614 #ifdef ELoutput_EMIT_TRACE
00615 std::cerr << "[][][] in emit: completed \n";
00616 #endif
00617
00618 }
00619
00620
00621
00622
00623
00624
00625 void ELoutput::includeTime() { wantTimestamp = true; }
00626 void ELoutput::suppressTime() { wantTimestamp = false; }
00627
00628 void ELoutput::includeModule() { wantModule = true; }
00629 void ELoutput::suppressModule() { wantModule = false; }
00630
00631 void ELoutput::includeSubroutine() { wantSubroutine = true; }
00632 void ELoutput::suppressSubroutine() { wantSubroutine = false; }
00633
00634 void ELoutput::includeText() { wantText = true; }
00635 void ELoutput::suppressText() { wantText = false; }
00636
00637 void ELoutput::includeContext() { wantSomeContext = true; }
00638 void ELoutput::suppressContext() { wantSomeContext = false; }
00639
00640 void ELoutput::suppressSerial() { wantSerial = false; }
00641 void ELoutput::includeSerial() { wantSerial = true; }
00642
00643 void ELoutput::useFullContext() { wantFullContext = true; }
00644 void ELoutput::useContext() { wantFullContext = false; }
00645
00646 void ELoutput::separateTime() { wantTimeSeparate = true; }
00647 void ELoutput::attachTime() { wantTimeSeparate = false; }
00648
00649 void ELoutput::separateEpilogue() { wantEpilogueSeparate = true; }
00650 void ELoutput::attachEpilogue() { wantEpilogueSeparate = false; }
00651
00652
00653
00654
00655
00656
00657 void ELoutput::summarization(
00658 const ELstring & fullTitle
00659 , const ELstring & sumLines
00660 ) {
00661 const int titleMaxLength( 40 );
00662
00663
00664
00665 ELstring title( fullTitle, 0, titleMaxLength );
00666 int q = (lineLength - title.length() - 2) / 2;
00667 ELstring line(q, '=');
00668 emit( "", true );
00669 emit( line );
00670 emit( " " );
00671 emit( title );
00672 emit( " " );
00673 emit( line, true );
00674
00675
00676
00677 *os << sumLines;
00678
00679
00680
00681 emit( "", true );
00682 emit( ELstring(lineLength, '='), true );
00683
00684 }
00685
00686
00687
00688
00689
00690
00691 void ELoutput::changeFile (std::ostream & os_) {
00692 if ( osIsOwned ) {
00693 ((std::ofstream*)os)->close();
00694 delete os;
00695 }
00696 os = &os_;
00697 osIsOwned = false;
00698 emit( "\n=======================================================", true );
00699 emit( "\nError Log changed to this stream\n" );
00700 emit( formatTime(time(0)), true );
00701 emit( "\n=======================================================\n", true );
00702 }
00703
00704 void ELoutput::changeFile (const ELstring & filename) {
00705 if ( osIsOwned ) {
00706 ((std::ofstream*)os)->close();
00707 delete os;
00708 }
00709 os = new std::ofstream( filename.c_str(), std::ios::app );
00710 osIsOwned = false;
00711 emit( "\n=======================================================", true );
00712 emit( "\nError Log changed to this file\n" );
00713 emit( formatTime(time(0)), true );
00714 emit( "\n=======================================================\n", true );
00715 }
00716
00717 void ELoutput::flush() {
00718 os->flush();
00719 }
00720
00721
00722
00723
00724
00725 }
00726 }