#include "TFile.h"
#include "TMacro.h"
#include "TProofLog.h"
#include "TProofMgr.h"
#include "TObjString.h"
#include "TUrl.h"
ClassImp(TProofLog)
TProofLog::TProofLog(const char *stag, const char *url, TProofMgr *mgr)
: TNamed(stag, url)
{
SetLogToBox();
fFILE = 0;
fElem = new TList;
fElem->SetOwner();
fMgr = mgr;
fStartTime.Set((UInt_t)0);
TString st(stag);
Int_t idx = st.Index('-');
if (idx != kNPOS) {
st.Remove(0, idx+1);
idx = st.Index('-');
if (idx != kNPOS) {
st.Remove(idx);
if (st.IsDigit()) {
fStartTime.Set(st.Atoi());
}
}
}
}
TProofLog::~TProofLog()
{
SafeDelete(fElem);
}
TProofLogElem *TProofLog::Add(const char *ord, const char *url)
{
TProofLogElem *ple = new TProofLogElem(ord, url, this);
fElem->Add(ple);
return ple;
}
Int_t TProofLog::Retrieve(const char *ord, TProofLog::ERetrieveOpt opt,
const char *fname, const char *pattern)
{
if (opt == TProofLog::kGrep && (!pattern || strlen(pattern) <= 0)) {
Error("Retrieve", "option 'Grep' requires a pattern");
return -1;
}
Int_t nel = (ord[0] == '*') ? fElem->GetSize() : 1;
TIter nxe(fElem);
TProofLogElem *ple = 0;
Int_t nd = 0, nb = 0;
TString msg;
while ((ple = (TProofLogElem *) nxe())) {
if (ord[0] == '*' || !strcmp(ord, ple->GetName())) {
if (ple->Retrieve(opt, pattern) != 0) {
nb++;
} else {
nd++;
}
Float_t frac = ((Float_t)nd + (Float_t)nb) * 100. / (Float_t)nel;
msg.Form("Retrieving logs: %d ok, %d not ok (%.0f%% processed)\r", nd, nb, frac);
Prt(msg.Data(), kFALSE);
}
}
Prt("\n");
if (fname)
Save(ord, fname);
return 0;
}
void TProofLog::Display(const char *ord, Int_t from, Int_t to)
{
TString msg;
if (ord[0] == '*') {
Int_t nel = (fElem) ? fElem->GetSize() : 0;
msg.Form("\n// --------- Displaying PROOF Session logs --------\n"
"// Server: %s \n// Session: %s \n// # of elements: %d \n"
"// ------------------------------------------------\n\n",
GetTitle(), GetName(), nel);
Prt(msg.Data());
}
TIter nxe(fElem);
TProofLogElem *ple = 0;
while ((ple = (TProofLogElem *) nxe())) {
if (ord[0] == '*' || !strcmp(ord, ple->GetName()))
ple->Display(from, to);
}
if (ord[0] == '*')
Prt("// --------- End of PROOF Session logs ---------\n");
}
void TProofLog::Print(Option_t *opt) const
{
Int_t nel = (fElem) ? fElem->GetSize() : 0;
fprintf(stderr, "// --------- PROOF Session logs object --------\n");
fprintf(stderr, "// Server: %s \n", GetTitle());
fprintf(stderr, "// Session: %s \n", GetName());
fprintf(stderr, "// # of elements: %d \n", nel);
fprintf(stderr, "// --------------------------------------------\n");
TIter nxe(fElem);
TProofLogElem *ple = 0;
while ((ple = (TProofLogElem *) nxe()))
ple->Print(opt);
fprintf(stderr, "// --------------------------------------------\n");
}
void TProofLog::Prt(const char *what, Bool_t newline)
{
if (what) {
if (LogToBox()) {
Emit("Prt(const char*)", what);
} else {
FILE *where = (fFILE) ? (FILE *)fFILE : stderr;
fputs(what, where);
if (newline) fputc('\n', where);
}
}
}
Int_t TProofLog::Save(const char *ord, const char *fname, Option_t *opt)
{
if (!fname) {
Warning("Save", "filename undefined - do nothing");
return -1;
}
TString option = opt;
option.ToLower();
FILE *fout=0;
if (option.Contains("a")){
fout = fopen(fname, "a");
} else {
fout = fopen(fname, "w");
}
if (!fout) {
Warning("Save", "file could not be opened - do nothing");
return -1;
}
fFILE = (void *) fout;
TString msg;
if (ord[0] == '*') {
Int_t nel = (fElem) ? fElem->GetSize() : 0;
msg.Form("\n// --------- Displaying PROOF Session logs --------\n"
"// Server: %s \n// Session: %s \n// # of elements: %d \n"
"// ------------------------------------------------\n\n",
GetTitle(), GetName(), nel);
Prt(msg.Data());
}
TIter nxe(fElem);
TProofLogElem *ple = 0;
while ((ple = (TProofLogElem *) nxe())) {
if (ord[0] == '*' || !strcmp(ord, ple->GetName()))
ple->Display(0);
}
if (ord[0] == '*') {
Prt("// --------- End of PROOF Session logs ---------\n");
}
fclose(fout);
fFILE = 0;
return 0;
}
Int_t TProofLog::Grep(const char *txt, Int_t from)
{
if (!txt || strlen(txt) <= 0) {
Warning("Grep", "text to be searched for is undefined - do nothing");
return -1;
}
Int_t nel = (fElem) ? fElem->GetSize() : 0;
TString msg;
msg.Form("\n// --------- Search in PROOF Session logs --------\n"
"// Server: %s \n// Session: %s \n// # of elements: %d \n"
"// Text searched for: \"%s\"", GetTitle(), GetName(), nel, txt);
Prt(msg.Data());
if (from > 1) {
msg.Form("// starting from line %d \n", from);
} else {
msg = "\n";
}
Prt(msg.Data());
Prt("// ------------------------------------------------\n");
TIter nxe(fElem);
TProofLogElem *ple = 0;
while ((ple = (TProofLogElem *) nxe())) {
TString res;
Int_t nf = ple->Grep(txt, res, from);
if (nf > 0) {
msg.Form("// Ord: %s - line(s): %s\n", ple->GetName(), res.Data());
Prt(msg.Data());
}
}
Prt("// ------------------------------------------------\n");
return 0;
}
void TProofLog::SetMaxTransferSize(Long64_t maxsz)
{
TProofLogElem::SetMaxTransferSize(maxsz);
}
Long64_t TProofLogElem::fgMaxTransferSize = 100000;
TProofLogElem::TProofLogElem(const char *ord, const char *url,
TProofLog *logger)
: TNamed(ord, url)
{
fLogger = logger;
fMacro = new TMacro;
fSize = -1;
fFrom = -1;
fTo = -1;
if (strstr(GetTitle(), "worker-")) {
fRole = "worker";
} else {
if (strchr(GetName(), '.')) {
fRole = "submaster";
} else {
fRole = "master";
}
}
}
TProofLogElem::~TProofLogElem()
{
SafeDelete(fMacro);
}
Long64_t TProofLogElem::GetMaxTransferSize()
{
return fgMaxTransferSize;
}
void TProofLogElem::SetMaxTransferSize(Long64_t maxsz)
{
fgMaxTransferSize = maxsz;
}
Int_t TProofLogElem::Retrieve(TProofLog::ERetrieveOpt opt, const char *pattern)
{
if (!fLogger->fMgr || !fLogger->fMgr->IsValid()) {
Warning("Retrieve", "No reference manager: corruption?");
return -1;
}
if (gDebug >= 2) {
Info("Retrieve", "Retrieving from ordinal %s file %s with pattern %s",
GetName(), GetTitle(), (pattern ? pattern : "(no pattern)"));
}
if (opt == TProofLog::kAll) {
fFrom = 0;
fTo = -1;
if (gDebug >= 1)
Info("Retrieve", "Retrieving the whole file");
} else if (opt == TProofLog::kLeading) {
fFrom = 0;
fTo = fgMaxTransferSize;
if (gDebug >= 1)
Info("Retrieve", "Retrieving the leading %lld lines of file", fTo);
} else if (opt == TProofLog::kGrep) {
if (!pattern || strlen(pattern) <= 0) {
Error("Retrieve", "option 'Grep' requires a pattern");
return -1;
}
if (gDebug >= 1)
Info("Retrieve", "Retrieving only lines filtered with %s", pattern);
} else {
fFrom = -fgMaxTransferSize;
fTo = -1;
if (gDebug >= 1)
Info("Retrieve", "Retrieving the last %lld lines of file", -fFrom);
}
SafeDelete(fMacro);
fMacro = new TMacro;
Long64_t len = (fTo > fFrom) ? fTo - fFrom : -1;
TObjString *os = 0;
if (fLogger->fMgr) {
TString fileName = GetTitle();
if (fileName.Contains("__igprof.pp__")) {
if (gDebug >= 1)
Info("Retrieve", "Retrieving analyzed IgProf performance profile");
TString analyzeAndFilter = \
"|( T=`mktemp` && cat > \"$T\" ; igprof-analyse -d -g \"$T\" ; rm -f \"$T\" )";
if (pattern && (*pattern == '|'))
analyzeAndFilter.Append(pattern);
os = fLogger->fMgr->ReadBuffer(fileName.Data(), analyzeAndFilter.Data());
}
else if (opt == TProofLog::kGrep)
os = fLogger->fMgr->ReadBuffer(fileName.Data(), pattern);
else
os = fLogger->fMgr->ReadBuffer(fileName.Data(), fFrom, len);
}
if (os) {
TString ln;
Ssiz_t from = 0;
while (os->String().Tokenize(ln, from, "\n"))
fMacro->AddLine(ln.Data());
delete os;
}
return 0;
}
void TProofLogElem::Display(Int_t from, Int_t to)
{
Int_t nls = (fMacro->GetListOfLines()) ?
fMacro->GetListOfLines()->GetSize() : 0;
Int_t i = 0;
Int_t ie = (to > -1 && to < nls) ? to : nls;
if (from > 1) {
if (from <= nls)
i = from - 1;
} else if (from < 0) {
if (-from <= nls)
i = nls + from;
ie = nls;
}
TString msg;
Prt("// --------- Start of element log -----------------\n");
msg.Form("// Ordinal: %s (role: %s)\n", GetName(), fRole.Data());
Prt(msg.Data());
TString path(GetTitle());
Int_t ic = path.Index(",");
if (ic != kNPOS) {
TString subm(path);
path.Remove(0, ic+1);
subm.Remove(ic);
msg.Form("// Submaster: %s \n", subm.Data());
Prt(msg.Data());
}
msg.Form("// Path: %s \n// # of retrieved lines: %d ", path.Data(), nls);
Prt(msg.Data());
if (i > 0 || ie < nls) {
msg.Form("(displaying lines: %d -> %d)\n", i+1, ie);
} else {
msg = "\n";
}
Prt(msg.Data());
Prt("// ------------------------------------------------\n");
msg = "";
if (fMacro->GetListOfLines()) {
TIter nxl(fMacro->GetListOfLines());
TObjString *os = 0;
Int_t kk = 0;
while ((os = (TObjString *) nxl())) {
kk++;
if (kk > i) {
if (msg.Length() < 100000) {
if (msg.Length() > 0) msg += "\n";
msg += os->GetName();
} else {
Prt(msg.Data());
msg = "";
}
}
if (kk > ie) break;
}
}
if (msg.Length() > 0) Prt(msg.Data());
Prt("// --------- End of element log -------------------\n\n");
}
void TProofLogElem::Print(Option_t *) const
{
Int_t nls = (fMacro->GetListOfLines()) ?
fMacro->GetListOfLines()->GetSize() : 0;
const char *role = (strstr(GetTitle(), "worker-")) ? "worker" : "master";
fprintf(stderr, "Ord: %s Host: Role: %s lines: %d\n", GetName(), role, nls);
}
void TProofLogElem::Prt(const char *what)
{
if (fLogger)
fLogger->Prt(what);
}
Int_t TProofLogElem::Grep(const char *txt, TString &res, Int_t from)
{
Int_t nls = (fMacro->GetListOfLines()) ?
fMacro->GetListOfLines()->GetSize() : 0;
Int_t nf = 0;
Int_t i = (from > 0) ? (from - 1) : 0;
for( ; i < nls; i++) {
TObjString *os = (TObjString *) fMacro->GetListOfLines()->At(i);
if (os) {
if (strstr(os->GetName(), txt)) {
if (res.Length() > 0)
res += " ";
res += (i + 1);
nf++;
}
}
}
return nf;
}