| # Gaudi Framework, version v23r1 |

Home |  | Generated: Wed Feb 29 2012

# GoogleAuditor.cpp

Go to the documentation of this file.

    00001
    00002 #include <vector>
    00003 #include <string>
    00004 #include <utility>
    00005 #include <memory>
    00006 #include <algorithm>
    00007
    00008 #include "GaudiKernel/AudFactory.h"
    00009 #include "GaudiKernel/Auditor.h"
    00010 #include "GaudiKernel/IAuditorSvc.h"
    00011 #include "GaudiKernel/GaudiException.h"
    00012 #include "GaudiKernel/MsgStream.h"
    00013 #include "GaudiKernel/IIncidentListener.h"
    00014 #include "GaudiKernel/IIncidentSvc.h"
    00015
    00016 #include "GaudiAlg/GaudiSequencer.h"
    00017 #include "GaudiAlg/Sequencer.h"
    00018
    00019 #include "boost/assign/list_of.hpp"
    00020
    00021 #include "google/heap-profiler.h"
    00022 #include "google/heap-checker.h"
    00023 #include "google/profiler.h"
    00024
    00025 namespace Google
    00026 {
    00027
    00035   class AuditorBase : public extends1<Auditor, IIncidentListener>
    00036   {
    00037
    00038   public:
    00039
    00041     AuditorBase( const std::string& name, ISvcLocator* pSvcLocator);
    00042
    00044     virtual ~AuditorBase() {  }
    00045
    00047     StatusCode initialize()
    00048     {
    00049       m_log << MSG::INFO << "Initialised" << endmsg;
    00050
    00051       SmartIF<IIncidentSvc> inSvc(serviceLocator()->service("IncidentSvc"));
    00052       if ( ! inSvc.isValid() ) return StatusCode::FAILURE;
    00053
    00054       inSvc->addListener( this, IncidentType::BeginEvent );
    00055
    00056       return StatusCode::SUCCESS;
    00057     }
    00058
    00060     StatusCode finalize()
    00061     {
    00062       if ( alreadyRunning() ) stopAudit();
    00063       return StatusCode::SUCCESS;
    00064     }
    00065
    00066   private:
    00067
    00069     void startAudit()
    00070     {
    00071       m_log << MSG::INFO << " -> Starting full audit from event " << m_nEvts << " to "
    00072             << m_nEvts+m_nSampleEvents << endmsg;
    00073       m_inFullAudit = true;
    00074       m_sampleEventCount = 1;
    00075       std::ostringstream t;
    00076       t << "FULL-Events" << m_nEvts << "To" << m_nEvts+m_nSampleEvents ;
    00077       google_before(t.str());
    00078     }
    00079
    00081     void stopAudit()
    00082     {
    00083       m_log << MSG::INFO << " -> Stopping full audit" << endmsg;
    00084       std::ostringstream t;
    00085       t << "FULL-Events" << m_nEvts << "To" << m_nEvts+m_nSampleEvents ;
    00086       google_after(t.str());
    00087       m_inFullAudit = false;
    00088       m_sampleEventCount = 0;
    00089     }
    00090
    00093     bool isSequencer( INamedInterface* i ) const
    00094     {
    00095       return ( dynamic_cast<GaudiSequencer*>(i) != NULL ||
    00096                dynamic_cast<Sequencer*>(i)      != NULL );
    00097     }
    00098
    00099   public:
    00100
    00106     void handle( const Incident& incident )
    00107     {
    00108       if ( IncidentType::BeginEvent == incident.type() )
    00109       {
    00110         ++m_nEvts;
    00111         m_audit = ( m_nEvts > m_eventsToSkip &&
    00112                     ( m_freq < 0            ||
    00113                       m_nEvts == 1          ||
    00114                       m_nEvts % m_freq == 0  ) );
    00115         m_log << MSG::DEBUG << "Event " << m_nEvts
    00116               << " Audit=" << m_audit << endmsg;
    00117         if ( m_fullEventAudit )
    00118         {
    00119           if ( m_inFullAudit )
    00120           {
    00121             if ( m_sampleEventCount >= m_nSampleEvents &&
    00122                  alreadyRunning() )
    00123             {
    00124               stopAudit();
    00125             }
    00126             else
    00127             {
    00128               ++m_sampleEventCount;
    00129             }
    00130           }
    00131           if ( m_audit && !m_inFullAudit && !alreadyRunning() )
    00132           {
    00133             startAudit();
    00134           }
    00135         }
    00136       }
    00137     }
    00138
    00139   public:
    00140
    00141     void before(StandardEventType type, INamedInterface* i)
    00142     {
    00143       if ( !m_skipSequencers || !isSequencer(i) )
    00144       {
    00145         before(type,i->name());
    00146       }
    00147     }
    00148
    00149     void before(CustomEventTypeRef type, INamedInterface* i)
    00150     {
    00151       if ( !m_skipSequencers || !isSequencer(i) )
    00152       {
    00153         before(type,i->name());
    00154       }
    00155     }
    00156
    00157     void before(StandardEventType type, const std::string& s)
    00158     {
    00159       std::ostringstream t;
    00160       t << type;
    00161       before(t.str(),s);
    00162     }
    00163
    00164     void before(CustomEventTypeRef, const std::string& s)
    00165     {
    00166       if ( !m_fullEventAudit && m_audit &&
    00167            std::find(m_veto.begin(),m_veto.end(),s) == m_veto.end() &&
    00168            ( m_list.empty() || std::find(m_list.begin(),m_list.end(),s) != m_list.end() ) )
    00169       {
    00170         if ( !alreadyRunning() )
    00171         {
    00172           m_log << MSG::INFO << "Starting Auditor for " << s << endmsg;
    00173           m_startedBy = s;
    00174           std::ostringstream t;
    00175           t << s << "-Event" << m_nEvts;
    00176           google_before(t.str());
    00177         }
    00178         else
    00179         {
    00180           m_log << MSG::WARNING
    00181                 << "Auditor already running. Cannot be started for " << s
    00182                 << endmsg;
    00183         }
    00184       }
    00185     }
    00186
    00187     void after(StandardEventType type, INamedInterface* i, const StatusCode& sc)
    00188     {
    00189       if ( !m_skipSequencers || !isSequencer(i) )
    00190       {
    00191         std::ostringstream t;
    00192         t << type;
    00193         after(t.str(),i,sc);
    00194       }
    00195     }
    00196
    00197     void after(CustomEventTypeRef type, INamedInterface* i, const StatusCode& sc)
    00198     {
    00199       if ( !m_skipSequencers || !isSequencer(i) )
    00200       {
    00201         after(type,i->name(),sc);
    00202       }
    00203     }
    00204
    00205     void after(StandardEventType type, const std::string& s, const StatusCode& sc)
    00206     {
    00207       std::ostringstream t;
    00208       t << type;
    00209       after(t.str(),s,sc);
    00210     }
    00211
    00212     void after(CustomEventTypeRef, const std::string& s, const StatusCode&)
    00213     {
    00214       if ( !m_fullEventAudit && m_audit &&
    00215            std::find(m_veto.begin(),m_veto.end(),s) == m_veto.end() &&
    00216            ( m_list.empty() || std::find(m_list.begin(),m_list.end(),s) != m_list.end() ) )
    00217       {
    00218         if ( s == m_startedBy )
    00219         {
    00220           std::ostringstream t;
    00221           t << s << "-Event" << m_nEvts;
    00222           google_after(t.str());
    00223         }
    00224       }
    00225     }
    00226
    00227     // Obsolete methods
    00228     void beforeInitialize  (INamedInterface *i) { return before(IAuditor::Initialize,i);   }
    00229     void beforeReinitialize(INamedInterface *i) { return before(IAuditor::ReInitialize,i); }
    00230     void beforeExecute     (INamedInterface *i) { return before(IAuditor::Execute,i);      }
    00231     void beforeBeginRun    (INamedInterface *i) { return before(IAuditor::BeginRun,i);     }
    00232     void beforeEndRun      (INamedInterface *i) { return before(IAuditor::EndRun,i);       }
    00233     void beforeFinalize    (INamedInterface *i) { return before(IAuditor::Finalize,i);     }
    00234
    00235     void afterInitialize   (INamedInterface *i) { return after(IAuditor::Initialize,i,StatusCode::SUCCESS); }
    00236     void afterReinitialize (INamedInterface *i) { return after(IAuditor::ReInitialize,i,StatusCode::SUCCESS); }
    00237     void afterExecute      (INamedInterface *i, const StatusCode& s) { return after(IAuditor::Execute,i,s); }
    00238     void afterBeginRun     (INamedInterface *i) { return after(IAuditor::BeginRun,i,StatusCode::SUCCESS); }
    00239     void afterEndRun       (INamedInterface *i) { return after(IAuditor::EndRun,i,StatusCode::SUCCESS); }
    00240     void afterFinalize     (INamedInterface *i) { return after(IAuditor::Finalize,i,StatusCode::SUCCESS); }
    00241
    00242   protected:
    00243
    00245     virtual void google_before(const std::string& s) = 0;
    00246
    00248     virtual void google_after(const std::string& s) = 0;
    00249
    00251     virtual bool alreadyRunning() = 0;
    00252
    00253   protected:
    00254
    00255     mutable MsgStream         m_log;
    00256
    00257   private:
    00258
    00259     std::vector<std::string>  m_when;
    00260     std::vector<std::string>  m_veto;
    00261     std::vector<std::string>  m_list;
    00262
    00263     unsigned long long m_eventsToSkip;
    00264
    00265     bool m_skipSequencers;
    00266
    00267     int m_freq;
    00268
    00269     bool m_audit;
    00270
    00271     unsigned long long m_nEvts;
    00272
    00273     bool m_fullEventAudit;
    00274
    00275     unsigned long long m_nSampleEvents;
    00276
    00277     unsigned long long m_sampleEventCount;
    00278
    00279     bool m_inFullAudit;
    00280
    00281     std::string m_startedBy;
    00282
    00283   };
    00284
    00285   AuditorBase::AuditorBase( const std::string& name,
    00286                             ISvcLocator* pSvcLocator )
    00287     : base_class ( name , pSvcLocator )
    00288     , m_log      ( msgSvc() , name )
    00289     , m_audit    ( false )
    00290     , m_nEvts    ( 0 )
    00291     , m_sampleEventCount( 0 )
    00292     , m_inFullAudit ( false )
    00293   {
    00294     declareProperty("ActivateAt", m_when = boost::assign::list_of
    00295                     ("Initialize")
    00296                     ("ReInitialize")
    00297                     ("Execute")
    00298                     ("BeginRun")
    00299                     ("EndRun")
    00300                     ("Finalize"),
    00301                     "List of phases to activate the Auditoring during" );
    00302     declareProperty("DisableFor", m_veto,
    00303                     "List of component names to disable the auditing for" );
    00304     declareProperty("EnableFor", m_list );
    00305     declareProperty("ProfileFreq", m_freq = -1,
    00306                     "The frequence to audit events. -1 means all events" );
    00307     declareProperty("DoFullEventProfile", m_fullEventAudit = false,
    00308                     "If true, instead of individually auditing components, the full event (or events) will be audited in one go" );
    00309     declareProperty("FullEventNSampleEvents", m_nSampleEvents = 1,
    00310                     "The number of events to include in a full event audit, if enabled" );
    00311     declareProperty("SkipEvents", m_eventsToSkip = 0,
    00312                     "Number of events to skip before activating the auditing" );
    00313     declareProperty("SkipSequencers", m_skipSequencers = true,
    00314                     "If true, auditing will be skipped for Sequencer objects." );
    00315   }
    00316
    00330   class HeapProfiler : public AuditorBase
    00331   {
    00332
    00333   public:
    00334
    00336     HeapProfiler( const std::string& name, ISvcLocator* pSvcLocator)
    00337       : AuditorBase( name, pSvcLocator )
    00338     {
    00339       declareProperty( "DumpHeapProfiles",    m_dumpProfileHeaps   = true  );
    00340       declareProperty( "PrintProfilesToLog",  m_printProfilesToLog = false );
    00341     }
    00342
    00343   protected:
    00344
    00345     void google_before(const std::string& s)
    00346     {
    00347       HeapProfilerStart(s.c_str());
    00348     }
    00349
    00350     void google_after(const std::string& s)
    00351     {
    00352       if ( m_dumpProfileHeaps )
    00353       {
    00354         HeapProfilerDump(s.c_str());
    00355       }
    00356       if ( m_printProfilesToLog )
    00357       {
    00358         const char * profile = GetHeapProfile();
    00359         m_log << MSG::INFO << profile << endmsg;
    00360         delete profile;
    00361       }
    00362       HeapProfilerStop();
    00363     }
    00364
    00365     bool alreadyRunning() { return IsHeapProfilerRunning(); }
    00366
    00367   private:
    00368
    00369     bool m_dumpProfileHeaps;
    00370     bool m_printProfilesToLog;
    00371
    00372   };
    00373
    00387   class HeapChecker : public AuditorBase
    00388   {
    00389
    00390   public:
    00391
    00393     HeapChecker( const std::string& name, ISvcLocator* pSvcLocator)
    00394       : AuditorBase ( name, pSvcLocator ),
    00395         m_enabled   ( true ),
    00396         m_checker   ( NULL )
    00397     { }
    00398
    00399     virtual ~HeapChecker() { delete m_checker; }
    00400
    00401   public:
    00402
    00403     StatusCode initialize()
    00404     {
    00405       const StatusCode sc = AuditorBase::initialize();
    00406       if ( sc.isFailure() ) return sc;
    00407
    00408       const char * HEAPCHECK = getenv("HEAPCHECK");
    00409       if ( !HEAPCHECK )
    00410       {
    00411         m_log << MSG::FATAL
    00412               << "Environment variable HEAPCHECK must be set to 'local'"
    00413               << endmsg;
    00414         return StatusCode::FAILURE;
    00415       }
    00416       if ( std::string(HEAPCHECK) != "local" )
    00417       {
    00418         m_log << MSG::WARNING
    00419               << "Environment variable HEAPCHECK is set to " << HEAPCHECK
    00420               << " Partial Program Heap Checking is disabled"
    00421               << endmsg;
    00422         m_enabled = false;
    00423       }
    00424
    00425       return sc;
    00426     }
    00427
    00428   protected:
    00429
    00430     void google_before(const std::string& s)
    00431     {
    00432       if ( m_enabled && !m_checker )
    00433       {
    00434         m_checker = new HeapLeakChecker(s.c_str());
    00435       }
    00436     }
    00437
    00438     void google_after(const std::string& s)
    00439     {
    00440       if ( m_enabled && m_checker )
    00441       {
    00442         if ( ! m_checker->NoLeaks() )
    00443         {
    00444           m_log << MSG::WARNING << "Leak detected for " << s << endmsg;
    00445         }
    00446         delete m_checker;
    00447         m_checker = NULL;
    00448       }
    00449     }
    00450
    00451     bool alreadyRunning() { return m_enabled && m_checker != NULL ; }
    00452
    00453   private:
    00454
    00455     bool m_enabled;
    00456     HeapLeakChecker * m_checker;
    00457
    00458   };
    00459
    00473   class CPUProfiler : public AuditorBase
    00474   {
    00475
    00476   public:
    00477
    00478     CPUProfiler( const std::string& name, ISvcLocator* pSvcLocator )
    00479       : AuditorBase ( name, pSvcLocator ),
    00480         m_running   ( false )
    00481     { }
    00482
    00483   protected:
    00484
    00485     void google_before(const std::string& s)
    00486     {
    00487       if ( !m_running )
    00488       {
    00489         m_running = true;
    00490         ProfilerStart((s+".prof").c_str());
    00491       }
    00492     }
    00493
    00494     void google_after(const std::string&)
    00495     {
    00496       if ( m_running )
    00497       {
    00498         ProfilerStop();
    00499         m_running = false;
    00500       }
    00501     }
    00502
    00503     bool alreadyRunning() { return m_running; }
    00504
    00505   private:
    00506
    00507     bool m_running;
    00508
    00509   };
    00510
    00511   DECLARE_AUDITOR_FACTORY( HeapProfiler );
    00512   DECLARE_AUDITOR_FACTORY( HeapChecker  );
    00513   DECLARE_AUDITOR_FACTORY( CPUProfiler  );
    00514
    00515 }

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines