File indexing completed on 2024-04-06 12:12:44
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 JobReport::Token JobReport::inputFileOpened(std::string const& physicalFileName,
0355 std::string const& logicalFileName,
0356 std::string const& catalog,
0357 std::string const& inputType,
0358 std::string const& inputSourceClassName,
0359 std::string const& moduleLabel,
0360 std::string const& guid,
0361 std::vector<std::string> const& branchNames) {
0362 InputType theInputType = InputType::Primary;
0363 InputFile* newFile = nullptr;
0364 JobReport::Token newToken = 0;
0365
0366 if (inputType == "mixingFiles") {
0367 theInputType = InputType::SecondarySource;
0368 auto itr = impl_->inputFilesSecSource_.push_back(InputFile());
0369 newFile = &(*itr);
0370 newToken = itr - impl_->inputFilesSecSource_.begin();
0371 } else {
0372 if (inputType == "secondaryFiles") {
0373 theInputType = InputType::SecondaryFile;
0374 }
0375 impl_->inputFiles_.emplace_back();
0376 newFile = &impl_->inputFiles_.back();
0377 newToken = impl_->inputFiles_.size() - 1;
0378 }
0379
0380 if (theInputType == InputType::Primary) {
0381 impl_->lastOpenedPrimaryInputFile_ = impl_->inputFiles_.size() - 1;
0382 }
0383 newFile->logicalFileName = logicalFileName;
0384 newFile->physicalFileName = physicalFileName;
0385 newFile->catalog = catalog;
0386 newFile->inputType = inputType;
0387 newFile->inputSourceClassName = inputSourceClassName;
0388 newFile->moduleLabel = moduleLabel;
0389 newFile->guid = guid;
0390 newFile->numEventsRead = 0;
0391 newFile->branchNames = branchNames;
0392 newFile->fileHasBeenClosed = false;
0393
0394
0395
0396 impl_->insertInputForOutputs(theInputType, newToken);
0397 return newToken;
0398 }
0399
0400 void JobReport::eventReadFromFile(InputType inputType, JobReport::Token fileToken) {
0401 JobReport::InputFile& f = impl_->getInputFileForToken(inputType, fileToken);
0402 ++f.numEventsRead;
0403 }
0404
0405 void JobReport::reportDataType(Token fileToken, std::string const& dataType) {
0406 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0407 f.dataType = dataType;
0408 }
0409
0410 void JobReport::inputFileClosed(InputType inputType, JobReport::Token fileToken) {
0411 JobReport::InputFile& f = impl_->getInputFileForToken(inputType, fileToken);
0412 f.fileHasBeenClosed = true;
0413 std::lock_guard<std::mutex> lock(write_mutex);
0414 if (inputType == InputType::Primary) {
0415 impl_->writeInputFile(f);
0416 } else {
0417 impl_->writeInputFile(f);
0418 }
0419 temporarilyCloseXML();
0420 }
0421
0422 JobReport::Token JobReport::outputFileOpened(std::string const& physicalFileName,
0423 std::string const& logicalFileName,
0424 std::string const& catalog,
0425 std::string const& outputModuleClassName,
0426 std::string const& moduleLabel,
0427 std::string const& guid,
0428 std::string const& dataType,
0429 std::string const& branchHash,
0430 std::vector<std::string> const& branchNames) {
0431 auto itr = impl_->outputFiles_.emplace_back();
0432 JobReport::OutputFile& r = *itr;
0433
0434 r.logicalFileName = logicalFileName;
0435 r.physicalFileName = physicalFileName;
0436 r.catalog = catalog;
0437 r.outputModuleClassName = outputModuleClassName;
0438 r.moduleLabel = moduleLabel;
0439 r.guid = guid;
0440 r.dataType = dataType;
0441 r.branchHash = branchHash;
0442 r.numEventsWritten = 0;
0443 r.branchNames = branchNames;
0444 r.fileHasBeenClosed = false;
0445
0446
0447
0448 for (std::vector<Token>::size_type i = 0, iEnd = impl_->inputFiles_.size(); i < iEnd; ++i) {
0449 if (!impl_->inputFiles_[i].fileHasBeenClosed) {
0450 r.contributingInputs.push_back(i);
0451 }
0452 }
0453 for (oneapi::tbb::concurrent_vector<Token>::size_type i = 0, iEnd = impl_->inputFilesSecSource_.size(); i < iEnd;
0454 ++i) {
0455 if (!impl_->inputFilesSecSource_[i].fileHasBeenClosed) {
0456 r.contributingInputsSecSource.push_back(i);
0457 }
0458 }
0459 return itr - impl_->outputFiles_.begin();
0460 }
0461
0462 void JobReport::eventWrittenToFile(JobReport::Token fileToken, RunNumber_t , EventNumber_t) {
0463 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0464 ++f.numEventsWritten;
0465 }
0466
0467 void JobReport::outputFileClosed(JobReport::Token fileToken) {
0468 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0469 f.fileHasBeenClosed = true;
0470 std::lock_guard<std::mutex> lock(write_mutex);
0471 impl_->writeOutputFile(f);
0472 temporarilyCloseXML();
0473 }
0474
0475 void JobReport::reportSkippedEvent(RunNumber_t run, EventNumber_t event) {
0476 if (impl_->ost_) {
0477 std::ostream& msg = *(impl_->ost_);
0478 {
0479 std::lock_guard<std::mutex> lock(write_mutex);
0480 msg << "<SkippedEvent Run=\"" << run << "\"";
0481 msg << " Event=\"" << event << "\" />\n";
0482 temporarilyCloseXML();
0483 }
0484 }
0485 }
0486
0487 void JobReport::reportFastCopyingStatus(JobReport::Token fileToken,
0488 std::string const& inputFileName,
0489 bool fastCopying) {
0490 JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
0491 f.fastCopyingInputs.insert(std::make_pair(inputFileName, fastCopying));
0492 }
0493
0494 void JobReport::reportLumiSection(JobReport::Token token,
0495 unsigned int run,
0496 unsigned int lumiSectId,
0497 unsigned long nEvents) {
0498 impl_->associateLumiSection(token, run, lumiSectId, nEvents);
0499 }
0500
0501 void JobReport::reportInputLumiSection(unsigned int run, unsigned int lumiSectId) {
0502 impl_->associateInputLumiSection(run, lumiSectId);
0503 }
0504
0505 void JobReport::reportRunNumber(JobReport::Token token, unsigned int run) { impl_->associateRun(token, run); }
0506
0507 void JobReport::reportInputRunNumber(unsigned int run) { impl_->associateInputRun(run); }
0508
0509 void JobReport::reportAnalysisFile(std::string const& fileName, std::map<std::string, std::string> const& fileData) {
0510 tinyxml2::XMLDocument doc;
0511 if (impl_->ost_) {
0512 std::ostream& msg = *(impl_->ost_);
0513 {
0514 std::lock_guard<std::mutex> lock(write_mutex);
0515 msg << "<AnalysisFile>\n"
0516 << " <FileName>" << doc.NewText(fileName.c_str())->Value() << "</FileName>\n";
0517
0518 typedef std::map<std::string, std::string>::const_iterator const_iterator;
0519 for (const_iterator pos = fileData.begin(), posEnd = fileData.end(); pos != posEnd; ++pos) {
0520 msg << " <" << pos->first << " Value=\"" << pos->second << "\" />"
0521 << "\n";
0522 }
0523 msg << "</AnalysisFile>\n";
0524 temporarilyCloseXML();
0525 }
0526 }
0527 }
0528
0529 void JobReport::reportError(std::string const& shortDesc, std::string const& longDesc, int const& exitCode) {
0530 if (impl_->ost_) {
0531 {
0532 std::lock_guard<std::mutex> lock(write_mutex);
0533 errorLogged_ = true;
0534 std::ostream& msg = *(impl_->ost_);
0535 msg << "<FrameworkError ExitStatus=\"" << exitCode << "\" Type=\"" << shortDesc << "\" >\n";
0536 msg << "<![CDATA[\n" << longDesc << "\n]]>\n";
0537 msg << "</FrameworkError>\n";
0538 temporarilyCloseXML();
0539 }
0540 }
0541 }
0542
0543 void JobReport::reportShutdownSignal() {
0544 if (impl_->ost_) {
0545 {
0546 std::lock_guard<std::mutex> lock(write_mutex);
0547 std::ostream& msg = *(impl_->ost_);
0548 msg << "<ShutdownSignal/>\n";
0549 temporarilyCloseXML();
0550 }
0551 }
0552 }
0553
0554 void JobReport::reportSkippedFile(std::string const& pfn, std::string const& lfn) {
0555 if (impl_->ost_) {
0556 std::ostream& msg = *(impl_->ost_);
0557 tinyxml2::XMLDocument doc;
0558 tinyxml2::XMLPrinter printer;
0559 tinyxml2::XMLElement* skipped = doc.NewElement("SkippedFile");
0560 skipped->SetAttribute("Pfn", pfn.c_str());
0561 skipped->SetAttribute("Lfn", lfn.c_str());
0562 {
0563 std::lock_guard<std::mutex> lock(write_mutex);
0564 skipped->Accept(&printer);
0565 msg << printer.CStr();
0566 temporarilyCloseXML();
0567 }
0568 }
0569 }
0570
0571 void JobReport::reportFallbackAttempt(std::string const& pfn, std::string const& lfn, std::string const& err) {
0572 if (impl_->ost_) {
0573 std::ostream& msg = *(impl_->ost_);
0574 tinyxml2::XMLDocument doc;
0575 tinyxml2::XMLPrinter printer;
0576 tinyxml2::XMLElement* fallback = doc.NewElement("FallbackAttempt");
0577 fallback->SetAttribute("Pfn", pfn.c_str());
0578 fallback->SetAttribute("Lfn", lfn.c_str());
0579 {
0580 std::lock_guard<std::mutex> lock(write_mutex);
0581 fallback->Accept(&printer);
0582 msg << printer.CStr();
0583 msg << "<![CDATA[\n" << err << "\n]]>\n";
0584 temporarilyCloseXML();
0585 }
0586 }
0587 }
0588
0589 void JobReport::reportMemoryInfo(std::vector<std::string> const& memoryData) {
0590 if (impl_->ost_) {
0591 std::lock_guard<std::mutex> lock(write_mutex);
0592 std::ostream& msg = *(impl_->ost_);
0593 msg << "<MemoryService>\n";
0594
0595 typedef std::vector<std::string>::const_iterator const_iterator;
0596 for (const_iterator pos = memoryData.begin(), posEnd = memoryData.end(); pos != posEnd; ++pos) {
0597 msg << *pos << "\n";
0598 }
0599 msg << "</MemoryService>\n";
0600 temporarilyCloseXML();
0601 }
0602 }
0603
0604 void JobReport::reportMessageInfo(std::map<std::string, double> const& messageData) {
0605 if (impl_->ost_) {
0606 std::lock_guard<std::mutex> lock(write_mutex);
0607 std::ostream& msg = *(impl_->ost_);
0608 msg << "<MessageSummary>\n";
0609 typedef std::map<std::string, double>::const_iterator const_iterator;
0610 for (const_iterator pos = messageData.begin(), posEnd = messageData.end(); pos != posEnd; ++pos) {
0611 msg << " <" << pos->first << " Value=\"" << pos->second << "\" />"
0612 << "\n";
0613 }
0614 msg << "</MessageSummary>\n";
0615 temporarilyCloseXML();
0616 }
0617 }
0618
0619 void JobReport::reportReadBranches() {
0620 bool expected = false;
0621 if (not impl_->printedReadBranches_.compare_exchange_strong(expected, true))
0622 return;
0623 if (impl_->ost_) {
0624 std::lock_guard<std::mutex> lock(write_mutex);
0625 std::ostream& ost = *(impl_->ost_);
0626 ost << "<ReadBranches>\n";
0627 tinyxml2::XMLDocument doc;
0628 tinyxml2::XMLPrinter printer;
0629 for (auto const& iBranch : impl_->readBranches_) {
0630 tinyxml2::XMLElement* branch = doc.NewElement("Branch");
0631 branch->SetAttribute("Name", iBranch.first.c_str());
0632 branch->SetAttribute("ReadCount", int64_t(iBranch.second));
0633 branch->Accept(&printer);
0634 ost << printer.CStr();
0635 printer.ClearBuffer();
0636 }
0637 for (auto const& iBranch : impl_->readBranchesSecFile_) {
0638 tinyxml2::XMLElement* branch = doc.NewElement("Branch");
0639 branch->SetAttribute("Name", iBranch.first.c_str());
0640 branch->SetAttribute("ReadCount", int64_t(iBranch.second));
0641 branch->Accept(&printer);
0642 ost << printer.CStr();
0643 printer.ClearBuffer();
0644 }
0645 ost << "</ReadBranches>\n";
0646 if (!impl_->readBranchesSecSource_.empty()) {
0647 ost << "<SecondarySourceReadBranches>\n";
0648 for (auto const& iBranch : impl_->readBranchesSecSource_) {
0649 tinyxml2::XMLElement* branch = doc.NewElement("Branch");
0650 branch->SetAttribute("Name", iBranch.first.c_str());
0651 branch->SetAttribute("ReadCount", int64_t(iBranch.second.value().load()));
0652 branch->Accept(&printer);
0653 ost << printer.CStr();
0654 printer.ClearBuffer();
0655 }
0656 ost << "</SecondarySourceReadBranches>\n";
0657 }
0658 temporarilyCloseXML();
0659 }
0660 }
0661
0662 void JobReport::reportReadBranch(InputType inputType, std::string const& branchName) {
0663 if (inputType == InputType::Primary) {
0664
0665 std::set<std::string> const& clonedBranches =
0666 impl_->inputFiles_.at(impl_->lastOpenedPrimaryInputFile_).fastClonedBranches;
0667 if (clonedBranches.find(branchName) == clonedBranches.end()) {
0668 ++impl_->readBranches_[branchName];
0669 }
0670 } else if (inputType == InputType::SecondaryFile) {
0671 ++impl_->readBranchesSecFile_[branchName];
0672 } else if (inputType == InputType::SecondarySource) {
0673 ++impl_->readBranchesSecSource_[branchName].value();
0674 }
0675 }
0676
0677 void JobReport::reportFastClonedBranches(std::set<std::string> const& fastClonedBranches, long long nEvents) {
0678 std::set<std::string>& clonedBranches =
0679 impl_->inputFiles_.at(impl_->lastOpenedPrimaryInputFile_).fastClonedBranches;
0680 for (std::set<std::string>::const_iterator it = fastClonedBranches.begin(), itEnd = fastClonedBranches.end();
0681 it != itEnd;
0682 ++it) {
0683 if (clonedBranches.insert(*it).second) {
0684 impl_->readBranches_[*it] += nEvents;
0685 }
0686 }
0687 }
0688
0689 void JobReport::reportRandomStateFile(std::string const& name) {
0690 tinyxml2::XMLDocument doc;
0691 if (impl_->ost_) {
0692 std::ostream& msg = *(impl_->ost_);
0693 {
0694 std::lock_guard<std::mutex> lock(write_mutex);
0695 msg << "<RandomServiceStateFile>\n"
0696 << doc.NewText(name.c_str())->Value() << "\n"
0697 << "</RandomServiceStateFile>\n";
0698 temporarilyCloseXML();
0699 }
0700 }
0701 }
0702
0703 void JobReport::reportPerformanceSummary(std::string const& metricClass,
0704 std::map<std::string, std::string> const& metrics) {
0705 if (impl_->ost_) {
0706 std::ostream& msg = *(impl_->ost_);
0707 msg << "<PerformanceReport>\n"
0708 << " <PerformanceSummary Metric=\"" << metricClass << "\">\n";
0709
0710 typedef std::map<std::string, std::string>::const_iterator const_iterator;
0711 for (const_iterator iter = metrics.begin(), iterEnd = metrics.end(); iter != iterEnd; ++iter) {
0712 msg << " <Metric Name=\"" << iter->first << "\" "
0713 << "Value=\"" << iter->second << "\"/>\n";
0714 }
0715
0716 msg << " </PerformanceSummary>\n"
0717 << "</PerformanceReport>\n";
0718 temporarilyCloseXML();
0719 }
0720 }
0721
0722 void JobReport::reportPerformanceForModule(std::string const& metricClass,
0723 std::string const& moduleName,
0724 std::map<std::string, std::string> const& metrics) {
0725 if (impl_->ost_) {
0726 std::ostream& msg = *(impl_->ost_);
0727 msg << "<PerformanceReport>\n"
0728 << " <PerformanceModule Metric=\"" << metricClass << "\" "
0729 << " Module=\"" << moduleName << "\" >\n";
0730
0731 typedef std::map<std::string, std::string>::const_iterator const_iterator;
0732 for (const_iterator iter = metrics.begin(), iterEnd = metrics.end(); iter != iterEnd; ++iter) {
0733 msg << " <Metric Name=\"" << iter->first << "\" "
0734 << "Value=\"" << iter->second << "\"/>\n";
0735 }
0736
0737 msg << " </PerformanceModule>\n"
0738 << "</PerformanceReport>\n";
0739 temporarilyCloseXML();
0740 }
0741 }
0742
0743 std::string JobReport::dumpFiles(void) {
0744 std::ostringstream msg;
0745
0746 tinyxml2::XMLDocument doc;
0747 for (auto const& f : impl_->outputFiles_) {
0748 msg << "\n<File>";
0749 msg << f;
0750
0751 msg << "\n<LumiSections>";
0752 msg << "\n<Inputs>";
0753 typedef std::vector<JobReport::Token>::iterator iterator;
0754 for (auto const& iInput : f.contributingInputs) {
0755 auto const& inpFile = impl_->inputFiles_[iInput];
0756 msg << "\n<Input>";
0757 msg << "\n <LFN>" << doc.NewText(inpFile.logicalFileName.c_str())->Value() << "</LFN>";
0758 msg << "\n <PFN>" << doc.NewText(inpFile.physicalFileName.c_str())->Value() << "</PFN>";
0759 msg << "\n <FastCopying>" << findOrDefault(f.fastCopyingInputs, inpFile.physicalFileName) << "</FastCopying>";
0760 msg << "\n</Input>";
0761 doc.DeleteChildren();
0762 }
0763 msg << "\n</Inputs>";
0764 msg << "\n</File>";
0765 }
0766 return msg.str();
0767 }
0768
0769 }