The Gaudi Framework  v30r3 (a5ef0a68)
RootPerfMonSvc.cpp
Go to the documentation of this file.
1 //====================================================================
2 // RootPerfMonSvc implementation
3 //--------------------------------------------------------------------
4 //
5 // Description: Implementation of the ROOT data storage
6 //
7 // Author : M.Frank
8 //
9 //====================================================================
10 
11 // Framework include files
12 #include "RootCnv/RootPerfMonSvc.h"
15 #include "GaudiKernel/Incident.h"
16 #include "GaudiKernel/MsgStream.h"
17 #include "GaudiKernel/System.h"
18 #include "RootUtils.h"
19 
20 #include "TBranch.h"
21 #include "TDirectory.h"
22 #include "TMap.h"
23 #include "TSystem.h"
24 
25 using namespace std;
26 using namespace Gaudi;
27 typedef const string& CSTR;
28 
29 #define S_OK StatusCode::SUCCESS
30 #define S_FAIL StatusCode::FAILURE
31 
32 // Small routine to issue exceptions
33 StatusCode RootPerfMonSvc::error( CSTR msg )
34 {
35  if ( m_log ) {
36  log() << MSG::ERROR << "Error: " << msg << endmsg;
37  return S_FAIL;
38  }
39  MsgStream m( msgSvc(), name() );
40  m << MSG::ERROR << "Error: " << msg << endmsg;
41  return S_FAIL;
42 }
43 
44 // Initialize the Db data persistency service
45 StatusCode RootPerfMonSvc::initialize()
46 {
47  string cname;
49  if ( !status.isSuccess() ) return error( "Failed to initialize Service base class." );
50  m_log.reset( new MsgStream( msgSvc(), name() ) );
51  m_incidentSvc = service( "IncidentSvc" );
52  if ( !m_incidentSvc ) return error( "Unable to localize interface from service:IncidentSvc" );
53 
54  m_incidentSvc->addListener( this, IncidentType::BeginEvent, 1, false, false );
55  m_incidentSvc->addListener( this, "NEW_STREAM", 1, false, false );
56  m_incidentSvc->addListener( this, "CONNECTED_OUTPUT", 1, false, false );
57 
58  if ( m_ioPerfStats.empty() ) return error( "Performance monitoring file IOPerfStats was not defined." );
59 
60  TDirectory::TContext ctxt( nullptr );
61  m_perfFile.reset( new TFile( m_ioPerfStats.value().c_str(), "RECREATE" ) );
62  if ( !m_perfFile ) return error( "Could not create ROOT file." );
63 
64  if ( !( m_perfTree = new TTree( "T", "performance measurement" ) ) ) return error( "Could not create tree." );
65 
66  m_perfTree->Branch( "utime", &m_utime, "utime/l" );
67  m_perfTree->Branch( "stime", &m_stime, "stime/l" );
68  m_perfTree->Branch( "vsize", &m_vsize, "vsize/l" );
69  m_perfTree->Branch( "rss", &m_rss, "rss/L" );
70  m_perfTree->Branch( "time", &m_time, "time/L" );
71  m_eventNumber = 0;
72  m_perfTree->Branch( "event_number", &m_eventNumber, "event_number/L" );
73  m_perfTree->Branch( "event_type", &m_eventType, "event_type/I" );
74 
75  if ( m_setStreams.empty() ) m_setStreams = "undefined";
76  if ( m_basketSize.empty() ) m_basketSize = "undefined";
77  if ( m_bufferSize.empty() ) m_bufferSize = "undefined";
78  if ( m_splitLevel.empty() ) m_splitLevel = "undefined";
79 
80  auto map = new TMap();
81  map->Add( new TObjString( "streams" ), new TObjString( m_setStreams.value().c_str() ) );
82  map->Add( new TObjString( "basket_size" ), new TObjString( m_basketSize.value().c_str() ) );
83  map->Add( new TObjString( "buffer_size" ), new TObjString( m_bufferSize.value().c_str() ) );
84  map->Add( new TObjString( "split_level" ), new TObjString( m_splitLevel.value().c_str() ) );
85  map->Write( "params", TObject::kSingleKey );
86  return S_OK;
87 }
88 
89 void RootPerfMonSvc::record( EventType eventType )
90 {
91  SysProcStat data;
92  m_eventType = eventType;
93  m_utime = (ULong_t)data.utime;
94  m_stime = (ULong_t)data.stime;
95  m_vsize = (ULong_t)data.vsize;
96  m_rss = (Long_t)data.rss;
97  m_time = (Long_t)data.time;
98  m_perfTree->Fill();
99 }
100 
101 void RootPerfMonSvc::handle( const Incident& incident )
102 {
103  std::string t = incident.type();
104  if ( !t.compare( IncidentType::BeginEvent ) ) {
105  m_eventNumber++;
106  record( EVENT );
107  return;
108  }
109  if ( !t.compare( "CONNECTED_OUTPUT" ) ) {
110  m_outputs.insert( incident.source() );
111  }
112 }
113 
114 // Stop the performance monitoring service
115 StatusCode RootPerfMonSvc::stop()
116 {
117  char text[64];
118  record( FSR );
119  auto map = new TMap();
120  for ( const auto& i : m_outputs ) {
121  const char* fn = i.c_str();
122  Long_t id, siz, flags, tim;
123  if ( 0 == gSystem->GetPathInfo( fn, &id, &siz, &flags, &tim ) ) {
124  ::sprintf( text, "%ld", siz );
125  map->Add( new TObjString( fn ), new TObjString( text ) );
126  }
127  }
128  TDirectory::TContext ctxt( m_perfFile.get() );
129  map->Write( "Outputs", TObject::kSingleKey );
130  return S_OK;
131 }
132 
133 // Finalize the performance monitoring service
134 StatusCode RootPerfMonSvc::finalize()
135 {
136  record( FSR );
137  log() << MSG::INFO;
138  m_log.reset();
139  m_incidentSvc.reset();
140 
141  m_perfFile->Write();
142  m_perfFile->Close();
143  m_perfFile.reset();
144 
145  return Service::finalize();
146 }
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode initialize() override
Definition: Service.cpp:63
long unsigned stime
Definition: SysProcStat.h:18
const std::string & type() const
Access to the incident type.
Definition: Incident.h:41
StatusCode finalize() override
Definition: Service.cpp:173
const std::string & source() const
Access to the source of the incident.
Definition: Incident.h:47
bool isSuccess() const
Definition: StatusCode.h:287
T log(T...args)
#define S_OK
#define S_FAIL
STL namespace.
STL class.
STL class.
long unsigned vsize
Definition: SysProcStat.h:18
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
constexpr double m
Definition: SystemOfUnits.h:94
const string & CSTR
long unsigned utime
Definition: SysProcStat.h:18
Base class for all Incidents (computing events).
Definition: Incident.h:17
T sprintf(T...args)
Helper functions to set/get the application return code.
Definition: __init__.py:1
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
T compare(T...args)