TProofLog.cxx

Go to the documentation of this file.
00001 // @(#)root/proof:$Id: TProofLog.cxx 29171 2009-06-23 14:13:06Z brun $
00002 // Author: G. Ganis   31/08/06
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TProofLog                                                            //
00015 //                                                                      //
00016 // Implementation of the PROOF session log handler                      //
00017 //                                                                      //
00018 //////////////////////////////////////////////////////////////////////////
00019 
00020 #include "TFile.h"
00021 #include "TMacro.h"
00022 #include "TProofLog.h"
00023 #include "TProofMgr.h"
00024 #include "TObjString.h"
00025 #include "TUrl.h"
00026 
00027 ClassImp(TProofLog)
00028 
00029 //________________________________________________________________________
00030 TProofLog::TProofLog(const char *stag, const char *url, TProofMgr *mgr)
00031           : TNamed(stag, url)
00032 {
00033    // Constructor.
00034 
00035    SetLogToBox();
00036    fFILE = 0;
00037    fElem = new TList;
00038    fElem->SetOwner();
00039    fMgr = mgr;
00040    // Set a fake starting time
00041    fStartTime.Set((UInt_t)0);
00042    // Extract real starting time
00043    TString st(stag);
00044    Int_t idx = st.Index('-');
00045    if (idx != kNPOS) {
00046       st.Remove(0, idx+1);
00047       idx = st.Index('-');
00048       if (idx != kNPOS) {
00049          st.Remove(idx);
00050          if (st.IsDigit()) {
00051             fStartTime.Set(st.Atoi());
00052          }
00053       }
00054    }
00055 }
00056 
00057 //________________________________________________________________________
00058 TProofLog::~TProofLog()
00059 {
00060    // Destructor.
00061 
00062    SafeDelete(fElem);
00063 }
00064 
00065 //________________________________________________________________________
00066 TProofLogElem *TProofLog::Add(const char *ord, const char *url)
00067 {
00068    // Add new entry to the list of elements.
00069 
00070    TProofLogElem *ple = new TProofLogElem(ord, url, this);
00071    fElem->Add(ple);
00072    // Done
00073    return ple;
00074 }
00075 
00076 //________________________________________________________________________
00077 Int_t TProofLog::Retrieve(const char *ord, TProofLog::ERetrieveOpt opt,
00078                           const char *fname, const char *pattern)
00079 {
00080    // Retrieve the content of the log file associated with worker 'ord'.
00081    // If 'ord' is "*" (default), all the workers are retrieved. If 'all'
00082    // is true, the whole files are retrieved; else a max of
00083    // fgMaxTransferSize (about 1000 lines) per file is read, starting from
00084    // the end (i.e. the last ~1000 lines).
00085    // The received buffer is added to the file fname, if the latter is defined.
00086    // If opt == TProofLog::kGrep only the lines containing 'pattern' are
00087    // retrieved (remote grep functionality); to filter out a pattern 'pat' use
00088    // pattern = "-v pat".
00089    // Return 0 on success, -1 in case of any error.
00090 
00091    // Validate inputs
00092    if (opt == TProofLog::kGrep && (!pattern || strlen(pattern) <= 0)) {
00093       Error("Retrieve", "option 'Grep' requires a pattern");
00094       return -1;
00095    }
00096 
00097    Int_t nel = (ord[0] == '*') ? fElem->GetSize() : 1;
00098    // Iterate over the elements
00099    TIter nxe(fElem);
00100    TProofLogElem *ple = 0;
00101    Int_t nd = 0, nb = 0;
00102    TString msg;
00103    while ((ple = (TProofLogElem *) nxe())) {
00104       if (ord[0] == '*' || !strcmp(ord, ple->GetName())) {
00105          if (ple->Retrieve(opt, pattern) != 0) {
00106             nb++;
00107          } else {
00108             nd++;
00109          }
00110          Int_t frac = (nd + nb) / nel * 100;
00111          msg.Form("Retrieving logs: %d ok, %d not ok (%d %% processed) \r", nd, nb, frac);
00112          Prt(msg.Data());
00113       }
00114    }
00115    Prt("\n");
00116 
00117    // Save to file, if required
00118    if (fname)
00119       Save(ord, fname);
00120 
00121    // Done
00122    return 0;
00123 }
00124 
00125 //________________________________________________________________________
00126 void TProofLog::Display(const char *ord, Int_t from, Int_t to)
00127 {
00128    // Display the content associated with worker 'ord' from line 'from'
00129    // to line 'to' inclusive. A negative value
00130    // for 'from' indicates lines counted from the end (tail action); 'to'
00131    // is ignored in such a case.
00132    // If 'ord' is "*" (default), all the workers are displayed.
00133 
00134    TString msg;
00135    if (ord[0] == '*') {
00136       Int_t nel = (fElem) ? fElem->GetSize() : 0;
00137       // Write global header
00138       msg.Form("\n// --------- Displaying PROOF Session logs --------\n"
00139                "// Server: %s \n// Session: %s \n// # of elements: %d \n"
00140                "// ------------------------------------------------\n\n",
00141                GetTitle(), GetName(), nel);
00142       Prt(msg.Data());
00143    }
00144    // Iterate over the elements
00145    TIter nxe(fElem);
00146    TProofLogElem *ple = 0;
00147    while ((ple = (TProofLogElem *) nxe())) {
00148       if (ord[0] == '*' || !strcmp(ord, ple->GetName()))
00149          ple->Display(from, to);
00150    }
00151    if (ord[0] == '*')
00152       // Write global tail
00153       Prt("// --------- End of PROOF Session logs ---------\n");
00154 }
00155 
00156 //________________________________________________________________________
00157 void TProofLog::Print(Option_t *opt) const
00158 {
00159    // Print head info about the content
00160 
00161    Int_t nel = (fElem) ? fElem->GetSize() : 0;
00162    // Write global header
00163    fprintf(stderr, "// --------- PROOF Session logs object --------\n");
00164    fprintf(stderr, "// Server: %s \n", GetTitle());
00165    fprintf(stderr, "// Session: %s \n", GetName());
00166    fprintf(stderr, "// # of elements: %d \n", nel);
00167    fprintf(stderr, "// --------------------------------------------\n");
00168 
00169    // Iterate over the elements
00170    TIter nxe(fElem);
00171    TProofLogElem *ple = 0;
00172    while ((ple = (TProofLogElem *) nxe()))
00173       ple->Print(opt);
00174 
00175    // Write global tail
00176    fprintf(stderr, "// --------------------------------------------\n");
00177 }
00178 
00179 //________________________________________________________________________
00180 void TProofLog::Prt(const char *what)
00181 {
00182    // Special printing procedure
00183 
00184    if (what) {
00185       if (LogToBox()) {
00186          // Send to log box:
00187          Emit("Prt(const char*)", what);
00188       } else {
00189          FILE *where = (fFILE) ? (FILE *)fFILE : stderr;
00190          fprintf(where, "%s\n", what);
00191       }
00192    }
00193 }
00194 
00195 //________________________________________________________________________
00196 Int_t TProofLog::Save(const char *ord, const char *fname, Option_t *opt)
00197 {
00198    // Save the content associated with worker 'ord' to finel 'fname'.
00199    // If 'ord' is "*" (default), the log from all the workers is saved.
00200    // If 'opt' is "a" the file is open in append mode; otherwise the file
00201    // is truncated.
00202 
00203    // Make sure we got a file name
00204    if (!fname) {
00205       Warning("Save", "filename undefined - do nothing");
00206       return -1;
00207    }
00208 
00209    // Open file to write header
00210    // Check, if the option is to append
00211    TString option = opt;
00212    option.ToLower();
00213    FILE *fout=0;
00214    if (option.Contains("a")){
00215       fout = fopen(fname, "a");
00216    } else {
00217       fout = fopen(fname, "w");
00218    }
00219    if (!fout) {
00220       Warning("Save", "file could not be opened - do nothing");
00221       return -1;
00222    }
00223    fFILE = (void *) fout;
00224 
00225    TString msg;
00226    if (ord[0] == '*') {
00227       Int_t nel = (fElem) ? fElem->GetSize() : 0;
00228       // Write global header
00229       msg.Form("\n// --------- Displaying PROOF Session logs --------\n"
00230                "// Server: %s \n// Session: %s \n// # of elements: %d \n"
00231                "// ------------------------------------------------\n\n",
00232                GetTitle(), GetName(), nel);
00233       Prt(msg.Data());
00234    }
00235 
00236    // Iterate over the elements
00237    TIter nxe(fElem);
00238    TProofLogElem *ple = 0;
00239    while ((ple = (TProofLogElem *) nxe())) {
00240       if (ord[0] == '*' || !strcmp(ord, ple->GetName()))
00241          ple->Display(0);
00242    }
00243 
00244    if (ord[0] == '*') {
00245       // Write global tail
00246       Prt("// --------- End of PROOF Session logs ---------\n");
00247    }
00248 
00249    // Close file
00250    fclose(fout);
00251    fFILE = 0;
00252 
00253    // Done
00254    return 0;
00255 }
00256 
00257 //________________________________________________________________________
00258 Int_t TProofLog::Grep(const char *txt, Int_t from)
00259 {
00260    // Search lines containing 'txt', starting from line 'from'.
00261    // Print the lines where this happens.
00262 
00263    if (!txt || strlen(txt) <= 0) {
00264       Warning("Grep", "text to be searched for is undefined - do nothing");
00265       return -1;
00266    }
00267 
00268    Int_t nel = (fElem) ? fElem->GetSize() : 0;
00269    // Write global header
00270    TString msg;
00271    msg.Form("\n// --------- Search in PROOF Session logs --------\n"
00272             "// Server: %s \n// Session: %s \n// # of elements: %d \n"
00273             "// Text searched for: \"%s\"", GetTitle(), GetName(), nel, txt);
00274    Prt(msg.Data());
00275    if (from > 1) {
00276       msg.Form("// starting from line %d \n", from);
00277    } else {
00278       msg = "\n";
00279    }
00280    Prt(msg.Data());
00281    Prt("// ------------------------------------------------\n");
00282 
00283    // Iterate over the elements
00284    TIter nxe(fElem);
00285    TProofLogElem *ple = 0;
00286    while ((ple = (TProofLogElem *) nxe())) {
00287       TString res;
00288       Int_t nf = ple->Grep(txt, res, from);
00289       if (nf > 0) {
00290          msg.Form("// Ord: %s - line(s): %s\n", ple->GetName(), res.Data());
00291          Prt(msg.Data());
00292       }
00293    }
00294 
00295    Prt("// ------------------------------------------------\n");
00296 
00297    // Done
00298    return 0;
00299 }
00300 
00301 //________________________________________________________________________
00302 void TProofLog::SetMaxTransferSize(Long64_t maxsz)
00303 {
00304    // Set max transfer size.
00305 
00306    TProofLogElem::SetMaxTransferSize(maxsz);
00307 }
00308 
00309 //
00310 // TProofLogElem
00311 //
00312 
00313 Long64_t TProofLogElem::fgMaxTransferSize = 100000; // about 1000 lines
00314 
00315 //________________________________________________________________________
00316 TProofLogElem::TProofLogElem(const char *ord, const char *url,
00317                              TProofLog *logger)
00318               : TNamed(ord, url)
00319 {
00320    // Constructor.
00321 
00322    fLogger = logger;
00323    fMacro = new TMacro;
00324    fSize = -1;
00325    fFrom = -1;
00326    fTo = -1;
00327 
00328    //Note the role here, don't redo at each call of Display()
00329    if (strstr(GetTitle(), "worker-")) {
00330       fRole = "worker";
00331    } else {
00332       if (strchr(GetName(), '.')) {
00333          fRole = "submaster";
00334       } else {
00335          fRole = "master";
00336       }
00337    }
00338 }
00339 
00340 //________________________________________________________________________
00341 TProofLogElem::~TProofLogElem()
00342 {
00343    // Destructor.
00344 
00345    SafeDelete(fMacro);
00346 }
00347 
00348 //________________________________________________________________________
00349 Long64_t TProofLogElem::GetMaxTransferSize()
00350 {
00351    // Get max transfer size.
00352 
00353    return fgMaxTransferSize;
00354 }
00355 
00356 //________________________________________________________________________
00357 void TProofLogElem::SetMaxTransferSize(Long64_t maxsz)
00358 {
00359    // Set max transfer size.
00360 
00361    fgMaxTransferSize = maxsz;
00362 }
00363 
00364 //________________________________________________________________________
00365 Int_t TProofLogElem::Retrieve(TProofLog::ERetrieveOpt opt, const char *pattern)
00366 {
00367    // Retrieve the content of the associated file. The approximate number
00368    // of lines to be retrieved is given by 'lines', with the convention that
00369    // 0 means 'all', a positive number means the first 'lines' and a negative
00370    // number means the last '-lines'. Default is -1000.
00371    // If opt == TProofLog::kGrep only the lines containing 'pattern' are
00372    // retrieved (remote grep functionality); to filter out a pattern 'pat' use
00373    // pattern = "-v pat".
00374    // Return 0 on success, -1 in case of any error.
00375 
00376    // Make sure we have a reference manager
00377    if (!fLogger->fMgr || !fLogger->fMgr->IsValid()) {
00378       Warning("Retrieve","No reference manager: corruption?");
00379       return -1;
00380    }
00381 
00382    // Determine offsets
00383    if (opt == TProofLog::kAll) {
00384       // Re-read everything
00385       fFrom = 0;
00386       fTo = -1;
00387    } else if (opt == TProofLog::kLeading) {
00388       // Read leading part
00389       fFrom = 0;
00390       fTo = fgMaxTransferSize;
00391    } else if (opt == TProofLog::kGrep) {
00392       // Retrieve lines containing 'pattern', which must be defined
00393       if (!pattern || strlen(pattern) <= 0) {
00394          Error("Retrieve", "option 'Grep' requires a pattern");
00395          return -1;
00396       }
00397    } else {
00398       // Read trailing part
00399       fFrom = -fgMaxTransferSize;
00400       fTo = -1;
00401    }
00402 
00403    // Reset the macro
00404    SafeDelete(fMacro);
00405    fMacro = new TMacro;
00406 
00407    // Size to be read
00408    Long64_t len = (fTo > fFrom) ? fTo - fFrom : -1;
00409 
00410    // Readout the buffer
00411    TObjString *os = 0;
00412    if (fLogger->fMgr) {
00413       if (opt == TProofLog::kGrep)
00414          os = fLogger->fMgr->ReadBuffer(GetTitle(), pattern);
00415       else
00416          os = fLogger->fMgr->ReadBuffer(GetTitle(), fFrom, len);
00417    }
00418    if (os) {
00419       // Loop over lines
00420       TString ln;
00421       Ssiz_t from = 0;
00422       while (os->String().Tokenize(ln, from, "\n"))
00423          fMacro->AddLine(ln.Data());
00424 
00425       // Cleanup
00426       delete os;
00427    }
00428 
00429    // Done
00430    return 0;
00431 }
00432 
00433 //_____________________________________________________________________________
00434 void TProofLogElem::Display(Int_t from, Int_t to)
00435 {
00436    // Display the current content starting from line 'from' to line 'to'
00437    // inclusive.
00438    // A negative value for 'from' indicates lines counted from the end
00439    // (tail action); 'to' is ignored in such a case.
00440    // TProofLog::Prt is called to display: the location (screen, file, box)
00441    // is defined there.
00442    // Return 0 on success, -1 in case of any error.
00443 
00444    Int_t nls = (fMacro->GetListOfLines()) ?
00445                 fMacro->GetListOfLines()->GetSize() : 0;
00446 
00447    // Starting line
00448    Int_t i = 0;
00449    Int_t ie = (to > -1 && to < nls) ? to : nls;
00450    if (from > 1) {
00451       if (from <= nls)
00452          i = from - 1;
00453    } else if (from < 0) {
00454       // Tail action
00455       if (-from <= nls)
00456          i = nls + from;
00457       ie = nls;
00458    }
00459    // Write header
00460    TString msg;
00461    Prt("// --------- Start of element log -----------------\n");
00462    msg.Form("// Ordinal: %s (role: %s)\n", GetName(), fRole.Data());
00463    Prt(msg.Data());
00464    // Separate out the submaster path, if any
00465    TString path(GetTitle());
00466    Int_t ic = path.Index(",");
00467    if (ic != kNPOS) {
00468       TString subm(path);
00469       path.Remove(0, ic+1);
00470       subm.Remove(ic);
00471       msg.Form("// Submaster: %s \n", subm.Data());
00472       Prt(msg.Data());
00473    }
00474    msg.Form("// Path: %s \n// # of retrieved lines: %d ", path.Data(), nls);
00475    Prt(msg.Data());
00476    if (i > 0 || ie < nls) {
00477       msg.Form("(displaying lines: %d -> %d)\n", i+1, ie);
00478    } else {
00479       msg = "\n";
00480    }
00481    Prt(msg.Data());
00482    Prt("// ------------------------------------------------\n");
00483    // Write lines
00484    msg = "";
00485    if (fMacro->GetListOfLines()) {
00486       TIter nxl(fMacro->GetListOfLines());
00487       TObjString *os = 0;
00488       Int_t kk = 0;
00489       while ((os = (TObjString *) nxl())) {
00490          kk++;
00491          if (kk > i) {
00492             if (msg.Length() < 100000) {
00493                if (msg.Length() > 0) msg += "\n";
00494                msg += os->GetName();
00495             } else {
00496                Prt(msg.Data());
00497                msg = "";
00498             }
00499          }
00500          if (kk > ie) break;
00501       }
00502    }
00503    if (msg.Length() > 0) Prt(msg.Data());
00504    // Write tail
00505    Prt("// --------- End of element log -------------------\n\n");
00506 }
00507 
00508 //________________________________________________________________________
00509 void TProofLogElem::Print(Option_t *) const
00510 {
00511    // Print a line with the relevant info.
00512 
00513    Int_t nls = (fMacro->GetListOfLines()) ?
00514                 fMacro->GetListOfLines()->GetSize() : 0;
00515    const char *role = (strstr(GetTitle(), "worker-")) ? "worker" : "master";
00516 
00517    fprintf(stderr, "Ord: %s Host: Role: %s lines: %d\n", GetName(), role, nls);
00518 }
00519 
00520 //________________________________________________________________________
00521 void TProofLogElem::Prt(const char *what)
00522 {
00523    // Special printing procedure.
00524 
00525    if (fLogger)
00526       fLogger->Prt(what);
00527 }
00528 
00529 //________________________________________________________________________
00530 Int_t TProofLogElem::Grep(const char *txt, TString &res, Int_t from)
00531 {
00532    // Search lines containing 'txt', starting from line 'from'. Return
00533    // their blanck-separated list into 'res'.
00534    // Return the number of lines found, or -1 in case of error.
00535 
00536    Int_t nls = (fMacro->GetListOfLines()) ?
00537                 fMacro->GetListOfLines()->GetSize() : 0;
00538 
00539    Int_t nf = 0;
00540    Int_t i = (from > 0) ? (from - 1) : 0;
00541    for( ; i < nls; i++) {
00542       TObjString *os = (TObjString *) fMacro->GetListOfLines()->At(i);
00543       if (os) {
00544          if (strstr(os->GetName(), txt)) {
00545             if (res.Length() > 0)
00546                res += " ";
00547             res += (i + 1);
00548             nf++;
00549          }
00550       }
00551    }
00552 
00553    // Done
00554    return nf;
00555 }

Generated on Tue Jul 5 14:51:38 2011 for ROOT_528-00b_version by  doxygen 1.5.1