File indexing completed on 2025-03-14 23:36:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include "FWCore/MessageLogger/interface/JobReport.h"
0021 #include "FWCore/Utilities/interface/Map.h"
0022 #include "FWCore/Utilities/interface/EDMException.h"
0023
0024
0025
0026 #include "tinyxml2.h"
0027 #include <fstream>
0028 #include <iomanip>
0029 #include <ostream>
0030 #include <sstream>
0031
0032 namespace edm {
0033
0034
0035
0036
0037
0038
0039 template <typename S, typename T>
0040 S& formatFile(T const& f, S& os) {
0041 tinyxml2::XMLDocument doc;
0042 if (f.fileHasBeenClosed) {
0043 os << "\n<State Value=\"closed\"/>";
0044 } else {
0045 os << "\n<State Value=\"open\"/>";
0046 }
0047 os << "\n<LFN>" << doc.NewText(f.logicalFileName.c_str())->Value() << "</LFN>";
0048 os << "\n<PFN>" << doc.NewText(f.physicalFileName.c_str())->Value() << "</PFN>";
0049 os << "\n<Catalog>" << doc.NewText(f.catalog.c_str())->Value() << "</Catalog>";
0050 os << "\n<ModuleLabel>" << doc.NewText(f.moduleLabel.c_str())->Value() << "</ModuleLabel>";
0051 os << "\n<GUID>" << f.guid << "</GUID>";
0052 os << "\n<Branches>";
0053 for (auto const& branch : f.branchNames) {
0054 os << "\n <Branch>" << doc.NewText(branch.c_str())->Value() << "</Branch>";
0055 doc.DeleteChildren();
0056 }
0057 os << "\n</Branches>";
0058 return os;
0059 }
0060
0061
0062
0063
0064
0065 template <typename S>
0066 S& print(S& os, JobReport::InputFile const& f) {
0067 tinyxml2::XMLDocument doc;
0068 os << "\n<InputFile>";
0069 formatFile(f, os);
0070 os << "\n<InputType>" << f.inputType << "</InputType>";
0071 os << "\n<InputSourceClass>" << doc.NewText(f.inputSourceClassName.c_str())->Value() << "</InputSourceClass>";
0072 os << "\n<EventsRead>" << f.numEventsRead << "</EventsRead>";
0073 return os;
0074 }
0075
0076 template <typename S>
0077 S& print(S& os, JobReport::OutputFile const& f) {
0078 tinyxml2::XMLDocument doc;
0079 formatFile(f, os);
0080 os << "\n<OutputModuleClass>" << doc.NewText(f.outputModuleClassName.c_str())->Value() << "</OutputModuleClass>";
0081 os << "\n<TotalEvents>" << f.numEventsWritten << "</TotalEvents>\n";
0082 os << "\n<DataType>" << doc.NewText(f.dataType.c_str())->Value() << "</DataType>\n";
0083 os << "\n<BranchHash>" << doc.NewText(f.branchHash.c_str())->Value() << "</BranchHash>\n";
0084 return os;
0085 }
0086
0087 template <typename S>
0088 S& print(S& os, JobReport::RunReport const& rep) {
0089 os << "\n<Run ID=\"" << rep.runNumber << "\">\n";
0090
0091 for (auto const& il : rep.lumiSectionsToNEvents) {
0092 if (std::numeric_limits<unsigned long>::max() == il.second) {
0093 os << " <LumiSection ID=\"" << il.first << "\"/>\n";
0094
0095 } else {
0096 os << " <LumiSection ID=\"" << il.first << "\" NEvents=\"" << il.second << "\"/>\n";
0097 }
0098 }
0099 os << "</Run>\n";
0100 return os;
0101 }
0102
0103 std::ostream& operator<<(std::ostream& os, JobReport::InputFile const& f) { return print(os, f); }
0104 std::ostream& operator<<(std::ostream& os, JobReport::OutputFile const& f) { return print(os, f); }
0105 std::ostream& operator<<(std::ostream& os, JobReport::RunReport const& f) { return print(os, f); }
0106
0107 JobReport::InputFile& JobReport::JobReportImpl::getInputFileForToken(InputType inputType, JobReport::Token t) {
0108 InputFile* inputFile = nullptr;
0109 if (inputType == InputType::SecondarySource) {
0110 if (t >= inputFilesSecSource_.size()) {
0111 throw edm::Exception(edm::errors::LogicError) << "Access reported for secondary source input file with token "
0112 << t << " but no matching input file is found\n";
0113 }
0114 inputFile = &inputFilesSecSource_[t];
0115 } else {
0116 if (t >= inputFiles_.size()) {
0117 throw edm::Exception(edm::errors::LogicError)
0118 << "Access reported for input file with token " << t << " but no matching input file is found\n";
0119 }
0120 inputFile = &inputFiles_[t];
0121 }
0122 if (inputFile->fileHasBeenClosed) {
0123 throw edm::Exception(edm::errors::LogicError)
0124 << "Access reported for input file with token " << t << " after this file has been closed.\n"
0125 << "File record follows:\n"
0126 << *inputFile << '\n';
0127 }
0128 return *inputFile;
0129 }
0130
0131 JobReport::OutputFile& JobReport::JobReportImpl::getOutputFileForToken(JobReport::Token t) {
0132 if (t >= outputFiles_.size()) {
0133 throw edm::Exception(edm::errors::LogicError)
0134 << "Access reported for output file with token " << t << " but no matching output file is found\n";
0135 }
0136 if (outputFiles_[t].fileHasBeenClosed) {
0137 throw edm::Exception(edm::errors::LogicError)
0138 << "Access reported for output file with token " << t << " after this file has been closed.\n"
0139 << "File record follows:\n"
0140 << outputFiles_[t] << '\n';
0141 }
0142 return outputFiles_[t];
0143 }
0144
0145
0146
0147
0148
0149
0150
0151 void JobReport::JobReportImpl::insertInputForOutputs(InputType inputType, JobReport::Token t) {
0152 for (auto& outputFile : outputFiles_) {
0153 if (!outputFile.fileHasBeenClosed) {
0154 if (inputType == InputType::SecondarySource) {
0155 outputFile.contributingInputsSecSource.push_back(t);
0156 } else {
0157 outputFile.contributingInputs.push_back(t);
0158 }
0159 }
0160 }
0161 }
0162
0163
0164
0165
0166
0167
0168 void JobReport::JobReportImpl::writeInputFile(JobReport::InputFile const& f) {
0169 if (ost_) {
0170 *ost_ << f;
0171 *ost_ << "\n<Runs>";
0172 for (auto const& runReport : f.runReports) {
0173 *ost_ << runReport.second;
0174 }
0175 *ost_ << "\n</Runs>\n";
0176 *ost_ << "</InputFile>\n";
0177 *ost_ << std::flush;
0178 }
0179 }
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 void JobReport::JobReportImpl::writeOutputFile(JobReport::OutputFile const& f) {
0196 tinyxml2::XMLDocument doc;
0197 if (ost_) {
0198 *ost_ << "\n<File>";
0199 *ost_ << f;
0200
0201 *ost_ << "\n<Runs>";
0202 for (auto const& runReport : f.runReports) {
0203 *ost_ << runReport.second;
0204 }
0205 *ost_ << "\n</Runs>\n";
0206
0207 *ost_ << "\n<Inputs>";
0208 for (auto token : f.contributingInputs) {
0209 JobReport::InputFile inpFile = inputFiles_.at(token);
0210 *ost_ << "\n<Input>";
0211 *ost_ << "\n <LFN>" << doc.NewText(inpFile.logicalFileName.c_str())->Value() << "</LFN>";
0212 *ost_ << "\n <PFN>" << doc.NewText(inpFile.physicalFileName.c_str())->Value() << "</PFN>";
0213 *ost_ << "\n <FastCopying>" << findOrDefault(f.fastCopyingInputs, inpFile.physicalFileName)
0214 << "</FastCopying>";
0215 *ost_ << "\n</Input>";
0216 doc.DeleteChildren();
0217 }
0218 for (auto token : f.contributingInputsSecSource) {
0219 JobReport::InputFile inpFile = inputFilesSecSource_.at(token);
0220 *ost_ << "\n<Input>";
0221 *ost_ << "\n <LFN>" << doc.NewText(inpFile.logicalFileName.c_str())->Value() << "</LFN>";
0222 *ost_ << "\n <PFN>" << doc.NewText(inpFile.physicalFileName.c_str())->Value() << "</PFN>";
0223 *ost_ << "\n <FastCopying>" << findOrDefault(f.fastCopyingInputs, inpFile.physicalFileName)
0224 << "</FastCopying>";
0225 *ost_ << "\n</Input>";
0226 doc.DeleteChildren();
0227 }
0228 *ost_ << "\n</Inputs>";
0229 *ost_ << "\n</File>\n";
0230 }
0231 }
0232
0233
0234
0235
0236
0237 void JobReport::JobReportImpl::flushFiles(void) {
0238 for (auto const& inputFile : inputFiles_) {
0239 if (!(inputFile.fileHasBeenClosed)) {
0240 writeInputFile(inputFile);
0241 }
0242 }
0243 for (auto const& inputFile : inputFilesSecSource_) {
0244 if (!(inputFile.fileHasBeenClosed)) {
0245 writeInputFile(inputFile);
0246 }
0247 }
0248 for (auto const& outputFile : outputFiles_) {
0249 if (!(outputFile.fileHasBeenClosed)) {
0250 writeOutputFile(outputFile);
0251 }
0252 }
0253 }
0254
0255 void JobReport::JobReportImpl::associateRun(JobReport::Token token, unsigned int runNumber) {
0256 auto& theMap = outputFiles_.at(token).runReports;
0257 std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
0258 if (iter == theMap.end() || runNumber < iter->first) {
0259 theMap.emplace_hint(iter, runNumber, JobReport::RunReport{runNumber, {}});
0260 }
0261 }
0262
0263 void JobReport::JobReportImpl::associateInputRun(unsigned int runNumber) {
0264 for (auto& inputFile : inputFiles_) {
0265 if (!inputFile.fileHasBeenClosed) {
0266 std::map<RunNumber, RunReport>& theMap = inputFile.runReports;
0267 std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
0268 if (iter == theMap.end() || runNumber < iter->first) {
0269 theMap.emplace_hint(iter, runNumber, JobReport::RunReport{runNumber, {}});
0270 }
0271 }
0272 }
0273 }
0274
0275 void JobReport::JobReportImpl::associateLumiSection(JobReport::Token token,
0276 unsigned int runNumber,
0277 unsigned int lumiSect,
0278 unsigned long nEvents) {
0279 auto& theMap = outputFiles_.at(token).runReports;
0280 std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
0281 if (iter == theMap.end() || runNumber < iter->first) {
0282 theMap.emplace_hint(iter, runNumber, JobReport::RunReport{runNumber, {{{lumiSect, nEvents}}}});
0283 } else {
0284 iter->second.lumiSectionsToNEvents[lumiSect] += nEvents;
0285 }
0286 }
0287
0288 void JobReport::JobReportImpl::associateInputLumiSection(unsigned int runNumber, unsigned int lumiSect) {
0289 for (auto& inputFile : inputFiles_) {
0290 if (!inputFile.fileHasBeenClosed) {
0291 std::map<RunNumber, RunReport>& theMap = inputFile.runReports;
0292 std::map<RunNumber, RunReport>::iterator iter(theMap.lower_bound(runNumber));
0293 if (iter == theMap.end() || runNumber < iter->first) {
0294 theMap.emplace_hint(
0295 iter,
0296 runNumber,
0297 JobReport::RunReport{runNumber, {{lumiSect, std::numeric_limits<unsigned long>::max()}}});
0298 } else {
0299 iter->second.lumiSectionsToNEvents[lumiSect] = std::numeric_limits<unsigned long>::max();
0300 }
0301 }
0302 }
0303 }
0304
0305 static constexpr std::string_view kJobReportEndElement = "</FrameworkJobReport>\n";
0306 static constexpr int kMinSizeOfComment = 8;
0307
0308 JobReport::~JobReport() {
0309 impl_->flushFiles();
0310 if (impl_->ost_) {
0311
0312 auto pos = impl_->ost_->tellp();
0313 impl_->ost_->seekp(0, std::ios_base::end);
0314 auto endpos = impl_->ost_->tellp();
0315 impl_->ost_->seekp(pos);
0316 if ((endpos - pos) > static_cast<long int>(kJobReportEndElement.size())) {
0317
0318
0319
0320 auto padding = (endpos - pos) - (kJobReportEndElement.size() + kMinSizeOfComment);
0321 *(impl_->ost_) << "<!--";
0322 for (int i = padding; i > 0; --i) {
0323 (*impl_->ost_) << ' ';
0324 }
0325 *(impl_->ost_) << "-->\n";
0326 }
0327 *(impl_->ost_) << kJobReportEndElement << std::flush;
0328 }
0329 }
0330
0331 void JobReport::temporarilyCloseXML() {
0332 if (impl_->ost_) {
0333
0334 auto pos = impl_->ost_->tellp();
0335 if (not errorLogged_) {
0336 *(impl_->ost_) << "<FrameworkError ExitStatus=\"8901\" Type=\"UnexpectedJobTermination\"/>\n";
0337 }
0338 *(impl_->ost_) << kJobReportEndElement << std::flush;
0339
0340
0341 impl_->ost_->seekp(pos);
0342 }
0343 }
0344
0345 JobReport::JobReport() : impl_(new JobReportImpl(nullptr)) {}
0346
0347 JobReport::JobReport(std::ostream* iOstream) : impl_(new JobReportImpl(iOstream)) {
0348 if (impl_->ost_) {
0349 *(impl_->ost_) << "<FrameworkJobReport>\n";
0350 }
0351 temporarilyCloseXML();
0352 }
0353
0354 void JobReport::reportProcess(std::string_view processName,
0355 ProcessConfigurationID const& reducedProcessID,
0356 ParameterSetID const& psetID) {
0357 if (impl_->ost_) {
0358 *(impl_->ost_) << "\n<Process>\n";
0359 *(impl_->ost_) << " <Name>" << processName << "</Name>\n";
0360 *(impl_->ost_) << " <ReducedConfigurationID>" << reducedProcessID << "</ReducedConfigurationID>\n";
0361 *(impl_->ost_) << " <ParameterSetID>" << psetID << "</ParameterSetID>\n";
0362 *(impl_->ost_) << "</Process>\n";
0363 }
0364 temporarilyCloseXML();
0365 }
0366
0367 JobReport::Token JobReport::inputFileOpened(std::string const& physicalFileName,
0368 std::string const& logicalFileName,
0369 std::string const& catalog,
0370 std::string const& inputType,
0371 std::string const& inputSourceClassName,
0372 std::string const& moduleLabel,
0373 std::string const& guid,
0374 std::vector<std::string> const& branchNames) {
0375 InputType theInputType = InputType::Primary;
0376 InputFile* newFile = nullptr;
0377 JobReport::Token newToken = 0;
0378
0379 if (inputType == "mixingFiles") {
0380 theInputType = InputType::SecondarySource;
0381 auto itr = impl_->inputFilesSecSource_.push_back(InputFile());
0382 newFile = &(*itr);
0383 newToken = itr - impl_->inputFilesSecSource_.begin();
0384 } else {
0385 if (inputType == "secondaryFiles") {
0386 theInputType = InputType::SecondaryFile;
0387 }
0388 impl_->inputFiles_.emplace_back();
0389 newFile = &impl_->inputFiles_.back();
0390 newToken = impl_->inputFiles_.size() - 1;
0391 }
0392
0393 if (theInputType == InputType::Primary) {
0394 impl_->lastOpenedPrimaryInputFile_ = impl_->inputFiles_.size() - 1;
0395 }
0396 newFile->logicalFileName = logicalFileName;
0397 newFile->physicalFileName = physicalFileName;
0398 newFile->catalog = catalog;
0399 newFile->inputType = inputType;
0400 newFile->inputSourceClassName = inputSourceClassName;
0401 newFile->moduleLabel = moduleLabel;
0402 newFile->guid = guid;
0403 newFile->numEventsRead = 0;
0404 newFile->branchNames = branchNames;
0405 newFile->fileHasBeenClosed = false;
0406
0407
0408
0409 impl_->insertInputForOutputs(theInputType, newToken);
0410 return newToken;
0411 }
0412
0413 void JobReport::eventReadFromFile(InputType inputType, JobReport::Token fileToken) {
0414 JobReport::InputFile& f = impl_->getInputFileForToken(inputType, fileToken);
0415 ++f.numEventsRead;
0416 }
0417
0418 void JobReport::reportDataType(Token fileToken, std::string const& dataType) {
0419 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0420 f.dataType = dataType;
0421 }
0422
0423 void JobReport::inputFileClosed(InputType inputType, JobReport::Token fileToken) {
0424 JobReport::InputFile& f = impl_->getInputFileForToken(inputType, fileToken);
0425 f.fileHasBeenClosed = true;
0426 std::lock_guard<std::mutex> lock(write_mutex);
0427 if (inputType == InputType::Primary) {
0428 impl_->writeInputFile(f);
0429 } else {
0430 impl_->writeInputFile(f);
0431 }
0432 temporarilyCloseXML();
0433 }
0434
0435 JobReport::Token JobReport::outputFileOpened(std::string const& physicalFileName,
0436 std::string const& logicalFileName,
0437 std::string const& catalog,
0438 std::string const& outputModuleClassName,
0439 std::string const& moduleLabel,
0440 std::string const& guid,
0441 std::string const& dataType,
0442 std::string const& branchHash,
0443 std::vector<std::string> const& branchNames) {
0444 auto itr = impl_->outputFiles_.emplace_back();
0445 JobReport::OutputFile& r = *itr;
0446
0447 r.logicalFileName = logicalFileName;
0448 r.physicalFileName = physicalFileName;
0449 r.catalog = catalog;
0450 r.outputModuleClassName = outputModuleClassName;
0451 r.moduleLabel = moduleLabel;
0452 r.guid = guid;
0453 r.dataType = dataType;
0454 r.branchHash = branchHash;
0455 r.numEventsWritten = 0;
0456 r.branchNames = branchNames;
0457 r.fileHasBeenClosed = false;
0458
0459
0460
0461 for (std::vector<Token>::size_type i = 0, iEnd = impl_->inputFiles_.size(); i < iEnd; ++i) {
0462 if (!impl_->inputFiles_[i].fileHasBeenClosed) {
0463 r.contributingInputs.push_back(i);
0464 }
0465 }
0466 for (oneapi::tbb::concurrent_vector<Token>::size_type i = 0, iEnd = impl_->inputFilesSecSource_.size(); i < iEnd;
0467 ++i) {
0468 if (!impl_->inputFilesSecSource_[i].fileHasBeenClosed) {
0469 r.contributingInputsSecSource.push_back(i);
0470 }
0471 }
0472 return itr - impl_->outputFiles_.begin();
0473 }
0474
0475 void JobReport::eventWrittenToFile(JobReport::Token fileToken, RunNumber_t , EventNumber_t) {
0476 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0477 ++f.numEventsWritten;
0478 }
0479
0480 void JobReport::outputFileClosed(JobReport::Token fileToken) {
0481 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0482 f.fileHasBeenClosed = true;
0483 std::lock_guard<std::mutex> lock(write_mutex);
0484 impl_->writeOutputFile(f);
0485 temporarilyCloseXML();
0486 }
0487
0488 void JobReport::reportSkippedEvent(RunNumber_t run, EventNumber_t event) {
0489 if (impl_->ost_) {
0490 std::ostream& msg = *(impl_->ost_);
0491 {
0492 std::lock_guard<std::mutex> lock(write_mutex);
0493 msg << "<SkippedEvent Run=\"" << run << "\"";
0494 msg << " Event=\"" << event << "\" />\n";
0495 temporarilyCloseXML();
0496 }
0497 }
0498 }
0499
0500 void JobReport::reportFastCopyingStatus(JobReport::Token fileToken,
0501 std::string const& inputFileName,
0502 bool fastCopying) {
0503 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0504 f.fastCopyingInputs.insert(std::make_pair(inputFileName, fastCopying));
0505 }
0506
0507 void JobReport::reportLumiSection(JobReport::Token token,
0508 unsigned int run,
0509 unsigned int lumiSectId,
0510 unsigned long nEvents) {
0511 impl_->associateLumiSection(token, run, lumiSectId, nEvents);
0512 }
0513
0514 void JobReport::reportInputLumiSection(unsigned int run, unsigned int lumiSectId) {
0515 impl_->associateInputLumiSection(run, lumiSectId);
0516 }
0517
0518 void JobReport::reportRunNumber(JobReport::Token token, unsigned int run) { impl_->associateRun(token, run); }
0519
0520 void JobReport::reportInputRunNumber(unsigned int run) { impl_->associateInputRun(run); }
0521
0522 void JobReport::reportAnalysisFile(std::string const& fileName, std::map<std::string, std::string> const& fileData) {
0523 tinyxml2::XMLDocument doc;
0524 if (impl_->ost_) {
0525 std::ostream& msg = *(impl_->ost_);
0526 {
0527 std::lock_guard<std::mutex> lock(write_mutex);
0528 msg << "<AnalysisFile>\n"
0529 << " <FileName>" << doc.NewText(fileName.c_str())->Value() << "</FileName>\n";
0530
0531 typedef std::map<std::string, std::string>::const_iterator const_iterator;
0532 for (const_iterator pos = fileData.begin(), posEnd = fileData.end(); pos != posEnd; ++pos) {
0533 msg << " <" << pos->first << " Value=\"" << pos->second << "\" />"
0534 << "\n";
0535 }
0536 msg << "</AnalysisFile>\n";
0537 temporarilyCloseXML();
0538 }
0539 }
0540 }
0541
0542 void JobReport::reportError(std::string const& shortDesc, std::string const& longDesc, int const& exitCode) {
0543 if (impl_->ost_) {
0544 {
0545 std::lock_guard<std::mutex> lock(write_mutex);
0546 errorLogged_ = true;
0547 std::ostream& msg = *(impl_->ost_);
0548 msg << "<FrameworkError ExitStatus=\"" << exitCode << "\" Type=\"" << shortDesc << "\" >\n";
0549 msg << "<![CDATA[\n" << longDesc << "\n]]>\n";
0550 msg << "</FrameworkError>\n";
0551 temporarilyCloseXML();
0552 }
0553 }
0554 }
0555
0556 void JobReport::reportShutdownSignal() {
0557 if (impl_->ost_) {
0558 {
0559 std::lock_guard<std::mutex> lock(write_mutex);
0560 std::ostream& msg = *(impl_->ost_);
0561 msg << "<ShutdownSignal/>\n";
0562 temporarilyCloseXML();
0563 }
0564 }
0565 }
0566
0567 void JobReport::reportSkippedFile(std::string const& pfn, std::string const& lfn) {
0568 if (impl_->ost_) {
0569 std::ostream& msg = *(impl_->ost_);
0570 tinyxml2::XMLDocument doc;
0571 tinyxml2::XMLPrinter printer;
0572 tinyxml2::XMLElement* skipped = doc.NewElement("SkippedFile");
0573 skipped->SetAttribute("Pfn", pfn.c_str());
0574 skipped->SetAttribute("Lfn", lfn.c_str());
0575 {
0576 std::lock_guard<std::mutex> lock(write_mutex);
0577 skipped->Accept(&printer);
0578 msg << printer.CStr();
0579 temporarilyCloseXML();
0580 }
0581 }
0582 }
0583
0584 void JobReport::reportFallbackAttempt(std::string const& pfn, std::string const& lfn, std::string const& err) {
0585 if (impl_->ost_) {
0586 std::ostream& msg = *(impl_->ost_);
0587 tinyxml2::XMLDocument doc;
0588 tinyxml2::XMLPrinter printer;
0589 tinyxml2::XMLElement* fallback = doc.NewElement("FallbackAttempt");
0590 fallback->SetAttribute("Pfn", pfn.c_str());
0591 fallback->SetAttribute("Lfn", lfn.c_str());
0592 {
0593 std::lock_guard<std::mutex> lock(write_mutex);
0594 fallback->Accept(&printer);
0595 msg << printer.CStr();
0596 msg << "<![CDATA[\n" << err << "\n]]>\n";
0597 temporarilyCloseXML();
0598 }
0599 }
0600 }
0601
0602 void JobReport::reportMemoryInfo(std::vector<std::string> const& memoryData) {
0603 if (impl_->ost_) {
0604 std::lock_guard<std::mutex> lock(write_mutex);
0605 std::ostream& msg = *(impl_->ost_);
0606 msg << "<MemoryService>\n";
0607
0608 typedef std::vector<std::string>::const_iterator const_iterator;
0609 for (const_iterator pos = memoryData.begin(), posEnd = memoryData.end(); pos != posEnd; ++pos) {
0610 msg << *pos << "\n";
0611 }
0612 msg << "</MemoryService>\n";
0613 temporarilyCloseXML();
0614 }
0615 }
0616
0617 void JobReport::reportMessageInfo(std::map<std::string, double> const& messageData) {
0618 if (impl_->ost_) {
0619 std::lock_guard<std::mutex> lock(write_mutex);
0620 std::ostream& msg = *(impl_->ost_);
0621 msg << "<MessageSummary>\n";
0622 typedef std::map<std::string, double>::const_iterator const_iterator;
0623 for (const_iterator pos = messageData.begin(), posEnd = messageData.end(); pos != posEnd; ++pos) {
0624 msg << " <" << pos->first << " Value=\"" << pos->second << "\" />"
0625 << "\n";
0626 }
0627 msg << "</MessageSummary>\n";
0628 temporarilyCloseXML();
0629 }
0630 }
0631
0632 void JobReport::reportReadBranches() {
0633 bool expected = false;
0634 if (not impl_->printedReadBranches_.compare_exchange_strong(expected, true))
0635 return;
0636 if (impl_->ost_) {
0637 std::lock_guard<std::mutex> lock(write_mutex);
0638 std::ostream& ost = *(impl_->ost_);
0639 ost << "<ReadBranches>\n";
0640 tinyxml2::XMLDocument doc;
0641 tinyxml2::XMLPrinter printer;
0642 for (auto const& iBranch : impl_->readBranches_) {
0643 tinyxml2::XMLElement* branch = doc.NewElement("Branch");
0644 branch->SetAttribute("Name", iBranch.first.c_str());
0645 branch->SetAttribute("ReadCount", int64_t(iBranch.second));
0646 branch->Accept(&printer);
0647 ost << printer.CStr();
0648 printer.ClearBuffer();
0649 }
0650 for (auto const& iBranch : impl_->readBranchesSecFile_) {
0651 tinyxml2::XMLElement* branch = doc.NewElement("Branch");
0652 branch->SetAttribute("Name", iBranch.first.c_str());
0653 branch->SetAttribute("ReadCount", int64_t(iBranch.second));
0654 branch->Accept(&printer);
0655 ost << printer.CStr();
0656 printer.ClearBuffer();
0657 }
0658 ost << "</ReadBranches>\n";
0659 if (!impl_->readBranchesSecSource_.empty()) {
0660 ost << "<SecondarySourceReadBranches>\n";
0661 for (auto const& iBranch : impl_->readBranchesSecSource_) {
0662 tinyxml2::XMLElement* branch = doc.NewElement("Branch");
0663 branch->SetAttribute("Name", iBranch.first.c_str());
0664 branch->SetAttribute("ReadCount", int64_t(iBranch.second.value().load()));
0665 branch->Accept(&printer);
0666 ost << printer.CStr();
0667 printer.ClearBuffer();
0668 }
0669 ost << "</SecondarySourceReadBranches>\n";
0670 }
0671 temporarilyCloseXML();
0672 }
0673 }
0674
0675 void JobReport::reportReadBranch(InputType inputType, std::string const& branchName) {
0676 if (inputType == InputType::Primary) {
0677
0678 std::set<std::string> const& clonedBranches =
0679 impl_->inputFiles_.at(impl_->lastOpenedPrimaryInputFile_).fastClonedBranches;
0680 if (clonedBranches.find(branchName) == clonedBranches.end()) {
0681 ++impl_->readBranches_[branchName];
0682 }
0683 } else if (inputType == InputType::SecondaryFile) {
0684 ++impl_->readBranchesSecFile_[branchName];
0685 } else if (inputType == InputType::SecondarySource) {
0686 ++impl_->readBranchesSecSource_[branchName].value();
0687 }
0688 }
0689
0690 void JobReport::reportFastClonedBranches(std::set<std::string> const& fastClonedBranches, long long nEvents) {
0691 std::set<std::string>& clonedBranches =
0692 impl_->inputFiles_.at(impl_->lastOpenedPrimaryInputFile_).fastClonedBranches;
0693 for (std::set<std::string>::const_iterator it = fastClonedBranches.begin(), itEnd = fastClonedBranches.end();
0694 it != itEnd;
0695 ++it) {
0696 if (clonedBranches.insert(*it).second) {
0697 impl_->readBranches_[*it] += nEvents;
0698 }
0699 }
0700 }
0701
0702 void JobReport::reportRandomStateFile(std::string const& name) {
0703 tinyxml2::XMLDocument doc;
0704 if (impl_->ost_) {
0705 std::ostream& msg = *(impl_->ost_);
0706 {
0707 std::lock_guard<std::mutex> lock(write_mutex);
0708 msg << "<RandomServiceStateFile>\n"
0709 << doc.NewText(name.c_str())->Value() << "\n"
0710 << "</RandomServiceStateFile>\n";
0711 temporarilyCloseXML();
0712 }
0713 }
0714 }
0715
0716 void JobReport::reportPerformanceSummary(std::string const& metricClass,
0717 std::map<std::string, std::string> const& metrics) {
0718 if (impl_->ost_) {
0719 std::ostream& msg = *(impl_->ost_);
0720 msg << "<PerformanceReport>\n"
0721 << " <PerformanceSummary Metric=\"" << metricClass << "\">\n";
0722
0723 typedef std::map<std::string, std::string>::const_iterator const_iterator;
0724 for (const_iterator iter = metrics.begin(), iterEnd = metrics.end(); iter != iterEnd; ++iter) {
0725 msg << " <Metric Name=\"" << iter->first << "\" "
0726 << "Value=\"" << iter->second << "\"/>\n";
0727 }
0728
0729 msg << " </PerformanceSummary>\n"
0730 << "</PerformanceReport>\n";
0731 temporarilyCloseXML();
0732 }
0733 }
0734
0735 void JobReport::reportPerformanceForModule(std::string const& metricClass,
0736 std::string const& moduleName,
0737 std::map<std::string, std::string> const& metrics) {
0738 if (impl_->ost_) {
0739 std::ostream& msg = *(impl_->ost_);
0740 msg << "<PerformanceReport>\n"
0741 << " <PerformanceModule Metric=\"" << metricClass << "\" "
0742 << " Module=\"" << moduleName << "\" >\n";
0743
0744 typedef std::map<std::string, std::string>::const_iterator const_iterator;
0745 for (const_iterator iter = metrics.begin(), iterEnd = metrics.end(); iter != iterEnd; ++iter) {
0746 msg << " <Metric Name=\"" << iter->first << "\" "
0747 << "Value=\"" << iter->second << "\"/>\n";
0748 }
0749
0750 msg << " </PerformanceModule>\n"
0751 << "</PerformanceReport>\n";
0752 temporarilyCloseXML();
0753 }
0754 }
0755
0756 std::string JobReport::dumpFiles(void) {
0757 std::ostringstream msg;
0758
0759 tinyxml2::XMLDocument doc;
0760 for (auto const& f : impl_->outputFiles_) {
0761 msg << "\n<File>";
0762 msg << f;
0763
0764 msg << "\n<LumiSections>";
0765 msg << "\n<Inputs>";
0766 typedef std::vector<JobReport::Token>::iterator iterator;
0767 for (auto const& iInput : f.contributingInputs) {
0768 auto const& inpFile = impl_->inputFiles_[iInput];
0769 msg << "\n<Input>";
0770 msg << "\n <LFN>" << doc.NewText(inpFile.logicalFileName.c_str())->Value() << "</LFN>";
0771 msg << "\n <PFN>" << doc.NewText(inpFile.physicalFileName.c_str())->Value() << "</PFN>";
0772 msg << "\n <FastCopying>" << findOrDefault(f.fastCopyingInputs, inpFile.physicalFileName) << "</FastCopying>";
0773 msg << "\n</Input>";
0774 doc.DeleteChildren();
0775 }
0776 msg << "\n</Inputs>";
0777 msg << "\n</File>";
0778 }
0779 return msg.str();
0780 }
0781
0782 }