Commit 500dc134 authored by Maiken's avatar Maiken
Browse files

Merge branch 'arcstat_json' into 'master'

Make arcstat output in JSON. BUGZ-3667

See merge request !739
parents 386a592b 9406ed1e
Pipeline #5203 passed with stages
in 74 minutes and 18 seconds
......@@ -32,6 +32,8 @@ skip jobs which are on a computing element with a given URL
only select jobs whose status is statusstr
.IP "\fB-l\fR, \fB--long\fR"
long format (more information)
.IP "\fB-J\fR, \fB--json\fR"
output information about jobs in JSON format
.IP "\fB-S\fR, \fB--sort\fR"
sort jobs according to jobid, submissiontime or jobname
.IP "\fB-R\fR, \fB--rsort\fR"
......
......@@ -157,15 +157,31 @@ int RUNMAIN(arcstat)(int argc, char **argv) {
std::sort(jobsSortable.rbegin(), jobsSortable.rend(), orderings[opt.sort]);
}
for (std::vector<Arc::Job>::const_iterator it = jobsSortable.begin();
it != jobsSortable.end(); ++it) {
// Option 'long' (longlist) takes precedence over option 'print-jobids' (printids)
if (opt.longlist || !opt.printids) {
it->SaveToStream(std::cout, opt.longlist);
if (!opt.show_json) {
for (std::vector<Arc::Job>::const_iterator it = jobsSortable.begin();
it != jobsSortable.end(); ++it) {
// Option 'long' (longlist) takes precedence over option 'print-jobids' (printids)
if (opt.longlist || !opt.printids) {
it->SaveToStream(std::cout, opt.longlist);
}
else {
std::cout << it->JobID << std::endl;
}
}
else {
std::cout << it->JobID << std::endl;
} else {
std::cout << "\"jobs\": [";
for (std::vector<Arc::Job>::const_iterator it = jobsSortable.begin();
it != jobsSortable.end(); ++it) {
std::cout << (it==jobsSortable.begin()?"":",") << std::endl;
if (opt.longlist || !opt.printids) {
it->SaveToStreamJSON(std::cout, opt.longlist);
}
else {
std::cout << "\"" << it->JobID << "\"";
}
}
std::cout << std::endl;
std::cout << "]" << std::endl;
}
if (opt.show_unavailable) {
......@@ -173,7 +189,9 @@ int RUNMAIN(arcstat)(int argc, char **argv) {
}
unsigned int returned_info_num = jobmaster.GetSelectedJobs().size();
std::cout << Arc::IString("Status of %d jobs was queried, %d jobs returned information", queried_num, returned_info_num) << std::endl;
if (!opt.show_json) {
std::cout << Arc::IString("Status of %d jobs was queried, %d jobs returned information", queried_num, returned_info_num) << std::endl;
}
return 0;
}
......@@ -378,6 +378,10 @@ ClientOptions::ClientOptions(Client_t c,
AddOption('u', "show-unavailable",
istring("show jobs where status information is unavailable"),
show_unavailable);
AddOption('J', "json",
istring("show status information in JSON format"),
show_json);
}
if (c == CO_RESUB) {
......
......@@ -153,6 +153,7 @@ public:
bool list_configured_services;
bool direct_submission;
bool show_unavailable;
bool show_json;
int testjobid;
int runtime;
......
......@@ -671,6 +671,171 @@ namespace Arc {
out << std::endl;
} // end Print
namespace _utils {
class JSONPair {
public:
JSONPair(char const * tag, std::string const & value) : tag(tag), value(value) {};
char const * tag;
std::string const & value;
};
class JSONPairNum {
public:
JSONPairNum(char const * tag, int64_t value) : tag(tag), value(value) {};
char const * tag;
int64_t value;
};
class JSONSimpleArray {
public:
JSONSimpleArray(char const * tag, std::list<std::string> const & values) : tag(tag), values(values) {};
char const * tag;
std::list<std::string> const & values;
};
class JSONStart {
public:
JSONStart(int ident = 0):ident(ident),first(true) {};
int operator++() { ++ident; first=true; return ident; };
int operator--() { --ident; return ident; };
int ident;
bool first;
};
std::ostream& operator<<(std::ostream& out, JSONPair const & pair) {
out << "\"" << pair.tag << "\": \"" << pair.value << "\"";
return out;
}
std::ostream& operator<<(std::ostream& out, JSONPairNum const & pair) {
out << "\"" << pair.tag << "\": " << pair.value;
return out;
}
std::ostream& operator<<(std::ostream& out, JSONSimpleArray const & list) {
out << "\"" << list.tag << "\": [";
for (std::list<std::string>::const_iterator it = list.values.begin(); it != list.values.end(); it++) {
out << (it==list.values.begin()?"":",") << std::endl;
out << "\"" << *it << "\"";
}
out << std::endl;
out << "]";
return out;
}
std::ostream& operator<<(std::ostream& out, JSONStart& st) {
if(!st.first) out << "," << std::endl;
st.first=false;
for(int n=0; n<st.ident; ++n) out << " ";
return out;
}
} // namespace _utils
void Job::SaveToStreamJSON(std::ostream& out, bool longlist) const {
using namespace _utils;
out << "{" << std::endl;
JSONStart s(1);
out << s << JSONPair("id", JobID);
if (!Name.empty())
out << s << JSONPair("name", Name);
out << s << JSONPair("state", State.GetGeneralState());
if (longlist && !State().empty()) {
out << s << JSONPair("specificState", State.GetSpecificState());
}
if (State == JobState::QUEUING && WaitingPosition != -1) {
out << s << JSONPairNum("waitingPosition", WaitingPosition);
}
if (ExitCode != -1)
out << s << JSONPairNum("exitCode", ExitCode);
if (!Error.empty()) {
out << s << JSONSimpleArray("jobError", Error);
}
if (longlist) {
if (!Owner.empty())
out << s << JSONPair("owner", Owner);
if (!OtherMessages.empty()) {
out << s << JSONSimpleArray("otherMessages", OtherMessages);
}
if (!Queue.empty())
out << s << JSONPair("queue", Queue);
if (RequestedSlots != -1)
out << s << JSONPairNum("requestedSlots", RequestedSlots);
if (WaitingPosition != -1)
out << s << JSONPairNum("waitingPosition", WaitingPosition);
if (!StdIn.empty())
out << s << JSONPair("stdin", StdIn);
if (!StdOut.empty())
out << s << JSONPair("stdout", StdOut);
if (!StdErr.empty())
out << s << JSONPair("stderr", StdErr);
if (!LogDir.empty())
out << s << JSONPair("logDirectory", LogDir);
if (SubmissionTime != -1)
out << s << JSONPair("submitted", (std::string)SubmissionTime);
if (EndTime != -1)
out << s << JSONPair("endTime", (std::string)EndTime);
if (!SubmissionHost.empty())
out << s << JSONPair("submittedFrom", SubmissionHost);
if (!SubmissionClientName.empty())
out << s << JSONPair("submittingClient", SubmissionClientName);
if (RequestedTotalCPUTime != -1)
out << s << JSONPair("requestedCPUTime", (std::string)RequestedTotalCPUTime);
if (UsedTotalCPUTime != -1) {
if (RequestedSlots > 1) {
out << s << JSONPair("usedCPUTimeTotal", (std::string)UsedTotalCPUTime);
out << s << JSONPair("usedCPUTimePerSlot", (std::string)Arc::Period(UsedTotalCPUTime.GetPeriod() / RequestedSlots));
} else {
out << s << JSONPair("usedCPUTimeTotal", (std::string)UsedTotalCPUTime);
}
}
if (UsedTotalWallTime != -1) {
if (RequestedSlots > 1) {
out << s << JSONPair("usedWallTimeTotal", (std::string)UsedTotalWallTime);
out << s << JSONPair("usedWallTimePerSlot", (std::string)Arc::Period(UsedTotalWallTime.GetPeriod() / RequestedSlots));
} else {
out << s << JSONPair("usedWallTimeTotal", (std::string)UsedTotalWallTime);
}
}
if (UsedMainMemory != -1)
out << s << JSONPairNum("usedMemory", UsedMainMemory);
if (WorkingAreaEraseTime != -1)
if (State == JobState::DELETED)
out << s << JSONPair("resultsDeleted", (std::string)WorkingAreaEraseTime);
else
out << s << JSONPair("resultsMustBeRetrieved", (std::string)WorkingAreaEraseTime);
if (ProxyExpirationTime != -1)
out << s << JSONPair("proxyValidUntil", (std::string)ProxyExpirationTime);
if (CreationTime != -1)
out << s << JSONPair("validFrom", (std::string)CreationTime);
if (Validity != -1)
out << s << JSONPair("validFor", (std::string)Validity);
if (!ActivityOldID.empty()) out << s << JSONSimpleArray("jobOldId", ActivityOldID);
// Proposed mandatory attributes for ARC 3.0
out << s << JSONPair("serviceId", IDFromEndpoint);
out << s << JSONPair("serviceInformationURL", ServiceInformationURL.fullstr());
out << s << JSONPair("serviceInformationInterface", ServiceInformationInterfaceName);
out << s << JSONPair("jobStatusURL", JobStatusURL.fullstr());
out << s << JSONPair("jobStatusInterface", JobStatusInterfaceName);
out << s << JSONPair("jobManagementURL", JobManagementURL.fullstr());
out << s << JSONPair("jobManagementInterface", JobManagementInterfaceName);
if (StageInDir) out << s << JSONPair("stageinURL", StageInDir.fullstr());
if (StageOutDir) out << s << JSONPair("stageoutURL", StageOutDir.fullstr());
if (SessionDir) out << s << JSONPair("sessionURL", SessionDir.fullstr());
if (!DelegationID.empty()) out << s << JSONSimpleArray("delegationId", DelegationID);
}
out << std::endl;
out << "}";
} // end Print
bool Job::PrepareHandler(const UserConfig& uc) {
if (jc != NULL) return true;
......
......@@ -143,6 +143,7 @@ namespace Arc {
* details).
**/
void SaveToStream(std::ostream& out, bool longlist) const;
void SaveToStreamJSON(std::ostream& out, bool longlist) const;
/// Set Job attributes from a XMLNode
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment