00001 // ---------------------------------------------------------------------- 00002 // 00003 // ELcollected.cc 00004 // 00005 // History: 00006 // 07-Jun-2000 WEB Reflect consolidation of ELdestination/X and of 00007 // ELoutput/X; consolidate ELcollected/X 00008 // 15-Sep-2000 MF Corrected bug: copy constructor needs to set sender 00009 // based on a clone() of *sender, not a bit copy, since 00010 // the whole reasoning was to protect against the user's 00011 // objects going out of scope. 00012 // 4-Apr-2001 MF Loginc to ignore ore respond to modules, using base 00013 // method thisShouldBeIgnored(). 00014 // 00015 // ---------------------------------------------------------------------- 00016 00017 #include "FWCore/MessageService/interface/ELcollected.h" 00018 #include "FWCore/MessageService/interface/ELdestination.h" 00019 #include "FWCore/MessageService/interface/ELadministrator.h" 00020 #include "FWCore/MessageService/interface/ELcontextSupplier.h" 00021 00022 #include <sstream> 00023 00024 // Possible Traces: 00025 //#define ELcollectedCONSTRUCTOR_TRACE 00026 //#define ELcollectedTRACE_LOG 00027 //#define ELcollected_EMIT_TRACE 00028 00029 namespace edm { 00030 namespace service { 00031 00032 00033 // ---------------------------------------------------------------------- 00034 // Constructors: 00035 // ---------------------------------------------------------------------- 00036 00037 ELcollected::ELcollected( const ELsender & snd ) 00038 : ELoutput() 00039 , sender ( snd.clone() ) 00040 { 00041 00042 #ifdef ELcollectedCONSTRUCTOR_TRACE 00043 std::cout << "Constructor for ELcollected(ELsender)\n"; 00044 #endif 00045 00046 // Unlike ELoutput, we do not emit Error Log established message. 00047 00048 } // ELcollected() 00049 00050 00051 ELcollected::ELcollected( const ELcollected & orig ) 00052 : ELoutput( orig ) 00053 , sender ( orig.sender->clone() ) // $$ mf 9/15/00 00054 { 00055 00056 #ifdef ELcollectedCONSTRUCTOR_TRACE 00057 std::cout << "Copy constructor for ELcollected\n"; 00058 #endif 00059 00060 ignoreMostModules = orig.ignoreMostModules; 00061 respondToThese = orig.respondToThese; 00062 respondToMostModules = orig.respondToMostModules; 00063 ignoreThese = orig.ignoreThese; 00064 00065 } // ELcollected() 00066 00067 00068 ELcollected::~ELcollected() { 00069 00070 #ifdef ELcollectedCONSTRUCTOR_TRACE 00071 std::cout << "Destructor for ELcollected)\n"; 00072 #endif 00073 00074 delete sender; 00075 00076 } // ~ELcollected() 00077 00078 00079 00080 // ---------------------------------------------------------------------- 00081 // Methods invoked by the ELadministrator: 00082 // ---------------------------------------------------------------------- 00083 00084 ELcollected * 00085 ELcollected::clone() const { 00086 00087 return new ELcollected( *this ); 00088 00089 } // clone() 00090 00091 00092 // Remainder are from base class. 00093 00094 // ======= 00095 // intoBuf 00096 // ======= 00097 00098 void ELcollected::intoBuf( const ELstring & s ) { 00099 00100 buf += s; 00101 buf += '\0'; 00102 00103 } // intoBuf(); 00104 00105 00106 // ======== 00107 // emitXid 00108 // ======== 00109 00110 void ELcollected::emitXid( const ELextendedID & xid ) { 00111 00112 buf = ""; 00113 00114 intoBuf ( xid.process ); 00115 intoBuf ( xid.module ); 00116 intoBuf ( xid.subroutine ); 00117 intoBuf ( xid.id ); 00118 std::ostringstream ost; 00119 ost << xid.severity.getLevel(); 00120 intoBuf ( ost.str() ); 00121 00122 } // emitXid 00123 00124 00125 // ===== 00126 // emit 00127 // ===== 00128 00129 void ELcollected::emit( const ELstring & s, bool nl ) { 00130 00131 #ifdef ELcollected_EMIT_TRACE 00132 std::cout << "[][][] in emit: s.length() " << s.length() << "\n"; 00133 #endif 00134 00135 // A forced newline is something that needs to be transmitted. 00136 // We shall insert it as its own item. 00137 00138 if (s.length() == 0) { 00139 if ( nl ) { 00140 intoBuf( newline ); 00141 charsOnLine = 0; 00142 } 00143 return; 00144 } 00145 00146 // Setting up for indentation if you start with a nweline, or if the length 00147 // exceeds column 80, is not done here, it is done on the server. 00148 00149 #ifdef ELcollected_EMIT_TRACE 00150 std::cout << "[][][] in emit: about to << s to buf: " << s << " \n"; 00151 #endif 00152 00153 // Place the item into the buffer 00154 00155 intoBuf (s); 00156 00157 // Accounting for trailing \n is done at the server. 00158 00159 // A forced trailing newline is something that needs to be transmitted. 00160 // We shall insert it as its own item. 00161 00162 if ( nl ) { 00163 intoBuf (newline); 00164 } 00165 00166 #ifdef ELcollected_EMIT_TRACE 00167 std::cout << "[][][] in emit: completed \n"; 00168 #endif 00169 00170 } // emit() 00171 00172 00173 00174 // ==== 00175 // log 00176 // ==== 00177 00178 bool ELcollected::log( const edm::ErrorObj & msg ) { 00179 00180 #ifdef ELcollectedTRACE_LOG 00181 std::cout << " =:=:=: Log to an ELcollected \n"; 00182 #endif 00183 00184 xid = msg.xid(); // Save the xid. 00185 00186 // See if this message is to be acted upon, and add it to limits table 00187 // if it was not already present: 00188 // 00189 if ( msg.xid().severity < threshold ) return false; 00190 if ( thisShouldBeIgnored(xid.module) ) return false; 00191 if ( ! limits.add( msg.xid() ) ) return false; 00192 00193 #ifdef ELcollectedTRACE_LOG 00194 std::cout << " =:=:=: Limits table work done \n"; 00195 #endif 00196 00197 // start the buffer with the xid 00198 00199 emitXid (xid); 00200 00201 // 00202 00203 #ifdef ELcollectedTRACE_LOG 00204 std::cout << " =:=:=: xid emitted \n"; 00205 #endif 00206 00207 // Provide the context information. The server side will use this to prime 00208 // its special context supplier. We will send over all three types of 00209 // context, even though probably only 1 or 2 will be needed. 00210 00211 emit( ELadministrator::instance()-> 00212 getContextSupplier().summaryContext()); 00213 emit( ELadministrator::instance()-> 00214 getContextSupplier().context()); 00215 emit( ELadministrator::instance()-> 00216 getContextSupplier().fullContext()); 00217 00218 #ifdef ELcollectedTRACE_LOG 00219 std::cout << " =:=:=: Context done: \n"; 00220 #endif 00221 00222 // No prologue separate from what the server will issue. 00223 00224 // No serial number of message separate from what the server will issue. 00225 00226 // collected each item in the message: 00227 // 00228 if ( wantText ) { 00229 ELlist_string::const_iterator it; 00230 for ( it = msg.items().begin(); it != msg.items().end(); ++it ) { 00231 #ifdef ELcollectedTRACE_LOG 00232 std::cout << " =:=:=: Item: " << *it <<"\n"; 00233 #endif 00234 emit( *it ); 00235 } 00236 } 00237 00238 // DO NOT Provide further identification such as module and subroutine; 00239 // the server side will provide that using the xid you have sent it, if 00240 // the server side user wants it. 00241 00242 // DO NOT provide time stamp; it would duplicate server's stamp! 00243 00244 // Provide traceback information: 00245 // 00246 if ( msg.xid().severity >= traceThreshold ) { 00247 emit( ELstring("\n") 00248 + ELadministrator::instance()->getContextSupplier().traceRoutine() 00249 , true ); 00250 } 00251 else { //else statement added JV:1 00252 emit( "", true ); 00253 } 00254 #ifdef ELcollectedTRACE_LOG 00255 std::cout << " =:=:=: Trace routine done: \n"; 00256 #endif 00257 00258 // Message has been fully processed through emit; now put in an extra 00259 // zero, and send out the buffer. 00260 // 00261 00262 buf += char(0); 00263 int nbuf = buf.length(); 00264 00265 sender->send ( nbuf, buf.data() ); 00266 00267 #ifdef ELcollectedTRACE_LOG 00268 std::cout << " =:=:=: log(msg) done: \n"; 00269 #endif 00270 00271 return true; 00272 00273 } // log() 00274 00275 00276 // ---------------------------------------------------------------------- 00277 00278 00279 } // end of namespace service 00280 } // end of namespace edm 00281