ELadministrator.cc
Go to the documentation of this file.
5 
6 #include <arpa/inet.h>
7 #include <ifaddrs.h>
8 #include <netdb.h>
9 #include <netinet/in.h>
10 
11 #include <fstream>
12 #include <iostream>
13 #include <list>
14 #include <sstream>
15 
16 using std::cerr;
17 
18 void
20 {
21  auto const severity = msg.xid().severity();
22  updateMsg_(msg);
23  int const lev = severity.getLevel();
24  ++severityCounts_[lev];
25  if (severity > highSeverity_)
26  highSeverity_ = severity;
27 
28  if (destinations_.empty()) {
29  std::cerr
30  << "\nERROR LOGGED WITHOUT DESTINATION!\n"
31  << "Attaching destination \"cerr\" to ELadministrator by default\n\n";
32  destinations_.emplace(
33  "cerr",
34  std::make_unique<ELostreamOutput>(default_destinations_config(),
35  cet::ostream_handle{std::cerr}));
36  }
37 
38  for_all_destinations([&msg](auto& d) { d.log(msg); });
39 }
40 
41 // ----------------------------------------------------------------------
42 // ELadministrator functionality:
43 // ----------------------------------------------------------------------
44 
45 void
47 {
49 }
50 
51 bool
53 {
54  return destinations_.find(name) != destinations_.end();
55 }
56 
59 {
60  ELseverityLevel const retval{highSeverity_};
62  return retval;
63 }
64 
65 int
67 {
68  return severityCounts_[sev.getLevel()];
69 }
70 
71 int
73  ELseverityLevel const to) const
74 {
75  int k = from.getLevel();
76  int sum = severityCounts_[k];
77 
78  while (++k <= to.getLevel())
79  sum += severityCounts_[k];
80 
81  return sum;
82 }
83 
84 void
86 {
87  severityCounts_[sev.getLevel()] = 0;
88 }
89 
90 void
92  ELseverityLevel const to)
93 {
94  for (int k = from.getLevel(); k <= to.getLevel(); ++k)
95  severityCounts_[k] = 0;
96 }
97 
98 void
100 {
102 }
103 
105  std::string const& applicationName)
106 {
107  // hostname
108  char hostname[1024];
109  hostname_ = (gethostname(hostname, 1023) == 0) ? hostname : "Unkonwn Host";
110 
111  // host ip address
112  hostent* host = nullptr;
113  host = gethostbyname(hostname);
114 
115  if (host != nullptr) {
116  // ip address from hostname if the entry exists in /etc/hosts
117  char* ip = inet_ntoa(*(struct in_addr*)host->h_addr);
118  hostaddr_ = ip;
119  } else {
120  // enumerate all network interfaces
121  struct ifaddrs* ifAddrStruct = nullptr;
122  struct ifaddrs* ifa = nullptr;
123  void* tmpAddrPtr = nullptr;
124 
125  if (getifaddrs(&ifAddrStruct)) {
126  // failed to get addr struct
127  hostaddr_ = "127.0.0.1";
128  } else {
129  // iterate through all interfaces
130  for (ifa = ifAddrStruct; ifa != nullptr; ifa = ifa->ifa_next) {
131  if (ifa->ifa_addr->sa_family == AF_INET) {
132  // a valid IPv4 addres
133  tmpAddrPtr = &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
134  char addressBuffer[INET_ADDRSTRLEN];
135  inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
136  hostaddr_ = addressBuffer;
137  } else if (ifa->ifa_addr->sa_family == AF_INET6) {
138  // a valid IPv6 address
139  tmpAddrPtr = &((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr;
140  char addressBuffer[INET6_ADDRSTRLEN];
141  inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
142  hostaddr_ = addressBuffer;
143  }
144 
145  // find first non-local address
146  if (!hostaddr_.empty() && hostaddr_.compare("127.0.0.1") &&
147  hostaddr_.compare("::1"))
148  break;
149  }
150 
151  if (hostaddr_.empty()) // failed to find anything
152  hostaddr_ = "127.0.0.1";
153  }
154  }
155 
156  // process id
157  pid_ = static_cast<long>(getpid());
158 
159  if (applicationName.empty()) {
160  // get process name from '/proc/pid/cmdline'
161  std::stringstream ss;
162  ss << "//proc//" << pid_ << "//cmdline";
163  std::ifstream procfile{ss.str().c_str()};
164 
165  std::string procinfo;
166 
167  if (procfile.is_open()) {
168  procfile >> procinfo;
169  procfile.close();
170  }
171 
172  size_t end = procinfo.find('\0');
173  size_t start = procinfo.find_last_of('/', end);
174 
175  application_ = procinfo.substr(start + 1, end - start - 1);
176  } else {
177  application_ = applicationName;
178  }
179 } // ELadministrator()
180 
181 void
183 {
184  auto const& xid = msg.xid();
185  if (xid.hostname().empty()) {
186  msg.setHostName(hostname());
187  }
188  if (xid.hostaddr().empty()) {
189  msg.setHostAddr(hostaddr());
190  }
191  if (xid.application().empty()) {
193  }
194  if (xid.pid() == 0) {
195  msg.setPID(pid());
196  }
197 }
ELextendedID const & xid() const
Definition: ErrorObj.cc:44
virtual void setHostName(const std::string &hostname)
Definition: ErrorObj.cc:137
std::string string
Definition: nybbler.cc:12
ELslProxy< ELhighestSeverityGen > constexpr ELhighestSeverity
virtual void setPID(long pid)
Definition: ErrorObj.cc:155
bool hasDestination(std::string const &) const
virtual void setHostAddr(const std::string &hostaddr)
Definition: ErrorObj.cc:143
void setApplication(std::string const &application)
std::string const & hostname() const
int severityCount(ELseverityLevel sev) const
void updateMsg_(ErrorObj &msg) const
ELslProxy< ELzeroSeverityGen > constexpr ELzeroSeverity
ELseverityLevel severity() const
Definition: ELextendedID.h:76
destination_collection_t destinations_
virtual void setApplication(const std::string &application)
Definition: ErrorObj.cc:149
ELadministrator(ELadministrator const &)=delete
start
Definition: test.py:4
end
Definition: test.py:8
std::array< int, ELseverityLevel::nLevels > severityCounts_
std::string const & hostaddr() const
ELseverityLevel checkSeverity()
std::string const & application() const