Loading...
Searching...
No Matches
XrdClRecorder.hh
Go to the documentation of this file.
//------------------------------------------------------------------------------
// Copyright (c) 2011-2017 by European Organization for Nuclear Research (CERN)
// Author: Michal Simon <michal.simon@cern.ch>
//------------------------------------------------------------------------------
// This file is part of the XRootD software suite.
//
// XRootD is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// XRootD is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
//
// In applying this licence, CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
#ifndef XRDCK_RECORDER_HH_
#define XRDCK_RECORDER_HH_
#include "XrdCl/XrdClPlugInInterface.hh"
#include "XrdCl/XrdClConstants.hh"
#include "XrdCl/XrdClDefaultEnv.hh"
#include "XrdCl/XrdClLog.hh"
#include "XrdClAction.hh"
#include <mutex>
#include <fcntl.h>
namespace XrdCl
{
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
class Recorder: public FilePlugIn
{
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
class Output
{
public:
//------------------------------------------------------------------------
//------------------------------------------------------------------------
inline static Output& Instance()
{
Output& output = Get();
std::unique_lock<std::mutex> lck( output.mtx );
if( !output.IsValid() )
{
if( !output.Open() )
DefaultEnv::GetLog()->Error( AppMsg, "[Recorder] Failed to create the output file." );
}
return output;
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
inline static Output& Get()
{
static Output output;
return output;
}
//------------------------------------------------------------------------
// Record the user action
// @param action : the action to be recorded
// @return : true if the data was successful written to disk,
// false otherwise
//------------------------------------------------------------------------
bool Write( std::unique_ptr<Action> action )
{
std::unique_lock<std::mutex> lck( mtx );
const std::string &entry = action->ToString();
int btsWritten = 0;
do
{
int rc = ::write( fd, entry.c_str(), entry.size() );
if( rc < 0 )
{
DefaultEnv::GetLog()->Warning( AppMsg, "[Recorder] failed to record an action: %s", strerror( errno ) );
return false;
}
else
btsWritten += rc;
}
while( size_t( btsWritten ) < entry.size() );
return true;;
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
bool Open()
{
fd = open( path.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644 );
if( fd < 0 )
DefaultEnv::GetLog()->Warning( AppMsg, "[Recorder] failed to open the output file: %s", strerror( errno ) );
return ( fd >= 0 );
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
inline bool IsValid()
{
return ( fd > 0 );
}
void SetPath( const std::string &path )
{
this->path = path;
}
private:
//------------------------------------------------------------------------
//------------------------------------------------------------------------
Output( ) : fd( -1 )
{
}
//------------------------------------------------------------------------
// Deleted copy/move constructors and assignment operators
//------------------------------------------------------------------------
Output( const Output& ) = delete;
Output( Output&& ) = delete;
Output& operator=( const Output& ) = delete;
Output& operator=( Output&& ) = delete;
//------------------------------------------------------------------------
//------------------------------------------------------------------------
~Output()
{
if( fd >= 0 )
{
int rc = close( fd );
if( rc < 0 )
DefaultEnv::GetLog()->Warning( AppMsg, "[Recorder] failed to close the output file: %s", strerror( errno ) );
}
}
std::mutex mtx; //< mutex guarding the writes
int fd; //< the csv file descriptor
std::string path; //< path to the csv file
};
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
struct RecordHandler : public ResponseHandler
{
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
RecordHandler( Output &output,
std::unique_ptr<Action> action,
ResponseHandler *handler ) :
output( output ),
action( std::move( action ) ),
handler( handler )
{
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
void HandleResponseWithHosts( XRootDStatus *status,
AnyObject *response,
HostList *hostList )
{
action->RecordResult( status, response );
output.Write( std::move( action ) );
if (handler)
handler->HandleResponseWithHosts( status, response, hostList );
delete this;
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
void HandleResponse( XRootDStatus *status,
AnyObject *response )
{
action->RecordResult( status, response );
output.Write( std::move( action ) );
if (handler)
handler->HandleResponse( status, response );
delete this;
}
Output &output; //< the object handling writes to csv file
std::unique_ptr<Action> action; //< user action
ResponseHandler *handler; //< user completion handler
};
public:
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
inline static void SetOutput( const std::string &cfgpath )
{
static const std::string defaultpath = "/tmp/xrdrecord.csv";
const char *envpath = getenv( "XRD_RECORDERPATH" );
std::string path = envpath ? envpath :
( !cfgpath.empty() ? cfgpath : defaultpath );
Output::Get().SetPath( path );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
Recorder():
file( false ),
output( Output::Instance() )
{
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
bool IsValid() const
{
return output.IsValid();
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual ~Recorder()
{
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual XRootDStatus Open(const std::string& url,
OpenFlags::Flags flags,
Access::Mode mode,
ResponseHandler* handler,
uint16_t timeout)
{
std::unique_ptr<Action> ptr( new OpenAction( this, url, flags, mode, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.Open( url, flags, mode, recHandler, timeout );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual XRootDStatus Close(ResponseHandler* handler,
uint16_t timeout)
{
std::unique_ptr<Action> ptr( new CloseAction( this, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.Close( recHandler, timeout );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual XRootDStatus Stat(bool force,
ResponseHandler* handler,
uint16_t timeout)
{
std::unique_ptr<Action> ptr( new StatAction( this, force, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.Stat(force, recHandler, timeout);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual XRootDStatus Read(uint64_t offset,
uint32_t size,
void* buffer,
ResponseHandler* handler,
uint16_t timeout)
{
std::unique_ptr<Action> ptr( new ReadAction( this, offset, size, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.Read( offset, size, buffer, recHandler, timeout );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual XRootDStatus Write(uint64_t offset,
uint32_t size,
const void* buffer,
ResponseHandler* handler,
uint16_t timeout)
{
std::unique_ptr<Action> ptr( new WriteAction( this, offset, size, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.Write( offset, size, buffer, recHandler, timeout );
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
virtual XRootDStatus PgRead( uint64_t offset,
uint32_t size,
void *buffer,
ResponseHandler *handler,
uint16_t timeout )
{
std::unique_ptr<Action> ptr( new PgReadAction( this, offset, size, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.PgRead( offset, size, buffer, recHandler, timeout );
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
virtual XRootDStatus PgWrite( uint64_t offset,
uint32_t size,
const void *buffer,
std::vector<uint32_t> &cksums,
ResponseHandler *handler,
uint16_t timeout )
{
std::unique_ptr<Action> ptr( new PgWriteAction( this, offset, size, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.PgWrite( offset, size, buffer, cksums, recHandler, timeout );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual XRootDStatus Sync(ResponseHandler* handler,
uint16_t timeout)
{
std::unique_ptr<Action> ptr( new SyncAction( this, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.Sync( recHandler, timeout );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual XRootDStatus Truncate(uint64_t size,
ResponseHandler* handler,
uint16_t timeout)
{
std::unique_ptr<Action> ptr( new TruncateAction( this, size, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.Truncate(size, recHandler, timeout);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual XRootDStatus VectorRead(const ChunkList& chunks,
void* buffer,
ResponseHandler* handler,
uint16_t timeout)
{
std::unique_ptr<Action> ptr( new VectorReadAction( this, chunks, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.VectorRead(chunks, buffer, recHandler, timeout);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual XRootDStatus VectorWrite( const ChunkList &chunks,
ResponseHandler *handler,
uint16_t timeout )
{
std::unique_ptr<Action> ptr( new VectorWriteAction( this, chunks, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.VectorWrite( chunks, recHandler, timeout );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual XRootDStatus Fcntl(const Buffer& arg,
ResponseHandler* handler,
uint16_t timeout)
{
std::unique_ptr<Action> ptr( new FcntlAction( this, arg, timeout ) );
RecordHandler *recHandler = new RecordHandler( output, std::move( ptr ), handler );
return file.Fcntl(arg, recHandler, timeout);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual XRootDStatus Visa(ResponseHandler* handler,
uint16_t timeout)
{
return file.Visa(handler, timeout);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual bool IsOpen() const
{
return file.IsOpen();
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual bool SetProperty(const std::string& name,
const std::string& value)
{
return file.SetProperty(name, value);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
virtual bool GetProperty(const std::string& name,
std::string& value) const
{
return file.GetProperty(name, value);
}
private:
File file; //< The file object that performs the actual operation
Output &output; //< The object for writing the recorded actions
};
} // namespace XrdCl
#endif /* XRDCK_RECORDER_HH_ */
XrdClAction.hh
XrdClConstants.hh
XrdClDefaultEnv.hh
XrdClLog.hh
XrdClPlugInInterface.hh
close
#define close(a)
Definition XrdPosix.hh:48
write
#define write(a, b, c)
Definition XrdPosix.hh:115
open
#define open
Definition XrdPosix.hh:76
XrdCl::AnyObject
Definition XrdClAnyObject.hh:33
XrdCl::Buffer
Binary blob representation.
Definition XrdClBuffer.hh:34
XrdCl::DefaultEnv::GetLog
static Log * GetLog()
Get default log.
Definition XrdClDefaultEnv.cc:493
XrdCl::FilePlugIn
An interface for file plug-ins.
Definition XrdClPlugInInterface.hh:39
XrdCl::File
A file.
Definition XrdClFile.hh:46
XrdCl::Log::Error
void Error(uint64_t topic, const char *format,...)
Report an error.
Definition XrdClLog.cc:231
XrdCl::Log::Warning
void Warning(uint64_t topic, const char *format,...)
Report a warning.
Definition XrdClLog.cc:248
XrdCl::Recorder::IsValid
bool IsValid() const
Definition XrdClRecorder.hh:249
XrdCl::Recorder::Open
virtual XRootDStatus Open(const std::string &url, OpenFlags::Flags flags, Access::Mode mode, ResponseHandler *handler, uint16_t timeout)
Open.
Definition XrdClRecorder.hh:264
XrdCl::Recorder::Fcntl
virtual XRootDStatus Fcntl(const Buffer &arg, ResponseHandler *handler, uint16_t timeout)
Fcntl.
Definition XrdClRecorder.hh:407
XrdCl::Recorder::Sync
virtual XRootDStatus Sync(ResponseHandler *handler, uint16_t timeout)
Sync.
Definition XrdClRecorder.hh:359
XrdCl::Recorder::PgRead
virtual XRootDStatus PgRead(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, uint16_t timeout)
Definition XrdClRecorder.hh:330
XrdCl::Recorder::Stat
virtual XRootDStatus Stat(bool force, ResponseHandler *handler, uint16_t timeout)
Stat.
Definition XrdClRecorder.hh:289
XrdCl::Recorder::SetProperty
virtual bool SetProperty(const std::string &name, const std::string &value)
SetProperty.
Definition XrdClRecorder.hh:436
XrdCl::Recorder::IsOpen
virtual bool IsOpen() const
IsOpen.
Definition XrdClRecorder.hh:428
XrdCl::Recorder::SetOutput
static void SetOutput(const std::string &cfgpath)
Definition XrdClRecorder.hh:228
XrdCl::Recorder::VectorWrite
virtual XRootDStatus VectorWrite(const ChunkList &chunks, ResponseHandler *handler, uint16_t timeout)
VectorRead.
Definition XrdClRecorder.hh:395
XrdCl::Recorder::Truncate
virtual XRootDStatus Truncate(uint64_t size, ResponseHandler *handler, uint16_t timeout)
Truncate.
Definition XrdClRecorder.hh:370
XrdCl::Recorder::Close
virtual XRootDStatus Close(ResponseHandler *handler, uint16_t timeout)
Close.
Definition XrdClRecorder.hh:278
XrdCl::Recorder::~Recorder
virtual ~Recorder()
Destructor.
Definition XrdClRecorder.hh:257
XrdCl::Recorder::GetProperty
virtual bool GetProperty(const std::string &name, std::string &value) const
GetProperty.
Definition XrdClRecorder.hh:445
XrdCl::Recorder::Visa
virtual XRootDStatus Visa(ResponseHandler *handler, uint16_t timeout)
Visa.
Definition XrdClRecorder.hh:419
XrdCl::Recorder::PgWrite
virtual XRootDStatus PgWrite(uint64_t offset, uint32_t size, const void *buffer, std::vector< uint32_t > &cksums, ResponseHandler *handler, uint16_t timeout)
Definition XrdClRecorder.hh:344
XrdCl::Recorder::Read
virtual XRootDStatus Read(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, uint16_t timeout)
Read.
Definition XrdClRecorder.hh:302
XrdCl::Recorder::Recorder
Recorder()
Constructor.
Definition XrdClRecorder.hh:240
XrdCl::Recorder::Write
virtual XRootDStatus Write(uint64_t offset, uint32_t size, const void *buffer, ResponseHandler *handler, uint16_t timeout)
Write.
Definition XrdClRecorder.hh:316
XrdCl::Recorder::VectorRead
virtual XRootDStatus VectorRead(const ChunkList &chunks, void *buffer, ResponseHandler *handler, uint16_t timeout)
VectorRead.
Definition XrdClRecorder.hh:382
XrdCl::ResponseHandler
Handle an async response.
Definition XrdClXRootDResponses.hh:1127
XrdCl::ResponseHandler::HandleResponseWithHosts
virtual void HandleResponseWithHosts(XRootDStatus *status, AnyObject *response, HostList *hostList)
Definition XrdClXRootDResponses.hh:1140
XrdCl::ResponseHandler::HandleResponse
virtual void HandleResponse(XRootDStatus *status, AnyObject *response)
Definition XrdClXRootDResponses.hh:1156
XrdCl::XRootDStatus
Request status.
Definition XrdClXRootDResponses.hh:219
XrdCl
Definition XrdClAction.hh:34
XrdCl::AppMsg
const uint64_t AppMsg
Definition XrdClConstants.hh:32
XrdCl::HostList
std::vector< HostInfo > HostList
Definition XrdClXRootDResponses.hh:1121
XrdCl::ChunkList
std::vector< ChunkInfo > ChunkList
List of chunks.
Definition XrdClXRootDResponses.hh:1056
XrdCl::value
Response NullRef< Response >::value
Definition XrdClOperationHandlers.hh:128
XrdCl::Access::Mode
Mode
Access mode.
Definition XrdClFileSystem.hh:122
XrdCl::CloseAction
Close action.
Definition XrdClAction.hh:172
XrdCl::FcntlAction
Fcntl action.
Definition XrdClAction.hh:429
XrdCl::OpenAction
Open action.
Definition XrdClAction.hh:142
XrdCl::OpenFlags::Flags
Flags
Open flags, may be or'd when appropriate.
Definition XrdClFileSystem.hh:76
XrdCl::PgReadAction
Definition XrdClAction.hh:252
XrdCl::PgWriteAction
Definition XrdClAction.hh:301
XrdCl::ReadAction
Read action.
Definition XrdClAction.hh:226
XrdCl::StatAction
Stat action.
Definition XrdClAction.hh:187
XrdCl::SyncAction
Sync action.
Definition XrdClAction.hh:326
XrdCl::TruncateAction
Truncate action.
Definition XrdClAction.hh:341
XrdCl::VectorReadAction
VectorRead action.
Definition XrdClAction.hh:359
XrdCl::VectorWriteAction
Vector Write action.
Definition XrdClAction.hh:402
XrdCl::WriteAction
Write action.
Definition XrdClAction.hh:284