artdaq_mfextensions  v1_03_01
MultiFile_mfPlugin.cc
1 #include "cetlib/PluginTypeDeducer.h"
2 #include "cetlib/ostream_handle.h"
3 #include "fhiclcpp/ParameterSet.h"
4 
5 #include "messagefacility/MessageService/ELdestination.h"
6 # include "messagefacility/Utilities/ELseverityLevel.h"
7 #include "messagefacility/Utilities/exception.h"
8 #include "cetlib/compiler_macros.h"
9 
10 #include <fstream>
11 
12 namespace mfplugins
13 {
14  using mf::service::ELdestination;
15  using mf::ELseverityLevel;
16  using mf::ErrorObj;
17 
21  class ELMultiFileOutput : public ELdestination
22  {
23 #if MESSAGEFACILITY_HEX_VERSION >= 0x20103
24  struct Config
25  {
26  fhicl::TableFragment<ELdestination::Config> elDestConfig;
27  fhicl::Atom<std::string> baseDir{ fhicl::Name{ "base_directory" },fhicl::Comment{ "Directory where log files will be created" },"/tmp" };
28  fhicl::Atom<bool> append{ fhicl::Name{ "append" },fhicl::Comment{ "Append to existing log files" },true };
29  fhicl::Atom<bool> useHostname{ fhicl::Name{ "use_hostname" },fhicl::Comment{ "Use the hostname when generating log file names" },true };
30  fhicl::Atom<bool> useApplication{ fhicl::Name{ "use_application" },fhicl::Comment{ "Use the application field when generating log file names" },true };
31  fhicl::Atom<bool> useCategory{ fhicl::Name{ "use_category" },fhicl::Comment{ "Use the category field when generating log file names" },false };
32  fhicl::Atom<bool> useModule{ fhicl::Name{ "use_module" },fhicl::Comment{ "Use the module field when generating log file names" },false };
33  };
34  using Parameters = fhicl::WrappedTable<Config>;
35 #endif
36  public:
37 #if MESSAGEFACILITY_HEX_VERSION < 0x20103 // v2_01_03 is s58, pre v2_01_03 is s50
38  ELMultiFileOutput(const fhicl::ParameterSet& pset);
39 #else
40  ELMultiFileOutput(Parameters const& pset);
41 #endif
42 
43  virtual ~ELMultiFileOutput() {}
44 
45  virtual void routePayload(const std::ostringstream&, const ErrorObj&) override;
46 
47  virtual void flush() override;
48 
49  private:
50  std::string baseDir_;
51  bool append_;
52  std::unordered_map<std::string, std::unique_ptr<cet::ostream_handle>> outputs_;
53 
54  bool useHost_;
55  bool useApplication_;
56  bool useCategory_;
57  bool useModule_;
58  };
59 
60  // END DECLARATION
61  //======================================================================
62  // BEGIN IMPLEMENTATION
63 
64 
65  //======================================================================
66  // ELMultiFileOutput c'tor
67  //======================================================================
68 
69 #if MESSAGEFACILITY_HEX_VERSION < 0x20103 // v2_01_03 is s58, pre v2_01_03 is s50
70  ELMultiFileOutput::ELMultiFileOutput(const fhicl::ParameterSet& pset)
71  : ELdestination(pset)
72  , baseDir_(pset.get<std::string>("base_directory", "/tmp"))
73  , append_(pset.get<bool>("append", true))
74  , useHost_(pset.get<bool>("use_hostname", true))
75  , useApplication_(pset.get<bool>("use_application", true))
76  , useCategory_(pset.get<bool>("use_category", false))
77  , useModule_(pset.get<bool>("use_module", false))
78  {}
79 #else
80  ELMultiFileOutput::ELMultiFileOutput(Parameters const& pset)
81  : ELdestination(pset().elDestConfig())
82  , baseDir_(pset().baseDir())
83  , append_(pset().append())
84  , useHost_(pset().useHostname())
85  , useApplication_(pset().useApplication())
86  , useCategory_(pset().useCategory())
87  , useModule_(pset().useModule())
88  {}
89 #endif
90 
91  //======================================================================
92  // Message router ( overriddes ELdestination::routePayload )
93  //======================================================================
94  void ELMultiFileOutput::routePayload(const std::ostringstream& oss, const ErrorObj& msg)
95  {
96  const auto& xid = msg.xid();
97  std::string fileName = baseDir_ + "/";
98  if (useModule_) { fileName += xid.module() + "-"; }
99  if (useCategory_) { fileName += xid.id() + "-"; }
100  if (useApplication_) { fileName += xid.application() + "-"; }
101  if (useHost_) { fileName += xid.hostname() + "-"; }
102  fileName += std::to_string(xid.pid()) + ".log";
103  if (outputs_.count(fileName) == 0)
104  {
105  outputs_[fileName] = std::make_unique<cet::ostream_handle>(fileName.c_str(), append_ ? std::ios::app : std::ios::trunc);
106  }
107  *outputs_[fileName] << oss.str();
108  flush();
109  }
110 
111  void ELMultiFileOutput::flush()
112  {
113  for (auto i = outputs_.begin(); i != outputs_.end(); ++i)
114  {
115  (*i).second->flush();
116  }
117  }
118 } // end namespace mfplugins
119 
120 //======================================================================
121 //
122 // makePlugin function
123 //
124 //======================================================================
125 
126 #ifndef EXTERN_C_FUNC_DECLARE_START
127 #define EXTERN_C_FUNC_DECLARE_START extern "C" {
128 #endif
129 
130 EXTERN_C_FUNC_DECLARE_START
131 auto makePlugin(const std::string&,
132  const fhicl::ParameterSet& pset)
133 {
134  return std::make_unique<mfplugins::ELMultiFileOutput>(pset);
135 }
136 }
137 
138 DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)
Message Facility Destination which automatically opens files and sorts messages into them based on gi...