1 #include "cetlib/PluginTypeDeducer.h"
2 #include "fhiclcpp/ParameterSet.h"
3 #include "fhiclcpp/types/ConfigurationTable.h"
5 #include "cetlib/compiler_macros.h"
6 #include "messagefacility/MessageLogger/MessageLogger.h"
7 #include "messagefacility/MessageService/ELdestination.h"
8 #include "messagefacility/Utilities/ELseverityLevel.h"
9 #include "messagefacility/Utilities/exception.h"
12 #include <arpa/inet.h>
15 #include <netinet/in.h>
22 #define TRACE_NAME "OTS_mfPlugin"
26 #include <boost/algorithm/string.hpp>
30 using mf::service::ELdestination;
36 class ELOTS :
public ELdestination
48 fhicl::Name{
"format_string"}, fhicl::Comment{
"Format specifier for printing to console. %% => '%' ... "},
52 fhicl::Atom<std::string>{fhicl::Name{
"filename_delimit"},
53 fhicl::Comment{
"Grab path after this. \"/srcs/\" /x/srcs/y/z.cc => y/z.cc"},
"/"};
70 void fillPrefix(std::ostringstream& o,
const ErrorObj& msg)
override;
77 void fillUsrMsg(std::ostringstream& o,
const ErrorObj& msg)
override;
82 void fillSuffix(std::ostringstream& ,
const ErrorObj& )
override {}
89 void routePayload(
const std::ostringstream& o,
const ErrorObj& e)
override;
94 std::string hostname_;
95 std::string hostaddr_;
97 std::string format_string_;
98 std::string filename_delimit_;
110 : ELdestination(pset().elDestConfig()), pid_(static_cast<int64_t>(getpid())), format_string_(pset().format_string()), 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);
123 char* ip = inet_ntoa(*reinterpret_cast<struct in_addr*>(host->h_addr));
129 struct ifaddrs* ifAddrStruct =
nullptr;
130 struct ifaddrs* ifa =
nullptr;
131 void* tmpAddrPtr =
nullptr;
133 if (getifaddrs(&ifAddrStruct) != 0)
136 hostaddr_ =
"127.0.0.1";
141 for (ifa = ifAddrStruct; ifa !=
nullptr; ifa = ifa->ifa_next)
143 if (ifa->ifa_addr->sa_family == AF_INET)
146 tmpAddrPtr = &(
reinterpret_cast<struct sockaddr_in*
>(ifa->ifa_addr))->sin_addr;
147 char addressBuffer[INET_ADDRSTRLEN];
148 inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
149 hostaddr_ = addressBuffer;
152 else if (ifa->ifa_addr->sa_family == AF_INET6)
155 tmpAddrPtr = &(
reinterpret_cast<struct sockaddr_in6*
>(ifa->ifa_addr))->sin6_addr;
156 char addressBuffer[INET6_ADDRSTRLEN];
157 inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
158 hostaddr_ = addressBuffer;
162 if (!hostaddr_.empty() && (hostaddr_ !=
"127.0.0.1") && (hostaddr_ !=
"::1"))
168 if (hostaddr_.empty())
170 hostaddr_ =
"127.0.0.1";
176 std::stringstream ss;
177 ss <<
"//proc//" << pid_ <<
"//cmdline";
178 std::ifstream procfile{ss.str().c_str()};
180 std::string procinfo;
182 if (procfile.is_open())
184 procfile >> procinfo;
188 size_t end = procinfo.find(
'\0');
189 size_t start = procinfo.find_last_of(
'/', end);
191 app_ = procinfo.substr(start + 1, end - start - 1);
199 const auto& xid = msg.xid();
201 const auto&
id = xid.id();
202 const auto& module = xid.module();
204 char* cp = &format_string_[0];
206 bool msg_printed =
false;
210 for (; *cp != 0; ++cp)
235 if (filename_delimit_.empty())
237 oss << msg.filename();
239 else if (filename_delimit_.size() == 1)
241 oss << (strrchr(&msg.filename()[0], filename_delimit_[0]) !=
nullptr
242 ? strrchr(&msg.filename()[0], filename_delimit_[0]) + 1
247 const char* cp = strstr(&msg.filename()[0], &filename_delimit_[0]);
251 cp += filename_delimit_.size() - 1;
252 while (*cp && *cp !=
'/') ++cp;
257 oss << msg.filename();
264 oss << xid.severity().getName();
268 for (
auto const& val : msg.items())
274 if (ossstr.compare(0, 1,
"\n") == 0)
278 if (ossstr.compare(ossstr.size() - 1, 1,
"\n") == 0)
280 ossstr.erase(ossstr.size() - 1, 1);
293 oss << mf::GetIteration();
296 sev = xid.severity().getName()[0] | 0x20;
300 oss << format_.timestamp(msg.timestamp());
303 oss << std::to_string(msg.lineNumber());
315 for (
auto const& val : msg.items())
319 if (ossstr.compare(0, 1,
"\n") == 0)
323 if (ossstr.compare(ossstr.size() - 1, 1,
"\n") == 0)
325 ossstr.erase(ossstr.size() - 1, 1);
335 const ErrorObj& msg __attribute__((__unused__)))
343 void ELOTS::routePayload(
const std::ostringstream& oss,
const ErrorObj& ) { std::cout << oss.str() << std::endl; }
351 #ifndef EXTERN_C_FUNC_DECLARE_START
352 #define EXTERN_C_FUNC_DECLARE_START extern "C" {
355 EXTERN_C_FUNC_DECLARE_START
auto makePlugin(
const std::string& ,
const fhicl::ParameterSet& pset)
357 return std::make_unique<mfplugins::ELOTS>(pset);
361 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