1 #include "cetlib/PluginTypeDeducer.h"
2 #include "cetlib/ostream_handle.h"
3 #include "fhiclcpp/ParameterSet.h"
5 #include "messagefacility/MessageService/ELdestination.h"
6 #include "messagefacility/MessageService/ELostreamOutput.h"
7 #include "messagefacility/Utilities/ELseverityLevel.h"
8 #if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
9 # include "messagefacility/MessageService/ELcontextSupplier.h"
10 # include "messagefacility/MessageLogger/MessageDrop.h"
12 #include "messagefacility/Utilities/exception.h"
13 #include "cetlib/compiler_macros.h"
20 #if MESSAGEFACILITY_HEX_VERSION < 0x20201 // format changed to format_ for s67
21 #define format_ format
26 using namespace mf::service;
27 using mf::ELseverityLevel;
35 #if MESSAGEFACILITY_HEX_VERSION >= 0x20103
38 fhicl::TableFragment<ELostreamOutput::Config> elOstrConfig;
39 fhicl::Atom<std::string> delimiter{ fhicl::Name{
"field_delimiter" },fhicl::Comment{
"String to print between each message field" },
" " };
41 using Parameters = fhicl::WrappedTable<Config>;
44 #if MESSAGEFACILITY_HEX_VERSION < 0x20103 // v2_01_03 is s58, pre v2_01_03 is s50
50 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
51 virtual void fillPrefix(std::ostringstream&,
const ErrorObj&)
override;
53 virtual void fillPrefix(std::ostringstream&,
const ErrorObj&,
const ELcontextSupplier&)
override;
55 virtual void fillUsrMsg(std::ostringstream&,
const ErrorObj&)
override;
56 virtual void fillSuffix(std::ostringstream&,
const ErrorObj&)
override;
59 std::string delimeter_;
71 #if MESSAGEFACILITY_HEX_VERSION < 0x20103 // v2_01_03 is s58, pre v2_01_03 is s50
72 ELFriendly::ELFriendly(
const fhicl::ParameterSet& pset)
73 : ELostreamOutput(pset, cet::ostream_handle{ std::cout },
false)
74 , delimeter_(pset.get<std::string>(
"field_delimeter",
" "))
76 ELFriendly::ELFriendly(Parameters
const& pset)
77 : ELostreamOutput(pset().elOstrConfig(), cet::ostream_handle{ std::cout },
false)
78 , delimeter_(pset().delimiter())
85 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
86 void ELFriendly::fillPrefix(std::ostringstream& oss,
const ErrorObj& msg)
88 void ELFriendly::fillPrefix(std::ostringstream& oss,
const ErrorObj& msg, ELcontextSupplier
const& contextSupplier)
95 #if MESSAGEFACILITY_HEX_VERSION < 0x20201 // format changed to format_ for s67
96 format_.preambleMode =
true;
99 auto const& xid = msg.xid();
101 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
103 auto app = xid.application();
104 auto module = xid.module();
105 auto subroutine = xid.subroutine();
108 auto app = xid.application;
109 auto process = xid.process;
110 auto module = xid.module;
111 auto subroutine = xid.subroutine;
112 std::replace(process.begin(), process.end(),
' ',
'-');
113 # define emitToken emit
115 std::replace(
id.begin(),
id.end(),
' ',
'-');
116 std::replace(app.begin(), app.end(),
' ',
'-');
117 std::replace(module.begin(), module.end(),
' ',
'-');
118 std::replace(subroutine.begin(), subroutine.end(),
' ',
'-');
120 emitToken(oss,
"%MSG");
121 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
122 emitToken(oss, xid.severity().getSymbol());
124 emit(oss, xid.severity.getSymbol());
126 emitToken(oss, delimeter_);
128 emitToken(oss, msg.idOverflow());
130 emitToken(oss, delimeter_);
134 if (format_.want(SERIAL)) {
135 std::ostringstream s;
137 emitToken(oss,
"[serial #" + s.str() +
"]");
138 emitToken(oss, delimeter_);
143 bool needAspace =
true;
144 if (format_.want(EPILOGUE_SEPARATE)) {
145 if (module.length() + subroutine.length() > 0) {
146 emitToken(oss,
"\n");
149 else if (format_.want(TIMESTAMP) && !format_.want(TIME_SEPARATE)) {
150 emitToken(oss,
"\n");
154 if (format_.want(MODULE) && (module.length() > 0)) {
156 emitToken(oss, delimeter_);
159 emitToken(oss, module +
" ");
161 if (format_.want(SUBROUTINE) && (subroutine.length() > 0)) {
163 emitToken(oss, delimeter_);
166 emitToken(oss, subroutine +
"()");
167 emitToken(oss, delimeter_);
172 if (format_.want(TIMESTAMP)) {
173 if (format_.want(TIME_SEPARATE)) {
174 emitToken(oss,
"\n");
178 emitToken(oss, delimeter_);
181 emitToken(oss, format_.timestamp(msg.timestamp()));
182 emitToken(oss, delimeter_);
187 if (format_.want(SOME_CONTEXT)) {
189 emitToken(oss, delimeter_);
192 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
193 emitToken(oss, msg.context());
195 if (format_.want(FULL_CONTEXT)) {
196 emit(oss, contextSupplier.fullContext());
199 emit(oss, contextSupplier.context());
208 void ELFriendly::fillUsrMsg(std::ostringstream& oss, ErrorObj
const& msg)
210 if (!format_.want(TEXT))
return;
212 #if MESSAGEFACILITY_HEX_VERSION < 0x20201 // format changed to format_ for s67
213 format_.preambleMode =
false;
215 auto const usrMsgStart = std::next(msg.items().cbegin(), 4);
216 auto it = msg.items().cbegin();
219 if (
true || !msg.is_verbatim()) {
222 while (it != usrMsgStart) {
223 if (!it->compare(
" ") && !std::next(it)->compare(
"--")) {
229 emitToken(oss, *it++);
234 if (format_.want(NO_LINE_BREAKS)) emitToken(oss,
" ==> ");
235 else emitToken(oss,
"",
true);
239 auto const end = msg.items().cend();
240 for (; it != end; ++it) {
248 void ELFriendly::fillSuffix(std::ostringstream& oss, ErrorObj
const& msg)
250 if ((
true || !msg.is_verbatim()) && !format_.want(NO_LINE_BREAKS)) {
251 emitToken(oss,
"\n%MSG");
266 #ifndef EXTERN_C_FUNC_DECLARE_START
267 #define EXTERN_C_FUNC_DECLARE_START extern "C" {
270 EXTERN_C_FUNC_DECLARE_START
271 auto makePlugin(
const std::string&,
272 const fhicl::ParameterSet& pset)
274 return std::make_unique<mfplugins::ELFriendly>(pset);
278 DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)
Parser-Friendly Message Facility destination plugin