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