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>
29 using mf::service::ELdestination;
35 class ELOTS :
public ELdestination
47 fhicl::Name{
"format_string"}, fhicl::Comment{
"Format specifier for printing to console. %% => '%' ... "},
51 fhicl::Atom<std::string>{fhicl::Name{
"filename_delimit"},
52 fhicl::Comment{
"Grab path after this. \"/srcs/\" /x/srcs/y/z.cc => y/z.cc"},
"/"};
69 void fillPrefix(std::ostringstream& o,
const ErrorObj& msg)
override;
76 void fillUsrMsg(std::ostringstream& o,
const ErrorObj& msg)
override;
81 void fillSuffix(std::ostringstream& ,
const ErrorObj& )
override {}
88 void routePayload(
const std::ostringstream& o,
const ErrorObj& e)
override;
93 std::string hostname_;
94 std::string hostaddr_;
96 std::string format_string_;
97 std::string filename_delimit_;
109 : ELdestination(pset().elDestConfig()), pid_(static_cast<int64_t>(getpid())), format_string_(pset().format_string()), filename_delimit_(pset().filename_delimit())
112 char hostname_c[1024];
113 hostname_ = (gethostname(hostname_c, 1023) == 0) ? hostname_c :
"Unkonwn Host";
116 hostent* host =
nullptr;
117 host = gethostbyname(hostname_c);
122 char* ip = inet_ntoa(*reinterpret_cast<struct in_addr*>(host->h_addr));
128 struct ifaddrs* ifAddrStruct =
nullptr;
129 struct ifaddrs* ifa =
nullptr;
130 void* tmpAddrPtr =
nullptr;
132 if (getifaddrs(&ifAddrStruct) != 0)
135 hostaddr_ =
"127.0.0.1";
140 for (ifa = ifAddrStruct; ifa !=
nullptr; ifa = ifa->ifa_next)
142 if (ifa->ifa_addr->sa_family == AF_INET)
145 tmpAddrPtr = &(
reinterpret_cast<struct sockaddr_in*
>(ifa->ifa_addr))->sin_addr;
146 char addressBuffer[INET_ADDRSTRLEN];
147 inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
148 hostaddr_ = addressBuffer;
151 else if (ifa->ifa_addr->sa_family == AF_INET6)
154 tmpAddrPtr = &(
reinterpret_cast<struct sockaddr_in6*
>(ifa->ifa_addr))->sin6_addr;
155 char addressBuffer[INET6_ADDRSTRLEN];
156 inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
157 hostaddr_ = addressBuffer;
161 if (!hostaddr_.empty() && (hostaddr_ !=
"127.0.0.1") && (hostaddr_ !=
"::1"))
167 if (hostaddr_.empty())
169 hostaddr_ =
"127.0.0.1";
175 std::stringstream ss;
176 ss <<
"//proc//" << pid_ <<
"//cmdline";
177 std::ifstream procfile{ss.str().c_str()};
179 std::string procinfo;
181 if (procfile.is_open())
183 procfile >> procinfo;
187 size_t end = procinfo.find(
'\0');
188 size_t start = procinfo.find_last_of(
'/', end);
190 app_ = procinfo.substr(start + 1, end - start - 1);
198 const auto& xid = msg.xid();
200 const auto&
id = xid.id();
201 const auto& module = xid.module();
203 char* cp = &format_string_[0];
205 bool msg_printed =
false;
209 for (; *cp != 0; ++cp)
234 if (filename_delimit_.empty())
236 oss << msg.filename();
238 else if (filename_delimit_.size() == 1)
240 oss << (strrchr(&msg.filename()[0], filename_delimit_[0]) !=
nullptr
241 ? strrchr(&msg.filename()[0], filename_delimit_[0]) + 1
246 oss << (strstr(&msg.filename()[0], &filename_delimit_[0]) !=
nullptr
247 ? strstr(&msg.filename()[0], &filename_delimit_[0]) + filename_delimit_.size()
255 oss << xid.severity().getName();
259 for (
auto const& val : msg.items())
265 if (ossstr.compare(0, 1,
"\n") == 0)
269 if (ossstr.compare(ossstr.size() - 1, 1,
"\n") == 0)
271 ossstr.erase(ossstr.size() - 1, 1);
284 oss << mf::GetIteration();
287 sev = xid.severity().getName()[0] | 0x20;
291 oss << format_.timestamp(msg.timestamp());
294 oss << std::to_string(msg.lineNumber());
306 for (
auto const& val : msg.items())
310 if (ossstr.compare(0, 1,
"\n") == 0)
314 if (ossstr.compare(ossstr.size() - 1, 1,
"\n") == 0)
316 ossstr.erase(ossstr.size() - 1, 1);
326 const ErrorObj& msg __attribute__((__unused__)))
334 void ELOTS::routePayload(
const std::ostringstream& oss,
const ErrorObj& ) { std::cout << oss.str() << std::endl; }
342 #ifndef EXTERN_C_FUNC_DECLARE_START
343 #define EXTERN_C_FUNC_DECLARE_START extern "C" {
346 EXTERN_C_FUNC_DECLARE_START
auto makePlugin(
const std::string& ,
const fhicl::ParameterSet& pset)
348 return std::make_unique<mfplugins::ELOTS>(pset);
352 DEFINE_BASIC_PLUGINTYPE_FUNC(mf::service::ELdestination)
void fillSuffix(std::ostringstream &, const ErrorObj &) override
Fill the "Suffix" portion of the message (Unused)
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...
fhicl::TableFragment< ELdestination::Config > elDestConfig
ELDestination common config parameters.
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 ...
void fillPrefix(std::ostringstream &o, const ErrorObj &msg) override
Fill the "Prefix" portion of the message.
fhicl::WrappedTable< Config > Parameters
Used for ParameterSet validation.
void fillUsrMsg(std::ostringstream &o, const ErrorObj &msg) override
Fill the "User Message" portion of the message.
ELOTS(Parameters const &pset)
ELOTS Constructor