00001
00002
00003
00004 #include "AlgErrorAuditor.h"
00005 #include "GaudiKernel/MsgStream.h"
00006 #include "GaudiKernel/IMessageSvc.h"
00007 #include "GaudiKernel/INamedInterface.h"
00008 #include "GaudiKernel/AudFactory.h"
00009 #include "GaudiKernel/GaudiException.h"
00010
00011
00012 DECLARE_AUDITOR_FACTORY(AlgErrorAuditor);
00013
00014 AlgErrorAuditor::AlgErrorAuditor(const std::string& name, ISvcLocator* pSvcLocator)
00015 : Auditor(name, pSvcLocator), m_error(0), m_fatal(0) {
00016
00017 declareProperty( "Abort", m_abort = false,
00018 "Abort job upon illegal Algorithm return code");
00019 declareProperty( "Throw", m_throw = false,
00020 "Throw GaudiException upon illegal Algorithm return code");
00021 }
00022
00023 AlgErrorAuditor::~AlgErrorAuditor(){
00024 }
00025
00026
00027 void
00028 AlgErrorAuditor:: beforeExecute(INamedInterface* ){
00029 m_error = msgSvc()->messageCount(MSG::ERROR);
00030 m_fatal = msgSvc()->messageCount(MSG::FATAL);
00031 }
00032
00033 StatusCode
00034 AlgErrorAuditor:: initialize() {
00035
00036 if (m_abort && m_throw) {
00037 MsgStream log(msgSvc(), name());
00038 log << MSG::INFO << "Both \"Throw\" and \"Abort\" options have been set."
00039 << " Abort takes precedence." << endreq;
00040 }
00041
00042 return StatusCode::SUCCESS;
00043 }
00044
00045
00046 void
00047 AlgErrorAuditor:: afterExecute(INamedInterface* alg, const StatusCode& sc) {
00048
00049 bool fail(false);
00050 if (msgSvc()->messageCount(MSG::ERROR) != m_error && ! sc.isRecoverable() ) {
00051 std::ostringstream os;
00052 os << "Illegal Return Code: Algorithm " << alg->name()
00053 << " reported an ERROR, but returned a StatusCode \"" << sc << "\"";
00054 os << std::endl << "Error policy described in "
00055 << "https://twiki.cern.ch/twiki/bin/view/Atlas/ReportingErrors";
00056
00057 MsgStream log(msgSvc(), name());
00058 log << MSG::ERROR << os.str() << endreq;
00059 incrMap(alg->name(), 0);
00060 fail = true;
00061
00062 if (m_throw && ! m_abort) {
00063 throw GaudiException(os.str(),"AlgErrorAuditor",0);
00064 }
00065 }
00066
00067 if (msgSvc()->messageCount(MSG::FATAL) != m_fatal &&
00068 sc != StatusCode::FAILURE ) {
00069 std::ostringstream os;
00070 os << "Illegal Return Code: Algorithm " << alg->name()
00071 << " reported a FATAL, but returned a StatusCode \"" << sc << "\"";
00072 os << std::endl << "Error policy described in "
00073 << "https://twiki.cern.ch/twiki/bin/view/Atlas/ReportingErrors";
00074
00075 MsgStream log(msgSvc(), name());
00076 log << MSG::ERROR << os.str() << endreq;
00077 incrMap(alg->name(), 1);
00078 fail = true;
00079
00080 if (m_throw && ! m_abort) {
00081 throw GaudiException(os.str(),"AlgErrorAuditor",0);
00082 }
00083
00084 }
00085
00086 if (fail && m_abort) {
00087 abort();
00088 }
00089
00090 }
00091
00092 StatusCode
00093 AlgErrorAuditor::finalize() {
00094
00095
00096 std::map<std::string,int>::const_iterator itr;
00097 if (m_algMap[0].size() != 0) {
00098 MsgStream log(msgSvc(), name());
00099 log << MSG::INFO << "Found " << m_algMap[0].size()
00100 << " instances where an Algorithm::execute() produced an ERROR "
00101 << "but returned a SUCCESS:" << std::endl;
00102
00103 for (itr = m_algMap[0].begin(); itr != m_algMap[0].end(); ++itr) {
00104 log << itr->first << ": " << itr->second << std::endl;
00105 }
00106
00107 log << endreq;
00108 }
00109
00110 if (m_algMap[1].size() != 0) {
00111 MsgStream log(msgSvc(), name());
00112 log << MSG::INFO << "Found " << m_algMap[1].size()
00113 << " instances where an Algorithm::execute() produced a FATAL "
00114 << "but returned a SUCCESS:" << std::endl;
00115
00116 for (itr = m_algMap[1].begin(); itr != m_algMap[1].end(); ++itr) {
00117 log << itr->first << ": " << itr->second << std::endl;
00118 }
00119
00120 log << endreq;
00121 }
00122
00123
00124 return StatusCode::SUCCESS;
00125
00126 }
00127
00128 void
00129 AlgErrorAuditor::incrMap(const std::string& alg, int level) {
00130 std::map<std::string, int>::iterator itr;
00131 if ( (itr=m_algMap[level].find(alg)) != m_algMap[level].end()) {
00132 itr->second++;
00133 } else {
00134 m_algMap[level].insert( std::pair<std::string,int>(alg,1) );
00135 }
00136 }
00137