XRootD
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 
28 #include "XrdCl/XrdClConstants.hh"
29 #include "XrdCl/XrdClDefaultEnv.hh"
30 #include "XrdCl/XrdClLog.hh"
31 #include "XrdClAction.hh"
32 
33 #include <mutex>
34 #include <fcntl.h>
35 
36 namespace XrdCl
37 {
38 //------------------------------------------------------------------------------
41 //------------------------------------------------------------------------------
42 class 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 
222 public:
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 
451 private:
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_ */
int open(const char *path, int oflag,...)
ssize_t write(int fildes, const void *buf, size_t nbyte)
#define close(a)
Definition: XrdPosix.hh:43
Binary blob representation.
Definition: XrdClBuffer.hh:34
static Log * GetLog()
Get default log.
An interface for file plug-ins.
A file.
Definition: XrdClFile.hh:46
XRootDStatus Read(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:206
XRootDStatus Close(ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:151
bool IsOpen() const
Check if the file is open.
Definition: XrdClFile.cc:846
XRootDStatus Truncate(uint64_t size, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:440
XRootDStatus VectorRead(const ChunkList &chunks, void *buffer, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:468
XRootDStatus Fcntl(const Buffer &arg, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:610
XRootDStatus Open(const std::string &url, OpenFlags::Flags flags, Access::Mode mode, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:99
bool GetProperty(const std::string &name, std::string &value) const
Definition: XrdClFile.cc:878
XRootDStatus Visa(ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Get access token to a file - async.
Definition: XrdClFile.cc:639
XRootDStatus Write(uint64_t offset, uint32_t size, const void *buffer, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:286
XRootDStatus PgRead(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:245
XRootDStatus Stat(bool force, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:177
bool SetProperty(const std::string &name, const std::string &value)
Definition: XrdClFile.cc:867
XRootDStatus Sync(ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:414
XRootDStatus PgWrite(uint64_t offset, uint32_t size, const void *buffer, std::vector< uint32_t > &cksums, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:380
XRootDStatus VectorWrite(const ChunkList &chunks, ResponseHandler *handler, uint16_t timeout=0) XRD_WARN_UNUSED_RESULT
Definition: XrdClFile.cc:498
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.
Mode
Access mode.
Close action.
Definition: XrdClAction.hh:172
Fcntl action.
Definition: XrdClAction.hh:422
Open action.
Definition: XrdClAction.hh:142
Flags
Open flags, may be or'd when appropriate.
Read action.
Definition: XrdClAction.hh:224
Stat action.
Definition: XrdClAction.hh:187
Sync action.
Definition: XrdClAction.hh:321
Truncate action.
Definition: XrdClAction.hh:336
VectorRead action.
Definition: XrdClAction.hh:354
Vector Write action.
Definition: XrdClAction.hh:395
Write action.
Definition: XrdClAction.hh:279