2 #include "TRACE/tracemf.h"
3 #include "artdaq/DAQdata/Globals.hh"
4 #define TRACE_NAME (app_name + "_RootDAQOut").c_str()
6 #include "artdaq/ArtModules/ArtdaqSharedMemoryServiceInterface.h"
7 #include "artdaq/ArtModules/RootDAQOutput-s124/RootDAQOutFile.h"
9 #include "art/Framework/Core/OutputModule.h"
10 #include "art/Framework/Core/RPManager.h"
11 #include "art/Framework/Core/ResultsProducer.h"
12 #include "art/Framework/IO/ClosingCriteria.h"
13 #include "art/Framework/IO/FileStatsCollector.h"
14 #include "art/Framework/IO/PostCloseFileRenamer.h"
15 #include "art/Framework/IO/detail/SafeFileNameConfig.h"
16 #include "art/Framework/IO/detail/logFileAction.h"
17 #include "art/Framework/IO/detail/validateFileNamePattern.h"
18 #include "art/Framework/Principal/EventPrincipal.h"
19 #include "art/Framework/Principal/ResultsPrincipal.h"
20 #include "art/Framework/Principal/RunPrincipal.h"
21 #include "art/Framework/Principal/SubRunPrincipal.h"
22 #include "art/Utilities/Globals.h"
23 #include "art/Utilities/parent_path.h"
24 #include "art/Utilities/unique_filename.h"
25 #include "art_root_io/DropMetaData.h"
26 #include "art_root_io/FastCloningEnabled.h"
27 #include "art_root_io/RootFileBlock.h"
28 #include "art_root_io/detail/rootOutputConfigurationTools.h"
29 #include "art_root_io/setup.h"
30 #include "canvas/Persistency/Provenance/ProductTables.h"
31 #include "canvas/Utilities/Exception.h"
32 #include "fhiclcpp/ParameterSet.h"
33 #include "fhiclcpp/types/Atom.h"
34 #include "fhiclcpp/types/ConfigurationTable.h"
35 #include "fhiclcpp/types/OptionalAtom.h"
36 #include "fhiclcpp/types/OptionalSequence.h"
37 #include "fhiclcpp/types/Table.h"
38 #include "fhiclcpp/types/TableFragment.h"
39 #include "messagefacility/MessageLogger/MessageLogger.h"
48 using namespace hep::concurrency;
51 string const dev_null{
"/dev/null"};
53 bool maxCriterionSpecified(art::ClosingCriteria
const& cc)
55 auto fp = mem_fn(&art::ClosingCriteria::fileProperties);
56 return (fp(cc).nEvents() !=
57 art::ClosingCriteria::Defaults::unsigned_max()) ||
59 art::ClosingCriteria::Defaults::unsigned_max()) ||
60 (fp(cc).nRuns() != art::ClosingCriteria::Defaults::unsigned_max()) ||
61 (fp(cc).size() != art::ClosingCriteria::Defaults::size_max()) ||
62 (fp(cc).age().count() !=
63 art::ClosingCriteria::Defaults::seconds_max());
66 auto shouldFastClone(
bool const fastCloningSet,
67 bool const fastCloning,
68 bool const wantAllEvents,
69 art::ClosingCriteria
const& cc)
71 art::FastCloningEnabled enabled;
72 if (fastCloningSet and not fastCloning)
75 "RootDAQOut configuration explicitly disables fast cloning.");
79 if (not wantAllEvents)
82 "Event-selection has been specified in the RootDAQOut configuration.");
84 if (fastCloning && maxCriterionSpecified(cc) &&
85 cc.granularity() < art::Granularity::InputFile)
88 "File-switching has been requested at event, subrun, or "
100 static constexpr
char const* default_tmpDir{
"<parent-path-of-filename>"};
104 using Name = fhicl::Name;
105 using Comment = fhicl::Comment;
107 using Atom = fhicl::Atom<T>;
109 using OptionalAtom = fhicl::OptionalAtom<T>;
110 fhicl::TableFragment<OutputModule::Config> omConfig;
111 Atom<string> catalog{Name(
"catalog"),
""};
112 OptionalAtom<bool> dropAllEvents{Name(
"dropAllEvents")};
113 Atom<bool> dropAllSubRuns{Name(
"dropAllSubRuns"),
false};
114 OptionalAtom<bool> fastCloning{Name(
"fastCloning")};
115 Atom<string> tmpDir{Name(
"tmpDir"), default_tmpDir};
116 Atom<int> compressionLevel{Name(
"compressionLevel"), 7};
117 Atom<unsigned> freePercent{Name(
"freePercent"), 0};
118 Atom<unsigned> freeMB{Name(
"freeMB"), 0};
119 Atom<int64_t> saveMemoryObjectThreshold{Name(
"saveMemoryObjectThreshold"),
121 Atom<int64_t> treeMaxVirtualSize{Name(
"treeMaxVirtualSize"), -1};
122 Atom<int> splitLevel{Name(
"splitLevel"), 1};
123 Atom<int> basketSize{Name(
"basketSize"), 16384};
124 Atom<bool> dropMetaDataForDroppedData{Name(
"dropMetaDataForDroppedData"),
126 Atom<string> dropMetaData{Name(
"dropMetaData"),
"NONE"};
127 Atom<bool> writeParameterSets{Name(
"writeParameterSets"),
true};
128 fhicl::Table<ClosingCriteria::Config> fileProperties{
129 Name(
"fileProperties"),
130 Comment(
"The 'fileProperties' parameter is specified to enable "
131 "output-file switching.")};
132 fhicl::TableFragment<detail::SafeFileNameConfig> safeFileName;
133 Atom<int> firstLoggerRank{Name(
"firstLoggerRank"), -1};
137 fhicl::Atom<string> appName{fhicl::Name(
"appName")};
138 fhicl::Atom<string> newString{fhicl::Name(
"newString")};
142 fhicl::Atom<string> targetString{fhicl::Name(
"targetString")};
143 fhicl::Sequence<fhicl::Table<NewSubStringForApp>> replacementList{fhicl::Name(
"replacementList")};
145 fhicl::OptionalSequence<fhicl::Table<FileNameSubstitution>> fileNameSubstitutions{Name(
"fileNameSubstitutions")};
154 using namespace fhicl::detail;
155 ParameterBase* adjustFilename{
156 const_cast<fhicl::Atom<string>*
>(&omConfig().fileName)};
157 adjustFilename->set_par_style(fhicl::par_style::REQUIRED);
165 set<string> keys{OutputModule::Config::KeysToIgnore::get()};
166 keys.insert(
"results");
172 using Parameters = fhicl::WrappedTable<Config, Config::KeysToIgnore>;
181 void postSelectProducts()
override;
182 void beginJob()
override;
183 void endJob()
override;
184 void beginRun(RunPrincipal
const&)
override;
185 void endRun(RunPrincipal
const&)
override;
186 void beginSubRun(SubRunPrincipal
const&)
override;
187 void endSubRun(SubRunPrincipal
const&)
override;
188 void event(EventPrincipal
const&)
override;
192 string fileNameAtOpen()
const;
193 string fileNameAtClose(
string const& currentFileName);
194 string const& lastClosedFileName()
const override;
195 Granularity fileGranularity()
const override;
196 void openFile(FileBlock
const&)
override;
197 void respondToOpenInputFile(FileBlock
const&)
override;
198 void readResults(ResultsPrincipal
const& resp)
override;
199 void respondToCloseInputFile(FileBlock
const&)
override;
200 void incrementInputFileNumber()
override;
201 void write(EventPrincipal&)
override;
202 void writeSubRun(SubRunPrincipal&)
override;
203 void writeRun(RunPrincipal&)
override;
204 void setSubRunAuxiliaryRangeSetID(RangeSet
const&)
override;
205 void setRunAuxiliaryRangeSetID(RangeSet
const&)
override;
206 bool isFileOpen()
const override;
207 void setFileStatus(OutputFileStatus)
override;
208 bool requestsToCloseFile()
const override;
209 void startEndFile()
override;
210 void writeFileFormatVersion()
override;
211 void writeFileIndex()
override;
212 void writeProcessConfigurationRegistry()
override;
213 void writeProcessHistoryRegistry()
override;
214 void writeParameterSetRegistry()
override;
215 void writeProductDescriptionRegistry()
override;
216 void writeParentageRegistry()
override;
217 void doWriteFileCatalogMetadata(
218 FileCatalogMetadata::collection_type
const& md,
219 FileCatalogMetadata::collection_type
const& ssmd)
override;
220 void writeProductDependencies()
override;
221 void finishEndFile()
override;
222 void doRegisterProducts(ProductDescriptions& productsToProduce,
223 ModuleDescription
const& md)
override;
224 std::string modifyFilePattern(std::string
const& ,
Config const& );
230 mutable std::recursive_mutex mutex_;
231 string const catalog_;
232 bool dropAllEvents_{
false};
233 bool dropAllSubRuns_;
234 string const moduleLabel_;
235 int inputFileCount_{};
236 unique_ptr<RootDAQOutFile> rootOutputFile_{
nullptr};
237 FileStatsCollector fstats_;
238 PostCloseFileRenamer fRenamer_;
239 string const filePattern_;
241 string lastClosedFileName_{};
242 int const compressionLevel_;
243 unsigned freePercent_;
245 int64_t
const saveMemoryObjectThreshold_;
246 int64_t
const treeMaxVirtualSize_;
247 int const splitLevel_;
248 int const basketSize_;
249 DropMetaData dropMetaData_;
250 bool dropMetaDataForDroppedData_;
251 FastCloningEnabled fastCloningEnabled_{};
254 bool writeParameterSets_;
255 ClosingCriteria fileProperties_;
256 ProductDescriptions productsToProduce_{};
257 ProductTables producedResultsProducts_{ProductTables::invalid()};
261 RootDAQOut::~RootDAQOut() =
default;
263 RootDAQOut::RootDAQOut(Parameters
const& config)
266 , catalog_{config().catalog()}
267 , dropAllSubRuns_{config().dropAllSubRuns()}
268 , moduleLabel_{config.get_PSet().get<
string>(
"module_label")}
269 , fstats_{moduleLabel_, processName()}
271 , filePattern_{modifyFilePattern(config().omConfig().fileName(), config())}
272 , tmpDir_{config().tmpDir() == default_tmpDir ? parent_path(filePattern_) : config().tmpDir()}
273 , compressionLevel_{config().compressionLevel()}
274 , freePercent_{config().freePercent()}
275 , freeMB_{config().freeMB()}
276 , saveMemoryObjectThreshold_{config().saveMemoryObjectThreshold()}
277 , treeMaxVirtualSize_{config().treeMaxVirtualSize()}
278 , splitLevel_{config().splitLevel()}
279 , basketSize_{config().basketSize()}
280 , dropMetaData_{config().dropMetaData()}
281 , dropMetaDataForDroppedData_{config().dropMetaDataForDroppedData()}
282 , writeParameterSets_{config().writeParameterSets()}
283 , fileProperties_{config().fileProperties()}
284 , rpm_{config.get_PSet()}
286 TLOG(TLVL_INFO) <<
"RootDAQOut_module (s124 version) CONSTRUCTOR Start";
287 bool const check_filename = config.get_PSet().has_key(
"fileProperties") and
288 config().safeFileName().checkFileName();
289 detail::validateFileNamePattern(check_filename, filePattern_);
294 bool const dropAllEventsSet{config().dropAllEvents(dropAllEvents_)};
295 dropAllEvents_ = detail::shouldDropEvents(
296 dropAllEventsSet, dropAllEvents_, dropAllSubRuns_);
302 bool fastCloningEnabled{
true};
303 bool const fastCloningSet{config().fastCloning(fastCloningEnabled)};
304 fastCloningEnabled_ = shouldFastClone(
305 fastCloningSet, fastCloningEnabled, wantAllEvents(), fileProperties_);
307 if (
auto const n = Globals::instance()->nschedules(); n > 1)
309 std::ostringstream oss;
310 oss <<
"More than one schedule (" << n <<
") is being used.";
311 fastCloningEnabled_.disable(oss.str());
314 if (!writeParameterSets_)
316 mf::LogWarning(
"PROVENANCE")
317 <<
"Output module " << moduleLabel_
318 <<
" has parameter writeParameterSets set to false.\n"
319 <<
"Parameter set provenance will not be available in subsequent "
321 <<
"Check your experiment's policy on this issue to avoid future "
323 <<
"with analysis reproducibility.\n";
327 void RootDAQOut::openFile(FileBlock
const& fb)
329 std::lock_guard sentry{mutex_};
337 respondToOpenInputFile(fb);
341 void RootDAQOut::postSelectProducts()
343 std::lock_guard sentry{mutex_};
346 rootOutputFile_->selectProducts();
350 void RootDAQOut::respondToOpenInputFile(FileBlock
const& fb)
352 std::lock_guard sentry{mutex_};
358 auto const* rfb =
dynamic_cast<RootFileBlock const*
>(&fb);
359 auto fastCloneThisOne = fastCloningEnabled_;
362 fastCloneThisOne.disable(
"Input source does not read art/ROOT files.");
366 fastCloneThisOne.merge(rfb->fastClonable());
368 rootOutputFile_->beginInputFile(rfb, std::move(fastCloneThisOne));
369 fstats_.recordInputFile(fb.fileName());
372 void RootDAQOut::readResults(ResultsPrincipal
const& resp)
374 std::lock_guard sentry{mutex_};
375 rpm_.for_each_RPWorker(
376 [&resp](RPWorker& w) { w.rp().doReadResults(resp); });
379 void RootDAQOut::respondToCloseInputFile(FileBlock
const& fb)
381 std::lock_guard sentry{mutex_};
384 rootOutputFile_->respondToCloseInputFile(fb);
388 void RootDAQOut::write(EventPrincipal& ep)
390 std::lock_guard sentry{mutex_};
395 if (hasNewlyDroppedBranch()[InEvent])
397 ep.addToProcessHistory();
398 ep.refreshProcessHistoryID();
400 rootOutputFile_->writeOne(ep);
401 fstats_.recordEvent(ep.eventID());
404 void RootDAQOut::setSubRunAuxiliaryRangeSetID(RangeSet
const& rs)
406 std::lock_guard sentry{mutex_};
407 rootOutputFile_->setSubRunAuxiliaryRangeSetID(rs);
410 void RootDAQOut::writeSubRun(SubRunPrincipal& sr)
412 std::lock_guard sentry{mutex_};
417 if (hasNewlyDroppedBranch()[InSubRun])
419 sr.addToProcessHistory();
421 rootOutputFile_->writeSubRun(sr);
422 fstats_.recordSubRun(sr.subRunID());
425 void RootDAQOut::setRunAuxiliaryRangeSetID(RangeSet
const& rs)
427 std::lock_guard sentry{mutex_};
428 rootOutputFile_->setRunAuxiliaryRangeSetID(rs);
431 void RootDAQOut::writeRun(RunPrincipal& rp)
433 std::lock_guard sentry{mutex_};
434 if (hasNewlyDroppedBranch()[InRun])
436 rp.addToProcessHistory();
438 rootOutputFile_->writeRun(rp);
439 fstats_.recordRun(rp.runID());
442 void RootDAQOut::startEndFile()
444 std::lock_guard sentry{mutex_};
445 auto resp = make_unique<ResultsPrincipal>(
446 ResultsAuxiliary{}, moduleDescription().processConfiguration(),
nullptr);
447 resp->createGroupsForProducedProducts(producedResultsProducts_);
448 resp->enableLookupOfProducedProducts();
449 if (!producedResultsProducts_.descriptions(InResults).empty() ||
450 hasNewlyDroppedBranch()[InResults])
452 resp->addToProcessHistory();
454 rpm_.for_each_RPWorker(
455 [&resp](RPWorker& w) { w.rp().doWriteResults(*resp); });
456 rootOutputFile_->writeResults(*resp);
459 void RootDAQOut::writeFileFormatVersion()
461 std::lock_guard sentry{mutex_};
462 rootOutputFile_->writeFileFormatVersion();
465 void RootDAQOut::writeFileIndex()
467 std::lock_guard sentry{mutex_};
468 rootOutputFile_->writeFileIndex();
471 void RootDAQOut::writeProcessConfigurationRegistry()
473 std::lock_guard sentry{mutex_};
474 rootOutputFile_->writeProcessConfigurationRegistry();
477 void RootDAQOut::writeProcessHistoryRegistry()
479 std::lock_guard sentry{mutex_};
480 rootOutputFile_->writeProcessHistoryRegistry();
483 void RootDAQOut::writeParameterSetRegistry()
485 std::lock_guard sentry{mutex_};
486 if (writeParameterSets_)
488 rootOutputFile_->writeParameterSetRegistry();
492 void RootDAQOut::writeProductDescriptionRegistry()
494 std::lock_guard sentry{mutex_};
495 rootOutputFile_->writeProductDescriptionRegistry();
498 void RootDAQOut::writeParentageRegistry()
500 std::lock_guard sentry{mutex_};
501 rootOutputFile_->writeParentageRegistry();
504 void RootDAQOut::doWriteFileCatalogMetadata(
505 FileCatalogMetadata::collection_type
const& md,
506 FileCatalogMetadata::collection_type
const& ssmd)
508 std::lock_guard sentry{mutex_};
509 rootOutputFile_->writeFileCatalogMetadata(fstats_, md, ssmd);
512 void RootDAQOut::writeProductDependencies()
514 std::lock_guard sentry{mutex_};
515 rootOutputFile_->writeProductDependencies();
518 void RootDAQOut::finishEndFile()
520 std::lock_guard sentry{mutex_};
521 string const currentFileName{rootOutputFile_->currentFileName()};
522 rootOutputFile_->writeTTrees();
523 rootOutputFile_.reset();
524 fstats_.recordFileClose();
525 lastClosedFileName_ = fileNameAtClose(currentFileName);
526 TLOG(TLVL_INFO) << __func__ <<
": Closed output file \"" << lastClosedFileName_ <<
"\"";
527 rpm_.invoke(&ResultsProducer::doClear);
530 void RootDAQOut::doRegisterProducts(ProductDescriptions& producedProducts,
531 ModuleDescription
const& md)
533 std::lock_guard sentry{mutex_};
535 rpm_.for_each_RPWorker([&producedProducts, &md](RPWorker& w) {
536 auto const& params = w.params();
537 w.setModuleDescription(
538 ModuleDescription{params.rpPSetID,
540 md.moduleLabel() +
'#' + params.rpLabel,
541 ModuleThreadingType::legacy,
542 md.processConfiguration()});
543 w.rp().registerProducts(producedProducts, w.moduleDescription());
548 productsToProduce_ = producedProducts;
549 producedResultsProducts_ = ProductTables{productsToProduce_};
552 void RootDAQOut::setFileStatus(OutputFileStatus
const ofs)
554 std::lock_guard sentry{mutex_};
557 rootOutputFile_->setFileStatus(ofs);
561 bool RootDAQOut::isFileOpen()
const
563 std::lock_guard sentry{mutex_};
564 return rootOutputFile_.get() !=
nullptr;
567 void RootDAQOut::incrementInputFileNumber()
569 std::lock_guard sentry{mutex_};
572 rootOutputFile_->incrementInputFileNumber();
576 bool RootDAQOut::requestsToCloseFile()
const
578 std::lock_guard sentry{mutex_};
579 return isFileOpen() ? rootOutputFile_->requestsToCloseFile() :
false;
583 RootDAQOut::fileGranularity()
const
585 std::lock_guard sentry{mutex_};
586 return fileProperties_.granularity();
589 void RootDAQOut::doOpenFile()
591 std::lock_guard sentry{mutex_};
592 if (inputFileCount_ == 0)
594 throw Exception(errors::LogicError)
595 <<
"Attempt to open output file before input file. "
596 <<
"Please report this to the core framework developers.\n";
598 rootOutputFile_ = make_unique<RootDAQOutFile>(
this,
604 saveMemoryObjectThreshold_,
609 dropMetaDataForDroppedData_);
610 fstats_.recordFileOpen();
611 TLOG(TLVL_INFO) << __func__ <<
": Opened output file with pattern \"" << filePattern_ <<
"\"";
615 RootDAQOut::fileNameAtOpen()
const
617 return (filePattern_ == dev_null) ? dev_null : unique_filename(tmpDir_ +
"/RootDAQOut");
621 RootDAQOut::fileNameAtClose(std::string
const& currentFileName)
623 return (filePattern_ == dev_null) ? dev_null : fRenamer_.maybeRenameFile(currentFileName, filePattern_);
627 RootDAQOut::lastClosedFileName()
const
629 std::lock_guard sentry{mutex_};
630 if (lastClosedFileName_.empty())
632 throw Exception(errors::LogicError,
"RootDAQOut::currentFileName(): ")
633 <<
"called before meaningful.\n";
635 return lastClosedFileName_;
638 void RootDAQOut::beginJob()
640 std::lock_guard sentry{mutex_};
641 rpm_.invoke(&ResultsProducer::doBeginJob);
644 void RootDAQOut::endJob()
646 std::lock_guard sentry{mutex_};
647 rpm_.invoke(&ResultsProducer::doEndJob);
650 void RootDAQOut::event(EventPrincipal
const& ep)
652 std::lock_guard sentry{mutex_};
653 rpm_.for_each_RPWorker([&ep](RPWorker& w) { w.rp().doEvent(ep); });
656 void RootDAQOut::beginSubRun(SubRunPrincipal
const& srp)
658 std::lock_guard sentry{mutex_};
659 rpm_.for_each_RPWorker([&srp](RPWorker& w) { w.rp().doBeginSubRun(srp); });
662 void RootDAQOut::endSubRun(SubRunPrincipal
const& srp)
664 std::lock_guard sentry{mutex_};
665 rpm_.for_each_RPWorker([&srp](RPWorker& w) { w.rp().doEndSubRun(srp); });
668 void RootDAQOut::beginRun(RunPrincipal
const& rp)
670 std::lock_guard sentry{mutex_};
671 rpm_.for_each_RPWorker([&rp](RPWorker& w) { w.rp().doBeginRun(rp); });
674 void RootDAQOut::endRun(RunPrincipal
const& rp)
676 std::lock_guard sentry{mutex_};
677 rpm_.for_each_RPWorker([&rp](RPWorker& w) { w.rp().doEndRun(rp); });
681 RootDAQOut::modifyFilePattern(std::string
const& inputPattern,
Config const& config)
684 art::ServiceHandle<ArtdaqSharedMemoryServiceInterface> shm;
686 TLOG(TLVL_DEBUG + 32) << __func__ <<
": inputPattern=\"" << inputPattern <<
"\"";
690 int firstLoggerRank = config.firstLoggerRank();
691 std::vector<Config::FileNameSubstitution> subs;
692 config.fileNameSubstitutions(subs);
693 TLOG(TLVL_DEBUG + 33) << __func__ <<
": firstLoggerRank=" << firstLoggerRank
694 <<
", numberOfSubstitutionsProvided=" << subs.size();
697 std::string modifiedPattern = inputPattern;
698 std::string searchString;
699 size_t targetLocation;
700 int zeroBasedRelativeRank = my_rank;
701 int oneBasedRelativeRank = my_rank + 1;
702 if (firstLoggerRank >= 0)
704 zeroBasedRelativeRank -= firstLoggerRank;
705 oneBasedRelativeRank -= firstLoggerRank;
707 TLOG(TLVL_DEBUG + 33) << __func__ <<
": my_rank=" << my_rank <<
", zeroBasedRelativeRank=" << zeroBasedRelativeRank
708 <<
", oneBasedRelativeRank=" << oneBasedRelativeRank;
712 searchString =
"${ZeroBasedRelativeRank}";
713 targetLocation = modifiedPattern.find(searchString);
714 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
715 while (targetLocation != std::string::npos)
717 std::ostringstream oss;
718 oss << zeroBasedRelativeRank;
719 modifiedPattern.replace(targetLocation, searchString.length(), oss.str());
720 targetLocation = modifiedPattern.find(searchString);
721 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
726 searchString =
"${OneBasedRelativeRank}";
727 targetLocation = modifiedPattern.find(searchString);
728 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
729 while (targetLocation != std::string::npos)
731 std::ostringstream oss;
732 oss << oneBasedRelativeRank;
733 modifiedPattern.replace(targetLocation, searchString.length(), oss.str());
734 targetLocation = modifiedPattern.find(searchString);
735 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
740 searchString =
"${Rank}";
741 targetLocation = modifiedPattern.find(searchString);
742 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
743 while (targetLocation != std::string::npos)
745 std::ostringstream oss;
747 modifiedPattern.replace(targetLocation, searchString.length(), oss.str());
748 targetLocation = modifiedPattern.find(searchString);
749 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
754 searchString =
"${app_name}";
755 targetLocation = modifiedPattern.find(searchString);
756 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
757 while (targetLocation != std::string::npos)
759 std::ostringstream oss;
761 modifiedPattern.replace(targetLocation, searchString.length(), oss.str());
762 targetLocation = modifiedPattern.find(searchString);
763 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
767 for (
auto& sub : subs)
770 const std::string BLAH =
"none_provided";
771 std::string newString = BLAH;
772 std::vector<Config::NewSubStringForApp> replacementList = sub.replacementList();
773 for (
auto& rdx : replacementList)
777 newString = rdx.newString();
781 TLOG(TLVL_DEBUG + 33) << __func__ <<
": app_name=" << artdaq::Globals::app_name_ <<
", newString=" << newString;
782 if (newString != BLAH)
785 searchString =
"${" + sub.targetString() +
"}";
786 targetLocation = modifiedPattern.find(searchString);
787 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
788 while (targetLocation != std::string::npos)
790 modifiedPattern.replace(targetLocation, searchString.length(), newString);
791 targetLocation = modifiedPattern.find(searchString);
792 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
797 searchString = sub.targetString();
798 targetLocation = modifiedPattern.find(searchString);
799 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
800 while (targetLocation != std::string::npos)
802 modifiedPattern.replace(targetLocation, searchString.length(), newString);
803 targetLocation = modifiedPattern.find(searchString);
804 TLOG(TLVL_DEBUG + 33) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
809 TLOG(TLVL_DEBUG + 32) << __func__ <<
": modifiedPattern = \"" << modifiedPattern <<
"\"";
810 return modifiedPattern;
static std::string app_name_
The name of the current application, to be used in logging and metrics.
Configuration for simple_metric_sender.