The Gaudi Framework  master (181af51f)
Loading...
Searching...
No Matches
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"
27#include <GaudiKernel/System.h>
29
30#include <TBranch.h>
31#include <TDirectory.h>
32#include <TMap.h>
33#include <TObjString.h>
34#include <TSystem.h>
35
36using namespace std;
37using namespace Gaudi;
38typedef const string& CSTR;
39
40#define S_OK StatusCode::SUCCESS
41#define S_FAIL StatusCode::FAILURE
42
43// Small routine to issue exceptions
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
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
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
109void RootPerfMonSvc::handle( const Incident& incident ) {
110 std::string t = incident.type();
111 if ( !t.compare( IncidentType::BeginEvent ) ) {
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
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
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}
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
const std::string CSTR
#define S_OK
#define S_FAIL
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
StatusCode stop() override
Gaudi::Property< std::string > m_setStreams
StatusCode finalize() override
Service overload: Finalize the service.
MsgStream & log() const
Helper: Use message streamer.
std::set< std::string > m_outputs
SmartIF< IIncidentSvc > m_incidentSvc
Reference to incident service.
void handle(const Incident &incident) override
IIncidentListener override: Inform that a new incident has occurred.
virtual void record(EventType eventType)
Gaudi::Property< std::string > m_splitLevel
Gaudi::Property< std::string > m_ioPerfStats
Gaudi::Property< std::string > m_basketSize
std::unique_ptr< TFile > m_perfFile
StatusCode initialize() override
Service overload: initialize the service.
Gaudi::Property< std::string > m_bufferSize
StatusCode error(const std::string &msg)
Standard way to print errors.
std::unique_ptr< MsgStream > m_log
Message streamer.
long unsigned utime
Definition SysProcStat.h:25
long unsigned vsize
Definition SysProcStat.h:25
long unsigned stime
Definition SysProcStat.h:25
Base class for all Incidents (computing events).
Definition Incident.h:24
const std::string & type() const
Access to the incident type.
Definition Incident.h:43
const std::string & source() const
Access to the source of the incident.
Definition Incident.h:49
Definition of the MsgStream class used to transmit messages.
Definition MsgStream.h:29
StatusCode finalize() override
Definition Service.cpp:223
const std::string & name() const override
Retrieve name of the service.
Definition Service.cpp:333
SmartIF< IFace > service(const std::string &name, bool createIf=true) const
Definition Service.h:79
StatusCode initialize() override
Definition Service.cpp:118
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isSuccess() const
Definition StatusCode.h:314
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
@ ERROR
Definition IMessageSvc.h:22
@ INFO
Definition IMessageSvc.h:22
STL namespace.