CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ELlog4cplus.cc
Go to the documentation of this file.
1 // ----------------------------------------------------------------------
2 //
3 // ELcontextSupplier.cc
4 //
5 //
6 // 12/20/05 jm, mf Created, based on ELoutput.
7 //
8 // ----------------------------------------------------------------------
9 
10 
12 
16 
17 #include "log4cplus/logger.h"
18 #include "log4cplus/fileappender.h"
19 #include "log4cplus/loglevel.h"
20 
21 #include "xdaq/Application.h"
22 #include <memory>
23 
24 // Possible Traces:
25 // #define ELoutputCONSTRUCTOR_TRACE
26 //#define ELlog4cplusTRACE_LOG
27 //#define ELlog4cplus_EMIT_TRACE
28 
29 #include <iostream>
30 #include <fstream>
31 
32 namespace edm
33 {
34 
35 namespace {
36  void makeFileAppender()
37  {
38  static bool iscalled = false;
39  if(iscalled) return;
40  iscalled=true;
41 
42  using namespace log4cplus;
43  using namespace log4cplus::helpers;
44 
45  SharedAppenderPtr ap(new FileAppender("log4cplus.output"));
46  ap->setName("Main");
47  ap->setLayout(std::auto_ptr<Layout>(new log4cplus::TTCCLayout()) );
48  Logger::getRoot().addAppender(ap);
49  }
50 }
51 
52 // ----------------------------------------------------------------------
53 // Useful function:
54 // ----------------------------------------------------------------------
55 
56 
57 static char * formatTime( const time_t t ) {
58 
59 static char ts[] = "dd-Mon-yyyy hh:mm:ss XYZ";
60 
61 
62 #ifdef ANALTERNATIVE
63  char * c = ctime( &t ); // 6/14/99 mf Can't be static!
64  strncpy( ts+ 0, c+ 8, 2 ); // dd
65  strncpy( ts+ 3, c+ 4, 3 ); // Mon
66  strncpy( ts+ 7, c+20, 4 ); // yyyy
67  strncpy( ts+12, c+11, 8 ); // hh:mm:ss
68  strncpy( ts+21, tzname[localtime(&t)->tm_isdst], 3 ); // CST
69 #endif
70 
71  strftime( ts, strlen(ts)+1, "%d-%b-%Y %H:%M:%S %Z", localtime(&t) );
72  // mf 4-9-04
73 
74 
75  return ts;
76 
77 } // formatTime()
78 
79 
80 // ----------------------------------------------------------------------
81 // Constructors:
82 // ----------------------------------------------------------------------
83 
85 : ELdestination ( )
86 , os ( &os_ )
87 , osIsOwned ( false )
88 , charsOnLine ( 0 )
89 , xid ( )
90 , wantTimestamp ( true )
91 , wantModule ( true )
92 , wantSubroutine ( true )
93 , wantText ( true )
94 , wantSomeContext ( true )
95 , wantSerial ( false )
96 , wantFullContext ( false )
97 , wantTimeSeparate ( false )
98 , wantEpilogueSeparate( false )
99 , xxxxInt ( 0 )
100 , appl_ ( 0 )
101 {
102  // makeFileAppender(); // this is not needed/wanted. An appender must be provided by the application itself
103 
104  #ifdef ELlog4cplusCONSTRUCTOR_TRACE
105  std::cerr << "Constructor for ELlog4cplus()\n";
106  #endif
107 
108  lineLength = 32000;
109 
110  emit( "\n=======================================================", true );
111  emit( "\nMessageLogger service established\n" );
112  emit( formatTime(time(0)), true );
113  emit( "\n=======================================================\n", true );
114 
115 } // ELlog4cplus()
116 
117 
118 
120 : ELdestination ( )
121 , os ( &os_ )
122 , osIsOwned ( orig.osIsOwned )
123 , charsOnLine ( orig.charsOnLine )
124 , xid ( orig.xid )
125 , wantTimestamp ( orig.wantTimestamp )
126 , wantModule ( orig.wantModule )
127 , wantSubroutine ( orig.wantSubroutine )
128 , wantText ( orig.wantText )
129 , wantSomeContext ( orig.wantSomeContext )
130 , wantSerial ( orig.wantSerial )
131 , wantFullContext ( orig.wantFullContext )
132 , wantTimeSeparate ( orig.wantTimeSeparate )
133 , wantEpilogueSeparate( orig.wantEpilogueSeparate )
134 , xxxxInt ( orig.xxxxInt )
135 , appl_ ( orig.appl_ )
136 {
137 
138  #ifdef ELlog4cplusCONSTRUCTOR_TRACE
139  std::cerr << "Copy constructor for ELlog4cplus\n";
140  #endif
141 
142  // mf 6/15/01 fix of Bug 005
143  threshold = orig.threshold;
145 
146  limits = orig.limits;
147  preamble = orig.preamble;
148  newline = orig.newline;
149  indent = orig.indent;
150  lineLength = orig.lineLength;
151 
155  ignoreThese = orig.ignoreThese;
156 
157  // ownership, if any, passes to new copy:
158  const_cast<ELlog4cplus &>(orig).osIsOwned = false;
159 
160 } // ELlog4cplus()
161 
162 
164 
165  #ifdef ELlog4cplusCONSTRUCTOR_TRACE
166  std::cerr << "Destructor for ELlog4cplus\n";
167  #endif
168 
169  if ( osIsOwned ) { // we have an ofstream
170  ((std::ofstream*)os)->close();
171  delete os;
172  }
173 
174 } // ~ELlog4cplus()
175 
176 
177 // ----------------------------------------------------------------------
178 // Methods invoked by the ELadministrator:
179 // ----------------------------------------------------------------------
180 
181 ELlog4cplus *
183 
184  return new ELlog4cplus( *this );
185 
186 } // clone()
187 
188 
189 bool ELlog4cplus::log( const ErrorObj & msg ) {
190  os->str(std::string());
191 
192  #ifdef ELlog4cplusTRACE_LOG
193  std::cerr << " =:=:=: Log to an ELlog4cplus \n";
194  #endif
195 
196  xid = msg.xid(); // Save the xid.
197 
198  // See if this message is to be acted upon, and add it to limits table
199  // if it was not already present:
200  //
201  if ( msg.xid().severity < threshold ) return false;
202  if ( thisShouldBeIgnored(xid.module) ) return false;
203  if ( ! limits.add( msg.xid() ) ) return false;
204 
205 #ifdef ELlog4cplusTRACE_LOG
206  std::cerr << " =:=:=: Limits table work done \n";
207 #endif
208 
209  // get log4cplus logger and establish (log4cplus) context
210  bool mustPop = false;
211 
212  log4cplus::Logger loghere = appl_ ? appl_->getApplicationLogger() :
213  log4cplus::Logger::getInstance(msg.xid().module.c_str());
214  LOG4CPLUS_DEBUG(loghere, "Message2log4cplus will use logger from appl_ ? "
215  << (appl_ ? "yes" : "no"));
216  if(appl_)
217  {
218  log4cplus::getNDC().push(msg.xid().module.c_str());
219  mustPop = true;
220  }
221  log4cplus::getNDC().push(msg.context().c_str());
222 
223  // Output the prologue:
224  //
225  emit( preamble );
226  emit( xid.severity.getSymbol() );
227  emit( " " );
228  emit( xid.id );
229  emit( msg.idOverflow() );
230  emit( ": " );
231 
232  #ifdef ELlog4cplusTRACE_LOG
233  std::cerr << " =:=:=: Prologue done \n";
234  #endif
235  // Output serial number of message:
236  //
237  if ( wantSerial ) {
238  std::ostringstream s;
239  s << msg.serial();
240  emit( "[serial #" + s.str() + ELstring("] ") );
241  }
242 
243  // Output each item in the message:
244  //
245  if ( wantText ) {
246  ELlist_string::const_iterator it;
247  for ( it = msg.items().begin(); it != msg.items().end(); ++it ) {
248  #ifdef ELlog4cplusTRACE_LOG
249  std::cerr << " =:=:=: Item: " << *it << '\n';
250  #endif
251  emit( *it );
252  }
253  }
254 
255  // Provide further identification:
256  //
257  bool needAspace = true;
258  if ( wantEpilogueSeparate ) {
259  if ( xid.module.length() + xid.subroutine.length() > 0 ) {
260  emit("\n");
261  needAspace = false;
262  }
263  else if ( wantTimestamp && !wantTimeSeparate ) {
264  emit("\n");
265  needAspace = false;
266  }
267  }
268  if ( wantModule && (xid.module.length() > 0) ) {
269  if (needAspace) { emit(ELstring(" ")); needAspace = false; }
270  emit( xid.module + ELstring(" ") );
271  }
272  if ( wantSubroutine && (xid.subroutine.length() > 0) ) {
273  if (needAspace) { emit(ELstring(" ")); needAspace = false; }
274  emit( xid.subroutine + "()" + ELstring(" ") );
275  }
276 
277  #ifdef ELlog4cplusTRACE_LOG
278  std::cerr << " =:=:=: Module and Subroutine done \n";
279  #endif
280 
281  // Provide time stamp:
282  //
283  if ( wantTimestamp ) {
284  if ( wantTimeSeparate ) {
285  emit( ELstring("\n") );
286  needAspace = false;
287  }
288  if (needAspace) { emit(ELstring(" ")); needAspace = false; }
289  emit( formatTime(msg.timestamp()) + ELstring(" ") );
290  }
291 
292  #ifdef ELlog4cplusTRACE_LOG
293  std::cerr << " =:=:=: TimeStamp done \n";
294  #endif
295 
296  // Provide the context information:
297  //
298  if ( wantSomeContext )
299  if (needAspace) { emit(ELstring(" ")); needAspace = false; }
300  #ifdef ELlog4cplusTRACE_LOG
301  std::cerr << " =:=:=:>> context supplier is at 0x"
302  << std::hex
304  std::cerr << " =:=:=:>> context is --- "
306  << '\n';
307  #endif
308  if ( wantFullContext ) {
309  emit( service::ELadministrator::instance()->getContextSupplier().fullContext());
310  #ifdef ELlog4cplusTRACE_LOG
311  std::cerr << " =:=:=: fullContext done: \n";
312  #endif
313  } else {
314  emit( service::ELadministrator::instance()->getContextSupplier().context());
315  #ifdef ELlog4cplusTRACE_LOG
316  std::cerr << " =:=:=: Context done: \n";
317  #endif
318  }
319 
320  // Provide traceback information:
321  //
322  if ( msg.xid().severity >= traceThreshold ) {
323  emit( ELstring("\n")
324  + service::ELadministrator::instance()->getContextSupplier().traceRoutine()
325  , true );
326  }
327  else { //else statement added JV:1
328  emit ("", true);
329  }
330  #ifdef ELlog4cplusTRACE_LOG
331  std::cerr << " =:=:=: Trace routine done: \n";
332  #endif
333 
334  // Done; message has been fully processed:
335  //
336 
337  #ifdef ELlog4cplusTRACE_LOG
338  std::cerr << " =:=:=: log(msg) done: \n";
339  #endif
340 
341  // std::cout << os->str() << "\n";
342 
343  switch(msg.xid().severity.getLevel())
344  {
346  {
347  // success is used for debug here
348  LOG4CPLUS_DEBUG(loghere,os->str());
349  break;
350  }
352  {
353  LOG4CPLUS_INFO(loghere,os->str());
354  break;
355  }
357  {
358  LOG4CPLUS_WARN(loghere,os->str());
359  break;
360  }
362  default:
363  {
364  LOG4CPLUS_ERROR(loghere,os->str());
365  break;
366  }
367  }
368  if(mustPop) log4cplus::getNDC().pop();
369  log4cplus::getNDC().pop();
370  return true;
371 
372 } // log()
373 
374 
375 // Remainder are from base class.
376 
377 
378 // ----------------------------------------------------------------------
379 // Maintenance and test functionality:
380 // ----------------------------------------------------------------------
381 
382 void ELlog4cplus::xxxxSet( int i ) {
383  xxxxInt = i;
384 }
385 
387  std::cerr << "XXXX ELlog4cplus: " << xxxxInt << std::endl;
388 }
389 
390 
391 // ----------------------------------------------------------------------
392 // Output methods:
393 // ----------------------------------------------------------------------
394 
395 void ELlog4cplus::emit( const ELstring & s, bool nl ) {
396 
397  #ifdef ELlog4cplus_EMIT_TRACE
398  std::cerr << "[][][] in emit: charsOnLine is " << charsOnLine << '\n';
399  std::cerr << "[][][] in emit: s.length() " << s.length() << '\n';
400  std::cerr << "[][][] in emit: lineLength is " << lineLength << '\n';
401  #endif
402 
403  if (s.length() == 0) {
404  if ( nl ) {
405  (*os) << newline << std::flush;
406  charsOnLine = 0;
407  }
408  return;
409  }
410 
411  char first = s[0];
412  char second,
413  last,
414  last2;
415  second = (s.length() < 2) ? '\0' : s[1];
416  last = (s.length() < 2) ? '\0' : s[s.length()-1];
417  last2 = (s.length() < 3) ? '\0' : s[s.length()-2];
418  //checking -2 because the very last char is sometimes a ' ' inserted
419  //by ErrorLog::operator<<
420 
421  //Accounts for newline @ the beginning of the ELstring JV:2
422  if ( first == '\n'
423  || (charsOnLine + static_cast<int>(s.length())) > lineLength ) {
424  #ifdef ELlog4cplus_EMIT_TRACE
425  std::cerr << "[][][] in emit: about to << to *os \n";
426  #endif
427  (*os) << newline << indent;
428  charsOnLine = indent.length();
429  if (second != ' ') {
430  (*os) << ' ';
431  charsOnLine++;
432  }
433  if ( first == '\n' ) {
434  (*os) << s.substr(1);
435  }
436  else {
437  (*os) << s;
438  }
439  }
440 
441  #ifdef ELlog4cplus_EMIT_TRACE
442  std::cerr << "[][][] in emit: about to << s to *os: " << s << " \n";
443  #endif
444 
445  else {
446  (*os) << s;
447  }
448 
449  if (last == '\n' || last2 == '\n') { //accounts for newline @ end $$ JV:2
450  (*os) << indent; //of the ELstring
451  if (last != ' ')
452  (*os) << ' ';
453  charsOnLine = indent.length() + 1;
454  }
455 
456  if ( nl ) { (*os) << newline << std::flush; charsOnLine = 0; }
457  else { charsOnLine += s.length(); }
458 
459  #ifdef ELlog4cplus_EMIT_TRACE
460  std::cerr << "[][][] in emit: completed \n";
461  #endif
462 
463 } // emit()
464 
465 
466 // ----------------------------------------------------------------------
467 // Methods controlling message formatting:
468 // ----------------------------------------------------------------------
469 
472 
475 
478 
481 
484 
487 
490 
493 
496 
497 
498 // ----------------------------------------------------------------------
499 // Summary output:
500 // ----------------------------------------------------------------------
501 
503  const ELstring & fullTitle
504 , const ELstring & sumLines
505 ) {
506  const int titleMaxLength( 40 );
507 
508  // title:
509  //
510  ELstring title( fullTitle, 0, titleMaxLength );
511  int q = (lineLength - title.length() - 2) / 2;
512  ELstring line(q, '=');
513  emit( "", true );
514  emit( line );
515  emit( " " );
516  emit( title );
517  emit( " " );
518  emit( line, true );
519 
520  // body:
521  //
522  *os << sumLines;
523 
524  // finish:
525  //
526  emit( "", true );
527  emit( ELstring(lineLength, '='), true );
528 
529 } // summarization()
530 
531 void ELlog4cplus::setAppl(xdaq::Application *a)
532 {
533  std::cout << "setting application pointer in ELlog4cplus" << std::endl;
534  appl_ = a;
535 }
536 
537 // ----------------------------------------------------------------------
538 
539 
540 } // end of namespace edm */
ELseverityLevel traceThreshold
const ELcontextSupplier & getContextSupplier() const
int i
Definition: DBlmapReader.cc:9
virtual ~ELlog4cplus()
Definition: ELlog4cplus.cc:163
virtual void suppressSerial()
Definition: ELlog4cplus.cc:485
ELseverityLevel severity
Definition: ELextendedID.h:36
const ELstring & idOverflow() const
Definition: ErrorObj.cc:127
std::ostringstream * os
Definition: ELlog4cplus.h:118
virtual void attachEpilogue()
Definition: ELlog4cplus.cc:495
virtual void separateTime()
Definition: ELlog4cplus.cc:491
virtual void includeSerial()
Definition: ELlog4cplus.cc:486
virtual void suppressSubroutine()
Definition: ELlog4cplus.cc:477
virtual void includeText()
Definition: ELlog4cplus.cc:479
virtual void includeSubroutine()
Definition: ELlog4cplus.cc:476
time_t timestamp() const
Definition: ErrorObj.cc:128
virtual bool thisShouldBeIgnored(const ELstring &s) const
virtual void includeTime()
Definition: ELlog4cplus.cc:470
void setAppl(xdaq::Application *a)
Definition: ELlog4cplus.cc:531
virtual void suppressContext()
Definition: ELlog4cplus.cc:483
U second(std::pair< T, U > const &p)
void xxxxSet(int i)
Definition: ELlog4cplus.cc:382
const ELstring getSymbol() const
virtual void separateEpilogue()
Definition: ELlog4cplus.cc:494
virtual void emit(const ELstring &s, bool nl=false)
Definition: ELlog4cplus.cc:395
const ELextendedID & xid() const
Definition: ErrorObj.cc:126
bool add(const ELextendedID &xid)
virtual bool log(const ErrorObj &msg)
Definition: ELlog4cplus.cc:189
virtual void attachTime()
Definition: ELlog4cplus.cc:492
virtual ELlog4cplus * clone() const
Definition: ELlog4cplus.cc:182
xdaq::Application * appl_
Definition: ELlog4cplus.h:143
int serial() const
Definition: ErrorObj.cc:125
virtual void includeModule()
Definition: ELlog4cplus.cc:473
virtual ELstring context() const =0
ELstring subroutine
Definition: ELextendedID.h:38
const ELlist_string & items() const
Definition: ErrorObj.cc:129
static ELadministrator * instance()
virtual void suppressModule()
Definition: ELlog4cplus.cc:474
static char * formatTime(const time_t t)
Definition: ELlog4cplus.cc:57
virtual void suppressText()
Definition: ELlog4cplus.cc:480
double a
Definition: hdecay.h:121
ELextendedID xid
Definition: ELlog4cplus.h:121
tuple cout
Definition: gather_cfg.py:41
virtual void suppressTime()
Definition: ELlog4cplus.cc:471
virtual void includeContext()
Definition: ELlog4cplus.cc:482
virtual void useFullContext()
Definition: ELlog4cplus.cc:488
string s
Definition: asciidump.py:422
bool wantEpilogueSeparate
Definition: ELlog4cplus.h:124
T first(std::pair< T, U > const &p)
std::string ELstring
Definition: ELstring.h:26
virtual void useContext()
Definition: ELlog4cplus.cc:489
ELstring context() const
Definition: ErrorObj.cc:133
virtual void summarization(const ELstring &fullTitle, const ELstring &sumLines)
Definition: ELlog4cplus.cc:502