00001 #include "cetlib/PluginTypeDeducer.h"
00002 #include "cetlib/ostream_handle.h"
00003 #include "fhiclcpp/ParameterSet.h"
00004
00005 #include "messagefacility/MessageService/ELdestination.h"
00006 # include "messagefacility/Utilities/ELseverityLevel.h"
00007 #include "messagefacility/Utilities/exception.h"
00008 #include "cetlib/compiler_macros.h"
00009
00010 #include <fstream>
00011
00012 namespace mfplugins
00013 {
00014 using mf::service::ELdestination;
00015 using mf::ELseverityLevel;
00016 using mf::ErrorObj;
00017
00021 class ELMultiFileOutput : public ELdestination
00022 {
00023 #if MESSAGEFACILITY_HEX_VERSION >= 0x20103
00024 struct Config
00025 {
00026 fhicl::TableFragment<ELdestination::Config> elDestConfig;
00027 fhicl::Atom<std::string> baseDir{ fhicl::Name{ "base_directory" },fhicl::Comment{ "Directory where log files will be created" },"/tmp" };
00028 fhicl::Atom<bool> append{ fhicl::Name{ "append" },fhicl::Comment{ "Append to existing log files" },true };
00029 fhicl::Atom<bool> useHostname{ fhicl::Name{ "use_hostname" },fhicl::Comment{ "Use the hostname when generating log file names" },true };
00030 fhicl::Atom<bool> useApplication{ fhicl::Name{ "use_application" },fhicl::Comment{ "Use the application field when generating log file names" },true };
00031 fhicl::Atom<bool> useCategory{ fhicl::Name{ "use_category" },fhicl::Comment{ "Use the category field when generating log file names" },false };
00032 fhicl::Atom<bool> useModule{ fhicl::Name{ "use_module" },fhicl::Comment{ "Use the module field when generating log file names" },false };
00033 };
00034 using Parameters = fhicl::WrappedTable<Config>;
00035 #endif
00036 public:
00041 #if MESSAGEFACILITY_HEX_VERSION < 0x20103 // v2_01_03 is s58, pre v2_01_03 is s50
00042 ELMultiFileOutput(const fhicl::ParameterSet& pset);
00043 #else
00044 ELMultiFileOutput(Parameters const& pset);
00045 #endif
00049 virtual ~ELMultiFileOutput() {}
00050
00056 virtual void routePayload(const std::ostringstream& oss, const ErrorObj& msg) override;
00057
00061 virtual void flush() override;
00062
00063 private:
00064 std::string baseDir_;
00065 bool append_;
00066 std::unordered_map<std::string, std::unique_ptr<cet::ostream_handle>> outputs_;
00067
00068 bool useHost_;
00069 bool useApplication_;
00070 bool useCategory_;
00071 bool useModule_;
00072 };
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #if MESSAGEFACILITY_HEX_VERSION < 0x20103 // v2_01_03 is s58, pre v2_01_03 is s50
00084 ELMultiFileOutput::ELMultiFileOutput(const fhicl::ParameterSet& pset)
00085 : ELdestination(pset)
00086 , baseDir_(pset.get<std::string>("base_directory", "/tmp"))
00087 , append_(pset.get<bool>("append", true))
00088 , useHost_(pset.get<bool>("use_hostname", true))
00089 , useApplication_(pset.get<bool>("use_application", true))
00090 , useCategory_(pset.get<bool>("use_category", false))
00091 , useModule_(pset.get<bool>("use_module", false))
00092 {}
00093 #else
00094 ELMultiFileOutput::ELMultiFileOutput(Parameters const& pset)
00095 : ELdestination(pset().elDestConfig())
00096 , baseDir_(pset().baseDir())
00097 , append_(pset().append())
00098 , useHost_(pset().useHostname())
00099 , useApplication_(pset().useApplication())
00100 , useCategory_(pset().useCategory())
00101 , useModule_(pset().useModule())
00102 {}
00103 #endif
00104
00105
00106
00107
00108 void ELMultiFileOutput::routePayload(const std::ostringstream& oss, const ErrorObj& msg)
00109 {
00110 const auto& xid = msg.xid();
00111 std::string fileName = baseDir_ + "/";
00112 if (useModule_) { fileName += xid.module() + "-"; }
00113 if (useCategory_) { fileName += xid.id() + "-"; }
00114 if (useApplication_) { fileName += xid.application() + "-"; }
00115 if (useHost_) { fileName += xid.hostname() + "-"; }
00116 fileName += std::to_string(xid.pid()) + ".log";
00117 if (outputs_.count(fileName) == 0)
00118 {
00119 outputs_[fileName] = std::make_unique<cet::ostream_handle>(fileName.c_str(), append_ ? std::ios::app : std::ios::trunc);
00120 }
00121 *outputs_[fileName] << oss.str();
00122 flush();
00123 }
00124
00125 void ELMultiFileOutput::flush()
00126 {
00127 for (auto i = outputs_.begin(); i != outputs_.end(); ++i)
00128 {
00129 (*i).second->flush();
00130 }
00131 }
00132 }
00133
00134
00135
00136
00137
00138
00139
00140 #ifndef EXTERN_C_FUNC_DECLARE_START
00141 #define EXTERN_C_FUNC_DECLARE_START extern "C" {
00142 #endif
00143
00144 EXTERN_C_FUNC_DECLARE_START
00145 auto makePlugin(const std::string&,
00146 const fhicl::ParameterSet& pset)
00147 {
00148 return std::make_unique<mfplugins::ELMultiFileOutput>(pset);
00149 }
00150 }
00151
00152 DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)