Skip to content

Commit

Permalink
Xrdpfc new cmd line option. print in json format
Browse files Browse the repository at this point in the history
This will be much easier for other clients (tools reading cinfo file). This is mainly an interest for cache work in CMS with Rucio.
  • Loading branch information
juztas authored and gganis committed Nov 23, 2021
1 parent faf62ef commit 5bc1773
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 20 deletions.
7 changes: 6 additions & 1 deletion docs/man/xrdpfc_print.8
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ xrdpfc_print - print content of ProxyFileCache meta data

\fBxrdpfc_print\fR [\fIoptions\fR] \fRpath ...\fR

\fIoptions\fR: [\fB--config\fR \fIargs\fR] [\fB--verbose\fR] [\fB--help\fR]
\fIoptions\fR: [\fB--config\fR \fIargs\fR] [\fB--json\fR] [\fB--verbose\fR] [\fB--help\fR]

.fi
.br
Expand All @@ -24,6 +24,11 @@ xrootd configuration file. Used to load non-default file system (directive ofs.o
.RS 5
prints additional info for each downloaded file block

.RE
\fB-j\fR | \fB--json\fR
.RS 5
prints output in json format

.RE
\fB-h\fR | \fB--help\fR
.RS 5
Expand Down
1 change: 1 addition & 0 deletions src/XrdPfc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ add_executable(

target_link_libraries(
xrdpfc_print
${JSON_LIBRARIES}
XrdServer
XrdCl
XrdUtils )
Expand Down
149 changes: 132 additions & 17 deletions src/XrdPfc/XrdPfcPrint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <iostream>
#include <fcntl.h>
#include <vector>
#include "json.h"
#include "XrdPfcPrint.hh"
#include "XrdOuc/XrdOucEnv.hh"
#include "XrdOuc/XrdOucStream.hh"
Expand All @@ -31,19 +32,20 @@

using namespace XrdPfc;

Print::Print(XrdOss* oss, bool v, const char* path) : m_oss(oss), m_verbose(v), m_ossUser("nobody")
Print::Print(XrdOss* oss, bool v, bool j, const char* path) : m_oss(oss), m_verbose(v), m_json(j), m_ossUser("nobody")
{
if (isInfoFile(path))
{
printFile(std::string(path));
if (m_json) printFileJson(std::string(path));
else printFile(std::string(path));
}
else
{
XrdOssDF* dh = m_oss->newDir(m_ossUser);
if ( dh->Opendir(path, m_env) >= 0 )
{
printDir(dh, path);
}
XrdOssDF* dh = m_oss->newDir(m_ossUser);
if ( dh->Opendir(path, m_env) >= 0 )
{
printDir(dh, path, m_json);
}
}
}

Expand All @@ -57,6 +59,112 @@ bool Print::isInfoFile(const char* path)
return true;
}


void Print::printFileJson(const std::string& path)
{
printf("FILE: %s\n", path.c_str());
struct json_object *jobj;
jobj = json_object_new_object();

// Filename
json_object_object_add(jobj, "file", json_object_new_string(path.c_str()));

XrdOssDF* fh = m_oss->newFile(m_ossUser);
fh->Open((path).c_str(),O_RDONLY, 0600, m_env);

XrdSysTrace tr("XrdPfcPrint"); tr.What = 2;
Info cfi(&tr);

if ( ! cfi.Read(fh, path.c_str()))
{
json_object_put(jobj); // Delete the json object
return;
}

int cntd = 0;
for (int i = 0; i < cfi.GetNBlocks(); ++i)
{
if (cfi.TestBitWritten(i)) cntd++;
}
const Info::Store& store = cfi.RefStoredData();
char timeBuff[128];
strftime(timeBuff, 128, "%c", localtime(&store.m_creationTime));

json_object_object_add(jobj, "version", json_object_new_int(cfi.GetVersion()));
json_object_object_add(jobj, "created", json_object_new_string(timeBuff));
json_object_object_add(jobj, "cksum", json_object_new_string(cfi.GetCkSumStateAsText()));

if (cfi.HasNoCkSumTime()) {
strftime(timeBuff, 128, "%c", localtime(&store.m_noCkSumTime));
json_object_object_add(jobj, "no-cksum-time", json_object_new_string(timeBuff));
}

//json_object_object_add(jobj, "version", json_object_new_string( ));
json_object_object_add(jobj, "file_size", json_object_new_int(cfi.GetFileSize() >> 10));
json_object_object_add(jobj, "buffer_size", json_object_new_int(cfi.GetBufferSize() >> 10));
json_object_object_add(jobj, "n_blocks", json_object_new_int(cfi.GetNBlocks()));
json_object_object_add(jobj, "state_complete", json_object_new_string((cntd < cfi.GetNBlocks()) ? "incomplete" : "complete"));
json_object_object_add(jobj, "state_percentage", json_object_new_double(100.0 * cntd / cfi.GetNBlocks()));

// verbose needed in json?
if (m_verbose)
{
struct json_object *block_array;
block_array = json_object_new_array();
for (int i = 0; i < cfi.GetNBlocks(); ++i)
{
json_object_array_add(block_array, json_object_new_int(cfi.TestBitWritten(i) ? 1 : 0));
}
json_object_object_add(jobj, "block_array", json_object_get(block_array));
json_object_put(block_array); // Delete the json object
}

json_object_object_add(jobj, "n_acc_total", json_object_new_int(store.m_accessCnt));

int idx = 1;
const std::vector<Info::AStat> &astats = cfi.RefAStats();
struct json_object *access_array;
access_array = json_object_new_array();
for (std::vector<Info::AStat>::const_iterator it = astats.begin(); it != astats.end(); ++it)
{
const int MM = 128;
char s[MM];
struct json_object *obj1;
obj1 = json_object_new_object();

strftime(s, MM, "%y%m%d:%H%M%S", localtime(&(it->AttachTime)));
std::string at = s;
strftime(s, MM, "%y%m%d:%H%M%S", localtime(&(it->DetachTime)));
std::string dt = it->DetachTime > 0 ? s : "------:------";
{
int hours = it->Duration/3600;
int min = (it->Duration - hours * 3600)/60;
int sec = it->Duration % 60;
snprintf(s, MM, "%d:%02d:%02d", hours, min, sec);
}
std::string dur = s;
json_object_object_add(obj1, "record", json_object_new_int(idx++));
json_object_object_add(obj1, "attach", json_object_new_string(at.c_str()));
json_object_object_add(obj1, "detach", json_object_new_string(dt.c_str()));
json_object_object_add(obj1, "duration", json_object_new_string(dur.c_str()));
json_object_object_add(obj1, "n_ios", json_object_new_int(it->NumIos));
json_object_object_add(obj1, "n_mrg", json_object_new_int(it->NumMerged));
json_object_object_add(obj1, "B_hit[kB]", json_object_new_int(it->BytesHit >> 10));
json_object_object_add(obj1, "B_miss[kB]", json_object_new_int(it->BytesMissed >> 10));
json_object_object_add(obj1, "B_bypass[kB]", json_object_new_int(it->BytesBypassed >> 10));
json_object_array_add(access_array, json_object_get(obj1));
json_object_put(obj1); // Delete the json object
}
json_object_object_add(jobj, "accesses", access_array);

printf(json_object_to_json_string(jobj));
printf("\n");
delete fh;
json_object_put(access_array); // Delete the json object
json_object_put(jobj); // Delete the json object
}


void Print::printFile(const std::string& path)
{
printf("FILE: %s\n", path.c_str());
Expand Down Expand Up @@ -143,7 +251,7 @@ void Print::printFile(const std::string& path)
delete fh;
}

void Print::printDir(XrdOssDF* iOssDF, const std::string& path)
void Print::printDir(XrdOssDF* iOssDF, const std::string& path, bool m_json)
{
// printf("---------> print dir %s \n", path.c_str());

Expand All @@ -163,17 +271,17 @@ void Print::printDir(XrdOssDF* iOssDF, const std::string& path)
std::string np = path + "/" + std::string(&buff[0]);
if (isInfoFile(buff))
{
if (first) first = false;
else printf("\n");

printFile(np);
if (first) first = false;
else printf("\n");
if (m_json) printFileJson(np);
else printFile(np);
}
else
{
XrdOssDF* dh = m_oss->newDir(m_ossUser);
if (dh->Opendir(np.c_str(), m_env) >= 0)
{
printDir(dh, np);
printDir(dh, np, m_json);
}
delete dh; dh = 0;
}
Expand All @@ -186,8 +294,9 @@ void Print::printDir(XrdOssDF* iOssDF, const std::string& path)

int main(int argc, char *argv[])
{
static const char* usage = "Usage: pfc_print [-c config_file] [-v] path\n\n";
static const char* usage = "Usage: pfc_print [-c config_file] [-v] [-j] path\n\n";
bool verbose = false;
bool json = false;
const char* cfgn = 0;

XrdOucEnv myEnv;
Expand All @@ -199,6 +308,7 @@ int main(int argc, char *argv[])
XrdOucArgs Spec(&err, "xrdpfc_print: ", "",
"verbose", 1, "v",
"config", 1, "c",
"json", 1, "j",
(const char *) 0);

Spec.Set(argc-1, &argv[1]);
Expand All @@ -220,6 +330,11 @@ int main(int argc, char *argv[])
verbose = true;
break;
}
case 'j':
{
json = true;
break;
}
default:
{
printf("%s", usage);
Expand Down Expand Up @@ -250,7 +365,7 @@ int main(int argc, char *argv[])
printf("%s", usage);
exit(1);
}

// append oss.localroot if path starts with 'root://'
if ( ! strncmp(&path[0], "root:/", 6))
{
Expand All @@ -268,13 +383,13 @@ int main(int argc, char *argv[])
std::string tmp = Config.GetWord();
tmp += &path[6];
// printf("Absolute path %s \n", tmp.c_str());
XrdPfc::Print p(oss, verbose, tmp.c_str());
XrdPfc::Print p(oss, verbose, json, tmp.c_str());
}
}
}
else
{
XrdPfc::Print p(oss, verbose, path);
XrdPfc::Print p(oss, verbose, json, path);
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/XrdPfc/XrdPfcPrint.hh
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,25 @@ public:
//------------------------------------------------------------------------
//! Constructor.
//------------------------------------------------------------------------
Print(XrdOss* oss, bool v, const char* path);
Print(XrdOss* oss, bool v, bool j, const char* path);

private:
XrdOss* m_oss; //! file system
XrdOucEnv m_env; //! env used by file system
bool m_verbose; //! print each block
bool m_json; //! print in json format
const char* m_ossUser; //! file system user

//---------------------------------------------------------------------
//! Check file ends with *.cinfo suffix
//---------------------------------------------------------------------
bool isInfoFile(const char* path);

//---------------------------------------------------------------------
//! Print information in meta-data file in json format
//---------------------------------------------------------------------
void printFileJson(const std::string& path);

//---------------------------------------------------------------------
//! Print information in meta-data file
//---------------------------------------------------------------------
Expand All @@ -51,7 +57,7 @@ private:
//---------------------------------------------------------------------
//! Print information in meta-data file recursivly
//---------------------------------------------------------------------
void printDir(XrdOssDF* iOssDF, const std::string& path);
void printDir(XrdOssDF* iOssDF, const std::string& path, bool m_json);
};
}

Expand Down

0 comments on commit 5bc1773

Please sign in to comment.