Gaudi Framework, version v23r6

Home   Generated: Wed Jan 30 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GoogleAuditor.cpp
Go to the documentation of this file.
1 
2 #include <vector>
3 #include <string>
4 #include <utility>
5 #include <memory>
6 #include <algorithm>
7 
9 #include "GaudiKernel/Auditor.h"
12 #include "GaudiKernel/MsgStream.h"
15 
17 #include "GaudiAlg/Sequencer.h"
18 
19 #include "boost/assign/list_of.hpp"
20 
21 #include "google/heap-profiler.h"
22 #include "google/heap-checker.h"
23 #include "google/profiler.h"
24 
25 namespace Google
26 {
27 
35  class AuditorBase : public extends1<Auditor, IIncidentListener>
36  {
37 
38  public:
39 
41  AuditorBase( const std::string& name, ISvcLocator* pSvcLocator);
42 
44  virtual ~AuditorBase() { }
45 
48  {
49  m_log << MSG::INFO << "Initialised" << endmsg;
50 
51  SmartIF<IIncidentSvc> inSvc(serviceLocator()->service("IncidentSvc"));
52  if ( ! inSvc.isValid() ) return StatusCode::FAILURE;
53 
54  inSvc->addListener( this, IncidentType::BeginEvent );
55 
56  return StatusCode::SUCCESS;
57  }
58 
61  {
62  if ( alreadyRunning() ) stopAudit();
63  return StatusCode::SUCCESS;
64  }
65 
66  private:
67 
69  void startAudit()
70  {
71  m_log << MSG::INFO << " -> Starting full audit from event " << m_nEvts << " to "
73  m_inFullAudit = true;
76  t << "FULL-Events" << m_nEvts << "To" << m_nEvts+m_nSampleEvents ;
77  google_before(t.str());
78  }
79 
81  void stopAudit()
82  {
83  m_log << MSG::INFO << " -> Stopping full audit" << endmsg;
85  t << "FULL-Events" << m_nEvts << "To" << m_nEvts+m_nSampleEvents ;
86  google_after(t.str());
87  m_inFullAudit = false;
89  }
90 
93  bool isSequencer( INamedInterface* i ) const
94  {
95  return ( dynamic_cast<GaudiSequencer*>(i) != NULL ||
96  dynamic_cast<Sequencer*>(i) != NULL );
97  }
98 
99  public:
100 
106  void handle( const Incident& incident )
107  {
108  if ( IncidentType::BeginEvent == incident.type() )
109  {
110  ++m_nEvts;
112  ( m_freq < 0 ||
113  m_nEvts == 1 ||
114  m_nEvts % m_freq == 0 ) );
115  m_log << MSG::DEBUG << "Event " << m_nEvts
116  << " Audit=" << m_audit << endmsg;
117  if ( m_fullEventAudit )
118  {
119  if ( m_inFullAudit )
120  {
122  alreadyRunning() )
123  {
124  stopAudit();
125  }
126  else
127  {
129  }
130  }
131  if ( m_audit && !m_inFullAudit && !alreadyRunning() )
132  {
133  startAudit();
134  }
135  }
136  }
137  }
138 
139  public:
140 
141  void before(StandardEventType type, INamedInterface* i)
142  {
143  if ( !m_skipSequencers || !isSequencer(i) )
144  {
145  before(type,i->name());
146  }
147  }
148 
149  void before(CustomEventTypeRef type, INamedInterface* i)
150  {
151  if ( !m_skipSequencers || !isSequencer(i) )
152  {
153  before(type,i->name());
154  }
155  }
156 
157  void before(StandardEventType type, const std::string& s)
158  {
160  t << type;
161  before(t.str(),s);
162  }
163 
164  void before(CustomEventTypeRef, const std::string& s)
165  {
166  if ( !m_fullEventAudit && m_audit &&
167  std::find(m_veto.begin(),m_veto.end(),s) == m_veto.end() &&
168  ( m_list.empty() || std::find(m_list.begin(),m_list.end(),s) != m_list.end() ) )
169  {
170  if ( !alreadyRunning() )
171  {
172  m_log << MSG::INFO << "Starting Auditor for " << s << endmsg;
173  m_startedBy = s;
175  t << s << "-Event" << m_nEvts;
176  google_before(t.str());
177  }
178  else
179  {
181  << "Auditor already running. Cannot be started for " << s
182  << endmsg;
183  }
184  }
185  }
186 
187  void after(StandardEventType type, INamedInterface* i, const StatusCode& sc)
188  {
189  if ( !m_skipSequencers || !isSequencer(i) )
190  {
192  t << type;
193  after(t.str(),i,sc);
194  }
195  }
196 
197  void after(CustomEventTypeRef type, INamedInterface* i, const StatusCode& sc)
198  {
199  if ( !m_skipSequencers || !isSequencer(i) )
200  {
201  after(type,i->name(),sc);
202  }
203  }
204 
205  void after(StandardEventType type, const std::string& s, const StatusCode& sc)
206  {
208  t << type;
209  after(t.str(),s,sc);
210  }
211 
212  void after(CustomEventTypeRef, const std::string& s, const StatusCode&)
213  {
214  if ( !m_fullEventAudit && m_audit &&
215  std::find(m_veto.begin(),m_veto.end(),s) == m_veto.end() &&
216  ( m_list.empty() || std::find(m_list.begin(),m_list.end(),s) != m_list.end() ) )
217  {
218  if ( s == m_startedBy )
219  {
221  t << s << "-Event" << m_nEvts;
222  google_after(t.str());
223  }
224  }
225  }
226 
227  // Obsolete methods
234 
241 
242  protected:
243 
245  virtual void google_before(const std::string& s) = 0;
246 
248  virtual void google_after(const std::string& s) = 0;
249 
251  virtual bool alreadyRunning() = 0;
252 
253  protected:
254 
255  mutable MsgStream m_log;
256 
257  private:
258 
262 
263  unsigned long long m_eventsToSkip;
264 
266 
267  int m_freq;
268 
269  bool m_audit;
270 
271  unsigned long long m_nEvts;
272 
274 
275  unsigned long long m_nSampleEvents;
276 
277  unsigned long long m_sampleEventCount;
278 
280 
282 
283  };
284 
286  ISvcLocator* pSvcLocator )
287  : base_class ( name , pSvcLocator )
288  , m_log ( msgSvc() , name )
289  , m_audit ( false )
290  , m_nEvts ( 0 )
291  , m_sampleEventCount( 0 )
292  , m_inFullAudit ( false )
293  {
294  {
295  // Note: 'tmp' is needed to avoid an issue with list_of and C++11.
296  const std::vector<std::string> tmp =
297  boost::assign::list_of
298  ("Initialize")
299  ("ReInitialize")
300  ("Execute")
301  ("BeginRun")
302  ("EndRun")
303  ("Finalize");
304  m_when = tmp;
305  }
306 
307  declareProperty("ActivateAt", m_when,
308  "List of phases to activate the Auditoring during" );
309  declareProperty("DisableFor", m_veto,
310  "List of component names to disable the auditing for" );
311  declareProperty("EnableFor", m_list );
312  declareProperty("ProfileFreq", m_freq = -1,
313  "The frequence to audit events. -1 means all events" );
314  declareProperty("DoFullEventProfile", m_fullEventAudit = false,
315  "If true, instead of individually auditing components, the full event (or events) will be audited in one go" );
316  declareProperty("FullEventNSampleEvents", m_nSampleEvents = 1,
317  "The number of events to include in a full event audit, if enabled" );
318  declareProperty("SkipEvents", m_eventsToSkip = 0,
319  "Number of events to skip before activating the auditing" );
320  declareProperty("SkipSequencers", m_skipSequencers = true,
321  "If true, auditing will be skipped for Sequencer objects." );
322  }
323 
337  class HeapProfiler : public AuditorBase
338  {
339 
340  public:
341 
343  HeapProfiler( const std::string& name, ISvcLocator* pSvcLocator)
344  : AuditorBase( name, pSvcLocator )
345  {
346  declareProperty( "DumpHeapProfiles", m_dumpProfileHeaps = true );
347  declareProperty( "PrintProfilesToLog", m_printProfilesToLog = false );
348  }
349 
350  protected:
351 
353  {
354  HeapProfilerStart(s.c_str());
355  }
356 
358  {
359  if ( m_dumpProfileHeaps )
360  {
361  HeapProfilerDump(s.c_str());
362  }
363  if ( m_printProfilesToLog )
364  {
365  const char * profile = GetHeapProfile();
366  m_log << MSG::INFO << profile << endmsg;
367  delete profile;
368  }
369  HeapProfilerStop();
370  }
371 
372  bool alreadyRunning() { return IsHeapProfilerRunning(); }
373 
374  private:
375 
378 
379  };
380 
394  class HeapChecker : public AuditorBase
395  {
396 
397  public:
398 
400  HeapChecker( const std::string& name, ISvcLocator* pSvcLocator)
401  : AuditorBase ( name, pSvcLocator ),
402  m_enabled ( true ),
403  m_checker ( NULL )
404  { }
405 
406  virtual ~HeapChecker() { delete m_checker; }
407 
408  public:
409 
411  {
413  if ( sc.isFailure() ) return sc;
414 
415  const char * HEAPCHECK = getenv("HEAPCHECK");
416  if ( !HEAPCHECK )
417  {
418  m_log << MSG::FATAL
419  << "Environment variable HEAPCHECK must be set to 'local'"
420  << endmsg;
421  return StatusCode::FAILURE;
422  }
423  if ( std::string(HEAPCHECK) != "local" )
424  {
426  << "Environment variable HEAPCHECK is set to " << HEAPCHECK
427  << " Partial Program Heap Checking is disabled"
428  << endmsg;
429  m_enabled = false;
430  }
431 
432  return sc;
433  }
434 
435  protected:
436 
438  {
439  if ( m_enabled && !m_checker )
440  {
441  m_checker = new HeapLeakChecker(s.c_str());
442  }
443  }
444 
446  {
447  if ( m_enabled && m_checker )
448  {
449  if ( ! m_checker->NoLeaks() )
450  {
451  m_log << MSG::WARNING << "Leak detected for " << s << endmsg;
452  }
453  delete m_checker;
454  m_checker = NULL;
455  }
456  }
457 
458  bool alreadyRunning() { return m_enabled && m_checker != NULL ; }
459 
460  private:
461 
462  bool m_enabled;
463  HeapLeakChecker * m_checker;
464 
465  };
466 
480  class CPUProfiler : public AuditorBase
481  {
482 
483  public:
484 
485  CPUProfiler( const std::string& name, ISvcLocator* pSvcLocator )
486  : AuditorBase ( name, pSvcLocator ),
487  m_running ( false )
488  { }
489 
490  protected:
491 
493  {
494  if ( !m_running )
495  {
496  m_running = true;
497  ProfilerStart((s+".prof").c_str());
498  }
499  }
500 
502  {
503  if ( m_running )
504  {
505  ProfilerStop();
506  m_running = false;
507  }
508  }
509 
510  bool alreadyRunning() { return m_running; }
511 
512  private:
513 
514  bool m_running;
515 
516  };
517 
521 
522 }

Generated at Wed Jan 30 2013 17:13:41 for Gaudi Framework, version v23r6 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004