ATLAS Offline Software
Loading...
Searching...
No Matches
xAOD::TFileAccessTracer Class Reference

Helper class keeping track of the files that got accessed. More...

#include <TFileAccessTracer.h>

Collaboration diagram for xAOD::TFileAccessTracer:

Classes

struct  Impl

Public Member Functions

 ~TFileAccessTracer ()
 Destructor.
void add (std::string_view fileName)
 Add information about a new file that got accessed.
const std::string & serverAddress () const
 The address of the server that information is sent to.
void setServerAddress (const std::string &addr)
 Set the address of the server that information is sent to.
double monitoredFraction () const
 Fraction of jobs that should send monitoring information.
void setMonitoredFraction (double value)
 Set the fraction of jobs that should send monitoring information.
void enableDataSubmission (bool value)
 Function for turning data submission on/off.

Static Public Member Functions

static TFileAccessTracerinstance ()
 Access the singleton instance of this class.

Private Member Functions

 TFileAccessTracer ()
 Default constructor.

Private Attributes

std::unique_ptr< Implm_impl
 Pointer to the implementation of the class.

Detailed Description

Helper class keeping track of the files that got accessed.

This class helps in keeping track of which files get accessed during a job. To be able to report about them to the DDM (Rucio) system in a way that doesn't rely on the grid middleware. (So backdoor access to files stored at data centres becomes visible to the DDM system.)

The class can also send information about which branches/variables got accessed in the job. This it simply gets from the xAODCore code.

xAOD::TEvent and xAOD::REvent use this class to send information about xAOD access to the central Rucio monitoring infrastructure. This default behaviour can be influenced in two ways:

  • Using the the public functions on the singleton instance of this class;
  • Setting the following environment variables before running a job:
    • "XAOD_ACCESSTRACER_FRACTION": This is a floating point value, which is the fraction of jobs that should be monitored within that session.
    • "XAOD_ACCESSTRACER_SERVER": This is the address of the server to which the monitoring information should be sent.

Definition at line 37 of file TFileAccessTracer.h.

Constructor & Destructor Documentation

◆ ~TFileAccessTracer()

xAOD::TFileAccessTracer::~TFileAccessTracer ( )

Destructor.

The destructor of the class is the one doing most of the heavy lifting.

If the $SEND_XAOD_FILE_ACCESS_STAT environment variable is set when the object gets deleted, it posts all the information it collected, to the address defined by SERVER_ADDRESS. By constructing an HTTP message from scratch.

Definition at line 81 of file TFileAccessTracer.cxx.

