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
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 #include "FWCore/MessageService/interface/ELadministrator.h"
00162 #include "FWCore/MessageService/interface/ELoutput.h"
00163 #include "FWCore/MessageService/interface/ELstatistics.h"
00164 #include "FWCore/MessageService/interface/ELfwkJobReport.h"
00165 #include "FWCore/MessageService/interface/ErrorLog.h"
00166 #include "FWCore/MessageService/interface/MessageLoggerScribe.h"
00167
00168 #include "FWCore/MessageLogger/interface/ErrorObj.h"
00169 #include "FWCore/MessageLogger/interface/MessageLoggerQ.h"
00170 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00171 #include "FWCore/MessageLogger/interface/ConfigurationHandshake.h"
00172
00173 #include "FWCore/Utilities/interface/EDMException.h"
00174 #include "FWCore/Utilities/interface/Algorithms.h"
00175
00176 #include <algorithm>
00177 #include <cassert>
00178 #include <fstream>
00179 #include <iostream>
00180 #include <string>
00181 #include <signal.h>
00182
00183 using std::cerr;
00184
00185 namespace edm {
00186 namespace service {
00187
00188
00189 MessageLoggerScribe::MessageLoggerScribe()
00190 : admin_p ( ELadministrator::instance() )
00191 , early_dest( admin_p->attach(ELoutput(std::cerr, false)) )
00192 , errorlog_p( new ErrorLog() )
00193 , file_ps ( )
00194 , job_pset_p( 0 )
00195 , extern_dests( )
00196 , jobReportOption( )
00197 , clean_slate_configuration( true )
00198 , active( true )
00199 {
00200 admin_p->setContextSupplier(msg_context);
00201 }
00202
00203 MessageLoggerScribe::~MessageLoggerScribe()
00204 {
00205 admin_p->finish();
00206 delete errorlog_p;
00207 for( ; not file_ps.empty(); file_ps.pop_back() ) {
00208 delete file_ps.back();
00209 }
00210 delete job_pset_p;
00211 assert( extern_dests.empty() );
00212 }
00213
00214
00215 void
00216 MessageLoggerScribe::run()
00217 {
00218 MessageLoggerQ::OpCode opcode;
00219 void * operand;
00220 bool done = false;
00221 bool purge_mode = false;
00222 int count = 0;
00223
00224 MessageDrop::instance()->messageLoggerScribeIsRunning =
00225 MLSCRIBE_RUNNING_INDICATOR;
00226
00227
00228
00229
00230 do {
00231 MessageLoggerQ::consume(opcode, operand);
00232 switch(opcode) {
00233 default: {
00234 assert(false);
00235 break;
00236 }
00237 case MessageLoggerQ::END_THREAD: {
00238 assert( operand == 0 );
00239 done = true;
00240 MessageDrop::instance()->messageLoggerScribeIsRunning =
00241 (unsigned char) -1;
00242 break;
00243 }
00244 case MessageLoggerQ::LOG_A_MESSAGE: {
00245 ErrorObj * errorobj_p = static_cast<ErrorObj *>(operand);
00246 try {
00247 if(active && !purge_mode) log (errorobj_p);
00248 }
00249 catch(cms::Exception& e)
00250 {
00251 ++count;
00252 std::cerr << "MessageLoggerScribe caught " << count
00253 << " cms::Exceptions, text = \n"
00254 << e.what() << "\n";
00255
00256 if(count > 25)
00257 {
00258 cerr << "MessageLogger will no longer be processing "
00259 << "messages due to errors (entering purge mode).\n";
00260 purge_mode = true;
00261 }
00262 }
00263 catch(...)
00264 {
00265 std::cerr << "MessageLoggerScribe caught an unknown exception and "
00266 << "will no longer be processing "
00267 << "messages. (entering purge mode)\n";
00268 purge_mode = true;
00269 }
00270 delete errorobj_p;
00271 break;
00272 }
00273 case MessageLoggerQ::CONFIGURE: {
00274 ConfigurationHandshake * h_p =
00275 static_cast<ConfigurationHandshake *>(operand);
00276 job_pset_p = static_cast<ParameterSet *>(h_p->p);
00277 boost::mutex::scoped_lock sl(h_p->m);
00278 try {
00279 configure_errorlog();
00280 }
00281 catch(edm::Exception& e)
00282 {
00283 Place_for_passing_exception_ptr epp = h_p->epp;
00284 if ( *epp == 0 ) {
00285 *epp = new edm::Exception(e);
00286 } else {
00287 Pointer_to_new_exception_on_heap ep = *epp;
00288 (*ep) << "\n and another exception: \n" << e.what();
00289 }
00290 }
00291
00292
00293
00294
00295
00296 h_p->c.notify_all();
00297
00298 break;
00299 }
00300 case MessageLoggerQ::EXTERN_DEST: {
00301 try {
00302 extern_dests.push_back( static_cast<NamedDestination *>(operand) );
00303 configure_external_dests();
00304 }
00305 catch(cms::Exception& e)
00306 {
00307 std::cerr << "MessageLoggerScribe caught a cms::Exception "
00308 << "during extern dest configuration:\n"
00309 << e.what() << "\n"
00310 << "This is a serious problem, and the extern dest "
00311 << "will not be produced.\n"
00312 << "However, the rest of the logger continues to run.\n";
00313 }
00314 catch(...)
00315 {
00316 std::cerr << "MessageLoggerScribe caught unkonwn exception type\n"
00317 << "during extern dest configuration. "
00318 << "This is a serious problem, and the extern dest "
00319 << "will not be produced.\n"
00320 << "The rest of the logger will attempt to continue to run.\n";
00321 }
00322 break;
00323 }
00324 case MessageLoggerQ::SUMMARIZE: {
00325 assert( operand == 0 );
00326 try {
00327 triggerStatisticsSummaries();
00328 }
00329 catch(cms::Exception& e)
00330 {
00331 std::cerr << "MessageLoggerScribe caught exception "
00332 << "during summarize:\n"
00333 << e.what() << "\n";
00334 }
00335 catch(...)
00336 {
00337 std::cerr << "MessageLoggerScribe caught unkonwn exception type "
00338 << "during summarize. (Ignored)\n";
00339 }
00340 break;
00341 }
00342 case MessageLoggerQ::JOBREPORT: {
00343 std::string* jobReportOption_p =
00344 static_cast<std::string*>(operand);
00345 try {
00346 jobReportOption = *jobReportOption_p;
00347 }
00348 catch(cms::Exception& e)
00349 {
00350 std::cerr << "MessageLoggerScribe caught a cms::Exception "
00351 << "during processing of --jobReport option:\n"
00352 << e.what() << "\n"
00353 << "This likely will affect or prevent the job reoport.\n"
00354 << "However, the rest of the logger continues to run.\n";
00355 }
00356 catch(...)
00357 {
00358 std::cerr << "MessageLoggerScribe caught unkonwn exception type\n"
00359 << "during processing of --jobReport option.\n"
00360 << "This likely will affect or prevent the job reoport.\n"
00361 << "However, the rest of the logger continues to run.\n";
00362 }
00363 delete jobReportOption_p;
00364 break;
00365 }
00366 case MessageLoggerQ::JOBMODE: {
00367 std::string* jobMode_p =
00368 static_cast<std::string*>(operand);
00369 JobMode jm = MessageLoggerDefaults::mode(*jobMode_p);
00370 messageLoggerDefaults =
00371 value_ptr<MessageLoggerDefaults>(new MessageLoggerDefaults(jm));
00372
00373
00374 delete jobMode_p;
00375 break;
00376 }
00377 case MessageLoggerQ::SHUT_UP: {
00378 assert( operand == 0 );
00379 active = false;
00380 break;
00381 }
00382 case MessageLoggerQ::FLUSH_LOG_Q: {
00383 ConfigurationHandshake * h_p =
00384 static_cast<ConfigurationHandshake *>(operand);
00385 job_pset_p = static_cast<ParameterSet *>(h_p->p);
00386 boost::mutex::scoped_lock sl(h_p->m);
00387 h_p->c.notify_all();
00388
00389 break;
00390 }
00391 case MessageLoggerQ::GROUP_STATS: {
00392 std::string* cat_p =
00393 static_cast<std::string*>(operand);
00394 ELstatistics::noteGroupedCategory(*cat_p);
00395 delete cat_p;
00396 break;
00397 }
00398 case MessageLoggerQ::FJR_SUMMARY: {
00399 ConfigurationHandshake * h_p =
00400 static_cast<ConfigurationHandshake *>(operand);
00401 boost::mutex::scoped_lock sl(h_p->m);
00402 std::map<std::string, double> * smp =
00403 static_cast<std::map<std::string, double> *>(h_p->p);
00404 triggerFJRmessageSummary(*smp);
00405 h_p->c.notify_all();
00406
00407 break;
00408 }
00409 }
00410
00411 } while(! done);
00412
00413 }
00414
00415 void MessageLoggerScribe::log ( ErrorObj * errorobj_p ) {
00416 ELcontextSupplier& cs =
00417 const_cast<ELcontextSupplier&>(admin_p->getContextSupplier());
00418 MsgContext& mc = dynamic_cast<MsgContext&>(cs);
00419 mc.setContext(errorobj_p->context());
00420 std::vector<std::string> categories;
00421 parseCategories(errorobj_p->xid().id, categories);
00422 for (unsigned int icat = 0; icat < categories.size(); ++icat) {
00423 errorobj_p->setID(categories[icat]);
00424 (*errorlog_p)( *errorobj_p );
00425 }
00426 }
00427
00428 void
00429 MessageLoggerScribe::configure_errorlog()
00430 {
00431 vString empty_vString;
00432 String empty_String;
00433 PSet empty_PSet;
00434
00435
00436 String preconfiguration_message
00437 = getAparameter<String>
00438 (job_pset_p, "generate_preconfiguration_message", empty_String);
00439 if (preconfiguration_message != empty_String) {
00440
00441
00442
00443
00444 early_dest.suppressTime();
00445 LogError ("preconfiguration") << preconfiguration_message;
00446 MessageLoggerQ::OpCode opcode;
00447 void * operand;
00448 MessageLoggerQ::consume(opcode, operand);
00449 assert (opcode == MessageLoggerQ::LOG_A_MESSAGE);
00450 ErrorObj * errorobj_p = static_cast<ErrorObj *>(operand);
00451 log (errorobj_p);
00452 delete errorobj_p;
00453 }
00454
00455 if ( !stream_ps.empty() ) {
00456 LogWarning ("multiLogConfig")
00457 << "The message logger has been configured multiple times";
00458 clean_slate_configuration = false;
00459 }
00460 configure_fwkJobReports();
00461 configure_ordinary_destinations();
00462 configure_statistics();
00463
00464 configure_external_dests();
00465
00466 }
00467
00468
00469 void
00470 MessageLoggerScribe::configure_dest( ELdestControl & dest_ctrl
00471 , String const & filename
00472 )
00473 {
00474 static const int NO_VALUE_SET = -45654;
00475 vString empty_vString;
00476 PSet empty_PSet;
00477 String empty_String;
00478
00479
00480 const std::string COMMON_DEFAULT_THRESHOLD = "INFO";
00481 const int COMMON_DEFAULT_LIMIT = NO_VALUE_SET;
00482 const int COMMON_DEFAULT_INTERVAL = NO_VALUE_SET;
00483 const int COMMON_DEFAULT_TIMESPAN = NO_VALUE_SET;
00484
00485 char * severity_array[] = {"WARNING", "INFO", "ERROR", "DEBUG"};
00486 vString const severities(severity_array+0, severity_array+4);
00487
00488
00489 vString categories
00490 = getAparameter<vString>(job_pset_p,"categories", empty_vString);
00491
00492
00493
00494 {
00495 vString messageIDs
00496 = getAparameter<vString>(job_pset_p,"messageIDs", empty_vString);
00497
00498
00499 copy_all( messageIDs, std::back_inserter(categories) );
00500 }
00501
00502
00503
00504 {
00505 std::vector<std::string> hardcats = messageLoggerDefaults->categories;
00506
00507 copy_all( hardcats, std::back_inserter(categories) );
00508 }
00509
00510
00511 String default_threshold
00512 = getAparameter<String>(job_pset_p,"threshold",empty_String);
00513
00514
00515
00516
00517 PSet default_pset
00518 = getAparameter<PSet>(job_pset_p,"default", empty_PSet);
00519 int default_limit
00520 = getAparameter<int>(&default_pset,"limit", COMMON_DEFAULT_LIMIT);
00521 int default_interval
00522 = getAparameter<int>(&default_pset,"reportEvery", COMMON_DEFAULT_INTERVAL);
00523
00524 int default_timespan
00525 = getAparameter<int>(&default_pset,"timespan", COMMON_DEFAULT_TIMESPAN);
00526
00527
00528
00529
00530 PSet dest_pset = getAparameter<PSet>(job_pset_p,filename,empty_PSet);
00531
00532
00533 bool is_placeholder
00534 = getAparameter<bool>(&dest_pset,"placeholder", false);
00535 if (is_placeholder) return;
00536
00537
00538 PSet dest_default_pset
00539 = getAparameter<PSet>(&dest_pset,"default", empty_PSet);
00540 int dest_default_limit
00541 = getAparameter<int>(&dest_default_pset,"limit", default_limit);
00542 int dest_default_interval
00543 = getAparameter<int>(&dest_default_pset,"reportEvery", default_interval);
00544
00545 int dest_default_timespan
00546 = getAparameter<int>(&dest_default_pset,"timespan", default_timespan);
00547
00548 if ( dest_default_limit != NO_VALUE_SET ) {
00549 if ( dest_default_limit < 0 ) dest_default_limit = 2000000000;
00550 dest_ctrl.setLimit("*", dest_default_limit );
00551 }
00552 if ( dest_default_interval != NO_VALUE_SET ) {
00553 dest_ctrl.setInterval("*", dest_default_interval );
00554 }
00555 if ( dest_default_timespan != NO_VALUE_SET ) {
00556 if ( dest_default_timespan < 0 ) dest_default_timespan = 2000000000;
00557 dest_ctrl.setTimespan("*", dest_default_timespan );
00558 }
00559
00560
00561 String dest_threshold
00562 = getAparameter<String>(&dest_pset,"threshold", default_threshold);
00563 if (dest_threshold == empty_String) {
00564 dest_threshold = messageLoggerDefaults->threshold(filename);
00565 }
00566 if (dest_threshold == empty_String) dest_threshold = COMMON_DEFAULT_THRESHOLD;
00567 ELseverityLevel threshold_sev(dest_threshold);
00568 dest_ctrl.setThreshold(threshold_sev);
00569
00570
00571 for( vString::const_iterator id_it = categories.begin()
00572 ; id_it != categories.end()
00573 ; ++id_it
00574 )
00575 {
00576 String msgID = *id_it;
00577 PSet default_category_pset
00578 = getAparameter<PSet>(&default_pset,msgID, empty_PSet);
00579 PSet category_pset
00580 = getAparameter<PSet>(&dest_pset,msgID, default_category_pset);
00581
00582 int category_default_limit
00583 = getAparameter<int>(&default_category_pset,"limit",NO_VALUE_SET);
00584 int limit
00585 = getAparameter<int>(&category_pset,"limit", category_default_limit);
00586 if (limit == NO_VALUE_SET) limit = dest_default_limit;
00587
00588 int category_default_interval
00589 = getAparameter<int>(&default_category_pset,"reportEvery",NO_VALUE_SET);
00590 int interval
00591 = getAparameter<int>(&category_pset,"reportEvery",category_default_interval);
00592 if (interval == NO_VALUE_SET) interval = dest_default_interval;
00593
00594 int category_default_timespan
00595 = getAparameter<int>(&default_category_pset,"timespan",NO_VALUE_SET);
00596 int timespan
00597 = getAparameter<int>(&category_pset,"timespan",category_default_timespan);
00598 if (timespan == NO_VALUE_SET) timespan = dest_default_timespan;
00599
00600
00601 std::string category = msgID;
00602 if ( limit == NO_VALUE_SET ) {
00603 limit = messageLoggerDefaults->limit(filename,category);
00604 }
00605 if ( interval == NO_VALUE_SET ) {
00606 interval = messageLoggerDefaults->reportEvery(filename,category);
00607 }
00608 if ( timespan == NO_VALUE_SET ) {
00609 timespan = messageLoggerDefaults->timespan(filename,category);
00610 }
00611
00612 if( limit != NO_VALUE_SET ) {
00613 if ( limit < 0 ) limit = 2000000000;
00614 dest_ctrl.setLimit(msgID, limit);
00615 }
00616 if( interval != NO_VALUE_SET ) {
00617 dest_ctrl.setInterval(msgID, interval);
00618 }
00619 if( timespan != NO_VALUE_SET ) {
00620 if ( timespan < 0 ) timespan = 2000000000;
00621 dest_ctrl.setTimespan(msgID, timespan);
00622 }
00623
00624 }
00625
00626
00627 for( vString::const_iterator sev_it = severities.begin()
00628 ; sev_it != severities.end()
00629 ; ++sev_it
00630 )
00631 {
00632 String sevID = *sev_it;
00633 ELseverityLevel severity(sevID);
00634 PSet default_sev_pset
00635 = getAparameter<PSet>(&default_pset,sevID, empty_PSet);
00636 PSet sev_pset
00637 = getAparameter<PSet>(&dest_pset,sevID, default_sev_pset);
00638
00639 int limit = getAparameter<int>(&sev_pset,"limit", NO_VALUE_SET);
00640 if ( limit == NO_VALUE_SET ) {
00641 limit = messageLoggerDefaults->sev_limit(filename,sevID);
00642 }
00643 if( limit != NO_VALUE_SET ) dest_ctrl.setLimit(severity, limit );
00644 int interval = getAparameter<int>(&sev_pset,"reportEvery", NO_VALUE_SET);
00645 if ( interval == NO_VALUE_SET ) {
00646 interval = messageLoggerDefaults->sev_reportEvery(filename,sevID);
00647 }
00648 if( interval != NO_VALUE_SET ) dest_ctrl.setInterval(severity, interval);
00649
00650 int timespan = getAparameter<int>(&sev_pset,"timespan", NO_VALUE_SET);
00651 if ( timespan == NO_VALUE_SET ) {
00652 timespan = messageLoggerDefaults->sev_timespan(filename,sevID);
00653 }
00654 if( timespan != NO_VALUE_SET ) dest_ctrl.setTimespan(severity, timespan );
00655
00656 }
00657
00658
00659 bool noLineBreaks_default
00660 = getAparameter<bool> (&default_pset,"noLineBreaks",false);
00661
00662 bool noLineBreaks
00663 = getAparameter<bool> (&dest_pset,"noLineBreaks",noLineBreaks_default);
00664 if (noLineBreaks) {
00665 dest_ctrl.setLineLength(32000);
00666 }
00667 else {
00668 int lenDef = 80;
00669 int lineLen_default
00670 = getAparameter<int> (&default_pset,"lineLength",lenDef);
00671
00672 int lineLen = getAparameter<int> (&dest_pset,"lineLength",lineLen_default);
00673 if (lineLen != lenDef) {
00674 dest_ctrl.setLineLength(lineLen);
00675 }
00676 }
00677
00678
00679 bool suppressTime_default
00680 = getAparameter<bool> (&default_pset,"noTimeStamps",false);
00681 bool suppressTime
00682 = getAparameter<bool> (&dest_pset,"noTimeStamps",suppressTime_default);
00683 if (suppressTime) {
00684 dest_ctrl.suppressTime();
00685 }
00686
00687 }
00688
00689 void
00690 MessageLoggerScribe::configure_default_fwkJobReport
00691 ( ELdestControl & dest_ctrl )
00692 {
00693
00694 dest_ctrl.setLimit("*", 0 );
00695 String msgID = "FwkJob";
00696 int FwkJob_limit = 10000000;
00697 dest_ctrl.setLimit(msgID, FwkJob_limit);
00698 dest_ctrl.setLineLength(32000);
00699 dest_ctrl.suppressTime();
00700
00701 }
00702
00703
00704 void
00705 MessageLoggerScribe::configure_fwkJobReports()
00706 {
00707 vString empty_vString;
00708 String empty_String;
00709 PSet empty_PSet;
00710
00711
00712 bool jobReportExists = false;
00713 bool enableJobReports = false;
00714 #ifdef DEFINE_THIS_TO_MAKE_REPORTS_THE_DEFAULT
00715 enableJobReports = true;
00716 #endif
00717 if (jobReportOption != empty_String) enableJobReports = true;
00718 if (jobReportOption == "~") enableJobReports = false;
00719 if (!enableJobReports) return;
00720
00721 if ((jobReportOption != "*") && (jobReportOption != empty_String)) {
00722 const std::string::size_type npos = std::string::npos;
00723 if ( jobReportOption.find('.') == npos ) {
00724 jobReportOption += ".xml";
00725 }
00726 }
00727
00728
00729 vString fwkJobReports
00730 = getAparameter<vString>(job_pset_p, "fwkJobReports", empty_vString);
00731
00732
00733
00734 if (fwkJobReports.empty()) {
00735 fwkJobReports = messageLoggerDefaults->fwkJobReports;
00736 }
00737
00738
00739 for( vString::const_iterator it = fwkJobReports.begin()
00740 ; it != fwkJobReports.end()
00741 ; ++it
00742 )
00743 {
00744 String filename = *it;
00745 String psetname = filename;
00746
00747
00748 PSet fjr_pset = getAparameter<PSet>(job_pset_p,psetname,empty_PSet);
00749 bool is_placeholder
00750 = getAparameter<bool>(&fjr_pset,"placeholder", false);
00751 if (is_placeholder) continue;
00752
00753
00754
00755 String explicit_filename
00756 = getAparameter<String>(&fjr_pset,"filename",empty_String);
00757 if (explicit_filename != empty_String) filename = explicit_filename;
00758 String explicit_extension
00759 = getAparameter<String>(&fjr_pset,"extension",empty_String);
00760 if (explicit_extension != empty_String) {
00761 if (explicit_extension[0] == '.') {
00762 filename += explicit_extension;
00763 } else {
00764 filename = filename + "." + explicit_extension;
00765 }
00766 }
00767
00768
00769 std::string actual_filename = filename;
00770 const std::string::size_type npos = std::string::npos;
00771 if ( filename.find('.') == npos ) {
00772 actual_filename += ".xml";
00773 }
00774
00775
00776 if ( stream_ps.find(actual_filename)!=stream_ps.end() ) {
00777 if (clean_slate_configuration) {
00778 throw edm::Exception ( edm::errors::Configuration )
00779 <<"Duplicate name for a MessageLogger Framework Job Report Destination: "
00780 << actual_filename
00781 << "\n";
00782 } else {
00783 LogWarning("duplicateDestination")
00784 <<"Duplicate name for a MessageLogger Framework Job Report Destination: "
00785 << actual_filename
00786 << "\n" << "Only original configuration instructions are used";
00787 continue;
00788 }
00789 }
00790
00791 jobReportExists = true;
00792 if ( actual_filename == jobReportOption ) jobReportOption = empty_String;
00793
00794 std::ofstream * os_p = new std::ofstream(actual_filename.c_str());
00795 file_ps.push_back(os_p);
00796 ELdestControl dest_ctrl;
00797 dest_ctrl = admin_p->attach( ELfwkJobReport(*os_p) );
00798 stream_ps[actual_filename] = os_p;
00799
00800
00801 configure_dest(dest_ctrl, psetname);
00802
00803 }
00804
00805
00806 if (jobReportOption==empty_String) return;
00807 if (jobReportExists && ( jobReportOption=="*" )) return;
00808 if (jobReportOption=="*") jobReportOption = "FrameworkJobReport.xml";
00809
00810
00811 std::string actual_filename = jobReportOption;
00812 if ( stream_ps.find(actual_filename)!=stream_ps.end() ) return;
00813
00814 std::ofstream * os_p = new std::ofstream(actual_filename.c_str());
00815 file_ps.push_back(os_p);
00816 ELdestControl dest_ctrl;
00817 dest_ctrl = admin_p->attach( ELfwkJobReport(*os_p) );
00818 stream_ps[actual_filename] = os_p;
00819
00820
00821 configure_default_fwkJobReport (dest_ctrl);
00822
00823 }
00824
00825 void
00826 MessageLoggerScribe::configure_ordinary_destinations()
00827 {
00828 vString empty_vString;
00829 String empty_String;
00830 PSet empty_PSet;
00831
00832
00833 vString destinations
00834 = getAparameter<vString>(job_pset_p, "destinations", empty_vString);
00835
00836
00837
00838 if (destinations.empty()) {
00839 destinations = messageLoggerDefaults->destinations;
00840 }
00841
00842
00843 if( ! destinations.empty() )
00844 early_dest.setThreshold(ELhighestSeverity);
00845
00846
00847 for( vString::const_iterator it = destinations.begin()
00848 ; it != destinations.end()
00849 ; ++it
00850 )
00851 {
00852 String filename = *it;
00853 String psetname = filename;
00854
00855
00856 PSet dest_pset = getAparameter<PSet>(job_pset_p,psetname,empty_PSet);
00857 bool is_placeholder
00858 = getAparameter<bool>(&dest_pset,"placeholder", false);
00859 if (is_placeholder) continue;
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873 String filename_default
00874 = getAparameter<String>(&dest_pset,"output",empty_String);
00875 if ( filename_default == empty_String ) {
00876 filename_default = messageLoggerDefaults->output(psetname);
00877 if (filename_default == empty_String) {
00878 filename_default = filename;
00879 }
00880 }
00881
00882 String explicit_filename
00883 = getAparameter<String>(&dest_pset,"filename",filename_default);
00884 if (explicit_filename != empty_String) filename = explicit_filename;
00885 String explicit_extension
00886 = getAparameter<String>(&dest_pset,"extension",empty_String);
00887 if (explicit_extension != empty_String) {
00888 if (explicit_extension[0] == '.') {
00889 filename += explicit_extension;
00890 } else {
00891 filename = filename + "." + explicit_extension;
00892 }
00893 }
00894
00895
00896
00897
00898 std::string actual_filename = filename;
00899 if ( (filename != "cout") && (filename != "cerr") ) {
00900 const std::string::size_type npos = std::string::npos;
00901 if ( filename.find('.') == npos ) {
00902 actual_filename += ".log";
00903 }
00904 }
00905
00906
00907 if ( stream_ps.find(actual_filename)!=stream_ps.end() ) {
00908 if (clean_slate_configuration) {
00909 throw edm::Exception ( edm::errors::Configuration )
00910 <<"Duplicate name for a MessageLogger Destination: "
00911 << actual_filename
00912 << "\n";
00913 } else {
00914 LogWarning("duplicateDestination")
00915 <<"Duplicate name for a MessageLogger Destination: "
00916 << actual_filename
00917 << "\n" << "Only original configuration instructions are used";
00918 continue;
00919 }
00920 }
00921
00922 ordinary_destination_filenames.push_back(actual_filename);
00923
00924
00925 ELdestControl dest_ctrl;
00926 if( actual_filename == "cout" ) {
00927 dest_ctrl = admin_p->attach( ELoutput(std::cout) );
00928 stream_ps["cout"] = &std::cout;
00929 }
00930 else if( actual_filename == "cerr" ) {
00931 early_dest.setThreshold(ELzeroSeverity);
00932 dest_ctrl = early_dest;
00933 stream_ps["cerr"] = &std::cerr;
00934 }
00935 else {
00936 std::ofstream * os_p = new std::ofstream(actual_filename.c_str());
00937 file_ps.push_back(os_p);
00938 dest_ctrl = admin_p->attach( ELoutput(*os_p) );
00939 stream_ps[actual_filename] = os_p;
00940 }
00941
00942
00943
00944 configure_dest(dest_ctrl, psetname);
00945
00946 }
00947
00948 }
00949
00950
00951 void
00952 MessageLoggerScribe::configure_statistics()
00953 {
00954 vString empty_vString;
00955 String empty_String;
00956 PSet empty_PSet;
00957
00958
00959 vString statistics
00960 = getAparameter<vString>(job_pset_p,"statistics", empty_vString);
00961
00962 bool no_statistics_configured = statistics.empty();
00963
00964 if ( no_statistics_configured ) {
00965
00966
00967
00968
00969 vString destinations
00970 = getAparameter<vString>(job_pset_p, "destinations", empty_vString);
00971 if (destinations.empty()) {
00972 statistics = messageLoggerDefaults->statistics;
00973 no_statistics_configured = statistics.empty();
00974 }
00975 }
00976
00977
00978 for( vString::const_iterator it = statistics.begin()
00979 ; it != statistics.end()
00980 ; ++it
00981 )
00982 {
00983 String statname = *it;
00984 String psetname = statname;
00985
00986
00987 PSet stat_pset = getAparameter<PSet>(job_pset_p,psetname,empty_PSet);
00988 bool is_placeholder
00989 = getAparameter<bool>(&stat_pset,"placeholder", false);
00990 if (is_placeholder) continue;
00991
00992
00993 String filename
00994 = getAparameter<String>(&stat_pset,"output",empty_String);
00995 if ( filename == empty_String ) {
00996 filename = messageLoggerDefaults->output(psetname);
00997 if (filename == empty_String) {
00998 filename = statname;
00999 }
01000 }
01001
01002
01003
01004
01005
01006 String explicit_filename
01007 = getAparameter<String>(&stat_pset,"filename",filename);
01008 if (explicit_filename != empty_String) filename = explicit_filename;
01009 String explicit_extension
01010 = getAparameter<String>(&stat_pset,"extension",empty_String);
01011 if (explicit_extension != empty_String) {
01012 if (explicit_extension[0] == '.') {
01013 filename += explicit_extension;
01014 } else {
01015 filename = filename + "." + explicit_extension;
01016 }
01017 }
01018
01019
01020
01021
01022 std::string actual_filename = filename;
01023 if ( (filename != "cout") && (filename != "cerr") ) {
01024 const std::string::size_type npos = std::string::npos;
01025 if ( filename.find('.') == npos ) {
01026 actual_filename += ".log";
01027 }
01028 }
01029
01030
01031
01032 if ( !search_all(ordinary_destination_filenames, actual_filename) ) {
01033 if ( stream_ps.find(actual_filename)!=stream_ps.end() ) {
01034 if (clean_slate_configuration) {
01035 throw edm::Exception ( edm::errors::Configuration )
01036 <<"Duplicate name for a MessageLogger Statistics Destination: "
01037 << actual_filename
01038 << "\n";
01039 } else {
01040 LogWarning("duplicateDestination")
01041 <<"Duplicate name for a MessageLogger Statistics Destination: "
01042 << actual_filename
01043 << "\n" << "Only original configuration instructions are used";
01044 continue;
01045 }
01046 }
01047 }
01048
01049
01050
01051
01052
01053
01054 bool statistics_destination_is_real = !no_statistics_configured;
01055 std::ostream * os_p;
01056 if ( stream_ps.find(actual_filename) == stream_ps.end() ) {
01057 if ( actual_filename == "cout" ) {
01058 os_p = &std::cout;
01059 } else if ( actual_filename == "cerr" ) {
01060 os_p = &std::cerr;
01061 } else {
01062 std::ofstream * osf_p = new std::ofstream(actual_filename.c_str());
01063 os_p = osf_p;
01064 file_ps.push_back(osf_p);
01065 }
01066 stream_ps[actual_filename] = os_p;
01067 } else {
01068 statistics_destination_is_real = true;
01069 os_p = stream_ps[actual_filename];
01070 }
01071
01072 if (statistics_destination_is_real) {
01073
01074 ELdestControl dest_ctrl;
01075 dest_ctrl = admin_p->attach( ELstatistics(*os_p) );
01076 statisticsDestControls.push_back(dest_ctrl);
01077 bool reset = getAparameter<bool>(&stat_pset,"reset",false);
01078 statisticsResets.push_back(reset);
01079
01080
01081 configure_dest(dest_ctrl, psetname);
01082
01083
01084
01085 dest_ctrl.noTerminationSummary();
01086 }
01087
01088 }
01089
01090 }
01091
01092 void
01093 MessageLoggerScribe::configure_external_dests()
01094 {
01095 if( ! job_pset_p )
01096 {
01097
01098
01099 return;
01100 }
01101
01102 for( std::vector<NamedDestination*>::const_iterator it = extern_dests.begin()
01103 ; it != extern_dests.end()
01104 ; ++it
01105 )
01106 {
01107 ELdestination * dest_p = (*it)->dest_p().get();
01108 ELdestControl dest_ctrl = admin_p->attach( *dest_p );
01109
01110
01111 configure_dest( dest_ctrl, (*it)->name() );
01112 delete *it;
01113 }
01114 extern_dests.clear();
01115
01116 }
01117
01118 void
01119 MessageLoggerScribe::parseCategories (std::string const & s,
01120 std::vector<std::string> & cats)
01121 {
01122 const std::string::size_type npos = std::string::npos;
01123 std::string::size_type i = 0;
01124 while ( i != npos ) {
01125 std::string::size_type j = s.find('|',i);
01126 cats.push_back (s.substr(i,j-i));
01127 i = j;
01128 while ( (i != npos) && (s[i] == '|') ) ++i;
01129
01130 }
01131
01132
01133 }
01134
01135 void
01136 MessageLoggerScribe::triggerStatisticsSummaries() {
01137 assert (statisticsDestControls.size() == statisticsResets.size());
01138 for (unsigned int i = 0; i != statisticsDestControls.size(); ++i) {
01139 statisticsDestControls[i].summary( );
01140 if (statisticsResets[i]) statisticsDestControls[i].wipe( );
01141 }
01142 }
01143
01144 void
01145 MessageLoggerScribe::
01146 triggerFJRmessageSummary(std::map<std::string, double> & sm)
01147 {
01148 if (statisticsDestControls.empty()) {
01149 sm["NoStatisticsDestinationsConfigured"] = 0.0;
01150 } else {
01151 statisticsDestControls[0].summaryForJobReport(sm);
01152 }
01153 }
01154
01155 ErrorLog * MessageLoggerScribe::static_errorlog_p;
01156
01157
01158 }
01159 }
01160