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 #if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
00008 # include "messagefacility/MessageService/ELcontextSupplier.h"
00009 # include "messagefacility/MessageLogger/MessageDrop.h"
00010 #endif
00011 #include "messagefacility/Utilities/exception.h"
00012
00013 #include <fstream>
00014
00015 namespace mfplugins
00016 {
00017 using mf::service::ELdestination;
00018 using mf::ELseverityLevel;
00019 using mf::ErrorObj;
00020 #if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
00021 using mf::service::ELcontextSupplier;
00022 #endif
00023
00027 class ELMultiFileOutput : public ELdestination
00028 {
00029 public:
00030
00031 ELMultiFileOutput(const fhicl::ParameterSet& pset);
00032
00033 virtual ~ELMultiFileOutput() {}
00034
00035 virtual void routePayload(const std::ostringstream&, const ErrorObj&
00036 # if MESSAGEFACILITY_HEX_VERSION < 0x20002
00037 , const ELcontextSupplier&
00038 #endif
00039 ) override;
00040
00041 virtual void flush(
00042 # if MESSAGEFACILITY_HEX_VERSION < 0x20002
00043 const ELcontextSupplier&
00044 #endif
00045 ) override;
00046
00047 private:
00048 std::string baseDir_;
00049 bool append_;
00050 std::unordered_map<std::string, std::unique_ptr<cet::ostream_handle>> outputs_;
00051
00052 bool useHost_;
00053 bool useApplication_;
00054 bool useCategory_;
00055 bool useModule_;
00056 };
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 ELMultiFileOutput::ELMultiFileOutput(const fhicl::ParameterSet& pset)
00068 : ELdestination(pset)
00069 , baseDir_(pset.get<std::string>("base_directory", "/tmp"))
00070 , append_(pset.get<bool>("append", true))
00071 , useHost_(pset.get<bool>("use_hostname", true))
00072 , useApplication_(pset.get<bool>("use_application", true))
00073 , useCategory_(pset.get<bool>("use_category", false))
00074 , useModule_(pset.get<bool>("use_module", false)) { }
00075
00076
00077
00078
00079 void ELMultiFileOutput::routePayload(const std::ostringstream& oss, const ErrorObj& msg
00080 # if MESSAGEFACILITY_HEX_VERSION < 0x20002
00081 , ELcontextSupplier const& sup
00082 #endif
00083 )
00084 {
00085 const auto& xid = msg.xid();
00086 std::string fileName = baseDir_ + "/";
00087 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
00088 if (useModule_) { fileName += xid.module() + "-"; }
00089 if (useCategory_) { fileName += xid.id() + "-"; }
00090 if (useApplication_) { fileName += xid.application() + "-"; }
00091 if (useHost_) { fileName += xid.hostname() + "-"; }
00092 fileName += std::to_string(xid.pid()) + ".log";
00093 # else
00094 if (useModule_) { fileName += xid.module + "-"; }
00095 if (useCategory_) { fileName += xid.id + "-"; }
00096 if (useApplication_) { fileName += xid.application + "-"; }
00097 if (useHost_) { fileName += xid.hostname + "-"; }
00098 fileName += std::to_string(xid.pid) + ".log";
00099 # endif
00100 if (outputs_.count(fileName) == 0)
00101 {
00102 #ifndef CETLIB_EXPOSES_OSTREAM_OWNER // New cetlib
00103 outputs_[fileName] = std::make_unique<cet::ostream_handle>(fileName.c_str(), append_ ? std::ios::app : std::ios::trunc);
00104 #else // Old cetlib
00105 outputs_[fileName] = std::make_unique<cet::ostream_owner>(fileName.c_str(), append_ ? std::ios::app : std::ios::trunc);
00106 #endif
00107 }
00108 *outputs_[fileName] << oss.str();
00109 flush(
00110 # if MESSAGEFACILITY_HEX_VERSION < 0x20002
00111 sup
00112 #endif
00113 );
00114 }
00115
00116 void ELMultiFileOutput::flush(
00117 # if MESSAGEFACILITY_HEX_VERSION < 0x20002
00118 ELcontextSupplier const&
00119 #endif
00120 )
00121 {
00122 for (auto i = outputs_.begin(); i != outputs_.end(); ++i)
00123 {
00124 #ifndef CETLIB_EXPOSES_OSTREAM_OWNER // New cetlib
00125 (*i).second->flush();
00126 #else // Old cetlib
00127 (*i).second->stream().flush();
00128 #endif
00129 }
00130 }
00131 }
00132
00133
00134
00135
00136
00137
00138
00139 extern "C"
00140 {
00141 auto makePlugin(const std::string&,
00142 const fhicl::ParameterSet& pset)
00143 {
00144 return std::make_unique<mfplugins::ELMultiFileOutput>(pset);
00145 }
00146 }
00147
00148 DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)