81 {
82
83 // Make sure that nobody is trying to update the object at this point.
84 std::lock_guard<std::mutex> lock(m_impl->m_mutex);
85
86 // If the user turned off the data submission, then stop already here...
87 if (m_impl->m_enableDataSumbission == false) {
88 return;
89 }
90
91 // Decide what monitoring fraction to take. To make it possible for Panda
92 // to override it with larger/smaller values if needed.
93 double monitoredFraction = m_impl->m_monitoredFraction;
94 const char* fractionString = gSystem->Getenv("XAOD_ACCESSTRACER_FRACTION");
95 if (fractionString) {
96 char* endptr = 0;
97 const double fraction = strtod(fractionString, &endptr);
98 if (endptr != fractionString) {
99 monitoredFraction = fraction;
100 }
101 }
102
103 // Decide randomly whether to send the monitoring data or not. While
104 // TRandom is not good enough for statistical purposes, it's fast, and is
105 // perfectly good to make this decision...
106 ::TRandom rng(::TTimeStamp().GetNanoSec());
107 if (rng.Rndm() > monitoredFraction) {
108 return;
109 }
110
111 // Decide what server to send the information to. To make it possible for
112 // Panda to override it if needed.
113 std::string serverAddress = m_impl->m_serverAddress;
114 const char* serverAddressString = gSystem->Getenv("XAOD_ACCESSTRACER_SERVER");
115 if (serverAddressString) {
116 serverAddress = serverAddressString;
117 }
118
119 // Construct the "technical address" of the host:
120 const ::TUrl url(serverAddress.c_str());
121 const ::TInetAddress serverInetAddress =
122 gSystem->GetHostByName(url.GetHost());
123
124 // Open a socket to the server:
125 TSocket socket;
126 if (socket.connect(serverInetAddress, url.GetPort()).isSuccess() == false) {
127 // Just exit silently. If we can't send the info, we can't send the
128 // info. It's not a problem.
129 return;
130 }
131
132 // Let the user know what's happening:
133 ::Info("xAOD::TFileAccessTracer", "Sending file access statistics to %s",
134 serverAddress.c_str());
135
136 // Start constructing the header of the message to send to the server:
137 ::TString hdr = "POST /";
138 hdr += url.GetFile();
139 hdr += " HTTP/1.1\r\n";
140 hdr += "From: ";
141 hdr += gSystem->HostName();
142 hdr += "\r\n";
143 hdr += "Host: ";
144 hdr += url.GetHost();
145 hdr += "\r\n";
146 hdr += "User-Agent: xAODRootAccess\r\n";
147 hdr += "Content-Type: application/json\r\n";
148 hdr += "Connection: close\r\n";
149 hdr += "Content-Length: ";
150
151 //
152 // Now construct the message payload:
153 //
154 ::TString pld = "{";
155
156 //
157 // Collect the names of all the accessed files:
158 //
159 pld += "\"accessedFiles\": [";
160 bool first = true;
161 for (const Impl::AccessedFile& info : m_impl->m_accessedFiles) {
162 if (!first) {
163 pld += ", ";
164 }
165 pld += "\"";
166 pld += info.fullFilePath();
167 pld += "\"";
168 first = false;
169 }
170 pld += "], ";
171 //
172 // Collect the names of all the containers that were accessed:
173 //
174 pld += "\"accessedContainers\": [";
175 first = true;
176 for (const auto& bs : m_impl->m_readStats.containers()) {
177 if (!bs.second.readEntries()) {
178 continue;
179 }
180 if (!first) {
181 pld += ", ";
182 }
183 pld += "{\"";
184 pld += bs.second.GetName();
185 pld += "\": ";
186 pld += bs.second.readEntries();
187 pld += "}";
188 first = false;
189 }
190 pld += "], ";
191 //
192 // Collect the names of all the branches that were accessed:
193 //
194 pld += "\"accessedBranches\": [";
195 first = true;
196 for (const auto& branch : m_impl->m_readStats.branches()) {
197 for (const xAOD::BranchStats* bs : branch.second) {
198 if ((!bs) || (!bs->readEntries())) {
199 continue;
200 }
201 if (!first) {
202 pld += ", ";
203 }
204 pld += "{\"";
205 pld += bs->GetName();
206 pld += "\": ";
207 pld += bs->readEntries();
208 pld += "}";
209 first = false;
210 }
211 }
212 pld += "]";
213 //
214 // Collect some possible Panda information in case the job is running
215 // on the grid:
216 //
217 const char* pandaID = gSystem->Getenv("PandaID");
218 if (pandaID) {
219 pld += ", \"PandaID\": ";
220 pld += pandaID;
221 pld += "";
222 }
223 const char* taskID = gSystem->Getenv("PanDA_TaskID");
224 if (taskID) {
225 pld += ", \"PanDA_TaskID\": ";
226 pld += taskID;
227 pld += "";
228 }
229 //
230 // Add some simple information about the host:
231 //
232 pld += ", \"ROOT_RELEASE\": \"";
233 pld += ROOT_RELEASE;
234 pld += "\"";
235 pld += ", \"ReportRate\": ";
236 pld += monitoredFraction;
237 //
238 // Add some information about the file access pattern:
239 //
240 pld += ", \"ReadCalls\": ";
241 pld += m_impl->m_readStats.fileReads();
242 pld += ", \"ReadSize\": ";
243 pld +=
244 (m_impl->m_readStats.fileReads() != 0
245 ? m_impl->m_readStats.bytesRead() / m_impl->m_readStats.fileReads()
246 : 0);
247 pld += ", \"CacheSize\": ";
248 pld += m_impl->m_readStats.cacheSize();
249 pld += "}";
250
251 // Now finish constructing the header, and merge the two into a single
252 // message:
253 hdr += TString::Format("%i", pld.Length());
254 hdr += "\r\n\r\n";
255 const ::TString msg = hdr + pld;
256
257 // Send the message, and try to receive an answer.
258 socket.send(msg).ignore();
259 TString response;
260 socket.receive(4096, response).ignore();
261}
MDT_Response response
::Long64_t readEntries() const
Get how many entries were read from this branch.
double monitoredFraction() const
Fraction of jobs that should send monitoring information.
const std::string & serverAddress() const
The address of the server that information is sent to.
std::unique_ptr< Impl > m_impl
Pointer to the implementation of the class.
uint32_t rng()
Definition FillerAlg.cxx:40
bool first
Definition DeMoScan.py:534
Helper struct storing information about the accessed files.
MsgStream & msg
Definition testRead.cxx:32

