1 #include "cetlib/PluginTypeDeducer.h"
2 #include "fhiclcpp/ParameterSet.h"
4 #include "cetlib/compiler_macros.h"
5 #include "messagefacility/MessageLogger/MessageLogger.h"
6 #include "messagefacility/MessageService/ELdestination.h"
7 #include "messagefacility/Utilities/ELseverityLevel.h"
8 #include "messagefacility/Utilities/exception.h"
11 #include <arpa/inet.h>
14 #include <netinet/in.h>
21 #define TRACE_NAME "OTS_mfPlugin"
25 #include <boost/algorithm/string.hpp>
28 using mf::ELseverityLevel;
30 using mf::service::ELdestination;
36 class ELOTS :
public ELdestination {
46 fhicl::Name{
"format_string"}, fhicl::Comment{
"Format specifier for printing to console. %% => '%' ... "},
50 fhicl::Atom<std::string>{fhicl::Name{
"filename_delimit"},
51 fhicl::Comment{
"Grab path after this. \"/srcs/\" /x/srcs/y/z.cc => y/z.cc"},
"/"};
68 virtual void fillPrefix(std::ostringstream& o,
const ErrorObj& e)
override;
75 virtual void fillUsrMsg(std::ostringstream& o,
const ErrorObj& e)
override;
80 virtual void fillSuffix(std::ostringstream&,
const ErrorObj&)
override {}
87 virtual void routePayload(
const std::ostringstream& o,
const ErrorObj& e)
override;
92 std::string hostname_;
93 std::string hostaddr_;
95 std::string format_string_;
96 std::string filename_delimit_;
108 : ELdestination(pset().elDestConfig()),
109 pid_(static_cast<long>(getpid())),
110 format_string_(pset().format_string()),
111 filename_delimit_(pset().filename_delimit()) {
113 char hostname_c[1024];
114 hostname_ = (gethostname(hostname_c, 1023) == 0) ? hostname_c :
"Unkonwn Host";
117 hostent* host =
nullptr;
118 host = gethostbyname(hostname_c);
120 if (host !=
nullptr) {
122 char* ip = inet_ntoa(*(
struct in_addr*)host->h_addr);
126 struct ifaddrs* ifAddrStruct =
nullptr;
127 struct ifaddrs* ifa =
nullptr;
128 void* tmpAddrPtr =
nullptr;
130 if (getifaddrs(&ifAddrStruct)) {
132 hostaddr_ =
"127.0.0.1";
135 for (ifa = ifAddrStruct; ifa !=
nullptr; ifa = ifa->ifa_next) {
136 if (ifa->ifa_addr->sa_family == AF_INET) {
138 tmpAddrPtr = &((
struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
139 char addressBuffer[INET_ADDRSTRLEN];
140 inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
141 hostaddr_ = addressBuffer;
144 else if (ifa->ifa_addr->sa_family == AF_INET6) {
146 tmpAddrPtr = &((
struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr;
147 char addressBuffer[INET6_ADDRSTRLEN];
148 inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
149 hostaddr_ = addressBuffer;
153 if (!hostaddr_.empty() && hostaddr_.compare(
"127.0.0.1") && hostaddr_.compare(
"::1"))
break;
156 if (hostaddr_.empty())
157 hostaddr_ =
"127.0.0.1";
162 std::stringstream ss;
163 ss <<
"//proc//" << pid_ <<
"//cmdline";
164 std::ifstream procfile{ss.str().c_str()};
166 std::string procinfo;
168 if (procfile.is_open()) {
169 procfile >> procinfo;
173 size_t end = procinfo.find(
'\0');
174 size_t start = procinfo.find_last_of(
'/', end);
176 app_ = procinfo.substr(start + 1, end - start - 1);
183 const auto& xid = msg.xid();
186 auto module = xid.module();
188 char* cp = &format_string_[0];
190 bool msg_printed =
false;
215 if (filename_delimit_.size() == 0)
216 oss << msg.filename();
217 else if (filename_delimit_.size() == 1)
218 oss << (strrchr(&msg.filename()[0], filename_delimit_[0])
219 ? strrchr(&msg.filename()[0], filename_delimit_[0]) + 1
222 oss << (strstr(&msg.filename()[0], &filename_delimit_[0])
223 ? strstr(&msg.filename()[0], &filename_delimit_[0]) + filename_delimit_.size()
230 oss << xid.severity().getName();
234 for (
auto const& val : msg.items()) ossstr += val;
236 if (ossstr.compare(0, 1,
"\n") == 0) ossstr.erase(0, 1);
237 if (ossstr.compare(ossstr.size() - 1, 1,
"\n") == 0)
238 ossstr.erase(ossstr.size() - 1, 1);
250 oss << mf::GetIteration();
253 sev = xid.severity().getName()[0] | 0x20;
257 oss << format_.timestamp(msg.timestamp());
260 oss << std::to_string(msg.lineNumber());
271 for (
auto const& val : msg.items()) ossstr += val;
272 if (ossstr.compare(0, 1,
"\n") == 0) ossstr.erase(0, 1);
273 if (ossstr.compare(ossstr.size() - 1, 1,
"\n") == 0)
274 ossstr.erase(ossstr.size() - 1, 1);
283 const ErrorObj& msg __attribute__((__unused__))) {
290 void ELOTS::routePayload(
const std::ostringstream& oss,
const ErrorObj&) { std::cout << oss.str() << std::endl; }
298 #ifndef EXTERN_C_FUNC_DECLARE_START
299 #define EXTERN_C_FUNC_DECLARE_START extern "C" {
302 EXTERN_C_FUNC_DECLARE_START
auto makePlugin(
const std::string&,
const fhicl::ParameterSet& pset) {
303 return std::make_unique<mfplugins::ELOTS>(pset);
307 DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)
Configuration Parameters for ELOTS.
fhicl::Atom< std::string > filename_delimit
filename_delimit (Default: "/"): Grab path after this. "/srcs/" /x/srcs/y/z.cc => y/z...
virtual void fillUsrMsg(std::ostringstream &o, const ErrorObj &e) override
Fill the "User Message" portion of the message.
fhicl::TableFragment< ELdestination::Config > elDestConfig
ELDestination common config parameters.
virtual void routePayload(const std::ostringstream &o, const ErrorObj &e) override
Serialize a MessageFacility message to the output.
fhicl::Atom< std::string > format_string
format_string (Default: "%L:%N:%f [%u] %m"): Format specifier for printing to console. %% => '' ...
Message Facility OTS Console Destination Formats messages into Ryan's favorite format for OTS ...
virtual void fillPrefix(std::ostringstream &o, const ErrorObj &e) override
Fill the "Prefix" portion of the message.
fhicl::WrappedTable< Config > Parameters
Used for ParameterSet validation.
virtual void fillSuffix(std::ostringstream &, const ErrorObj &) override
Fill the "Suffix" portion of the message (Unused)
ELOTS(Parameters const &pset)
ELOTS Constructor