XRootD
Loading...
Searching...
No Matches
XrdClRecorder.hh
Go to the documentation of this file.
1//------------------------------------------------------------------------------
2// Copyright (c) 2011-2017 by European Organization for Nuclear Research (CERN)
3// Author: Michal Simon <michal.simon@cern.ch>
4//------------------------------------------------------------------------------
5// This file is part of the XRootD software suite.
6//
7// XRootD is free software: you can redistribute it and/or modify
8// it under the terms of the GNU Lesser General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// XRootD is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU Lesser General Public License
18// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
19//
20// In applying this licence, CERN does not waive the privileges and immunities
21// granted to it by virtue of its status as an Intergovernmental Organization
22// or submit itself to any jurisdiction.
23
24#ifndef XRDCK_RECORDER_HH_
25#define XRDCK_RECORDER_HH_
26
30#include "XrdCl/XrdClLog.hh"
31#include "XrdClAction.hh"
32
33#include <mutex>
34#include <fcntl.h>
35
36namespace XrdCl
37{
38//------------------------------------------------------------------------------
41//------------------------------------------------------------------------------
42class Recorder: public FilePlugIn
43{
44 //----------------------------------------------------------------------------
47 //----------------------------------------------------------------------------
48 class Output
49 {
50 public:
51
52 //------------------------------------------------------------------------
55 //------------------------------------------------------------------------
56 inline static Output& Instance()
57 {
58 Output& output = Get();
59 std::unique_lock<std::mutex> lck( output.mtx );
60 if( !output.IsValid() )
61 {
62 if( !output.Open() )
63 DefaultEnv::GetLog()->Error( AppMsg, "[Recorder] Failed to create the output file." );
64 }
65 return output;
66 }
67
68 //------------------------------------------------------------------------
70 //------------------------------------------------------------------------
71 inline static Output& Get()
72 {
73 static Output output;
74 return output;
75 }
76
77 //------------------------------------------------------------------------
78 // Record the user action
79 // @param action : the action to be recorded
80 // @return : true if the data was successful written to disk,
81 // false otherwise
82 //------------------------------------------------------------------------
83 bool Write( std::unique_ptr<Action> action )
84 {
85 std::unique_lock<std::mutex> lck( mtx );
86 const std::string &entry = action->ToString();
87 int btsWritten = 0;
88 do
89 {
90 int rc = ::write( fd, entry.c_str(), entry.size() );
91 if( rc < 0 )
92 {
93 DefaultEnv::GetLog()->Warning( AppMsg, "[Recorder] failed to record an action: %s", strerror( errno ) );
94 return false;
95 }
96 else
97 btsWritten += rc;
98 }
99 while( size_t( btsWritten ) < entry.size() );
100 return true;;
101 }
102
103 //------------------------------------------------------------------------
107 //------------------------------------------------------------------------
108 bool Open()
109 {
110 fd = open( path.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644 );
111 if( fd < 0 )
112 DefaultEnv::GetLog()->Warning( AppMsg, "[Recorder] failed to open the output file: %s", strerror( errno ) );
113 return ( fd >= 0 );
114 }
115
116 //------------------------------------------------------------------------
118 //------------------------------------------------------------------------
119 inline bool IsValid()
120 {
121 return ( fd > 0 );
122 }
123
124 void SetPath( const std::string &path )
125 {
126 this->path = path;
127 }
128
129 private:
130
131 //------------------------------------------------------------------------
133 //------------------------------------------------------------------------
134 Output( ) : fd( -1 )
135 {
136 }
137
138 //------------------------------------------------------------------------
139 // Deleted copy/move constructors and assignment operators
140 //------------------------------------------------------------------------
141 Output( const Output& ) = delete;
142 Output( Output&& ) = delete;
143 Output& operator=( const Output& ) = delete;
144 Output& operator=( Output&& ) = delete;
145
146 //------------------------------------------------------------------------
148 //------------------------------------------------------------------------
149 ~Output()
150 {
151 if( fd >= 0 )
152 {
153 int rc = close( fd );
154 if( rc < 0 )
155 DefaultEnv::GetLog()->Warning( AppMsg, "[Recorder] failed to close the output file: %s", strerror( errno ) );
156 }
157 }
158
159 std::mutex mtx; //< mutex guarding the writes
160 int fd; //< the csv file descriptor
161 std::string path; //< path to the csv file
162 };
163
164 //----------------------------------------------------------------------------
166 //----------------------------------------------------------------------------
167 struct RecordHandler : public ResponseHandler
168 {
169 //--------------------------------------------------------------------------
174 //--------------------------------------------------------------------------
175 RecordHandler( Output &output,
176 std::unique_ptr<Action> action,
177 ResponseHandler *handler ) :
178 output( output ),
179 action( std::move( action ) ),
180 handler( handler )
181 {
182 }
183
184 //--------------------------------------------------------------------------
189 //--------------------------------------------------------------------------
190 void HandleResponseWithHosts( XRootDStatus *status,
191 AnyObject *response,
192 HostList *hostList )
193 {
194 action->RecordResult( status, response );
195 output.Write( std::move( action ) );
196 if (handler)
197 handler->HandleResponseWithHosts( status, response, hostList );
198 delete this;
199 }
200
201 //--------------------------------------------------------------------------
205 //--------------------------------------------------------------------------
206 void HandleResponse( XRootDStatus *status,
207 AnyObject *response )
208 {
209 action->RecordResult( status, response );
210 output.Write( std::move( action ) );
211 if (handler)
212 handler->HandleResponse( status, response );
213 delete this;
214 }
215
216 Output &output; //< the object handling writes to csv file
217 std::unique_ptr<Action> action; //< user action
218 ResponseHandler *handler; //< user completion handler
219 };
220
221
222public:
223
224 //----------------------------------------------------------------------------
227 //----------------------------------------------------------------------------
228 inline static void SetOutput( const std::string &cfgpath )
229 {
230 static const std::string defaultpath = "/tmp/xrdrecord.csv";
231 const char *envpath = getenv( "XRD_RECORDERPATH" );
232 std::string path = envpath ? envpath :
233 ( !cfgpath.empty() ? cfgpath : defaultpath );
234 Output::Get().SetPath( path );
235 }
236
237 //----------------------------------------------------------------------------
239 //----------------------------------------------------------------------------
241 file( false ),
242 output( Output::Instance() )
243 {
244 }
245
246 //----------------------------------------------------------------------------
248 //----------------------------------------------------------------------------
249 bool IsValid() const
250 {
251 return output.IsValid();
252 }
253
254 //----------------------------------------------------------------------------
256 //----------------------------------------------------------------------------
257 virtual ~Recorder()
258 {
259 }
260
261 //----------------------------------------------------------------------------
263 //----------------------------------------------------------------------------
264 virtual XRootDStatus Open(const std::string& url,
265 OpenFlags::Flags flags,
266 Access::Mode mode,
267 ResponseHandler* handler,
268 uint16_t timeout)
269 {
270 std::unique_ptr<Action> ptr( new OpenAction( this, url, flags, mode, timeout ) );
271 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
272 return file.Open( url, flags, mode, recHandler, timeout );
273 }
274
275 //----------------------------------------------------------------------------
277 //----------------------------------------------------------------------------
279 uint16_t timeout)
280 {
281 std::unique_ptr<Action> ptr( new CloseAction( this, timeout ) );
282 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
283 return file.Close( recHandler, timeout );
284 }
285
286 //----------------------------------------------------------------------------
288 //----------------------------------------------------------------------------
289 virtual XRootDStatus Stat(bool force,
290 ResponseHandler* handler,
291 uint16_t timeout)
292 {
293 std::unique_ptr<Action> ptr( new StatAction( this, force, timeout ) );
294 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
295 return file.Stat(force, recHandler, timeout);
296 }
297
298
299 //----------------------------------------------------------------------------
301 //----------------------------------------------------------------------------
302 virtual XRootDStatus Read(uint64_t offset,
303 uint32_t size,
304 void* buffer,
305 ResponseHandler* handler,
306 uint16_t timeout)
307 {
308 std::unique_ptr<Action> ptr( new ReadAction( this, offset, size, timeout ) );
309 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
310 return file.Read( offset, size, buffer, recHandler, timeout );
311 }
312
313 //----------------------------------------------------------------------------
315 //----------------------------------------------------------------------------
316 virtual XRootDStatus Write(uint64_t offset,
317 uint32_t size,
318 const void* buffer,
319 ResponseHandler* handler,
320 uint16_t timeout)
321 {
322 std::unique_ptr<Action> ptr( new WriteAction( this, offset, size, timeout ) );
323 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
324 return file.Write( offset, size, buffer, recHandler, timeout );
325 }
326
327 //------------------------------------------------------------------------
329 //------------------------------------------------------------------------
330 virtual XRootDStatus PgRead( uint64_t offset,
331 uint32_t size,
332 void *buffer,
333 ResponseHandler *handler,
334 uint16_t timeout )
335 {
336 std::unique_ptr<Action> ptr( new PgReadAction( this, offset, size, timeout ) );
337 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
338 return file.PgRead( offset, size, buffer, recHandler, timeout );
339 }
340
341 //------------------------------------------------------------------------
343 //------------------------------------------------------------------------
344 virtual XRootDStatus PgWrite( uint64_t offset,
345 uint32_t size,
346 const void *buffer,
347 std::vector<uint32_t> &cksums,
348 ResponseHandler *handler,
349 uint16_t timeout )
350 {
351 std::unique_ptr<Action> ptr( new PgWriteAction( this, offset, size, timeout ) );
352 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
353 return file.PgWrite( offset, size, buffer, cksums, recHandler, timeout );
354 }
355
356 //----------------------------------------------------------------------------
358 //----------------------------------------------------------------------------
360 uint16_t timeout)
361 {
362 std::unique_ptr<Action> ptr( new SyncAction( this, timeout ) );
363 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
364 return file.Sync( recHandler, timeout );
365 }
366
367 //----------------------------------------------------------------------------
369 //----------------------------------------------------------------------------
370 virtual XRootDStatus Truncate(uint64_t size,
371 ResponseHandler* handler,
372 uint16_t timeout)
373 {
374 std::unique_ptr<Action> ptr( new TruncateAction( this, size, timeout ) );
375 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
376 return file.Truncate(size, recHandler, timeout);
377 }
378
379 //----------------------------------------------------------------------------
381 //----------------------------------------------------------------------------
382 virtual XRootDStatus VectorRead(const ChunkList& chunks,
383 void* buffer,
384 ResponseHandler* handler,
385 uint16_t timeout)
386 {
387 std::unique_ptr<Action> ptr( new VectorReadAction( this, chunks, timeout ) );
388 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
389 return file.VectorRead(chunks, buffer, recHandler, timeout);
390 }
391
392 //----------------------------------------------------------------------------
394 //----------------------------------------------------------------------------
395 virtual XRootDStatus VectorWrite( const ChunkList &chunks,
396 ResponseHandler *handler,
397 uint16_t timeout )
398 {
399 std::unique_ptr<Action> ptr( new VectorWriteAction( this, chunks, timeout ) );
400 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
401 return file.VectorWrite( chunks, recHandler, timeout );
402 }
403
404 //----------------------------------------------------------------------------
406 //----------------------------------------------------------------------------
407 virtual XRootDStatus Fcntl(const Buffer& arg,
408 ResponseHandler* handler,
409 uint16_t timeout)
410 {
411 std::unique_ptr<Action> ptr( new FcntlAction( this, arg, timeout ) );
412 RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
413 return file.Fcntl(arg, recHandler, timeout);
414 }
415
416 //----------------------------------------------------------------------------
418 //----------------------------------------------------------------------------
420 uint16_t timeout)
421 {
422 return file.Visa(handler, timeout);
423 }
424
425 //----------------------------------------------------------------------------
427 //----------------------------------------------------------------------------
428 virtual bool IsOpen() const
429 {
430 return file.IsOpen();
431 }
432
433 //----------------------------------------------------------------------------
435 //----------------------------------------------------------------------------
436 virtual bool SetProperty(const std::string& name,
437 const std::string& value)
438 {
439 return file.SetProperty(name, value);
440 }
441
442 //----------------------------------------------------------------------------
444 //----------------------------------------------------------------------------
445 virtual bool GetProperty(const std::string& name,
446 std::string& value) const
447 {
448 return file.GetProperty(name, value);
449 }
450
451private:
452
453 File file; //< The file object that performs the actual operation
454 Output &output; //< The object for writing the recorded actions
455};
456
457} // namespace XrdCl
458
459#endif /* XRDCK_RECORDER_HH_ */
#define close(a)
Definition XrdPosix.hh:43
#define write(a, b, c)
Definition XrdPosix.hh:110
#define open
Definition XrdPosix.hh:71
Binary blob representation.
static Log * GetLog()
Get default log.
An interface for file plug-ins.
A file.
Definition XrdClFile.hh:46
void Error(uint64_t topic, const char *format,...)
Report an error.
Definition XrdClLog.cc:231
void Warning(uint64_t topic, const char *format,...)
Report a warning.
Definition XrdClLog.cc:248
bool IsValid() const
virtual XRootDStatus Open(const std::string &url, OpenFlags::Flags flags, Access::Mode mode, ResponseHandler *handler, uint16_t timeout)
Open.
virtual XRootDStatus Fcntl(const Buffer &arg, ResponseHandler *handler, uint16_t timeout)
Fcntl.
virtual XRootDStatus Sync(ResponseHandler *handler, uint16_t timeout)
Sync.
virtual XRootDStatus PgRead(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus Stat(bool force, ResponseHandler *handler, uint16_t timeout)
Stat.
virtual bool SetProperty(const std::string &name, const std::string &value)
SetProperty.
virtual bool IsOpen() const
IsOpen.
static void SetOutput(const std::string &cfgpath)
virtual XRootDStatus VectorWrite(const ChunkList &chunks, ResponseHandler *handler, uint16_t timeout)
VectorRead.
virtual XRootDStatus Truncate(uint64_t size, ResponseHandler *handler, uint16_t timeout)
Truncate.
virtual XRootDStatus Close(ResponseHandler *handler, uint16_t timeout)
Close.
virtual ~Recorder()
Destructor.
virtual bool GetProperty(const std::string &name, std::string &value) const
GetProperty.
virtual XRootDStatus Visa(ResponseHandler *handler, uint16_t timeout)
Visa.
virtual XRootDStatus PgWrite(uint64_t offset, uint32_t size, const void *buffer, std::vector< uint32_t > &cksums, ResponseHandler *handler, uint16_t timeout)
virtual XRootDStatus Read(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, uint16_t timeout)
Read.
Recorder()
Constructor.
virtual XRootDStatus Write(uint64_t offset, uint32_t size, const void *buffer, ResponseHandler *handler, uint16_t timeout)
Write.
virtual XRootDStatus VectorRead(const ChunkList &chunks, void *buffer, ResponseHandler *handler, uint16_t timeout)
VectorRead.
Handle an async response.
virtual void HandleResponseWithHosts(XRootDStatus *status, AnyObject *response, HostList *hostList)
virtual void HandleResponse(XRootDStatus *status, AnyObject *response)
const uint64_t AppMsg
std::vector< HostInfo > HostList
std::vector< ChunkInfo > ChunkList
List of chunks.
Response NullRef< Response >::value
Close action.
Fcntl action.
Flags
Open flags, may be or'd when appropriate.
Truncate action.
VectorRead action.
Vector Write action.
Write action.