3 #include "art/Framework/Core/ModuleMacros.h"
4 #include "art/Framework/Core/OutputModule.h"
5 #include "art/Framework/Core/RPManager.h"
6 #include "art/Framework/Core/ResultsProducer.h"
7 #include "art/Framework/IO/ClosingCriteria.h"
8 #include "art/Framework/IO/FileStatsCollector.h"
9 #include "art/Framework/IO/PostCloseFileRenamer.h"
10 #include "art/Framework/IO/detail/logFileAction.h"
11 #include "art/Framework/IO/detail/validateFileNamePattern.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Principal/EventPrincipal.h"
14 #include "art/Framework/Principal/Principal.h"
15 #include "art/Framework/Principal/Results.h"
16 #include "art/Framework/Principal/ResultsPrincipal.h"
17 #include "art/Framework/Principal/Run.h"
18 #include "art/Framework/Principal/RunPrincipal.h"
19 #include "art/Framework/Principal/SubRun.h"
20 #include "art/Framework/Principal/SubRunPrincipal.h"
21 #include "art/Framework/Services/Registry/ServiceHandle.h"
22 #include "art/Utilities/parent_path.h"
23 #include "art/Utilities/unique_filename.h"
24 #include "art_root_io/DropMetaData.h"
25 #include "art_root_io/RootFileBlock.h"
26 #include "art_root_io/detail/rootOutputConfigurationTools.h"
27 #include "art_root_io/setup.h"
28 #include "artdaq/ArtModules/ArtdaqSharedMemoryService.h"
29 #include "artdaq/ArtModules/RootDAQOutput-s81/RootDAQOutFile.h"
30 #include "artdaq/DAQdata/Globals.hh"
31 #include "canvas/Persistency/Provenance/FileFormatVersion.h"
32 #include "canvas/Persistency/Provenance/ProductTables.h"
33 #include "canvas/Utilities/Exception.h"
34 #include "fhiclcpp/ParameterSet.h"
35 #include "fhiclcpp/types/Atom.h"
36 #include "fhiclcpp/types/ConfigurationTable.h"
37 #include "fhiclcpp/types/OptionalAtom.h"
38 #include "fhiclcpp/types/OptionalSequence.h"
39 #include "fhiclcpp/types/Table.h"
40 #include "hep_concurrency/RecursiveMutex.h"
41 #include "messagefacility/MessageLogger/MessageLogger.h"
43 #define TRACE_NAME (app_name + "_RootDAQOut").c_str()
53 using namespace hep::concurrency;
56 string const dev_null{
"/dev/null"};
67 static constexpr
char const* default_tmpDir{
"<parent-path-of-filename>"};
73 using Name = fhicl::Name;
74 using Comment = fhicl::Comment;
76 using Atom = fhicl::Atom<T>;
78 using OptionalAtom = fhicl::OptionalAtom<T>;
79 fhicl::TableFragment<OutputModule::Config> omConfig;
80 Atom<string> catalog{Name(
"catalog"),
""};
81 OptionalAtom<bool> dropAllEvents{Name(
"dropAllEvents")};
82 Atom<bool> dropAllSubRuns{Name(
"dropAllSubRuns"),
false};
83 OptionalAtom<bool> fastCloning{Name(
"fastCloning")};
84 Atom<string> tmpDir{Name(
"tmpDir"), default_tmpDir};
85 Atom<int> compressionLevel{Name(
"compressionLevel"), 7};
86 Atom<unsigned> freePercent{Name(
"freePercent"), 0};
87 Atom<unsigned> freeMB{Name(
"freeMB"), 0};
88 Atom<int64_t> saveMemoryObjectThreshold{Name(
"saveMemoryObjectThreshold"),
90 Atom<int64_t> treeMaxVirtualSize{Name(
"treeMaxVirtualSize"), -1};
91 Atom<int> splitLevel{Name(
"splitLevel"), 99};
92 Atom<int> basketSize{Name(
"basketSize"), 16384};
93 Atom<bool> dropMetaDataForDroppedData{Name(
"dropMetaDataForDroppedData"),
95 Atom<string> dropMetaData{Name(
"dropMetaData"),
"NONE"};
96 Atom<bool> writeParameterSets{Name(
"writeParameterSets"),
true};
97 fhicl::Table<ClosingCriteria::Config> fileProperties{
98 Name(
"fileProperties")};
99 Atom<int> firstLoggerRank{Name(
"firstLoggerRank"), -1};
103 fhicl::Atom<string> appName{fhicl::Name(
"appName")};
104 fhicl::Atom<string> newString{fhicl::Name(
"newString")};
108 fhicl::Atom<string> targetString{fhicl::Name(
"targetString")};
109 fhicl::Sequence<fhicl::Table<NewSubStringForApp>> replacementList{fhicl::Name(
"replacementList")};
111 fhicl::OptionalSequence<fhicl::Table<FileNameSubstitution>> fileNameSubstitutions{Name(
"fileNameSubstitutions")};
120 using namespace fhicl::detail;
121 ParameterBase* adjustFilename{
122 const_cast<fhicl::Atom<string>*
>(&omConfig().fileName)};
123 adjustFilename->set_par_style(fhicl::par_style::REQUIRED);
131 set<string> keys{OutputModule::Config::KeysToIgnore::get()};
132 keys.insert(
"results");
138 using Parameters = fhicl::WrappedTable<Config, Config::KeysToIgnore>;
151 void postSelectProducts()
override;
152 void beginJob()
override;
153 void endJob()
override;
154 void beginRun(RunPrincipal
const& )
override;
155 void endRun(RunPrincipal
const& )
override;
156 void beginSubRun(SubRunPrincipal
const& )
override;
157 void endSubRun(SubRunPrincipal
const& )
override;
158 void event(EventPrincipal
const& )
override;
162 string fileNameAtOpen()
const;
163 string fileNameAtClose(
string const& currentFileName);
164 string const& lastClosedFileName()
const override;
165 Granularity fileGranularity()
const override;
166 void openFile(FileBlock
const& )
override;
167 void respondToOpenInputFile(FileBlock
const& )
override;
168 void readResults(ResultsPrincipal
const& resp)
override;
169 void respondToCloseInputFile(FileBlock
const& )
override;
170 void incrementInputFileNumber()
override;
171 void write(EventPrincipal& )
override;
172 void writeSubRun(SubRunPrincipal& )
override;
173 void writeRun(RunPrincipal& )
override;
174 void setSubRunAuxiliaryRangeSetID(RangeSet
const& )
override;
175 void setRunAuxiliaryRangeSetID(RangeSet
const& )
override;
176 bool isFileOpen()
const override;
177 void setFileStatus(OutputFileStatus )
override;
178 bool requestsToCloseFile()
const override;
179 void startEndFile()
override;
180 void writeFileFormatVersion()
override;
181 void writeFileIndex()
override;
182 void writeEventHistory()
override;
183 void writeProcessConfigurationRegistry()
override;
184 void writeProcessHistoryRegistry()
override;
185 void writeParameterSetRegistry()
override;
186 void writeProductDescriptionRegistry()
override;
187 void writeParentageRegistry()
override;
188 void doWriteFileCatalogMetadata(
189 FileCatalogMetadata::collection_type
const& md,
190 FileCatalogMetadata::collection_type
const& ssmd)
override;
191 void writeProductDependencies()
override;
192 void finishEndFile()
override;
193 void doRegisterProducts(ProductDescriptions& producedProducts,
194 ModuleDescription
const& md)
override;
195 std::string modifyFilePattern(std::string
const& ,
Config const& );
203 mutable RecursiveMutex mutex_{
"RootDAQOut::mutex"};
204 string const catalog_;
205 bool dropAllEvents_{
false};
206 bool dropAllSubRuns_;
207 string const moduleLabel_;
208 int inputFileCount_{};
209 unique_ptr<RootDAQOutFile> rootOutputFile_{
nullptr};
210 FileStatsCollector fstats_;
211 PostCloseFileRenamer fRenamer_;
212 string const filePattern_;
214 string lastClosedFileName_{};
215 int const compressionLevel_;
216 unsigned freePercent_;
218 int64_t
const saveMemoryObjectThreshold_;
219 int64_t
const treeMaxVirtualSize_;
220 int const splitLevel_;
221 int const basketSize_;
222 DropMetaData dropMetaData_;
223 bool dropMetaDataForDroppedData_;
224 bool fastCloningEnabled_{
true};
227 bool writeParameterSets_;
228 ClosingCriteria fileProperties_;
229 ProductDescriptions productsToProduce_{};
230 ProductTables producedResultsProducts_{ProductTables::invalid()};
234 RootDAQOut::~RootDAQOut() =
default;
236 RootDAQOut::RootDAQOut(Parameters
const& config)
237 : OutputModule{config().omConfig, config.get_PSet()}
238 , catalog_{config().catalog()}
239 , dropAllSubRuns_{config().dropAllSubRuns()}
240 , moduleLabel_{config.get_PSet().get<
string>(
"module_label")}
241 , fstats_{moduleLabel_, processName()}
243 , filePattern_{modifyFilePattern(config().omConfig().fileName(), config())}
244 , tmpDir_{config().tmpDir() == default_tmpDir ? parent_path(filePattern_) : config().tmpDir()}
245 , compressionLevel_{config().compressionLevel()}
246 , freePercent_{config().freePercent()}
247 , freeMB_{config().freeMB()}
248 , saveMemoryObjectThreshold_{config().saveMemoryObjectThreshold()}
249 , treeMaxVirtualSize_{config().treeMaxVirtualSize()}
250 , splitLevel_{config().splitLevel()}
251 , basketSize_{config().basketSize()}
252 , dropMetaData_{config().dropMetaData()}
253 , dropMetaDataForDroppedData_{config().dropMetaDataForDroppedData()}
254 , writeParameterSets_{config().writeParameterSets()}
256 detail::validateFileNamePattern(
257 config.get_PSet().has_key(config().fileProperties.name()),
259 config().fileProperties())}
260 , rpm_{config.get_PSet()}
262 TLOG(TLVL_INFO) <<
"RootDAQOut_module (s81 version) CONSTRUCTOR Start";
266 bool const dropAllEventsSet{config().dropAllEvents(dropAllEvents_)};
267 dropAllEvents_ = detail::shouldDropEvents(
268 dropAllEventsSet, dropAllEvents_, dropAllSubRuns_);
274 bool const fastCloningSet{config().fastCloning(fastCloningEnabled_)};
275 fastCloningEnabled_ = RootDAQOutFile::shouldFastClone(
276 fastCloningSet, fastCloningEnabled_, wantAllEvents(), fileProperties_);
277 if (!writeParameterSets_)
279 mf::LogWarning(
"PROVENANCE")
280 <<
"Output module " << moduleLabel_
281 <<
" has parameter writeParameterSets set to false.\n"
282 <<
"Parameter set provenance will not be available in subsequent "
284 <<
"Check your experiment's policy on this issue to avoid future "
286 <<
"with analysis reproducibility.\n";
290 void RootDAQOut::openFile(FileBlock
const& fb)
292 RecursiveMutexSentry sentry{mutex_, __func__};
300 respondToOpenInputFile(fb);
304 void RootDAQOut::postSelectProducts()
306 RecursiveMutexSentry sentry{mutex_, __func__};
309 rootOutputFile_->selectProducts();
313 void RootDAQOut::respondToOpenInputFile(FileBlock
const& fb)
315 RecursiveMutexSentry sentry{mutex_, __func__};
321 auto const* rfb =
dynamic_cast<RootFileBlock const*
>(&fb);
322 bool fastCloneThisOne = fastCloningEnabled_ && (rfb !=
nullptr) &&
323 (rfb->tree() !=
nullptr) &&
324 ((remainingEvents() < 0) ||
325 (remainingEvents() >= rfb->tree()->GetEntries()));
326 if (fastCloningEnabled_ && !fastCloneThisOne)
328 mf::LogWarning(
"FastCloning")
329 <<
"Fast cloning deactivated for this input file due to "
330 <<
"empty event tree and/or event limits.";
332 if (fastCloneThisOne && !rfb->fastClonable())
334 mf::LogWarning(
"FastCloning")
335 <<
"Fast cloning deactivated for this input file due to "
336 <<
"information in FileBlock.";
337 fastCloneThisOne =
false;
339 rootOutputFile_->beginInputFile(rfb, fastCloneThisOne);
340 fstats_.recordInputFile(fb.fileName());
343 void RootDAQOut::readResults(ResultsPrincipal
const& resp)
345 RecursiveMutexSentry sentry{mutex_, __func__};
346 rpm_.for_each_RPWorker(
347 [&resp](RPWorker& w) { w.rp().doReadResults(resp); });
350 void RootDAQOut::respondToCloseInputFile(FileBlock
const& fb)
352 RecursiveMutexSentry sentry{mutex_, __func__};
355 rootOutputFile_->respondToCloseInputFile(fb);
359 void RootDAQOut::write(EventPrincipal& ep)
361 RecursiveMutexSentry sentry{mutex_, __func__};
366 if (hasNewlyDroppedBranch()[InEvent])
368 ep.addToProcessHistory();
370 rootOutputFile_->writeOne(ep);
371 fstats_.recordEvent(ep.eventID());
374 void RootDAQOut::setSubRunAuxiliaryRangeSetID(RangeSet
const& rs)
376 RecursiveMutexSentry sentry{mutex_, __func__};
377 rootOutputFile_->setSubRunAuxiliaryRangeSetID(rs);
380 void RootDAQOut::writeSubRun(SubRunPrincipal& sr)
382 RecursiveMutexSentry sentry{mutex_, __func__};
387 if (hasNewlyDroppedBranch()[InSubRun])
389 sr.addToProcessHistory();
391 rootOutputFile_->writeSubRun(sr);
392 fstats_.recordSubRun(sr.subRunID());
395 void RootDAQOut::setRunAuxiliaryRangeSetID(RangeSet
const& rs)
397 RecursiveMutexSentry sentry{mutex_, __func__};
398 rootOutputFile_->setRunAuxiliaryRangeSetID(rs);
401 void RootDAQOut::writeRun(RunPrincipal& rp)
403 RecursiveMutexSentry sentry{mutex_, __func__};
404 if (hasNewlyDroppedBranch()[InRun])
406 rp.addToProcessHistory();
408 rootOutputFile_->writeRun(rp);
409 fstats_.recordRun(rp.runID());
412 void RootDAQOut::startEndFile()
414 RecursiveMutexSentry sentry{mutex_, __func__};
415 auto resp = make_unique<ResultsPrincipal>(
416 ResultsAuxiliary{}, moduleDescription().processConfiguration(),
nullptr);
417 resp->createGroupsForProducedProducts(producedResultsProducts_);
418 resp->enableLookupOfProducedProducts(producedResultsProducts_);
419 if (!producedResultsProducts_.descriptions(InResults).empty() ||
420 hasNewlyDroppedBranch()[InResults])
422 resp->addToProcessHistory();
424 rpm_.for_each_RPWorker(
425 [&resp](RPWorker& w) { w.rp().doWriteResults(*resp); });
426 rootOutputFile_->writeResults(*resp);
429 void RootDAQOut::writeFileFormatVersion()
431 RecursiveMutexSentry sentry{mutex_, __func__};
432 rootOutputFile_->writeFileFormatVersion();
435 void RootDAQOut::writeFileIndex()
437 RecursiveMutexSentry sentry{mutex_, __func__};
438 rootOutputFile_->writeFileIndex();
441 void RootDAQOut::writeEventHistory()
443 RecursiveMutexSentry sentry{mutex_, __func__};
444 rootOutputFile_->writeEventHistory();
447 void RootDAQOut::writeProcessConfigurationRegistry()
449 RecursiveMutexSentry sentry{mutex_, __func__};
450 rootOutputFile_->writeProcessConfigurationRegistry();
453 void RootDAQOut::writeProcessHistoryRegistry()
455 RecursiveMutexSentry sentry{mutex_, __func__};
456 rootOutputFile_->writeProcessHistoryRegistry();
459 void RootDAQOut::writeParameterSetRegistry()
461 RecursiveMutexSentry sentry{mutex_, __func__};
462 if (writeParameterSets_)
464 rootOutputFile_->writeParameterSetRegistry();
468 void RootDAQOut::writeProductDescriptionRegistry()
470 RecursiveMutexSentry sentry{mutex_, __func__};
471 rootOutputFile_->writeProductDescriptionRegistry();
474 void RootDAQOut::writeParentageRegistry()
476 RecursiveMutexSentry sentry{mutex_, __func__};
477 rootOutputFile_->writeParentageRegistry();
480 void RootDAQOut::doWriteFileCatalogMetadata(
481 FileCatalogMetadata::collection_type
const& md,
482 FileCatalogMetadata::collection_type
const& ssmd)
484 RecursiveMutexSentry sentry{mutex_, __func__};
485 rootOutputFile_->writeFileCatalogMetadata(fstats_, md, ssmd);
488 void RootDAQOut::writeProductDependencies()
490 RecursiveMutexSentry sentry{mutex_, __func__};
491 rootOutputFile_->writeProductDependencies();
494 void RootDAQOut::finishEndFile()
496 RecursiveMutexSentry sentry{mutex_, __func__};
497 string const currentFileName{rootOutputFile_->currentFileName()};
498 rootOutputFile_->writeTTrees();
499 rootOutputFile_.reset();
500 fstats_.recordFileClose();
501 lastClosedFileName_ = fileNameAtClose(currentFileName);
502 TLOG(TLVL_INFO) << __func__ <<
": Closed output file \"" << lastClosedFileName_ <<
"\"";
503 rpm_.invoke(&ResultsProducer::doClear);
506 void RootDAQOut::doRegisterProducts(ProductDescriptions& producedProducts,
507 ModuleDescription
const& md)
509 RecursiveMutexSentry sentry{mutex_, __func__};
511 rpm_.for_each_RPWorker([&producedProducts, &md](RPWorker& w) {
512 auto const& params = w.params();
513 w.setModuleDescription(
514 ModuleDescription{params.rpPSetID,
516 md.moduleLabel() +
'#' + params.rpLabel,
517 ModuleThreadingType::legacy,
518 md.processConfiguration()});
519 w.rp().registerProducts(producedProducts, w.moduleDescription());
524 productsToProduce_ = producedProducts;
525 producedResultsProducts_ = ProductTables{productsToProduce_};
528 void RootDAQOut::setFileStatus(OutputFileStatus
const ofs)
530 RecursiveMutexSentry sentry{mutex_, __func__};
533 rootOutputFile_->setFileStatus(ofs);
537 bool RootDAQOut::isFileOpen()
const
539 RecursiveMutexSentry sentry{mutex_, __func__};
540 return rootOutputFile_ !=
nullptr;
543 void RootDAQOut::incrementInputFileNumber()
545 RecursiveMutexSentry sentry{mutex_, __func__};
548 rootOutputFile_->incrementInputFileNumber();
552 bool RootDAQOut::requestsToCloseFile()
const
554 RecursiveMutexSentry sentry{mutex_, __func__};
555 return isFileOpen() ? rootOutputFile_->requestsToCloseFile() :
false;
559 RootDAQOut::fileGranularity()
const
561 RecursiveMutexSentry sentry{mutex_, __func__};
562 return fileProperties_.granularity();
565 void RootDAQOut::doOpenFile()
567 RecursiveMutexSentry sentry{mutex_, __func__};
568 if (inputFileCount_ == 0)
570 throw Exception(errors::LogicError)
571 <<
"Attempt to open output file before input file. "
572 <<
"Please report this to the core framework developers.\n";
574 rootOutputFile_ = make_unique<RootDAQOutFile>(
this,
580 saveMemoryObjectThreshold_,
585 dropMetaDataForDroppedData_,
586 fastCloningEnabled_);
587 fstats_.recordFileOpen();
588 TLOG(TLVL_INFO) << __func__ <<
": Opened output file with pattern \"" << filePattern_ <<
"\"";
592 RootDAQOut::fileNameAtOpen()
const
594 return (filePattern_ == dev_null) ? dev_null : unique_filename(tmpDir_ +
"/RootDAQOut");
598 RootDAQOut::fileNameAtClose(std::string
const& currentFileName)
600 return (filePattern_ == dev_null) ? dev_null : fRenamer_.maybeRenameFile(currentFileName, filePattern_);
604 RootDAQOut::lastClosedFileName()
const
606 RecursiveMutexSentry sentry{mutex_, __func__};
607 if (lastClosedFileName_.empty())
609 throw Exception(errors::LogicError,
"RootDAQOut::currentFileName(): ")
610 <<
"called before meaningful.\n";
612 return lastClosedFileName_;
615 void RootDAQOut::beginJob()
617 RecursiveMutexSentry sentry{mutex_, __func__};
618 rpm_.invoke(&ResultsProducer::doBeginJob);
621 void RootDAQOut::endJob()
623 RecursiveMutexSentry sentry{mutex_, __func__};
624 rpm_.invoke(&ResultsProducer::doEndJob);
627 void RootDAQOut::event(EventPrincipal
const& ep)
629 RecursiveMutexSentry sentry{mutex_, __func__};
630 rpm_.for_each_RPWorker([&ep](RPWorker& w) { w.rp().doEvent(ep); });
633 void RootDAQOut::beginSubRun(SubRunPrincipal
const& srp)
635 RecursiveMutexSentry sentry{mutex_, __func__};
636 rpm_.for_each_RPWorker([&srp](RPWorker& w) { w.rp().doBeginSubRun(srp); });
639 void RootDAQOut::endSubRun(SubRunPrincipal
const& srp)
641 RecursiveMutexSentry sentry{mutex_, __func__};
642 rpm_.for_each_RPWorker([&srp](RPWorker& w) { w.rp().doEndSubRun(srp); });
645 void RootDAQOut::beginRun(RunPrincipal
const& rp)
647 RecursiveMutexSentry sentry{mutex_, __func__};
648 rpm_.for_each_RPWorker([&rp](RPWorker& w) { w.rp().doBeginRun(rp); });
651 void RootDAQOut::endRun(RunPrincipal
const& rp)
653 RecursiveMutexSentry sentry{mutex_, __func__};
654 rpm_.for_each_RPWorker([&rp](RPWorker& w) { w.rp().doEndRun(rp); });
658 RootDAQOut::modifyFilePattern(std::string
const& inputPattern,
Config const& config)
661 art::ServiceHandle<ArtdaqSharedMemoryServiceInterface> shm;
663 TLOG(TLVL_DEBUG) << __func__ <<
": inputPattern=\"" << inputPattern <<
"\"";
667 int firstLoggerRank = config.firstLoggerRank();
668 std::vector<Config::FileNameSubstitution> subs;
669 config.fileNameSubstitutions(subs);
670 TLOG(TLVL_TRACE) << __func__ <<
": firstLoggerRank=" << firstLoggerRank
671 <<
", numberOfSubstitutionsProvided=" << subs.size();
674 std::string modifiedPattern = inputPattern;
675 std::string searchString;
676 size_t targetLocation;
677 int zeroBasedRelativeRank = my_rank;
678 int oneBasedRelativeRank = my_rank + 1;
679 if (firstLoggerRank >= 0)
681 zeroBasedRelativeRank -= firstLoggerRank;
682 oneBasedRelativeRank -= firstLoggerRank;
684 TLOG(TLVL_TRACE) << __func__ <<
": my_rank=" << my_rank <<
", zeroBasedRelativeRank=" << zeroBasedRelativeRank
685 <<
", oneBasedRelativeRank=" << oneBasedRelativeRank;
689 searchString =
"${ZeroBasedRelativeRank}";
690 targetLocation = modifiedPattern.find(searchString);
691 TLOG(TLVL_TRACE) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
692 while (targetLocation != std::string::npos)
694 std::ostringstream oss;
695 oss << zeroBasedRelativeRank;
696 modifiedPattern.replace(targetLocation, searchString.length(), oss.str());
697 targetLocation = modifiedPattern.find(searchString);
698 TLOG(TLVL_TRACE) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
703 searchString =
"${OneBasedRelativeRank}";
704 targetLocation = modifiedPattern.find(searchString);
705 TLOG(TLVL_TRACE) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
706 while (targetLocation != std::string::npos)
708 std::ostringstream oss;
709 oss << oneBasedRelativeRank;
710 modifiedPattern.replace(targetLocation, searchString.length(), oss.str());
711 targetLocation = modifiedPattern.find(searchString);
712 TLOG(TLVL_TRACE) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
717 searchString =
"${Rank}";
718 targetLocation = modifiedPattern.find(searchString);
719 TLOG(TLVL_TRACE) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
720 while (targetLocation != std::string::npos)
722 std::ostringstream oss;
724 modifiedPattern.replace(targetLocation, searchString.length(), oss.str());
725 targetLocation = modifiedPattern.find(searchString);
726 TLOG(TLVL_TRACE) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
730 for (
auto& sub : subs)
733 const std::string BLAH =
"none_provided";
734 std::string newString = BLAH;
735 std::vector<Config::NewSubStringForApp> replacementList = sub.replacementList();
736 for (
auto& rdx : replacementList)
740 newString = rdx.newString();
745 if (newString != BLAH)
748 searchString =
"${" + sub.targetString() +
"}";
749 targetLocation = modifiedPattern.find(searchString);
750 TLOG(TLVL_TRACE) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
751 while (targetLocation != std::string::npos)
753 modifiedPattern.replace(targetLocation, searchString.length(), newString);
754 targetLocation = modifiedPattern.find(searchString);
755 TLOG(TLVL_TRACE) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
760 searchString = sub.targetString();
761 targetLocation = modifiedPattern.find(searchString);
762 TLOG(TLVL_TRACE) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
763 while (targetLocation != std::string::npos)
765 modifiedPattern.replace(targetLocation, searchString.length(), newString);
766 targetLocation = modifiedPattern.find(searchString);
767 TLOG(TLVL_TRACE) << __func__ <<
":" << __LINE__ <<
" searchString=" << searchString <<
", targetLocation=" << targetLocation;
772 TLOG(TLVL_DEBUG) << __func__ <<
": modifiedPattern = \"" << modifiedPattern <<
"\"";
773 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.