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/MessageService/ELostreamOutput.h"
00007 #include "messagefacility/Utilities/ELseverityLevel.h"
00008 #if MESSAGEFACILITY_HEX_VERSION < 0x20002 // v2_00_02 is s50, pre v2_00_02 is s48
00009 # include "messagefacility/MessageService/ELcontextSupplier.h"
00010 # include "messagefacility/MessageLogger/MessageDrop.h"
00011 #endif
00012 #include "messagefacility/Utilities/exception.h"
00013
00014
00015 #include <iostream>
00016 #include <memory>
00017 #include <algorithm>
00018
00019
00020 namespace mfplugins
00021 {
00022 using namespace mf::service;
00023 using mf::ELseverityLevel;
00024 using mf::ErrorObj;
00025
00029 class ELFriendly : public ELostreamOutput
00030 {
00031 public:
00032
00033 ELFriendly(const fhicl::ParameterSet& pset);
00034
00035 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
00036 virtual void fillPrefix(std::ostringstream&, const ErrorObj&) override;
00037 # else
00038 virtual void fillPrefix(std::ostringstream&, const ErrorObj&, const ELcontextSupplier&) override;
00039 # endif
00040 virtual void fillUsrMsg(std::ostringstream&, const ErrorObj&) override;
00041 virtual void fillSuffix(std::ostringstream&, const ErrorObj&) override;
00042
00043 private:
00044 std::string delimeter_;
00045 };
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 ELFriendly::ELFriendly(const fhicl::ParameterSet& pset)
00057 : ELostreamOutput(pset, cet::ostream_handle{ std::cout }, false)
00058 , delimeter_(pset.get<std::string>("field_delimeter", " "))
00059 {
00060 }
00061
00062
00063
00064
00065 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
00066 void ELFriendly::fillPrefix(std::ostringstream& oss, const ErrorObj& msg)
00067 # else
00068 void ELFriendly::fillPrefix(std::ostringstream& oss, const ErrorObj& msg, ELcontextSupplier const& contextSupplier)
00069 # endif
00070 {
00071
00072
00073
00074
00075 format.preambleMode = true;
00076
00077 auto const& xid = msg.xid();
00078
00079 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
00080 auto id = xid.id();
00081 auto app = xid.application();
00082 auto module = xid.module();
00083 auto subroutine = xid.subroutine();
00084 # else
00085 auto id = xid.id;
00086 auto app = xid.application;
00087 auto process = xid.process;
00088 auto module = xid.module;
00089 auto subroutine = xid.subroutine;
00090 std::replace(process.begin(), process.end(), ' ', '-');
00091 # define emitToken emit
00092 # endif
00093 std::replace(id.begin(), id.end(), ' ', '-');
00094 std::replace(app.begin(), app.end(), ' ', '-');
00095 std::replace(module.begin(), module.end(), ' ', '-');
00096 std::replace(subroutine.begin(), subroutine.end(), ' ', '-');
00097
00098 emitToken(oss, "%MSG");
00099 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
00100 emitToken(oss, xid.severity().getSymbol());
00101 # else
00102 emit(oss, xid.severity.getSymbol());
00103 # endif
00104 emitToken(oss, delimeter_);
00105 emitToken(oss, id);
00106 emitToken(oss, msg.idOverflow());
00107 emitToken(oss, ":");
00108 emitToken(oss, delimeter_);
00109
00110
00111
00112 if (format.want(SERIAL)) {
00113 std::ostringstream s;
00114 s << msg.serial();
00115 emitToken(oss, "[serial #" + s.str() + "]");
00116 emitToken(oss, delimeter_);
00117 }
00118
00119
00120
00121 bool needAspace = true;
00122 if (format.want(EPILOGUE_SEPARATE)) {
00123 if (module.length() + subroutine.length() > 0) {
00124 emitToken(oss, "\n");
00125 needAspace = false;
00126 }
00127 else if (format.want(TIMESTAMP) && !format.want(TIME_SEPARATE)) {
00128 emitToken(oss, "\n");
00129 needAspace = false;
00130 }
00131 }
00132 if (format.want(MODULE) && (module.length() > 0)) {
00133 if (needAspace) {
00134 emitToken(oss, delimeter_);
00135 needAspace = false;
00136 }
00137 emitToken(oss, module + " ");
00138 }
00139 if (format.want(SUBROUTINE) && (subroutine.length() > 0)) {
00140 if (needAspace) {
00141 emitToken(oss, delimeter_);
00142 needAspace = false;
00143 }
00144 emitToken(oss, subroutine + "()");
00145 emitToken(oss, delimeter_);
00146 }
00147
00148
00149
00150 if (format.want(TIMESTAMP)) {
00151 if (format.want(TIME_SEPARATE)) {
00152 emitToken(oss, "\n");
00153 needAspace = false;
00154 }
00155 if (needAspace) {
00156 emitToken(oss, delimeter_);
00157 needAspace = false;
00158 }
00159 emitToken(oss, format.timestamp(msg.timestamp()));
00160 emitToken(oss, delimeter_);
00161 }
00162
00163
00164
00165 if (format.want(SOME_CONTEXT)) {
00166 if (needAspace) {
00167 emitToken(oss, delimeter_);
00168 needAspace = false;
00169 }
00170 # if MESSAGEFACILITY_HEX_VERSION >= 0x20002 // an indication of a switch from s48 to s50
00171 emitToken(oss, msg.context());
00172 # else
00173 if (format.want(FULL_CONTEXT)) {
00174 emit(oss, contextSupplier.fullContext());
00175 }
00176 else {
00177 emit(oss, contextSupplier.context());
00178 }
00179 # endif
00180 }
00181
00182 }
00183
00184
00185
00186 void ELFriendly::fillUsrMsg(std::ostringstream& oss, ErrorObj const& msg)
00187 {
00188 if (!format.want(TEXT)) return;
00189
00190 format.preambleMode = false;
00191 auto const usrMsgStart = std::next(msg.items().cbegin(), 4);
00192 auto it = msg.items().cbegin();
00193
00194
00195 if (true || !msg.is_verbatim()) {
00196
00197
00198 while (it != usrMsgStart) {
00199 if (!it->compare(" ") && !std::next(it)->compare("--")) {
00200
00201 std::advance(it,4);
00202 }
00203 else {
00204
00205 emitToken(oss, *it++);
00206 }
00207 }
00208
00209
00210 if (format.want(NO_LINE_BREAKS)) emitToken(oss, " ==> ");
00211 else emitToken(oss, "", true);
00212 }
00213
00214
00215 auto const end = msg.items().cend();
00216 for (; it != end; ++it) {
00217 emitToken(oss, *it);
00218 }
00219
00220 }
00221
00222
00223
00224 void ELFriendly::fillSuffix(std::ostringstream& oss, ErrorObj const& msg)
00225 {
00226 if ((true || !msg.is_verbatim()) && !format.want(NO_LINE_BREAKS)) {
00227 emitToken(oss,"\n%MSG");
00228 }
00229 oss << '\n';
00230 }
00231
00232
00233
00234 }
00235
00236
00237
00238
00239
00240
00241
00242 extern "C"
00243 {
00244 auto makePlugin(const std::string&,
00245 const fhicl::ParameterSet& pset)
00246 {
00247 return std::make_unique<mfplugins::ELFriendly>(pset);
00248 }
00249 }
00250
00251 DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)