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:
00037 #if MESSAGEFACILITY_HEX_VERSION < 0x20103 // v2_01_03 is s58, pre v2_01_03 is s50
00038 ELMultiFileOutput(const fhicl::ParameterSet& pset);
00039 #else
00040 ELMultiFileOutput(Parameters const& pset);
00041 #endif
00042
00043 virtual ~ELMultiFileOutput() {}
00044
00045 virtual void routePayload(const std::ostringstream&, const ErrorObj&) override;
00046
00047 virtual void flush() override;
00048
00049 private:
00050 std::string baseDir_;
00051 bool append_;
00052 std::unordered_map<std::string, std::unique_ptr<cet::ostream_handle>> outputs_;
00053
00054 bool useHost_;
00055 bool useApplication_;
00056 bool useCategory_;
00057 bool useModule_;
00058 };
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #if MESSAGEFACILITY_HEX_VERSION < 0x20103 // v2_01_03 is s58, pre v2_01_03 is s50
00070 ELMultiFileOutput::ELMultiFileOutput(const fhicl::ParameterSet& pset)
00071 : ELdestination(pset)
00072 , baseDir_(pset.get<std::string>("base_directory", "/tmp"))
00073 , append_(pset.get<bool>("append", true))
00074 , useHost_(pset.get<bool>("use_hostname", true))
00075 , useApplication_(pset.get<bool>("use_application", true))
00076 , useCategory_(pset.get<bool>("use_category", false))
00077 , useModule_(pset.get<bool>("use_module", false))
00078 {}
00079 #else
00080 ELMultiFileOutput::ELMultiFileOutput(Parameters const& pset)
00081 : ELdestination(pset().elDestConfig())
00082 , baseDir_(pset().baseDir())
00083 , append_(pset().append())
00084 , useHost_(pset().useHostname())
00085 , useApplication_(pset().useApplication())
00086 , useCategory_(pset().useCategory())
00087 , useModule_(pset().useModule())
00088 {}
00089 #endif
00090
00091
00092
00093
00094 void ELMultiFileOutput::routePayload(const std::ostringstream& oss, const ErrorObj& msg)
00095 {
00096 const auto& xid = msg.xid();
00097 std::string fileName = baseDir_ + "/";
00098 if (useModule_) { fileName += xid.module() + "-"; }
00099 if (useCategory_) { fileName += xid.id() + "-"; }
00100 if (useApplication_) { fileName += xid.application() + "-"; }
00101 if (useHost_) { fileName += xid.hostname() + "-"; }
00102 fileName += std::to_string(xid.pid()) + ".log";
00103 if (outputs_.count(fileName) == 0)
00104 {
00105 outputs_[fileName] = std::make_unique<cet::ostream_handle>(fileName.c_str(), append_ ? std::ios::app : std::ios::trunc);
00106 }
00107 *outputs_[fileName] << oss.str();
00108 flush();
00109 }
00110
00111 void ELMultiFileOutput::flush()
00112 {
00113 for (auto i = outputs_.begin(); i != outputs_.end(); ++i)
00114 {
00115 (*i).second->flush();
00116 }
00117 }
00118 }
00119
00120
00121
00122
00123
00124
00125
00126 #ifndef EXTERN_C_FUNC_DECLARE_START
00127 #define EXTERN_C_FUNC_DECLARE_START extern "C" {
00128 #endif
00129
00130 EXTERN_C_FUNC_DECLARE_START
00131 auto makePlugin(const std::string&,
00132 const fhicl::ParameterSet& pset)
00133 {
00134 return std::make_unique<mfplugins::ELMultiFileOutput>(pset);
00135 }
00136 }
00137
00138 DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)