1 #include "cetlib/PluginTypeDeducer.h"
2 #include "cetlib/ostream_handle.h"
3 #include "fhiclcpp/ParameterSet.h"
5 #include "messagefacility/MessageService/ELdestination.h"
6 # include "messagefacility/Utilities/ELseverityLevel.h"
7 #if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
8 # include "messagefacility/MessageService/ELcontextSupplier.h"
9 # include "messagefacility/MessageLogger/MessageDrop.h"
11 #include "messagefacility/Utilities/exception.h"
12 #include "cetlib/compiler_macros.h"
18 using mf::service::ELdestination;
19 using mf::ELseverityLevel;
21 #if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
22 using mf::service::ELcontextSupplier;
30 #if MESSAGEFACILITY_HEX_VERSION >= 0x20103
33 fhicl::TableFragment<ELdestination::Config> elDestConfig;
34 fhicl::Atom<std::string> baseDir{ fhicl::Name{
"base_directory" },fhicl::Comment{
"Directory where log files will be created" },
"/tmp" };
35 fhicl::Atom<bool> append{ fhicl::Name{
"append" },fhicl::Comment{
"Append to existing log files" },
true };
36 fhicl::Atom<bool> useHostname{ fhicl::Name{
"use_hostname" },fhicl::Comment{
"Use the hostname when generating log file names" },
true };
37 fhicl::Atom<bool> useApplication{ fhicl::Name{
"use_application" },fhicl::Comment{
"Use the application field when generating log file names" },
true };
38 fhicl::Atom<bool> useCategory{ fhicl::Name{
"use_category" },fhicl::Comment{
"Use the category field when generating log file names" },
false };
39 fhicl::Atom<bool> useModule{ fhicl::Name{
"use_module" },fhicl::Comment{
"Use the module field when generating log file names" },
false };
41 using Parameters = fhicl::WrappedTable<Config>;
44 #if MESSAGEFACILITY_HEX_VERSION < 0x20103 // v2_01_03 is s58, pre v2_01_03 is s50
52 virtual void routePayload(
const std::ostringstream&,
const ErrorObj&
53 #
if MESSAGEFACILITY_HEX_VERSION < 0x20002
54 ,
const ELcontextSupplier&
59 #
if MESSAGEFACILITY_HEX_VERSION < 0x20002
60 const ELcontextSupplier&
67 std::unordered_map<std::string, std::unique_ptr<cet::ostream_handle>> outputs_;
84 #if MESSAGEFACILITY_HEX_VERSION < 0x20103 // v2_01_03 is s58, pre v2_01_03 is s50
85 ELMultiFileOutput::ELMultiFileOutput(
const fhicl::ParameterSet& pset)
87 , baseDir_(pset.get<std::string>(
"base_directory",
"/tmp"))
88 , append_(pset.get<bool>(
"append", true))
89 , useHost_(pset.get<bool>(
"use_hostname", true))
90 , useApplication_(pset.get<bool>(
"use_application", true))
91 , useCategory_(pset.get<bool>(
"use_category", false))
92 , useModule_(pset.get<bool>(
"use_module", false)) { }
94 ELMultiFileOutput::ELMultiFileOutput(Parameters
const& pset)
95 : ELdestination(pset().elDestConfig())
96 , baseDir_(pset().baseDir())
97 , append_(pset().append())
98 , useHost_(pset().useHostname())
99 , useApplication_(pset().useApplication())
100 , useCategory_(pset().useCategory())
101 , useModule_(pset().useModule()) { }
107 void ELMultiFileOutput::routePayload(
const std::ostringstream& oss,
const ErrorObj& msg
108 #
if MESSAGEFACILITY_HEX_VERSION < 0x20002
109 , ELcontextSupplier
const& sup
113 const auto& xid = msg.xid();
114 std::string fileName = baseDir_ +
"/";
115 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
116 if (useModule_) { fileName += xid.module() +
"-"; }
117 if (useCategory_) { fileName += xid.id() +
"-"; }
118 if (useApplication_) { fileName += xid.application() +
"-"; }
119 if (useHost_) { fileName += xid.hostname() +
"-"; }
120 fileName += std::to_string(xid.pid()) +
".log";
122 if (useModule_) { fileName += xid.module +
"-"; }
123 if (useCategory_) { fileName += xid.id +
"-"; }
124 if (useApplication_) { fileName += xid.application +
"-"; }
125 if (useHost_) { fileName += xid.hostname +
"-"; }
126 fileName += std::to_string(xid.pid) +
".log";
128 if (outputs_.count(fileName) == 0)
130 #ifndef CETLIB_EXPOSES_OSTREAM_OWNER // New cetlib
131 outputs_[fileName] = std::make_unique<cet::ostream_handle>(fileName.c_str(), append_ ? std::ios::app : std::ios::trunc);
133 outputs_[fileName] = std::make_unique<cet::ostream_owner>(fileName.c_str(), append_ ? std::ios::app : std::ios::trunc);
136 *outputs_[fileName] << oss.str();
138 #
if MESSAGEFACILITY_HEX_VERSION < 0x20002
144 void ELMultiFileOutput::flush(
145 #
if MESSAGEFACILITY_HEX_VERSION < 0x20002
146 ELcontextSupplier
const&
150 for (
auto i = outputs_.begin(); i != outputs_.end(); ++i)
152 #ifndef CETLIB_EXPOSES_OSTREAM_OWNER // New cetlib
153 (*i).second->flush();
155 (*i).second->stream().flush();
167 #ifndef EXTERN_C_FUNC_DECLARE_START
168 #define EXTERN_C_FUNC_DECLARE_START extern "C" {
171 EXTERN_C_FUNC_DECLARE_START
172 auto makePlugin(
const std::string&,
173 const fhicl::ParameterSet& pset)
175 return std::make_unique<mfplugins::ELMultiFileOutput>(pset);
179 DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)
Message Facility Destination which automatically opens files and sorts messages into them based on gi...