◆ TFileAccessTracer()

xAOD::TFileAccessTracer::TFileAccessTracer ( )
private

Default constructor.

Definition at line 327 of file TFileAccessTracer.cxx.

327: m_impl(std::make_unique<Impl>()) {}

Member Function Documentation

◆ add()

void xAOD::TFileAccessTracer::add ( std::string_view fileName)

Add information about a new file that got accessed.

This function is called by TEvent to record which files were read from during the job.

Parameters
fileNameThe name of the file that is being read from

Definition at line 274 of file TFileAccessTracer.cxx.

274 {
275
276 // Protect this call:
277 std::lock_guard<std::mutex> lock(m_impl->m_mutex);
278
279 // Remember this file:
280 m_impl->m_accessedFiles.insert(
281 {gSystem->DirName(fileName.data()), gSystem->BaseName(fileName.data())});
282}

◆ enableDataSubmission()

void xAOD::TFileAccessTracer::enableDataSubmission ( bool value)

Function for turning data submission on/off.

This function can be used by concerned users to turn off data collection and submission for their jobs completely.

Parameters
valueSetting whether data submission should be enabled or not

Definition at line 322 of file TFileAccessTracer.cxx.

322 {
323
324 m_impl->m_enableDataSumbission = value;
325}

◆ instance()

TFileAccessTracer & xAOD::TFileAccessTracer::instance ( )
static

Access the singleton instance of this class.

Definition at line 263 of file TFileAccessTracer.cxx.

263 {
264
266 return instance;
267}
TFileAccessTracer()
Default constructor.
static TFileAccessTracer & instance()
Access the singleton instance of this class.

◆ monitoredFraction()

double xAOD::TFileAccessTracer::monitoredFraction ( ) const

Fraction of jobs that should send monitoring information.

Definition at line 301 of file TFileAccessTracer.cxx.

301 {
302
303 // Protect this call:
304 std::lock_guard<std::mutex> lock(m_impl->m_mutex);
305
306 return m_impl->m_monitoredFraction;
307}

◆ serverAddress()

const std::string & xAOD::TFileAccessTracer::serverAddress ( ) const

The address of the server that information is sent to.

Definition at line 284 of file TFileAccessTracer.cxx.

284 {
285
286 // Protect this call:
287 std::lock_guard<std::mutex> lock(m_impl->m_mutex);
288
289 return m_impl->m_serverAddress;
290}

◆ setMonitoredFraction()

void xAOD::TFileAccessTracer::setMonitoredFraction ( double value)

Set the fraction of jobs that should send monitoring information.

Definition at line 309 of file TFileAccessTracer.cxx.

309 {
310
311 // Protect this call:
312 std::lock_guard<std::mutex> lock(m_impl->m_mutex);
313
314 m_impl->m_monitoredFraction = value;
315}

◆ setServerAddress()

void xAOD::TFileAccessTracer::setServerAddress ( const std::string & addr)

Set the address of the server that information is sent to.

Definition at line 292 of file TFileAccessTracer.cxx.

292 {
293
294 // Protect this call:
295 std::lock_guard<std::mutex> lock(m_impl->m_mutex);
296
297 // Set the address itself:
298 m_impl->m_serverAddress = addr;
299}

Member Data Documentation

◆ m_impl

std::unique_ptr<Impl> xAOD::TFileAccessTracer::m_impl
private

Pointer to the implementation of the class.

Definition at line 69 of file TFileAccessTracer.h.


The documentation for this class was generated from the following files: