artdaq_mfextensions  v1_03_05
MultiFile_mfPlugin.cc
1 #include "cetlib/PluginTypeDeducer.h"
2 #include "cetlib/ostream_handle.h"
3 #include "fhiclcpp/ParameterSet.h"
4 
5 #include "cetlib/compiler_macros.h"
6 #include "messagefacility/MessageService/ELdestination.h"
7 #include "messagefacility/Utilities/ELseverityLevel.h"
8 #include "messagefacility/Utilities/exception.h"
9 
10 #include <fstream>
11 
12 namespace mfplugins {
13 using mf::ELseverityLevel;
14 using mf::ErrorObj;
15 using mf::service::ELdestination;
16 
20 class ELMultiFileOutput : public ELdestination {
21  public:
25  struct Config {
27  fhicl::TableFragment<ELdestination::Config> elDestConfig;
29  fhicl::Atom<std::string> baseDir = fhicl::Atom<std::string>{
30  fhicl::Name{"base_directory"}, fhicl::Comment{"Directory where log files will be created"}, "/tmp"};
32  fhicl::Atom<bool> append =
33  fhicl::Atom<bool>{fhicl::Name{"append"}, fhicl::Comment{"Append to existing log files"}, true};
35  fhicl::Atom<bool> useHostname = fhicl::Atom<bool>{
36  fhicl::Name{"use_hostname"}, fhicl::Comment{"Use the hostname when generating log file names"}, true};
38  fhicl::Atom<bool> useApplication =
39  fhicl::Atom<bool>{fhicl::Name{"use_application"},
40  fhicl::Comment{"Use the application field when generating log file names"}, true};
42  fhicl::Atom<bool> useCategory = fhicl::Atom<bool>{
43  fhicl::Name{"use_category"}, fhicl::Comment{"Use the category field when generating log file names"}, false};
45  fhicl::Atom<bool> useModule = fhicl::Atom<bool>{
46  fhicl::Name{"use_module"},
47  fhicl::Comment{"Use the module field when generating log file names"}, false};
48  };
50  using Parameters = fhicl::WrappedTable<Config>;
51 
52  public:
57  ELMultiFileOutput(Parameters const& pset);
58 
62  virtual ~ELMultiFileOutput() {}
63 
69  virtual void routePayload(const std::ostringstream& oss, const ErrorObj& msg) override;
70 
74  virtual void flush() override;
75 
76  private:
77  std::string baseDir_;
78  bool append_;
79  std::unordered_map<std::string, std::unique_ptr<cet::ostream_handle>> outputs_;
80 
81  bool useHost_;
82  bool useApplication_;
83  bool useCategory_;
84  bool useModule_;
85 };
86 
87 // END DECLARATION
88 //======================================================================
89 // BEGIN IMPLEMENTATION
90 
91 //======================================================================
92 // ELMultiFileOutput c'tor
93 //======================================================================
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()) {}
102 
103 //======================================================================
104 // Message router ( overriddes ELdestination::routePayload )
105 //======================================================================
106 void ELMultiFileOutput::routePayload(const std::ostringstream& oss, const ErrorObj& msg) {
107  const auto& xid = msg.xid();
108  std::string fileName = baseDir_ + "/";
109  if (useModule_) {
110  fileName += xid.module() + "-";
111  }
112  if (useCategory_) {
113  fileName += xid.id() + "-";
114  }
115  if (useApplication_) {
116  fileName += xid.application() + "-";
117  }
118  if (useHost_) {
119  fileName += xid.hostname() + "-";
120  }
121  fileName += std::to_string(xid.pid()) + ".log";
122  if (outputs_.count(fileName) == 0) {
123  outputs_[fileName] =
124  std::make_unique<cet::ostream_handle>(fileName.c_str(), append_ ? std::ios::app : std::ios::trunc);
125  }
126  *outputs_[fileName] << oss.str();
127  flush();
128 }
129 
131  for (auto i = outputs_.begin(); i != outputs_.end(); ++i) {
132  (*i).second->flush();
133  }
134 }
135 } // end namespace mfplugins
136 
137 //======================================================================
138 //
139 // makePlugin function
140 //
141 //======================================================================
142 
143 #ifndef EXTERN_C_FUNC_DECLARE_START
144 #define EXTERN_C_FUNC_DECLARE_START extern "C" {
145 #endif
146 
147 EXTERN_C_FUNC_DECLARE_START
148 auto makePlugin(const std::string&, const fhicl::ParameterSet& pset) {
149  return std::make_unique<mfplugins::ELMultiFileOutput>(pset);
150 }
151 }
152 
153 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.
virtual ~ELMultiFileOutput()
Default virtual Destructor
virtual void routePayload(const std::ostringstream &oss, const ErrorObj &msg) override
Serialize a MessageFacility message to the output.
virtual 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.