artdaq_mfextensions  1.08.06
MultiFile_mfPlugin.cc
1 #include "cetlib/PluginTypeDeducer.h"
2 #include "cetlib/ostream_handle.h"
3 #include "fhiclcpp/ParameterSet.h"
4 #include "fhiclcpp/types/ConfigurationTable.h"
5 
6 #include "cetlib/compiler_macros.h"
7 #include "messagefacility/MessageService/ELdestination.h"
8 #include "messagefacility/Utilities/ELseverityLevel.h"
9 #include "messagefacility/Utilities/exception.h"
10 
11 #include <fstream>
12 
13 namespace mfplugins {
14 using mf::ErrorObj;
15 using mf::service::ELdestination;
16 
20 class ELMultiFileOutput : public ELdestination
21 {
22 public:
26  struct Config
27  {
29  fhicl::TableFragment<ELdestination::Config> elDestConfig;
31  fhicl::Atom<std::string> baseDir = fhicl::Atom<std::string>{
32  fhicl::Name{"base_directory"}, fhicl::Comment{"Directory where log files will be created"}, "/tmp"};
34  fhicl::Atom<bool> append =
35  fhicl::Atom<bool>{fhicl::Name{"append"}, fhicl::Comment{"Append to existing log files"}, true};
37  fhicl::Atom<bool> useHostname = fhicl::Atom<bool>{
38  fhicl::Name{"use_hostname"}, fhicl::Comment{"Use the hostname when generating log file names"}, true};
40  fhicl::Atom<bool> useApplication =
41  fhicl::Atom<bool>{fhicl::Name{"use_application"},
42  fhicl::Comment{"Use the application field when generating log file names"}, true};
44  fhicl::Atom<bool> useCategory = fhicl::Atom<bool>{
45  fhicl::Name{"use_category"}, fhicl::Comment{"Use the category field when generating log file names"}, false};
47  fhicl::Atom<bool> useModule = fhicl::Atom<bool>{
48  fhicl::Name{"use_module"}, fhicl::Comment{"Use the module field when generating log file names"}, false};
49  };
51  using Parameters = fhicl::WrappedTable<Config>;
52 
53 public:
58  explicit ELMultiFileOutput(Parameters const& pset);
59 
63  ~ELMultiFileOutput() override = default;
64 
70  void routePayload(const std::ostringstream& oss, const ErrorObj& msg) override;
71 
75  void flush() override;
76 
77 private:
78  ELMultiFileOutput(ELMultiFileOutput const&) = delete;
80  ELMultiFileOutput& operator=(ELMultiFileOutput const&) = delete;
81  ELMultiFileOutput& operator=(ELMultiFileOutput&&) = delete;
82 
83  std::string baseDir_;
84  bool append_;
85  std::unordered_map<std::string, std::unique_ptr<cet::ostream_handle>> outputs_;
86 
87  bool useHost_;
88  bool useApplication_;
89  bool useCategory_;
90  bool useModule_;
91 };
92 
93 // END DECLARATION
94 //======================================================================
95 // BEGIN IMPLEMENTATION
96 
97 //======================================================================
98 // ELMultiFileOutput c'tor
99 //======================================================================
101  : ELdestination(pset().elDestConfig()), baseDir_(pset().baseDir()), append_(pset().append()), useHost_(pset().useHostname()), useApplication_(pset().useApplication()), useCategory_(pset().useCategory()), useModule_(pset().useModule()) {}
102 
103 //======================================================================
104 // Message router ( overriddes ELdestination::routePayload )
105 //======================================================================
106 void ELMultiFileOutput::routePayload(const std::ostringstream& oss, const ErrorObj& msg)
107 {
108  const auto& xid = msg.xid();
109  std::string fileName = baseDir_ + "/";
110  if (useModule_)
111  {
112  fileName += xid.module() + "-";
113  }
114  if (useCategory_)
115  {
116  fileName += xid.id() + "-";
117  }
118  if (useApplication_)
119  {
120  fileName += xid.application() + "-";
121  }
122  if (useHost_)
123  {
124  fileName += xid.hostname() + "-";
125  }
126  fileName += std::to_string(xid.pid()) + ".log";
127  if (outputs_.count(fileName) == 0)
128  {
129  outputs_[fileName] =
130  std::make_unique<cet::ostream_handle>(fileName.c_str(), append_ ? std::ios::app : std::ios::trunc);
131  }
132  *outputs_[fileName] << oss.str();
133  flush();
134 }
135 
137 {
138  for (auto& output : outputs_)
139  {
140  output.second->flush();
141  }
142 }
143 } // end namespace mfplugins
144 
145 //======================================================================
146 //
147 // makePlugin function
148 //
149 //======================================================================
150 
151 #ifndef EXTERN_C_FUNC_DECLARE_START
152 #define EXTERN_C_FUNC_DECLARE_START extern "C" {
153 #endif
154 
155 EXTERN_C_FUNC_DECLARE_START
156 auto makePlugin(const std::string& /*unused*/, const fhicl::ParameterSet& pset)
157 {
158  return std::make_unique<mfplugins::ELMultiFileOutput>(pset);
159 }
160 }
161 
162 DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)
fhicl::Atom< bool > append
&quot;append&quot; (Default: true): Append to existing log files
Message Facility Destination which automatically opens files and sorts messages into them based on gi...
fhicl::Atom< std::string > baseDir
&quot;base_directory&quot; (Default: &quot;/tmp&quot;): Directory where log files will be created
fhicl::Atom< bool > useCategory
&quot;use_category&quot; (Default: false): Use the category field when generating log file names ...
ELMultiFileOutput(Parameters const &pset)
ELMultiFileOutput Constructor
fhicl::Atom< bool > useHostname
&quot;use_hostname&quot; (Default: true): Use the hostname when generating log file names
fhicl::WrappedTable< Config > Parameters
Used for ParameterSet validation.
void routePayload(const std::ostringstream &oss, const ErrorObj &msg) override
Serialize a MessageFacility message to the output.
~ELMultiFileOutput() override=default
Default virtual Destructor
void flush() override
Flush any text in the ostream buffer to disk.
Configuration parameters for ELMultiFileOutput.
fhicl::Atom< bool > useApplication
&quot;use_application&quot; (Default: true): Use the application field when generating log file names ...
fhicl::Atom< bool > useModule
&quot;use_module&quot; (Default: false): Use the module field when generating log file names ...
fhicl::TableFragment< ELdestination::Config > elDestConfig
ELdestination common config parameters.