X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=SHUTTLE%2FAliShuttle.cxx;h=02a723f4e0bd2cab204aa03a01ae174018434be9;hb=955d2abc1fff41f135abce1b4c40cfbca0cb2ff4;hp=d39dde880fcb3ba59f1e01237b58cf232f356aa9;hpb=1bcd28db10200743bfcd8cf8cfe7c74d298e4c55;p=u%2Fmrichter%2FAliRoot.git diff --git a/SHUTTLE/AliShuttle.cxx b/SHUTTLE/AliShuttle.cxx index d39dde880fc..02a723f4e0b 100644 --- a/SHUTTLE/AliShuttle.cxx +++ b/SHUTTLE/AliShuttle.cxx @@ -15,6 +15,125 @@ /* $Log$ +Revision 1.75 2007/12/18 15:42:14 jgrosseo +adding number of open runs to monitoring + +Revision 1.74 2007/12/17 03:23:32 jgrosseo +several bugfixes +added "empty preprocessor" as placeholder for Acorde in FDR + +Revision 1.73 2007/12/14 19:31:36 acolla +Sending email to DCS experts is temporarily commented + +Revision 1.72 2007/12/13 15:44:28 acolla +Run type added in mail sent to detector expert (eases understanding) + +Revision 1.71 2007/12/12 14:56:14 jgrosseo +sending shuttle_ignore to ML also in case of 0 events + +Revision 1.70 2007/12/12 13:45:35 acolla +Monalisa started in Collect() function. Alive message to monitor is sent at each Collect and every minute during preprocessor processing. + +Revision 1.69 2007/12/12 10:06:29 acolla +in AliShuttle.cxx: SHUTTLE logbook is updated in case of invalid run times: + +time_start==0 && time_end==0 + +logbook is NOT updated if time_start != 0 && time_end == 0, because it may mean that the run is still ongoing. + +Revision 1.68 2007/12/11 10:15:17 acolla +Added marking SHUTTLE=DONE for invalid runs +(invalid start time or end time) and runs with totalEvents < 1 + +Revision 1.67 2007/12/07 19:14:36 acolla +in AliShuttleTrigger: + +Added automatic collection of new runs on a regular time basis (settable from the configuration) + +in AliShuttleConfig: new members + +- triggerWait: time to wait for DIM trigger (s) before starting automatic collection of new runs +- mode: run mode (test, prod) -> used to build log folder (logs or logs_PROD) + +in AliShuttle: + +- logs now stored in logs/#RUN/DET_#RUN.log + +Revision 1.66 2007/12/05 10:45:19 jgrosseo +changed order of arguments to TMonaLisaWriter + +Revision 1.65 2007/11/26 16:58:37 acolla +Monalisa configuration added: host and table name + +Revision 1.64 2007/11/13 16:15:47 acolla +DCS map is stored in a file in the temp folder where the detector is processed. +If the preprocessor fails, the temp folder is not removed. This will help the debugging of the problem. + +Revision 1.63 2007/11/02 10:53:16 acolla +Protection added to AliShuttle::CopyFileLocally + +Revision 1.62 2007/10/31 18:23:13 acolla +Furter developement on the Shuttle: + +- Shuttle now connects to the Grid as alidaq. The OCDB and Reference folders +are now built from /alice/data, e.g.: +/alice/data/2007/LHC07a/OCDB + +the year and LHC period are taken from the Shuttle. +Raw metadata files are stored by GRP to: +/alice/data/2007/LHC07a//Raw/RunMetadata.root + +- Shuttle sends a mail to DCS experts each time DP retrieval fails. + +Revision 1.61 2007/10/30 20:33:51 acolla +Improved managing of temporary folders, which weren't correctly handled. +Resolved bug introduced in StoreReferenceFile, which caused SPD preprocessor fail. + +Revision 1.60 2007/10/29 18:06:16 acolla + +New function StoreRunMetadataFile added to preprocessor and Shuttle interface +This function can be used by GRP only. It stores raw data tags merged file to the +raw data folder (e.g. /alice/data/2008/LHC08a/000099999/Raw). + +KNOWN ISSUES: + +1. Shuttle cannot write to /alice/data/ because it belongs to alidaq. Tag file is stored in /alice/simulation/... for the time being. +2. Due to a bug in TAlien::Mkdir, the creation of a folder in recursive mode (-p option) does not work. The problem +has been corrected in the root package on the Shuttle machine. + +Revision 1.59 2007/10/05 12:40:55 acolla + +Result error code added to AliDCSClient data members (it was "lost" with the new implementation of TMap* GetAliasValues and GetDPValues). + +Revision 1.58 2007/09/28 15:27:40 acolla + +AliDCSClient "multiSplit" option added in the DCS configuration +in AliDCSMessage: variable MAX_BODY_SIZE set to 500000 + +Revision 1.57 2007/09/27 16:53:13 acolla +Detectors can have more than one AMANDA server. SHUTTLE queries the servers sequentially, +merges the dcs aliases/DPs in one TMap and sends it to the preprocessor. + +Revision 1.56 2007/09/14 16:46:14 jgrosseo +1) Connect and Close are called before and after each query, so one can +keep the same AliDCSClient object. +2) The splitting of a query is moved to GetDPValues/GetAliasValues. +3) Splitting interval can be specified in constructor + +Revision 1.55 2007/08/06 12:26:40 acolla +Function Bool_t GetHLTStatus added to preprocessor. It returns the status of HLT +read from the run logbook. + +Revision 1.54 2007/07/12 09:51:25 jgrosseo +removed duplicated log message in GetFile + +Revision 1.53 2007/07/12 09:26:28 jgrosseo +updating hlt fxs base path + +Revision 1.52 2007/07/12 08:06:45 jgrosseo +adding log messages in getfile... functions +adding not implemented copy constructor in alishuttleconfigholder + Revision 1.51 2007/07/03 17:24:52 acolla root moved to v5-16-00. TFileMerger->Cp moved to TFile::Cp. @@ -260,7 +379,6 @@ some docs added #include #include #include -#include #include #include @@ -463,16 +581,23 @@ Bool_t AliShuttle::StoreOCDB() return kFALSE; } - Log("SHUTTLE","Storing OCDB data ..."); + Log("SHUTTLE","StoreOCDB - Storing OCDB data ..."); Bool_t resultCDB = StoreOCDB(fgkMainCDB); - Log("SHUTTLE","Storing reference data ..."); + Log("SHUTTLE","StoreOCDB - Storing reference data ..."); Bool_t resultRef = StoreOCDB(fgkMainRefStorage); - Log("SHUTTLE","Storing reference files ..."); - Bool_t resultRefFiles = StoreRefFilesToGrid(); + Log("SHUTTLE","StoreOCDB - Storing reference files ..."); + Bool_t resultRefFiles = CopyFilesToGrid("reference"); - return resultCDB && resultRef && resultRefFiles; + Bool_t resultMetadata = kTRUE; + if(fCurrentDetector == "GRP") + { + Log("StoreOCDB - SHUTTLE","Storing Run Metadata file ..."); + resultMetadata = CopyFilesToGrid("metadata"); + } + + return resultCDB && resultRef && resultRefFiles && resultMetadata; } //______________________________________________________________________________________________ @@ -539,6 +664,7 @@ Bool_t AliShuttle::StoreOCDB(const TString& gridURI) Log("SHUTTLE", Form("StoreOCDB - %s: object %s has validity infinite but " "there are previous unprocessed runs!", fCurrentDetector.Data(), aLocId.GetPath().Data())); + result = kFALSE; continue; } @@ -576,7 +702,7 @@ Bool_t AliShuttle::StoreOCDB(const TString& gridURI) // removing local filename... TString filename; localSto->IdToFilename(aLocId, filename); - AliInfo(Form("Removing local file %s", filename.Data())); + Log("SHUTTLE", Form("StoreOCDB - Removing local file %s", filename.Data())); RemoveFile(filename.Data()); continue; } else { @@ -605,7 +731,7 @@ Bool_t AliShuttle::CleanReferenceStorage(const char* detector) TString targetDir = GetRefFilePrefix(localBaseFolder.Data(), detector); - Log("SHUTTLE", Form("Cleaning %s", targetDir.Data())); + Log("SHUTTLE", Form("CleanReferenceStorage - Cleaning %s", targetDir.Data())); TString begin; begin.Form("%d_", GetCurrentRun()); @@ -647,7 +773,7 @@ Bool_t AliShuttle::CleanReferenceStorage(const char* detector) if (result) { - Log("SHUTTLE", Form("Could not delete file %s!", fileName.Data())); + Log("SHUTTLE", Form("CleanReferenceStorage - Could not delete file %s!", fileName.Data())); success = kFALSE; } else { nDel++; @@ -671,10 +797,10 @@ Bool_t AliShuttle::CleanReferenceStorage(const char* detector) if (result == 0) { // delete directory - result = gSystem->Exec(Form("rm -r %s", targetDir.Data())); + result = gSystem->Exec(Form("rm -rf %s", targetDir.Data())); if (result != 0) { - Log("SHUTTLE", Form("StoreReferenceFile - Could not clear directory %s", targetDir.Data())); + Log("SHUTTLE", Form("CleanReferenceStorage - Could not clean directory %s", targetDir.Data())); return kFALSE; } } @@ -682,7 +808,7 @@ Bool_t AliShuttle::CleanReferenceStorage(const char* detector) result = gSystem->mkdir(targetDir, kTRUE); if (result != 0) { - Log("SHUTTLE", Form("StoreReferenceFile - Error creating base directory %s", targetDir.Data())); + Log("SHUTTLE", Form("CleanReferenceStorage - Error creating base directory %s", targetDir.Data())); return kFALSE; } @@ -711,74 +837,167 @@ Bool_t AliShuttle::StoreReferenceFile(const char* detector, const char* localFil TString localBaseFolder = sto->GetBaseFolder(); - TString targetDir = GetRefFilePrefix(localBaseFolder.Data(), detector); + TString target = GetRefFilePrefix(localBaseFolder.Data(), detector); + target.Append(Form("/%d_%s", GetCurrentRun(), gridFileName)); + + return CopyFileLocally(localFile, target); +} + +//______________________________________________________________________________________________ +Bool_t AliShuttle::StoreRunMetadataFile(const char* localFile, const char* gridFileName) +{ + // + // Stores Run metadata file to the Grid, in the run folder + // + // Only GRP can call this function. + + if (fTestMode & kErrorStorage) + { + Log(fCurrentDetector, "StoreRunMetaDataFile - In TESTMODE - Simulating error while storing locally"); + return kFALSE; + } + + AliCDBManager* man = AliCDBManager::Instance(); + AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage); + + TString localBaseFolder = sto->GetBaseFolder(); + + // Build Run level folder + // folder = /alice/data/year/lhcPeriod/runNb/raw + + + TString lhcPeriod = GetLHCPeriod(); + if (lhcPeriod.Length() == 0) + { + Log("SHUTTLE","StoreRunMetaDataFile - LHCPeriod not found in logbook!"); + return 0; + } + + TString target = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw/%s", + localBaseFolder.Data(), GetCurrentYear(), + lhcPeriod.Data(), GetCurrentRun(), gridFileName); + + return CopyFileLocally(localFile, target); +} + +//______________________________________________________________________________________________ +Bool_t AliShuttle::CopyFileLocally(const char* localFile, const TString& target) +{ + // + // Stores file locally. Called by StoreReferenceFile and StoreRunMetadataFile + // Files are temporarily stored in the local reference storage. When the preprocessor + // finishes, the Shuttle calls CopyFilesToGrid to transfer the files to AliEn + // (in reference or run level folders) + // - //try to open folder, if does not exist + TString targetDir(target(0, target.Last('/'))); + + //try to open base dir folder, if it does not exist void* dir = gSystem->OpenDirectory(targetDir.Data()); if (dir == NULL) { if (gSystem->mkdir(targetDir.Data(), kTRUE)) { - Log("SHUTTLE", Form("Can't open directory <%s>", targetDir.Data())); + Log("SHUTTLE", Form("StoreFileLocally - Can't open directory <%s>", targetDir.Data())); return kFALSE; } } else { gSystem->FreeDirectory(dir); } - - TString target; - target.Form("%s/%d_%s", targetDir.Data(), GetCurrentRun(), gridFileName); - Int_t result = gSystem->GetPathInfo(localFile, 0, (Long64_t*) 0, 0, 0); + Int_t result = 0; + + result = gSystem->GetPathInfo(localFile, 0, (Long64_t*) 0, 0, 0); if (result) { - Log("SHUTTLE", Form("StoreReferenceFile - %s does not exist", localFile)); + Log("SHUTTLE", Form("StoreFileLocally - %s does not exist", localFile)); return kFALSE; } + result = gSystem->GetPathInfo(target, 0, (Long64_t*) 0, 0, 0); + if (!result) + { + Log("SHUTTLE", Form("StoreFileLocally - target file %s already exist, removing...", target.Data())); + if (gSystem->Unlink(target.Data())) + { + Log("SHUTTLE", Form("StoreFileLocally - Could not remove existing target file %s!", target.Data())); + return kFALSE; + } + } + result = gSystem->CopyFile(localFile, target); if (result == 0) { - Log("SHUTTLE", Form("StoreReferenceFile - File %s stored locally to %s", localFile, target.Data())); + Log("SHUTTLE", Form("StoreFileLocally - File %s stored locally to %s", localFile, target.Data())); return kTRUE; } else { - Log("SHUTTLE", Form("StoreReferenceFile - Could not store file %s to %s!. Error code = %d", + Log("SHUTTLE", Form("StoreFileLocally - Could not store file %s to %s! Error code = %d", localFile, target.Data(), result)); return kFALSE; } + + + } //______________________________________________________________________________________________ -Bool_t AliShuttle::StoreRefFilesToGrid() +Bool_t AliShuttle::CopyFilesToGrid(const char* type) { // - // Transfers the reference file to the Grid. + // Transfers local files to the Grid. Local files can be reference files + // or run metadata file (from GRP only). // - // The files are stored under the following location: - // //_ + // According to the type (ref, metadata) the files are stored under the following location: + // ref --> //_ + // metadata --> / // - + AliCDBManager* man = AliCDBManager::Instance(); AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage); if (!sto) return kFALSE; TString localBaseFolder = sto->GetBaseFolder(); - - TString dir = GetRefFilePrefix(localBaseFolder.Data(), fCurrentDetector.Data()); - - AliCDBStorage* gridSto = man->GetStorage(fgkMainRefStorage); - if (!gridSto) - return kFALSE; - - TString gridBaseFolder = gridSto->GetBaseFolder(); - - TString alienDir = GetRefFilePrefix(gridBaseFolder.Data(), fCurrentDetector.Data()); + TString dir; + TString alienDir; TString begin; - begin.Form("%d_", GetCurrentRun()); + if (strcmp(type, "reference") == 0) + { + dir = GetRefFilePrefix(localBaseFolder.Data(), fCurrentDetector.Data()); + AliCDBStorage* gridSto = man->GetStorage(fgkMainRefStorage); + if (!gridSto) + return kFALSE; + TString gridBaseFolder = gridSto->GetBaseFolder(); + alienDir = GetRefFilePrefix(gridBaseFolder.Data(), fCurrentDetector.Data()); + begin = Form("%d_", GetCurrentRun()); + } + else if (strcmp(type, "metadata") == 0) + { + + TString lhcPeriod = GetLHCPeriod(); + + if (lhcPeriod.Length() == 0) + { + Log("SHUTTLE","CopyFilesToGrid - LHCPeriod not found in logbook!"); + return 0; + } + + dir = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw", + localBaseFolder.Data(), GetCurrentYear(), + lhcPeriod.Data(), GetCurrentRun()); + alienDir = dir(dir.Index("/alice/data/"), dir.Length()); + + begin = ""; + } + else + { + Log("SHUTTLE", "CopyFilesToGrid - Unexpected: type label must be reference or metadata!"); + return kFALSE; + } + TSystemDirectory* baseDir = new TSystemDirectory("/", dir); if (!baseDir) return kTRUE; @@ -796,7 +1015,7 @@ Bool_t AliShuttle::StoreRefFilesToGrid() if (!gGrid) { - Log("SHUTTLE", "Connection to Grid failed: Cannot continue!"); + Log("SHUTTLE", "CopyFilesToGrid - Connection to Grid failed: Cannot continue!"); delete dirList; return kFALSE; } @@ -822,7 +1041,7 @@ Bool_t AliShuttle::StoreRefFilesToGrid() if (first) { first = kFALSE; - // check that DET folder exists, otherwise create it + // check that folder exists, otherwise create it TGridResult* result = gGrid->Ls(alienDir.Data(), "a"); if (!result) @@ -833,18 +1052,20 @@ Bool_t AliShuttle::StoreRefFilesToGrid() if (!result->GetFileName(1)) // TODO: It looks like element 0 is always 0!! { - if (!gGrid->Mkdir(alienDir.Data(),"",0)) + // TODO It does not work currently! Bug in TAliEn::Mkdir + // TODO Manually fixed in local root v5-16-00 + if (!gGrid->Mkdir(alienDir.Data(),"-p",0)) { - Log("SHUTTLE", Form("StoreRefFilesToGrid - Cannot create directory %s", + Log("SHUTTLE", Form("CopyFilesToGrid - Cannot create directory %s", alienDir.Data())); delete dirList; return kFALSE; } else { - Log("SHUTTLE",Form("Folder %s created", alienDir.Data())); + Log("SHUTTLE",Form("CopyFilesToGrid - Folder %s created", alienDir.Data())); } } else { - Log("SHUTTLE",Form("Folder %s found", alienDir.Data())); + Log("SHUTTLE",Form("CopyFilesToGrid - Folder %s found", alienDir.Data())); } } @@ -854,23 +1075,25 @@ Bool_t AliShuttle::StoreRefFilesToGrid() TString fullGridPath; fullGridPath.Form("alien://%s/%s", alienDir.Data(), fileName.Data()); - TFileMerger fileMerger; Bool_t result = TFile::Cp(fullLocalPath, fullGridPath); if (result) { - Log("SHUTTLE", Form("StoreRefFilesToGrid - Copying local file %s to %s succeeded!", fullLocalPath.Data(), fullGridPath.Data())); + Log("SHUTTLE", Form("CopyFilesToGrid - Copying local file %s to %s succeeded!", + fullLocalPath.Data(), fullGridPath.Data())); RemoveFile(fullLocalPath); nTransfer++; } else { - Log("SHUTTLE", Form("StoreRefFilesToGrid - Copying local file %s to %s FAILED!", fullLocalPath.Data(), fullGridPath.Data())); + Log("SHUTTLE", Form("CopyFilesToGrid - Copying local file %s to %s FAILED!", + fullLocalPath.Data(), fullGridPath.Data())); success = kFALSE; } } - Log("SHUTTLE", Form("StoreRefFilesToGrid - %d (over %d) reference files in folder %s copied to Grid.", nTransfer, nDirs, dir.Data())); + Log("SHUTTLE", Form("CopyFilesToGrid - %d (over %d) files in folder %s copied to Grid.", + nTransfer, nDirs, dir.Data())); delete dirList; @@ -897,6 +1120,7 @@ const char* AliShuttle::GetRefFilePrefix(const char* base, const char* detector) } + //______________________________________________________________________________________________ void AliShuttle::CleanLocalStorage(const TString& uri) { @@ -927,9 +1151,9 @@ void AliShuttle::CleanLocalStorage(const TString& uri) TString filename(Form("%s/%s/*/Run*_v%d_s*.root", localSto->GetBaseFolder().Data(), GetOfflineDetName(fCurrentDetector.Data()), GetCurrentRun())); - AliInfo(Form("filename = %s", filename.Data())); + AliDebug(2, Form("filename = %s", filename.Data())); - AliInfo(Form("Removing remaining local files from run %d and detector %s ...", + Log("SHUTTLE", Form("Removing remaining local files for run %d and detector %s ...", GetCurrentRun(), fCurrentDetector.Data())); RemoveFile(filename.Data()); @@ -1027,7 +1251,7 @@ void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t AliShuttleStatus* status = dynamic_cast (fStatusEntry->GetObject()); if (!status){ - Log("SHUTTLE", "UNEXPECTED: status could not be read from current CDB entry"); + Log("SHUTTLE", "UpdateShuttleStatus - UNEXPECTED: status could not be read from current CDB entry"); return; } @@ -1067,7 +1291,9 @@ void AliShuttle::SendMLInfo() mlList.Add(&mlStatus); mlList.Add(&mlRetryCount); - fMonaLisa->SendParameters(&mlList); + TString mlID; + mlID.Form("%d", GetCurrentRun()); + fMonaLisa->SendParameters(&mlList, mlID); } //______________________________________________________________________________________________ @@ -1083,7 +1309,7 @@ Bool_t AliShuttle::ContinueProcessing() dynamic_cast (fPreprocessorMap.GetValue(fCurrentDetector)); if (!aPreprocessor) { - AliInfo(Form("%s: no preprocessor registered", fCurrentDetector.Data())); + Log("SHUTTLE", Form("ContinueProcessing - %s: no preprocessor registered", fCurrentDetector.Data())); return kFALSE; } @@ -1091,7 +1317,7 @@ Bool_t AliShuttle::ContinueProcessing() fLogbookEntry->GetDetectorStatus(fCurrentDetector); if(entryStatus != AliShuttleLogbookEntry::kUnprocessed) { - AliInfo(Form("ContinueProcessing - %s is %s", + Log("SHUTTLE", Form("ContinueProcessing - %s is %s", fCurrentDetector.Data(), fLogbookEntry->GetDetectorStatusName(entryStatus))); return kFALSE; @@ -1105,12 +1331,16 @@ Bool_t AliShuttle::ContinueProcessing() { if (fTestMode == kNone) { - Log("SHUTTLE", Form("ContinueProcessing - %s requires strict run ordering but this is not the first unprocessed run!")); + Log("SHUTTLE", Form("ContinueProcessing - %s requires strict run ordering" + " but this is not the first unprocessed run!")); return kFALSE; } else { - Log("SHUTTLE", Form("ContinueProcessing - In TESTMODE - Although %s requires strict run ordering and this is not the first unprocessed run, the SHUTTLE continues")); + Log("SHUTTLE", Form("ContinueProcessing - In TESTMODE - " + "Although %s requires strict run ordering " + "and this is not the first unprocessed run, " + "the SHUTTLE continues")); } } @@ -1137,14 +1367,14 @@ Bool_t AliShuttle::ContinueProcessing() if (status->GetStatus() == AliShuttleStatus::kStoreError) { Log("SHUTTLE", - Form("ContinueProcessing - %s: Grid storage of one or more objects failed. Trying again now", + Form("ContinueProcessing - %s: Grid storage of one or more " + "objects failed. Trying again now", fCurrentDetector.Data())); UpdateShuttleStatus(AliShuttleStatus::kStoreStarted); if (StoreOCDB()){ - Log("SHUTTLE", Form("ContinueProcessing - %s: all objects successfully stored into main storage", + Log("SHUTTLE", Form("ContinueProcessing - %s: all objects " + "successfully stored into main storage", fCurrentDetector.Data())); - UpdateShuttleStatus(AliShuttleStatus::kDone); - UpdateShuttleLogbook(fCurrentDetector.Data(), "DONE"); } else { Log("SHUTTLE", Form("ContinueProcessing - %s: Grid storage failed again", @@ -1174,7 +1404,8 @@ Bool_t AliShuttle::ContinueProcessing() // UpdateTableFailCase(); // Send mail to detector expert! - AliInfo(Form("Sending mail to %s expert...", fCurrentDetector.Data())); + Log("SHUTTLE", Form("ContinueProcessing - Sending mail to %s expert...", + fCurrentDetector.Data())); if (!SendMail()) Log("SHUTTLE", Form("ContinueProcessing - Could not send mail to %s expert", fCurrentDetector.Data())); @@ -1184,8 +1415,10 @@ Bool_t AliShuttle::ContinueProcessing() "Aborted before with %s. Retry number %d.", fCurrentDetector.Data(), status->GetStatusName(), status->GetCount())); Bool_t increaseCount = kTRUE; - if (status->GetStatus() == AliShuttleStatus::kDCSError || status->GetStatus() == AliShuttleStatus::kDCSStarted) - increaseCount = kFALSE; + if (status->GetStatus() == AliShuttleStatus::kDCSError || + status->GetStatus() == AliShuttleStatus::kDCSStarted) + increaseCount = kFALSE; + UpdateShuttleStatus(AliShuttleStatus::kStarted, increaseCount); cont = kTRUE; } @@ -1207,14 +1440,9 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) fLogbookEntry = entry; - AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^* \n", + Log("SHUTTLE", Form("\t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^*", GetCurrentRun())); - // create ML instance that monitors this run - fMonaLisa = new TMonaLisaWriter(Form("%d", GetCurrentRun()), "SHUTTLE", "aliendb1.cern.ch"); - // disable monitoring of other parameters that come e.g. from TFile - gMonitoringWriter = 0; - // Send the information to ML TMonaLisaText mlStatus("SHUTTLE_status", "Processing"); TMonaLisaText mlRunType("SHUTTLE_runtype", Form("%s (%s)", entry->GetRunType(), entry->GetRunParameter("log"))); @@ -1223,7 +1451,9 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) mlList.Add(&mlStatus); mlList.Add(&mlRunType); - fMonaLisa->SendParameters(&mlList); + TString mlID; + mlID.Form("%d", GetCurrentRun()); + fMonaLisa->SendParameters(&mlList, mlID); if (fLogbookEntry->IsDone()) { @@ -1257,7 +1487,7 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) Int_t testMode = tmpStr->String().Atoi(); if (testMode > 0) { - Log("SHUTTLE", Form("Enabling test mode %d", testMode)); + Log("SHUTTLE", Form("Process - Enabling test mode %d", testMode)); SetTestMode((TestMode) testMode); } } @@ -1265,46 +1495,67 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) } } } - - Log("SHUTTLE", Form("The test mode flag is %d", (Int_t) fTestMode)); - + fLogbookEntry->Print("all"); // Initialization Bool_t hasError = kFALSE; - AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB); - if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun()); - AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage); - if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun()); - + // Set the CDB and Reference folders according to the year and LHC period + TString lhcPeriod(GetLHCPeriod()); + if (lhcPeriod.Length() == 0) + { + Log("SHUTTLE","Process - LHCPeriod not found in logbook!"); + return 0; + } + + if (fgkMainCDB.Length() == 0) + fgkMainCDB = Form("alien://folder=/alice/data/%d/%s/OCDB?user=alidaq?cacheFold=/tmp/OCDBCache", + GetCurrentYear(), lhcPeriod.Data()); + + if (fgkMainRefStorage.Length() == 0) + fgkMainRefStorage = Form("alien://folder=/alice/data/%d/%s/Reference?user=alidaq?cacheFold=/tmp/OCDBCache", + GetCurrentYear(), lhcPeriod.Data()); + // Loop on detectors in the configuration TIter iter(fConfig->GetDetectors()); TObjString* aDetector = 0; + Bool_t first = kTRUE; + while ((aDetector = (TObjString*) iter.Next())) { fCurrentDetector = aDetector->String(); if (ContinueProcessing() == kFALSE) continue; + + if (first) + { + // only read QueryCDB when needed and only once + AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB); + if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun()); + AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage); + if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun()); + first = kFALSE; + } - AliInfo(Form("\n\n \t\t\t****** run %d - %s: START ******", + Log("SHUTTLE", Form("\t\t\t****** run %d - %s: START ******", GetCurrentRun(), aDetector->GetName())); for(Int_t iSys=0;iSys<3;iSys++) fFXSCalled[iSys]=kFALSE; - Log(fCurrentDetector.Data(), "Starting processing"); + Log(fCurrentDetector.Data(), "Process - Starting processing"); Int_t pid = fork(); if (pid < 0) { - Log("SHUTTLE", "ERROR: Forking failed"); + Log("SHUTTLE", "Process - ERROR: Forking failed"); } else if (pid > 0) { // parent - AliInfo(Form("In parent process of %d - %s: Starting monitoring", + Log("SHUTTLE", Form("Process - In parent process of %d - %s: Starting monitoring", GetCurrentRun(), aDetector->GetName())); Long_t begin = time(0); @@ -1317,8 +1568,9 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) if (expiredTime > fConfig->GetPPTimeOut()) { TString tmp; - tmp.Form("Process of %s time out. Run time: %d seconds. Killing...", - fCurrentDetector.Data(), expiredTime); + tmp.Form("Process - Process of %s time out. " + "Run time: %d seconds. Killing...", + fCurrentDetector.Data(), expiredTime); Log("SHUTTLE", tmp); Log(fCurrentDetector, tmp); @@ -1338,14 +1590,15 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) FILE* pipe = gSystem->OpenPipe(checkStr, "r"); if (!pipe) { - Log("SHUTTLE", Form("Error: Could not open pipe to %s", checkStr.Data())); + Log("SHUTTLE", Form("Process - Error: " + "Could not open pipe to %s", checkStr.Data())); continue; } char buffer[100]; if (!fgets(buffer, 100, pipe)) { - Log("SHUTTLE", "Error: ps did not return anything"); + Log("SHUTTLE", "Process - Error: ps did not return anything"); gSystem->ClosePipe(pipe); continue; } @@ -1356,18 +1609,23 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) Int_t mem = 0; if ((sscanf(buffer, "%d\n", &mem) != 1) || !mem) { - Log("SHUTTLE", "Error: Could not parse output of ps"); + Log("SHUTTLE", "Process - Error: Could not parse output of ps"); continue; } if (expiredTime % 60 == 0) - Log("SHUTTLE", Form("%s: Checking process. Run time: %d seconds - Memory consumption: %d KB", - fCurrentDetector.Data(), expiredTime, mem)); + { + Log("SHUTTLE", Form("Process - %s: Checking process. " + "Run time: %d seconds - Memory consumption: %d KB", + fCurrentDetector.Data(), expiredTime, mem)); + SendAlive(); + } if (mem > fConfig->GetPPMaxMem()) { TString tmp; - tmp.Form("Process exceeds maximum allowed memory (%d KB > %d KB). Killing...", + tmp.Form("Process - Process exceeds maximum allowed memory " + "(%d KB > %d KB). Killing...", mem, fConfig->GetPPMaxMem()); Log("SHUTTLE", tmp); Log(fCurrentDetector, tmp); @@ -1382,14 +1640,14 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) } } - AliInfo(Form("In parent process of %d - %s: Client has terminated.", + Log("SHUTTLE", Form("Process - In parent process of %d - %s: Client has terminated.", GetCurrentRun(), aDetector->GetName())); if (WIFEXITED(status)) { Int_t returnCode = WEXITSTATUS(status); - Log("SHUTTLE", Form("%s: the return code is %d", fCurrentDetector.Data(), + Log("SHUTTLE", Form("Process - %s: the return code is %d", fCurrentDetector.Data(), returnCode)); if (returnCode == 0) hasError = kTRUE; @@ -1398,36 +1656,57 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) else if (pid == 0) { // client - AliInfo(Form("In client process of %d - %s", GetCurrentRun(), aDetector->GetName())); + Log("SHUTTLE", Form("Process - In client process of %d - %s", GetCurrentRun(), + aDetector->GetName())); - AliInfo("Redirecting output..."); + Log("SHUTTLE", Form("Process - Redirecting output to %s log",fCurrentDetector.Data())); if ((freopen(GetLogFileName(fCurrentDetector), "a", stdout)) == 0) { - Log("SHUTTLE", "Could not freopen stdout"); + Log("SHUTTLE", "Process - Could not freopen stdout"); } else { fOutputRedirected = kTRUE; if ((dup2(fileno(stdout), fileno(stderr))) < 0) - Log("SHUTTLE", "Could not redirect stderr"); + Log("SHUTTLE", "Process - Could not redirect stderr"); } TString wd = gSystem->WorkingDirectory(); - TString tmpDir = Form("%s/%s_process",GetShuttleTempDir(),fCurrentDetector.Data()); + TString tmpDir = Form("%s/%s_%d_process", GetShuttleTempDir(), + fCurrentDetector.Data(), GetCurrentRun()); - gSystem->mkdir(tmpDir.Data()); - gSystem->ChangeDirectory(tmpDir.Data()); + Int_t result = gSystem->GetPathInfo(tmpDir.Data(), 0, (Long64_t*) 0, 0, 0); + if (!result) // temp dir already exists! + { + Log(fCurrentDetector.Data(), + Form("Process - %s dir already exists! Removing...", tmpDir.Data())); + gSystem->Exec(Form("rm -rf %s",tmpDir.Data())); + } - Bool_t success = ProcessCurrentDetector(); + if (gSystem->mkdir(tmpDir.Data(), 1)) + { + Log(fCurrentDetector.Data(), "Process - could not make temp directory!!"); + gSystem->Exit(1); + } - gSystem->ChangeDirectory(wd.Data()); + if (!gSystem->ChangeDirectory(tmpDir.Data())) + { + Log(fCurrentDetector.Data(), "Process - could not change directory!!"); + gSystem->Exit(1); + } - gSystem->Exec(Form("rm -rf %s",tmpDir.Data())); + Bool_t success = ProcessCurrentDetector(); + gSystem->ChangeDirectory(wd.Data()); + if (success) // Preprocessor finished successfully! { + // remove temporary folder + // temporary commented (JF) + //gSystem->Exec(Form("rm -rf %s",tmpDir.Data())); + // Update time_processed field in FXS DB if (UpdateTable() == kFALSE) Log("SHUTTLE", Form("Process - %s: Could not update FXS databases!", @@ -1437,16 +1716,23 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) UpdateShuttleStatus(AliShuttleStatus::kStoreStarted); if (StoreOCDB() == kFALSE) { - AliInfo(Form("\n \t\t\t****** run %d - %s: STORAGE ERROR ****** \n\n", + Log("SHUTTLE", + Form("\t\t\t****** run %d - %s: STORAGE ERROR ******", GetCurrentRun(), aDetector->GetName())); UpdateShuttleStatus(AliShuttleStatus::kStoreError); success = kFALSE; } else { - AliInfo(Form("\n \t\t\t****** run %d - %s: DONE ****** \n\n", + Log("SHUTTLE", + Form("\t\t\t****** run %d - %s: DONE ******", GetCurrentRun(), aDetector->GetName())); UpdateShuttleStatus(AliShuttleStatus::kDone); UpdateShuttleLogbook(fCurrentDetector, "DONE"); } + } else + { + Log("SHUTTLE", + Form("\t\t\t****** run %d - %s: PP ERROR ******", + GetCurrentRun(), aDetector->GetName())); } for (UInt_t iSys=0; iSys<3; iSys++) @@ -1454,7 +1740,7 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) if (fFXSCalled[iSys]) fFXSlist[iSys].Clear(); } - AliInfo(Form("Client process of %d - %s is exiting now with %d.", + Log("SHUTTLE", Form("Process - Client process of %d - %s is exiting now with %d.", GetCurrentRun(), aDetector->GetName(), success)); // the client exits here @@ -1464,14 +1750,15 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) } } - AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^* \n", + Log("SHUTTLE", Form("\t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^*", GetCurrentRun())); //check if shuttle is done for this run, if so update logbook TObjArray checkEntryArray; checkEntryArray.SetOwner(1); TString whereClause = Form("where run=%d", GetCurrentRun()); - if (!QueryShuttleLogbook(whereClause.Data(), checkEntryArray) || checkEntryArray.GetEntries() == 0) { + if (!QueryShuttleLogbook(whereClause.Data(), checkEntryArray) || + checkEntryArray.GetEntries() == 0) { Log("SHUTTLE", Form("Process - Warning: Cannot check status of run %d on Shuttle logbook!", GetCurrentRun())); return hasError == kFALSE; @@ -1501,10 +1788,6 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry) } } - // remove ML instance - delete fMonaLisa; - fMonaLisa = 0; - fLogbookEntry = 0; return hasError == kFALSE; @@ -1517,12 +1800,17 @@ Bool_t AliShuttle::ProcessCurrentDetector() // Makes data retrieval just for a specific detector (fCurrentDetector). // Threre should be a configuration for this detector. - AliInfo(Form("Retrieving values for %s, run %d", fCurrentDetector.Data(), GetCurrentRun())); + Log("SHUTTLE", Form("ProcessCurrentDetector - Retrieving values for %s, run %d", + fCurrentDetector.Data(), GetCurrentRun())); + TString wd = gSystem->WorkingDirectory(); + if (!CleanReferenceStorage(fCurrentDetector.Data())) return kFALSE; - - TMap* dcsMap = 0; + + gSystem->ChangeDirectory(wd.Data()); + + TMap* dcsMap = new TMap(); // call preprocessor AliPreprocessor* aPreprocessor = @@ -1534,69 +1822,113 @@ Bool_t AliShuttle::ProcessCurrentDetector() if (!processDCS) { - Log(fCurrentDetector, "The preprocessor requested to skip the retrieval of DCS values"); + Log(fCurrentDetector, "ProcessCurrentDetector -" + " The preprocessor requested to skip the retrieval of DCS values"); } else if (fTestMode & kSkipDCS) { - Log(fCurrentDetector, "In TESTMODE - Skipping DCS processing!"); + Log(fCurrentDetector, "ProcessCurrentDetector - In TESTMODE: Skipping DCS processing"); } else if (fTestMode & kErrorDCS) { - Log(fCurrentDetector, "In TESTMODE - Simulating DCS error"); + Log(fCurrentDetector, "ProcessCurrentDetector - In TESTMODE: Simulating DCS error"); UpdateShuttleStatus(AliShuttleStatus::kDCSStarted); UpdateShuttleStatus(AliShuttleStatus::kDCSError); + delete dcsMap; return kFALSE; } else { UpdateShuttleStatus(AliShuttleStatus::kDCSStarted); - TString host(fConfig->GetDCSHost(fCurrentDetector)); - Int_t port = fConfig->GetDCSPort(fCurrentDetector); - - if (fConfig->GetDCSAliases(fCurrentDetector)->GetEntries() > 0) - { - dcsMap = GetValueSet(host, port, fConfig->GetDCSAliases(fCurrentDetector), kAlias); - if (!dcsMap) - { - Log(fCurrentDetector, "ProcessCurrentDetector - Error while retrieving DCS aliases"); - UpdateShuttleStatus(AliShuttleStatus::kDCSError); - return kFALSE; - } - } + // Query DCS archive + Int_t nServers = fConfig->GetNServers(fCurrentDetector); - if (fConfig->GetDCSDataPoints(fCurrentDetector)->GetEntries() > 0) + for (int iServ=0; iServGetDCSDataPoints(fCurrentDetector), kDP); - if (!dcsMap2) + + TString host(fConfig->GetDCSHost(fCurrentDetector, iServ)); + Int_t port = fConfig->GetDCSPort(fCurrentDetector, iServ); + Int_t multiSplit = fConfig->GetMultiSplit(fCurrentDetector, iServ); + + Log(fCurrentDetector, Form("ProcessCurrentDetector -" + " Querying DCS Amanda server %s:%d (%d of %d)", + host.Data(), port, iServ+1, nServers)); + + TMap* aliasMap = 0; + TMap* dpMap = 0; + + if (fConfig->GetDCSAliases(fCurrentDetector, iServ)->GetEntries() > 0) { - Log(fCurrentDetector, "ProcessCurrentDetector - Error while retrieving DCS data points"); - UpdateShuttleStatus(AliShuttleStatus::kDCSError); - if (dcsMap) + aliasMap = GetValueSet(host, port, + fConfig->GetDCSAliases(fCurrentDetector, iServ), + kAlias, multiSplit); + if (!aliasMap) + { + Log(fCurrentDetector, + Form("ProcessCurrentDetector -" + " Error retrieving DCS aliases from server %s." + " Sending mail to DCS experts!", host.Data())); + UpdateShuttleStatus(AliShuttleStatus::kDCSError); + + //if (!SendMailToDCS()) + // Log("SHUTTLE", Form("ProcessCurrentDetector - Could not send mail to DCS experts!")); + delete dcsMap; - return kFALSE; + return kFALSE; + } } - if (!dcsMap) + if (fConfig->GetDCSDataPoints(fCurrentDetector, iServ)->GetEntries() > 0) { - dcsMap = dcsMap2; + dpMap = GetValueSet(host, port, + fConfig->GetDCSDataPoints(fCurrentDetector, iServ), + kDP, multiSplit); + if (!dpMap) + { + Log(fCurrentDetector, + Form("ProcessCurrentDetector -" + " Error retrieving DCS data points from server %s." + " Sending mail to DCS experts!", host.Data())); + UpdateShuttleStatus(AliShuttleStatus::kDCSError); + + //if (!SendMailToDCS()) + // Log("SHUTTLE", Form("ProcessCurrentDetector - Could not send mail to DCS experts!")); + + if (aliasMap) delete aliasMap; + delete dcsMap; + return kFALSE; + } } - else // merge - { - TIter iter(dcsMap2); + + // merge aliasMap and dpMap into dcsMap + if(aliasMap) { + TIter iter(aliasMap); TObjString* key = 0; while ((key = (TObjString*) iter.Next())) - dcsMap->Add(key, dcsMap2->GetValue(key->String())); - - dcsMap2->SetOwner(kFALSE); - delete dcsMap2; + dcsMap->Add(key, aliasMap->GetValue(key->String())); + + aliasMap->SetOwner(kFALSE); + delete aliasMap; + } + + if(dpMap) { + TIter iter(dpMap); + TObjString* key = 0; + while ((key = (TObjString*) iter.Next())) + dcsMap->Add(key, dpMap->GetValue(key->String())); + + dpMap->SetOwner(kFALSE); + delete dpMap; } } - } - - // still no map? - if (!dcsMap) - dcsMap = new TMap; + + // save map into file, to help debugging in case of preprocessor error + TFile* f = TFile::Open("DCSMap.root","recreate"); + f->cd(); + dcsMap->Write("DCSMap", TObject::kSingleKey); + f->Close(); + delete f; // DCS Archive DB processing successful. Call Preprocessor! UpdateShuttleStatus(AliShuttleStatus::kPPStarted); @@ -1605,7 +1937,8 @@ Bool_t AliShuttle::ProcessCurrentDetector() if (returnValue > 0) // Preprocessor error! { - Log(fCurrentDetector, Form("Preprocessor failed. Process returned %d.", returnValue)); + Log(fCurrentDetector, Form("ProcessCurrentDetector - " + "Preprocessor failed. Process returned %d.", returnValue)); UpdateShuttleStatus(AliShuttleStatus::kPPError); dcsMap->DeleteAll(); delete dcsMap; @@ -1623,6 +1956,58 @@ Bool_t AliShuttle::ProcessCurrentDetector() return kTRUE; } +//______________________________________________________________________________________________ +void AliShuttle::CountOpenRuns() +{ + // Query DAQ's Shuttle logbook and sends the number of open runs to ML + + // check connection, in case connect + if (!Connect(3)) + return; + + TString sqlQuery; + sqlQuery = Form("select count(*) from %s where shuttle_done=0", fConfig->GetShuttlelbTable()); + + TSQLResult* aResult = fServer[3]->Query(sqlQuery); + if (!aResult) { + AliError(Form("Can't execute query <%s>!", sqlQuery.Data())); + return; + } + + AliDebug(2,Form("Query = %s", sqlQuery.Data())); + + if (aResult->GetRowCount() == 0) { + AliError(Form("No result for query %s received", sqlQuery.Data())); + return; + } + + if (aResult->GetFieldCount() != 1) { + AliError(Form("Invalid field count for query %s received", sqlQuery.Data())); + return; + } + + TSQLRow* aRow = aResult->Next(); + if (!aRow) { + AliError(Form("Could not receive result of query %s", sqlQuery.Data())); + return; + } + + TString result(aRow->GetField(0), aRow->GetFieldLength(0)); + Int_t count = result.Atoi(); + + Log("SHUTTLE", Form("%d unprocessed runs", count)); + + delete aRow; + delete aResult; + + TMonaLisaValue mlStatus("SHUTTLE_openruns", count); + + TList mlList; + mlList.Add(&mlStatus); + + fMonaLisa->SendParameters(&mlList, "__PROCESSINGINFO__"); +} + //______________________________________________________________________________________________ Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause, TObjArray& entries) @@ -1634,7 +2019,7 @@ Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause, entries.SetOwner(1); // check connection, in case connect - if(!Connect(3)) return kFALSE; + if (!Connect(3)) return kFALSE; TString sqlQuery; sqlQuery = Form("select * from %s %s order by run", fConfig->GetShuttlelbTable(), whereClause); @@ -1648,7 +2033,7 @@ Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause, AliDebug(2,Form("Query = %s", sqlQuery.Data())); if(aResult->GetRowCount() == 0) { - AliInfo("No entries in Shuttle Logbook match request"); + Log("SHUTTLE", "No entries in Shuttle Logbook match request"); delete aResult; return kTRUE; } @@ -1656,7 +2041,7 @@ Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause, // TODO Check field count! const UInt_t nCols = 23; if (aResult->GetFieldCount() != (Int_t) nCols) { - AliError("Invalid SQL result field number!"); + Log("SHUTTLE", "Invalid SQL result field number!"); delete aResult; return kFALSE; } @@ -1698,7 +2083,7 @@ AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run) TSQLResult* aResult = fServer[3]->Query(sqlQuery); if (!aResult) { - AliError(Form("Can't execute query <%s>!", sqlQuery.Data())); + Log("SHUTTLE", Form("Can't execute query <%s>!", sqlQuery.Data())); return 0; } @@ -1709,7 +2094,8 @@ AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run) } if (aResult->GetRowCount() > 1) { - AliError(Form("More than one entry in DAQ Logbook for run %d. Skipping", run)); + Log("SHUTTLE", Form("QueryRunParameters - UNEXPECTED: " + "more than one entry in DAQ Logbook for run %d!", run)); delete aResult; return 0; } @@ -1717,7 +2103,7 @@ AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run) TSQLRow* aRow = aResult->Next(); if (!aRow) { - AliError(Form("Could not retrieve row for run %d. Skipping", run)); + Log("SHUTTLE", Form("QueryRunParameters - Could not retrieve row for run %d. Skipping", run)); delete aResult; return 0; } @@ -1730,139 +2116,156 @@ AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run) UInt_t startTime = entry->GetStartTime(); UInt_t endTime = entry->GetEndTime(); - if (!startTime || !endTime || startTime > endTime) { +// if (!startTime || !endTime || startTime > endTime) +// { +// Log("SHUTTLE", +// Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d. Skipping!", +// run, startTime, endTime)); +// +// Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run)); +// fLogbookEntry = entry; +// if (!UpdateShuttleLogbook("shuttle_done")) +// { +// AliError(Form("Could not update logbook for run %d !", run)); +// } +// fLogbookEntry = 0; +// +// delete entry; +// delete aRow; +// delete aResult; +// return 0; +// } + + if (!startTime) + { Log("SHUTTLE", - Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d", - run, startTime, endTime)); + Form("QueryRunParameters - Invalid parameters for Run %d: " + "startTime = %d, endTime = %d. Skipping!", + run, startTime, endTime)); + + Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run)); + fLogbookEntry = entry; + if (!UpdateShuttleLogbook("shuttle_ignored")) + { + AliError(Form("Could not update logbook for run %d !", run)); + } + fLogbookEntry = 0; + delete entry; delete aRow; delete aResult; return 0; } - - delete aRow; - delete aResult; - - return entry; -} - -//______________________________________________________________________________________________ -Bool_t AliShuttle::GetValueSet(const char* host, Int_t port, const char* entry, - TObjArray* valueSet, DCSType type) -{ - // Retrieve all "entry" data points from the DCS server - // host, port: TSocket connection parameters - // entry: name of the alias or data point - // valueSet: array of retrieved AliDCSValue's - // type: kAlias or kDP - - AliDCSClient client(host, port, fTimeout, fRetries); - if (!client.IsConnected()) + + if (startTime && !endTime) { - return kFALSE; + // TODO Here we don't mark SHUTTLE done, because this may mean + //the run is still ongoing!! + Log("SHUTTLE", + Form("QueryRunParameters - Invalid parameters for Run %d: " + "startTime = %d, endTime = %d. Skipping (Shuttle won't be marked as DONE)!", + run, startTime, endTime)); + + //Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run)); + //fLogbookEntry = entry; + //if (!UpdateShuttleLogbook("shuttle_done")) + //{ + // AliError(Form("Could not update logbook for run %d !", run)); + //} + //fLogbookEntry = 0; + + delete entry; + delete aRow; + delete aResult; + return 0; } - - Int_t result=0; - - if (type == kAlias) - { - result = client.GetAliasValues(entry, - GetCurrentStartTime(), GetCurrentEndTime(), valueSet); - } else - if (type == kDP) + + if (startTime && endTime && (startTime > endTime)) { - result = client.GetDPValues(entry, - GetCurrentStartTime(), GetCurrentEndTime(), valueSet); + Log("SHUTTLE", + Form("QueryRunParameters - Invalid parameters for Run %d: " + "startTime = %d, endTime = %d. Skipping!", + run, startTime, endTime)); + + Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run)); + fLogbookEntry = entry; + if (!UpdateShuttleLogbook("shuttle_ignored")) + { + AliError(Form("Could not update logbook for run %d !", run)); + } + fLogbookEntry = 0; + + delete entry; + delete aRow; + delete aResult; + return 0; } - - if (result < 0) + + TString totEventsStr = entry->GetRunParameter("totalEvents"); + Int_t totEvents = totEventsStr.Atoi(); + if (totEvents < 1) { - Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get '%s'! Reason: %s", - entry, AliDCSClient::GetErrorString(result))); - - if (result == AliDCSClient::fgkServerError) + Log("SHUTTLE", + Form("QueryRunParameters - Run %d has 0 events - Skipping!", run)); + + Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run)); + fLogbookEntry = entry; + if (!UpdateShuttleLogbook("shuttle_ignored")) { - Log(fCurrentDetector.Data(), Form("GetValueSet - Server error: %s", - client.GetServerError().Data())); + AliError(Form("Could not update logbook for run %d !", run)); } - - return kFALSE; + fLogbookEntry = 0; + + delete entry; + delete aRow; + delete aResult; + return 0; } - return kTRUE; + delete aRow; + delete aResult; + + return entry; } //______________________________________________________________________________________________ TMap* AliShuttle::GetValueSet(const char* host, Int_t port, const TSeqCollection* entries, - DCSType type) + DCSType type, Int_t multiSplit) { // Retrieve all "entry" data points from the DCS server // host, port: TSocket connection parameters // entries: list of name of the alias or data point // type: kAlias or kDP // returns TMap of values, 0 when failure - - const Int_t kSplit = 100; // maximum number of DPs at a time - - Int_t totalEntries = entries->GetEntries(); + AliDCSClient client(host, port, fTimeout, fRetries, multiSplit); + TMap* result = 0; - - for (Int_t index=0; index < totalEntries; index += kSplit) + if (type == kAlias) { - Int_t endIndex = index + kSplit; - - AliDCSClient client(host, port, fTimeout, fRetries); - if (!client.IsConnected()) - return 0; - - TMap* partialResult = 0; + result = client.GetAliasValues(entries, GetCurrentStartTime(), + GetCurrentEndTime()); + } + else if (type == kDP) + { + result = client.GetDPValues(entries, GetCurrentStartTime(), + GetCurrentEndTime()); + } - if (type == kAlias) - { - partialResult = client.GetAliasValues(entries, GetCurrentStartTime(), - GetCurrentEndTime(), index, endIndex); - } - else if (type == kDP) - { - partialResult = client.GetDPValues(entries, GetCurrentStartTime(), - GetCurrentEndTime(), index, endIndex); - } + if (result == 0) + { + Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get entries! Reason: %s", + client.GetErrorString(client.GetResultErrorCode()))); + if (client.GetResultErrorCode() == AliDCSClient::fgkServerError) + Log(fCurrentDetector.Data(), Form("GetValueSet - Server error code: %s", + client.GetServerError().Data())); - if (partialResult == 0) - { - Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get entries (%d...%d)! Reason: %s", - index, endIndex, client.GetServerError().Data())); - - if (result) - delete result; - - return 0; - } - - AliInfo(Form("Retrieved entries %d..%d (total %d); E.g. %s has %d values collected", - index, endIndex, totalEntries, entries->At(index)->GetName(), ((TObjArray*) - partialResult->GetValue(entries->At(index)->GetName()))->GetEntriesFast())); - - if (!result) - { - result = partialResult; - } - else - { - TIter iter(partialResult); - TObjString* key = 0; - while ((key = (TObjString*) iter.Next())) - result->Add(key, partialResult->GetValue(key->String())); - - partialResult->SetOwner(kFALSE); - delete partialResult; - } - + return 0; } - + return result; } + //______________________________________________________________________________________________ const char* AliShuttle::GetFile(Int_t system, const char* detector, const char* id, const char* source) @@ -1969,8 +2372,10 @@ const char* AliShuttle::GetFile(Int_t system, const char* detector, filePath.Data(), fileSize.Data(), fileChecksum.Data())); // retrieved file is renamed to make it unique - TString localFileName = Form("%s_%s_%d_%s_%s.shuttle", - GetSystemName(system), detector, GetCurrentRun(), id, sourceName.Data()); + TString localFileName = Form("%s/%s_%d_process/%s_%s_%d_%s_%s.shuttle", + GetShuttleTempDir(), detector, GetCurrentRun(), + GetSystemName(system), detector, GetCurrentRun(), + id, sourceName.Data()); // file retrieval from FXS @@ -1987,17 +2392,13 @@ const char* AliShuttle::GetFile(Int_t system, const char* detector, Log(detector, Form("GetFileName - Copy of file %s from %s FXS failed", filePath.Data(), GetSystemName(system))); continue; - } else { - AliInfo(Form("File %s copied from %s FXS into %s/%s", - filePath.Data(), GetSystemName(system), - GetShuttleTempDir(), localFileName.Data())); - } + } if (fileChecksum.Length()>0) { // compare md5sum of local file with the one stored in the FXS DB - Int_t md5Comp = gSystem->Exec(Form("md5sum %s/%s |grep %s 2>&1 > /dev/null", - GetShuttleTempDir(), localFileName.Data(), fileChecksum.Data())); + Int_t md5Comp = gSystem->Exec(Form("md5sum %s |grep %s 2>&1 > /dev/null", + localFileName.Data(), fileChecksum.Data())); if (md5Comp != 0) { @@ -2019,12 +2420,14 @@ const char* AliShuttle::GetFile(Int_t system, const char* detector, TObjString *fileParams = new TObjString(Form("%s#!?!#%s", id, sourceName.Data())); fFXSlist[system].Add(fileParams); - static TString fullLocalFileName; - fullLocalFileName.Form("%s/%s", GetShuttleTempDir(), localFileName.Data()); - - Log(fCurrentDetector, Form("GetFile - Retrieved file with id %s and source %s from %s to %s", id, source, GetSystemName(system), fullLocalFileName.Data())); - - return fullLocalFileName.Data(); + static TString staticLocalFileName; + staticLocalFileName.Form("%s", localFileName.Data()); + + Log(fCurrentDetector, Form("GetFile - Retrieved file with id %s and " + "source %s from %s to %s", id, source, + GetSystemName(system), localFileName.Data())); + + return staticLocalFileName.Data(); } //______________________________________________________________________________________________ @@ -2035,18 +2438,21 @@ Bool_t AliShuttle::RetrieveFile(UInt_t system, const char* fxsFileName, const ch // // check temp directory: trying to cd to temp; if it does not exist, create it - AliDebug(2, Form("Copy file %s from %s FXS into %s/%s", - GetSystemName(system), fxsFileName, GetShuttleTempDir(), localFileName)); + AliDebug(2, Form("Copy file %s from %s FXS into %s", + GetSystemName(system), fxsFileName, localFileName)); + + TString tmpDir(localFileName); + + tmpDir = tmpDir(0,tmpDir.Last('/')); - void* dir = gSystem->OpenDirectory(GetShuttleTempDir()); - if (dir == NULL) { - if (gSystem->mkdir(GetShuttleTempDir(), kTRUE)) { - AliError(Form("Can't open directory <%s>", GetShuttleTempDir())); + Int_t noDir = gSystem->GetPathInfo(tmpDir.Data(), 0, (Long64_t*) 0, 0, 0); + if (noDir) // temp dir does not exists! + { + if (gSystem->mkdir(tmpDir.Data(), 1)) + { + Log(fCurrentDetector.Data(), "RetrieveFile - could not make temp directory!!"); return kFALSE; } - - } else { - gSystem->FreeDirectory(dir); } TString baseFXSFolder; @@ -2060,17 +2466,16 @@ Bool_t AliShuttle::RetrieveFile(UInt_t system, const char* fxsFileName, const ch } else if (system == kHLT) { - baseFXSFolder = "/opt/FXS"; + baseFXSFolder = "/opt/FXS/"; } - TString command = Form("scp -oPort=%d -2 %s@%s:%s%s %s/%s", + TString command = Form("scp -oPort=%d -2 %s@%s:%s%s %s", fConfig->GetFXSPort(system), fConfig->GetFXSUser(system), fConfig->GetFXSHost(system), baseFXSFolder.Data(), fxsFileName, - GetShuttleTempDir(), localFileName); AliDebug(2, Form("%s",command.Data())); @@ -2099,7 +2504,7 @@ TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char if (system == kDCS) { - AliWarning("DCS system has only one source of data!"); + Log(detector, "GetFileSources - WARNING: DCS system has only one source of data!"); TList *list = new TList(); list->SetOwner(1); list->Add(new TObjString(" ")); @@ -2454,17 +2859,22 @@ Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status TString detName(detector); TString setClause; - if(detName == "shuttle_done") + if (detName == "shuttle_done" || detName == "shuttle_ignored") { setClause = "set shuttle_done=1"; - // Send the information to ML - TMonaLisaText mlStatus("SHUTTLE_status", "Done"); - - TList mlList; - mlList.Add(&mlStatus); + if (detName == "shuttle_done") + { + // Send the information to ML + TMonaLisaText mlStatus("SHUTTLE_status", "Done"); - fMonaLisa->SendParameters(&mlList); + TList mlList; + mlList.Add(&mlStatus); + + TString mlID; + mlID.Form("%d", GetCurrentRun()); + fMonaLisa->SendParameters(&mlList, mlID); + } } else { TString statusStr(status); if(statusStr.Contains("done", TString::kIgnoreCase) || @@ -2527,6 +2937,34 @@ UInt_t AliShuttle::GetCurrentEndTime() const return fLogbookEntry ? fLogbookEntry->GetEndTime() : 0; } +//______________________________________________________________________________________________ +UInt_t AliShuttle::GetCurrentYear() const +{ + // + // Get current year from logbook entry + // + + if (!fLogbookEntry) return 0; + + TTimeStamp startTime(GetCurrentStartTime()); + TString year = Form("%d",startTime.GetDate()); + year = year(0,4); + + return year.Atoi(); +} + +//______________________________________________________________________________________________ +const char* AliShuttle::GetLHCPeriod() const +{ + // + // Get current LHC period from logbook entry + // + + if (!fLogbookEntry) return 0; + + return fLogbookEntry->GetRunParameter("LHCperiod"); +} + //______________________________________________________________________________________________ void AliShuttle::Log(const char* detector, const char* message) { @@ -2534,9 +2972,13 @@ void AliShuttle::Log(const char* detector, const char* message) // Fill log string with a message // - void* dir = gSystem->OpenDirectory(GetShuttleLogDir()); + TString logRunDir = GetShuttleLogDir(); + if (GetCurrentRun() >=0) + logRunDir += Form("/%d", GetCurrentRun()); + + void* dir = gSystem->OpenDirectory(logRunDir.Data()); if (dir == NULL) { - if (gSystem->mkdir(GetShuttleLogDir(), kTRUE)) { + if (gSystem->mkdir(logRunDir.Data(), kTRUE)) { AliError(Form("Can't open directory <%s>", GetShuttleLogDir())); return; } @@ -2583,13 +3025,29 @@ TString AliShuttle::GetLogFileName(const char* detector) const TString fileName; if (GetCurrentRun() >= 0) - fileName.Form("%s/%s_%d.log", GetShuttleLogDir(), detector, GetCurrentRun()); - else + { + fileName.Form("%s/%d/%s_%d.log", GetShuttleLogDir(), GetCurrentRun(), + detector, GetCurrentRun()); + } else { fileName.Form("%s/%s.log", GetShuttleLogDir(), detector); + } return fileName; } +//______________________________________________________________________________________________ +void AliShuttle::SendAlive() +{ + // sends alive message to ML + + TMonaLisaText mlStatus("SHUTTLE_status", "Alive"); + + TList mlList; + mlList.Add(&mlStatus); + + fMonaLisa->SendParameters(&mlList, "__PROCESSINGINFO__"); +} + //______________________________________________________________________________________________ Bool_t AliShuttle::Collect(Int_t run) { @@ -2607,6 +3065,13 @@ Bool_t AliShuttle::Collect(Int_t run) SetLastAction("Starting"); + // create ML instance + if (!fMonaLisa) + fMonaLisa = new TMonaLisaWriter(fConfig->GetMonitorHost(), fConfig->GetMonitorTable()); + + SendAlive(); + CountOpenRuns(); + TString whereClause("where shuttle_done=0"); if (run != -1) whereClause += Form(" and run=%d", run); @@ -2689,8 +3154,8 @@ Bool_t AliShuttle::RetrieveConditionsData(const TObjArray& dateEntries) } // clean SHUTTLE temp directory - TString filename = Form("%s/*.shuttle", GetShuttleTempDir()); - RemoveFile(filename.Data()); + //TString filename = Form("%s/*.shuttle", GetShuttleTempDir()); + //RemoveFile(filename.Data()); } return hasError == kFALSE; @@ -2795,12 +3260,28 @@ Bool_t AliShuttle::SendMail() if (fTestMode != kNone) return kTRUE; + TString to=""; + TIter iterExperts(fConfig->GetResponsibles(fCurrentDetector)); + TObjString *anExpert=0; + while ((anExpert = (TObjString*) iterExperts.Next())) + { + to += Form("%s,", anExpert->GetName()); + } + if (to.Length() > 0) + to.Remove(to.Length()-1); + AliDebug(2, Form("to: %s",to.Data())); + + if (to.IsNull()) { + Log("SHUTTLE", "List of detector responsibles not yet set!"); + return kFALSE; + } + void* dir = gSystem->OpenDirectory(GetShuttleLogDir()); if (dir == NULL) { if (gSystem->mkdir(GetShuttleLogDir(), kTRUE)) { - AliError(Form("Can't open directory <%s>", GetShuttleLogDir())); + Log("SHUTTLE", Form("SendMail - Can't open directory <%s>", GetShuttleLogDir())); return kFALSE; } @@ -2817,40 +3298,152 @@ Bool_t AliShuttle::SendMail() if (!mailBody.is_open()) { - AliError(Form("Could not open mail body file %s", bodyFileName.Data())); + Log("SHUTTLE", Form("Could not open mail body file %s", bodyFileName.Data())); return kFALSE; } - TString to=""; - TIter iterExperts(fConfig->GetResponsibles(fCurrentDetector)); - TObjString *anExpert=0; - while ((anExpert = (TObjString*) iterExperts.Next())) + TString cc="alberto.colla@cern.ch"; + + TString subject = Form("%s Shuttle preprocessor FAILED in run %d (run type = %s)!", + fCurrentDetector.Data(), GetCurrentRun(), GetRunType()); + AliDebug(2, Form("subject: %s", subject.Data())); + + TString body = Form("Dear %s expert(s), \n\n", fCurrentDetector.Data()); + body += Form("SHUTTLE just detected that your preprocessor " + "failed processing run %d (run type = %s)!!\n\n", + GetCurrentRun(), GetRunType()); + body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n", + fCurrentDetector.Data()); + if (fConfig->GetRunMode() == AliShuttleConfig::kTest) { - to += Form("%s,", anExpert->GetName()); + body += Form("\thttp://pcalimonitor.cern.ch:8889/shuttle.jsp?time=168 \n\n"); + } else { + body += Form("\thttp://pcalimonitor.cern.ch/shuttle.jsp?instance=PROD&time=168 \n\n"); + } + + + TString logFolder = "logs"; + if (fConfig->GetRunMode() == AliShuttleConfig::kProd) + logFolder += "_PROD"; + + + body += Form("Find the %s log for the current run on \n\n" + "\thttp://pcalishuttle01.cern.ch:8880/%s/%d/%s_%d.log \n\n", + fCurrentDetector.Data(), logFolder.Data(), GetCurrentRun(), + fCurrentDetector.Data(), GetCurrentRun()); + body += Form("The last 10 lines of %s log file are following:\n\n", fCurrentDetector.Data()); + + AliDebug(2, Form("Body begin: %s", body.Data())); + + mailBody << body.Data(); + mailBody.close(); + mailBody.open(bodyFileName, ofstream::out | ofstream::app); + + TString logFileName = Form("%s/%d/%s_%d.log", GetShuttleLogDir(), + GetCurrentRun(), fCurrentDetector.Data(), GetCurrentRun()); + TString tailCommand = Form("tail -n 10 %s >> %s", logFileName.Data(), bodyFileName.Data()); + if (gSystem->Exec(tailCommand.Data())) + { + mailBody << Form("%s log file not found ...\n\n", fCurrentDetector.Data()); } - to.Remove(to.Length()-1); + + TString endBody = Form("------------------------------------------------------\n\n"); + endBody += Form("In case of problems please contact the SHUTTLE core team.\n\n"); + endBody += "Please do not answer this message directly, it is automatically generated.\n\n"; + endBody += "Greetings,\n\n \t\t\tthe SHUTTLE\n"; + + AliDebug(2, Form("Body end: %s", endBody.Data())); + + mailBody << endBody.Data(); + + mailBody.close(); + + // send mail! + TString mailCommand = Form("mail -s \"%s\" -c %s %s < %s", + subject.Data(), + cc.Data(), + to.Data(), + bodyFileName.Data()); + AliDebug(2, Form("mail command: %s", mailCommand.Data())); + + Bool_t result = gSystem->Exec(mailCommand.Data()); + + return result == 0; +} + +//______________________________________________________________________________________________ +Bool_t AliShuttle::SendMailToDCS() +{ + // + // sends a mail to the DCS experts in case of DCS error + // + + if (fTestMode != kNone) + return kTRUE; + + void* dir = gSystem->OpenDirectory(GetShuttleLogDir()); + if (dir == NULL) + { + if (gSystem->mkdir(GetShuttleLogDir(), kTRUE)) + { + Log("SHUTTLE", Form("SendMailToDCS - Can't open directory <%s>", GetShuttleLogDir())); + return kFALSE; + } + + } else { + gSystem->FreeDirectory(dir); + } + + TString bodyFileName; + bodyFileName.Form("%s/mail.body", GetShuttleLogDir()); + gSystem->ExpandPathName(bodyFileName); + + ofstream mailBody; + mailBody.open(bodyFileName, ofstream::out); + + if (!mailBody.is_open()) + { + Log("SHUTTLE", Form("SendMailToDCS - Could not open mail body file %s", bodyFileName.Data())); + return kFALSE; + } + + TString to="Vladimir.Fekete@cern.ch, Svetozar.Kapusta@cern.ch"; + //TString to="alberto.colla@cern.ch"; AliDebug(2, Form("to: %s",to.Data())); if (to.IsNull()) { - AliInfo("List of detector responsibles not yet set!"); + Log("SHUTTLE", "List of detector responsibles not yet set!"); return kFALSE; } TString cc="alberto.colla@cern.ch"; - TString subject = Form("%s Shuttle preprocessor FAILED in run %d !", + TString subject = Form("Retrieval of data points for %s FAILED in run %d !", fCurrentDetector.Data(), GetCurrentRun()); AliDebug(2, Form("subject: %s", subject.Data())); - TString body = Form("Dear %s expert(s), \n\n", fCurrentDetector.Data()); - body += Form("SHUTTLE just detected that your preprocessor " - "failed processing run %d!!\n\n", GetCurrentRun()); - body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n", fCurrentDetector.Data()); - body += Form("\thttp://pcalimonitor.cern.ch:8889/shuttle.jsp?time=168 \n\n"); + TString body = Form("Dear DCS experts, \n\n"); + body += Form("SHUTTLE couldn\'t retrieve the data points for detector %s " + "in run %d!!\n\n", fCurrentDetector.Data(), GetCurrentRun()); + body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n", + fCurrentDetector.Data()); + if (fConfig->GetRunMode() == AliShuttleConfig::kTest) + { + body += Form("\thttp://pcalimonitor.cern.ch:8889/shuttle.jsp?time=168 \n\n"); + } else { + body += Form("\thttp://pcalimonitor.cern.ch/shuttle.jsp?instance=PROD?time=168 \n\n"); + } + + TString logFolder = "logs"; + if (fConfig->GetRunMode() == AliShuttleConfig::kProd) + logFolder += "_PROD"; + + body += Form("Find the %s log for the current run on \n\n" - "\thttp://pcalishuttle01.cern.ch:8880/logs/%s_%d.log \n\n", - fCurrentDetector.Data(), fCurrentDetector.Data(), GetCurrentRun()); - body += Form("The last 10 lines of %s log file are following:\n\n"); + "\thttp://pcalishuttle01.cern.ch:8880/%s/%d/%s_%d.log \n\n", + fCurrentDetector.Data(), logFolder.Data(), GetCurrentRun(), + fCurrentDetector.Data(), GetCurrentRun()); + body += Form("The last 10 lines of %s log file are following:\n\n", fCurrentDetector.Data()); AliDebug(2, Form("Body begin: %s", body.Data())); @@ -2858,7 +3451,8 @@ Bool_t AliShuttle::SendMail() mailBody.close(); mailBody.open(bodyFileName, ofstream::out | ofstream::app); - TString logFileName = Form("%s/%s_%d.log", GetShuttleLogDir(), fCurrentDetector.Data(), GetCurrentRun()); + TString logFileName = Form("%s/%d/%s_%d.log", GetShuttleLogDir(), GetCurrentRun(), + fCurrentDetector.Data(), GetCurrentRun()); TString tailCommand = Form("tail -n 10 %s >> %s", logFileName.Data(), bodyFileName.Data()); if (gSystem->Exec(tailCommand.Data())) { @@ -2904,6 +3498,24 @@ const char* AliShuttle::GetRunType() return fLogbookEntry->GetRunType(); } +//______________________________________________________________________________________________ +Bool_t AliShuttle::GetHLTStatus() +{ + // Return HLT status (ON=1 OFF=0) + // Converts the HLT status from the status string read in the run logbook (not just a bool) + + if(!fLogbookEntry) { + AliError("No logbook entry!"); + return 0; + } + + // TODO implement when HLTStatus is inserted in run logbook + //TString hltStatus = fLogbookEntry->GetRunParameter("HLTStatus"); + //if(hltStatus == "OFF") {return kFALSE}; + + return kTRUE; +} + //______________________________________________________________________________________________ void AliShuttle::SetShuttleTempDir(const char* tmpDir) {