artdaq_mfextensions  v1_02_00
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 #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"
10 #endif
11 #include "messagefacility/Utilities/exception.h"
12 
13 #include <fstream>
14 
15 namespace mfplugins
16 {
17  using mf::service::ELdestination;
18  using mf::ELseverityLevel;
19  using mf::ErrorObj;
20 #if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
21  using mf::service::ELcontextSupplier;
22 #endif
23 
27  class ELMultiFileOutput : public ELdestination
28  {
29  public:
30 
31  ELMultiFileOutput(const fhicl::ParameterSet& pset);
32 
33  virtual ~ELMultiFileOutput() {}
34 
35  virtual void routePayload(const std::ostringstream&, const ErrorObj&
36 # if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
37  , const ELcontextSupplier&
38 #endif
39  ) override;
40 
41  virtual void flush(
42 # if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
43  const ELcontextSupplier&
44 #endif
45  ) override;
46 
47  private:
48  std::string baseDir_;
49  bool append_;
50  std::unordered_map<std::string, std::unique_ptr<cet::ostream_handle>> outputs_;
51 
52  bool useHost_;
53  bool useApplication_;
54  bool useCategory_;
55  bool useModule_;
56  };
57 
58  // END DECLARATION
59  //======================================================================
60  // BEGIN IMPLEMENTATION
61 
62 
63  //======================================================================
64  // ELMultiFileOutput c'tor
65  //======================================================================
66 
67  ELMultiFileOutput::ELMultiFileOutput(const fhicl::ParameterSet& pset)
68  : ELdestination(pset)
69  , baseDir_(pset.get<std::string>("base_directory", "/tmp"))
70  , append_(pset.get<bool>("append", true))
71  , useHost_(pset.get<bool>("use_hostname", true))
72  , useApplication_(pset.get<bool>("use_application", true))
73  , useCategory_(pset.get<bool>("use_category", false))
74  , useModule_(pset.get<bool>("use_module", false)) { }
75 
76  //======================================================================
77  // Message router ( overriddes ELdestination::routePayload )
78  //======================================================================
79  void ELMultiFileOutput::routePayload(const std::ostringstream& oss, const ErrorObj& msg
80 # if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
81  , ELcontextSupplier const& sup
82 #endif
83  )
84  {
85  const auto& xid = msg.xid();
86  std::string fileName = baseDir_ + "/";
87 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
88  if (useModule_) { fileName += xid.module() + "-"; }
89  if (useCategory_) { fileName += xid.id() + "-"; }
90  if (useApplication_) { fileName += xid.application() + "-"; }
91  if (useHost_) { fileName += xid.hostname() + "-"; }
92  fileName += std::to_string(xid.pid()) + ".log";
93 # else
94  if (useModule_) { fileName += xid.module + "-"; }
95  if (useCategory_) { fileName += xid.id + "-"; }
96  if (useApplication_) { fileName += xid.application + "-"; }
97  if (useHost_) { fileName += xid.hostname + "-"; }
98  fileName += std::to_string(xid.pid) + ".log";
99 # endif
100  if (outputs_.count(fileName) == 0)
101  {
102 #ifndef CETLIB_EXPOSES_OSTREAM_OWNER // New cetlib
103  outputs_[fileName] = std::make_unique<cet::ostream_handle>(fileName.c_str(), append_ ? std::ios::app : std::ios::trunc);
104 #else // Old cetlib
105  outputs_[fileName] = std::make_unique<cet::ostream_owner>(fileName.c_str(), append_ ? std::ios::app : std::ios::trunc);
106 #endif
107  }
108  *outputs_[fileName] << oss.str();
109  flush(
110 # if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
111  sup
112 #endif
113  );
114  }
115 
116  void ELMultiFileOutput::flush(
117 # if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
118  ELcontextSupplier const&
119 #endif
120  )
121  {
122  for (auto i = outputs_.begin(); i != outputs_.end(); ++i)
123  {
124 #ifndef CETLIB_EXPOSES_OSTREAM_OWNER // New cetlib
125  (*i).second->flush();
126 #else // Old cetlib
127  (*i).second->stream().flush();
128 #endif
129  }
130  }
131 } // end namespace mfplugins
132 
133 //======================================================================
134 //
135 // makePlugin function
136 //
137 //======================================================================
138 
139 extern "C"
140 {
141  auto makePlugin(const std::string&,
142  const fhicl::ParameterSet& pset)
143  {
144  return std::make_unique<mfplugins::ELMultiFileOutput>(pset);
145  }
146 }
147 
148 DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)
Message Facility Destination which automatically opens files and sorts messages into them based on gi...