The Gaudi Framework  master (37c0b60a)
RootPerfMonSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 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 "RootUtils.h"
25 #include <GaudiKernel/Incident.h>
26 #include <GaudiKernel/MsgStream.h>
27 #include <GaudiKernel/System.h>
28 #include <RootCnv/RootPerfMonSvc.h>
29 
30 #include <TBranch.h>
31 #include <TDirectory.h>
32 #include <TMap.h>
33 #include <TObjString.h>
34 #include <TSystem.h>
35 
36 using namespace std;
37 using namespace Gaudi;
38 typedef const string& CSTR;
39 
40 #define S_OK StatusCode::SUCCESS
41 #define S_FAIL StatusCode::FAILURE
42 
43 // Small routine to issue exceptions
44 StatusCode RootPerfMonSvc::error( CSTR msg ) {
45  if ( m_log ) {
46  log() << MSG::ERROR << "Error: " << msg << endmsg;
47  return S_FAIL;
48  }
49  MsgStream m( msgSvc(), name() );
50  m << MSG::ERROR << "Error: " << msg << endmsg;
51  return S_FAIL;
52 }
53 
54 // Initialize the Db data persistency service
55 StatusCode RootPerfMonSvc::initialize() {
56  string cname;
58  if ( !status.isSuccess() ) return error( "Failed to initialize Service base class." );
59  m_log.reset( new MsgStream( msgSvc(), name() ) );
60  m_incidentSvc = service( "IncidentSvc" );
61  if ( !m_incidentSvc ) return error( "Unable to localize interface from service:IncidentSvc" );
62 
63  m_incidentSvc->addListener( this, IncidentType::BeginEvent, 1, false, false );
64  m_incidentSvc->addListener( this, "NEW_STREAM", 1, false, false );
65  m_incidentSvc->addListener( this, "CONNECTED_OUTPUT", 1, false, false );
66 
67  if ( m_ioPerfStats.empty() ) return error( "Performance monitoring file IOPerfStats was not defined." );
68 
69  TDirectory::TContext ctxt( nullptr );
70  m_perfFile.reset( new TFile( m_ioPerfStats.value().c_str(), "RECREATE" ) );
71  if ( !m_perfFile ) return error( "Could not create ROOT file." );
72 
73  if ( !( m_perfTree = new TTree( "T", "performance measurement" ) ) ) return error( "Could not create tree." );
74 
75  m_perfTree->Branch( "utime", &m_utime, "utime/l" );
76  m_perfTree->Branch( "stime", &m_stime, "stime/l" );
77  m_perfTree->Branch( "vsize", &m_vsize, "vsize/l" );
78  m_perfTree->Branch( "rss", &m_rss, "rss/L" );
79  m_perfTree->Branch( "time", &m_time, "time/L" );
80  m_eventNumber = 0;
81  m_perfTree->Branch( "event_number", &m_eventNumber, "event_number/L" );
82  m_perfTree->Branch( "event_type", &m_eventType, "event_type/I" );
83 
84  if ( m_setStreams.empty() ) m_setStreams = "undefined";
85  if ( m_basketSize.empty() ) m_basketSize = "undefined";
86  if ( m_bufferSize.empty() ) m_bufferSize = "undefined";
87  if ( m_splitLevel.empty() ) m_splitLevel = "undefined";
88 
89  auto map = new TMap();
90  map->Add( new TObjString( "streams" ), new TObjString( m_setStreams.value().c_str() ) );
91  map->Add( new TObjString( "basket_size" ), new TObjString( m_basketSize.value().c_str() ) );
92  map->Add( new TObjString( "buffer_size" ), new TObjString( m_bufferSize.value().c_str() ) );
93  map->Add( new TObjString( "split_level" ), new TObjString( m_splitLevel.value().c_str() ) );
94  map->Write( "params", TObject::kSingleKey );
95  return S_OK;
96 }
97 
98 void RootPerfMonSvc::record( EventType eventType ) {
99  SysProcStat data;
100  m_eventType = eventType;
101  m_utime = data.utime;
102  m_stime = data.stime;
103  m_vsize = data.vsize;
104  m_rss = data.rss;
105  m_time = data.time;
106  m_perfTree->Fill();
107 }
108 
109 void RootPerfMonSvc::handle( const Incident& incident ) {
110  std::string t = incident.type();
111  if ( !t.compare( IncidentType::BeginEvent ) ) {
112  m_eventNumber++;
113  record( EVENT );
114  return;
115  }
116  if ( !t.compare( "CONNECTED_OUTPUT" ) ) { m_outputs.insert( incident.source() ); }
117 }
118 
119 // Stop the performance monitoring service
120 StatusCode RootPerfMonSvc::stop() {
121  char text[64];
122  record( FSR );
123  auto map = new TMap();
124  for ( const auto& i : m_outputs ) {
125  const char* fn = i.c_str();
126  Long_t id, siz, flags, tim;
127  if ( 0 == gSystem->GetPathInfo( fn, &id, &siz, &flags, &tim ) ) {
128  ::sprintf( text, "%ld", siz );
129  map->Add( new TObjString( fn ), new TObjString( text ) );
130  }
131  }
132  TDirectory::TContext ctxt( m_perfFile.get() );
133  map->Write( "Outputs", TObject::kSingleKey );
134  return S_OK;
135 }
136 
137 // Finalize the performance monitoring service
138 StatusCode RootPerfMonSvc::finalize() {
139  record( FSR );
140  log() << MSG::INFO;
141  m_log.reset();
142  m_incidentSvc.reset();
143 
144  m_perfFile->Write();
145  m_perfFile->Close();
146  m_perfFile.reset();
147 
148  return Service::finalize();
149 }
S_OK
#define S_OK
Definition: RootPerfMonSvc.cpp:40
Service::initialize
StatusCode initialize() override
Definition: Service.cpp:118
Incident::source
const std::string & source() const
Access to the source of the incident.
Definition: Incident.h:54
std::string
STL class.
Gaudi::SysProcStat::utime
long unsigned utime
Definition: SysProcStat.h:26
StatusCode::isSuccess
bool isSuccess() const
Definition: StatusCode.h:314
MSG::INFO
@ INFO
Definition: IMessageSvc.h:25
System.h
GaudiMP.FdsRegistry.msg
msg
Definition: FdsRegistry.py:19
DataIncident.h
Gaudi::SysProcStat::time
long time
Definition: SysProcStat.h:31
GaudiPartProp.tests.id
id
Definition: tests.py:111
Gaudi::SysProcStat::rss
long int rss
Definition: SysProcStat.h:28
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:222
AvalancheSchedulerErrorTest.msgSvc
msgSvc
Definition: AvalancheSchedulerErrorTest.py:80
Gaudi::SysProcStat
Definition: SysProcStat.h:22
Gaudi::SysProcStat::stime
long unsigned stime
Definition: SysProcStat.h:26
IIncidentSvc.h
bug_34121.t
t
Definition: bug_34121.py:31
CSTR
const string & CSTR
Definition: RootPerfMonSvc.cpp:38
S_FAIL
#define S_FAIL
Definition: RootPerfMonSvc.cpp:41
StatusCode
Definition: StatusCode.h:65
std::log
T log(T... args)
std::sprintf
T sprintf(T... args)
Gaudi::Units::m
constexpr double m
Definition: SystemOfUnits.h:108
Gaudi::SysProcStat::vsize
long unsigned vsize
Definition: SysProcStat.h:26
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
std::map
STL class.
MsgStream
Definition: MsgStream.h:33
Gaudi
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition: __init__.py:1
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
std
STL namespace.
MSG::ERROR
@ ERROR
Definition: IMessageSvc.h:25
RootUtils.h
Incident::type
const std::string & type() const
Access to the incident type.
Definition: Incident.h:48
Gaudi::RootPerfMonSvc::EventType
EventType
Definition: RootPerfMonSvc.h:75
Incident.h
Incident
Definition: Incident.h:27
MsgStream.h
RootPerfMonSvc.h