4 #include "cetlib/BasicPluginFactory.h" 5 #include "cetlib/HorizontalRule.h" 6 #include "cetlib/container_algorithms.h" 7 #include "cetlib/exempt_ptr.h" 8 #include "cetlib/os_libpath.h" 9 #include "cetlib/propagate_const.h" 10 #include "cetlib/trim.h" 15 #include "hep_concurrency/RecursiveMutex.h" 37 #include <type_traits> 41 #include <arpa/inet.h> 44 #include <netinet/in.h> 53 namespace ELdestConfig {
69 if (getenv(
"MF_PLUGIN_PATH") !=
nullptr) {
70 return cet::search_path{
"MF_PLUGIN_PATH"};
72 return cet::search_path{cet::os_libpath()};
75 cet::BasicPluginFactory pluginFactory_{getPluginPath(),
"mfPlugin"};
76 cet::BasicPluginFactory pluginStatsFactory_{getPluginPath(),
78 atomic<bool> isStarted{
false};
79 map<string const, unique_ptr<service::ELdestination>> destinations_;
80 bool cleanSlateConfiguration_{
true};
81 atomic<bool> purgeMode_{
false};
82 atomic<int> count_{0};
86 RecursiveMutex msgMutex_{
"MessageLogger::msgMutex_"};
94 thread_local
string module_ =
"Early";
99 thread_local
string iteration_ =
"pre-events";
102 initGlobalVars(
string const& applicationName =
"")
104 char hostname[1024] = {0};
106 (gethostname(hostname, 1023) == 0) ? hostname :
"Unknown Host";
107 hostent* host =
nullptr;
108 host = gethostbyname(hostname);
109 if (host !=
nullptr) {
111 char* ip = inet_ntoa(*(
struct in_addr*)host->h_addr);
116 ifaddrs* ifAddrStruct =
nullptr;
117 if (getifaddrs(&ifAddrStruct)) {
119 hostaddr_ =
"127.0.0.1";
122 for (ifaddrs* ifa = ifAddrStruct; ifa !=
nullptr;
123 ifa = ifa->ifa_next) {
124 if (ifa->ifa_addr->sa_family == AF_INET) {
126 void* tmpAddrPtr = &((sockaddr_in*)ifa->ifa_addr)->sin_addr;
127 char addressBuffer[INET_ADDRSTRLEN];
128 inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
129 hostaddr_ = addressBuffer;
130 }
else if (ifa->ifa_addr->sa_family == AF_INET6) {
132 void* tmpAddrPtr = &((sockaddr_in6*)ifa->ifa_addr)->sin6_addr;
133 char addressBuffer[INET6_ADDRSTRLEN];
134 inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
135 hostaddr_ = addressBuffer;
138 if (!hostaddr_.empty() && hostaddr_.compare(
"127.0.0.1") &&
139 hostaddr_.compare(
"::1")) {
143 if (hostaddr_.empty()) {
145 hostaddr_ =
"127.0.0.1";
149 if (!applicationName.empty()) {
150 application_ = applicationName;
154 ss <<
"//proc//" << pid_ <<
"//cmdline";
155 ifstream procfile{ss.str().c_str()};
157 if (procfile.is_open()) {
159 procfile >> procinfo;
162 auto end = procinfo.find(
'\0');
163 auto start = procinfo.find_last_of(
'/',
end);
164 application_ = procinfo.substr(start + 1,
end - start - 1);
166 pid_ =
static_cast<long>(getpid());
177 unique_ptr<service::ELdestination>
178 makePlugin_(cet::BasicPluginFactory& plugin_factory,
179 string const& libspec,
180 string const& psetname,
183 unique_ptr<service::ELdestination> result;
185 auto const pluginType = plugin_factory.pluginType(libspec);
189 plugin_factory.makePlugin<unique_ptr<service::ELdestination>>(
190 libspec, psetname, pset);
193 <<
"unrecognized plugin type " << pluginType <<
"for plugin " 199 <<
"Exception caught while processing plugin spec.\n";
204 string const default_destination_config_string =
" type: cerr" 212 default_destination_config()
220 default_destination_set_config()
222 string const config{
"cerr: { "s + default_destination_config_string +
232 map<
string const, unique_ptr<service::ELdestination>>& destinations)
243 if (msg.
xid().
pid() == 0) {
246 if (destinations.empty()) {
247 cerr <<
"\nERROR LOGGED WITHOUT DESTINATION!\nAttaching destination " 248 "\"cerr\" by default\n\n";
249 destinations.emplace(
251 make_unique<service::ELostreamOutput>(
252 default_destination_set_config(), cet::ostream_handle{cerr}));
254 for (
auto& destid_and_destination : destinations) {
255 destid_and_destination.second->log(msg);
264 vector<string> config_errors;
267 if (dest_pset.is_empty()) {
268 dest_pset = default_destination_config();
272 if (!dest_pset.get_if_present(
"type", dest_type)) {
274 <<
"No 'type' specified for destination '" << psetname <<
"'.\n";
277 if ((dest_type !=
"cout"s) && (dest_type !=
"cerr"s) &&
278 (dest_type !=
"file"s)) {
281 <<
"Unsupported type [ " << dest_type
282 <<
" ] chosen for statistics printout.\n" 283 <<
"Must choose ostream type: \"cout\", \"cerr\", or \"file\"" 287 string outputId{dest_type};
288 if ((dest_type !=
"cout"s) && (dest_type !=
"cerr"s) &&
289 (dest_type !=
"syslog"s)) {
290 outputId +=
":" + dest_pset.get<
string>(
"filename", psetname);
292 if (!ids.emplace(outputId).second) {
297 <<
" Output identifier: \"" << outputId <<
"\"" 298 <<
" already specified within ordinary/statistics block in FHiCL " 303 auto iter_id_dest = destinations_.find(outputId);
304 if (iter_id_dest != destinations_.end()) {
305 string const hrule{
"\n===============================================" 306 "============================= \n"};
307 ostringstream except_msg;
308 except_msg << hrule <<
"\n Duplicate name for a ";
310 except_msg <<
"MessageLogger";
312 except_msg <<
"MessageLogger Statistics";
314 except_msg <<
" destination: \"" << outputId <<
'"';
315 ostringstream orig_config_msg;
317 <<
"\n Only original configuration instructions are used. \n" 319 if (cleanSlateConfiguration_) {
321 << except_msg.str() << orig_config_msg.str();
324 << except_msg.str() << orig_config_msg.str();
328 string const& libspec = dest_type;
329 auto& plugin_factory =
331 pluginStatsFactory_ :
334 destinations_[outputId] =
335 makePlugin_(plugin_factory, libspec, psetname, dest_pset);
338 string msg{
"Configuration error for destination: " +
341 config_errors.push_back(move(msg));
344 if (!config_errors.empty()) {
345 string msg{
"\nThe following messagefacility destinations have " 346 "configuration errors:\n\n"};
347 constexpr cet::HorizontalRule rule{60};
350 auto start = cbegin(config_errors);
353 for (
auto it = start,
e = cend(config_errors); it !=
e; ++it) {
367 if (destinations_.size() > 1) {
369 <<
"The message logger has been configured multiple times";
370 cleanSlateConfiguration_ =
false;
375 dest_psets = default_destination_set_config();
377 ordinaryDests = dest_psets;
378 ordinaryDests.
erase(
"statistics");
384 string const default_config{
"file_stats: {\n" 386 " filename: \"err.log\"\n" 387 " threshold: WARNING\n" 393 "statistics", default_statistics_config);
438 RecursiveMutexSentry sentry{msgMutex_, __func__};
441 unique_ptr<ErrorObj> msgHolder{msg};
443 sendMsgToDests(*msg, destinations_);
447 cerr <<
"MessageLoggerScribe caught " << count_
448 <<
" cet::exceptions, text = \n" 451 cerr <<
"MessageLogger will no longer be processing messages due to " 452 "errors (entering purge mode).\n";
457 cerr <<
"MessageLoggerScribe caught an unknown exception and will no " 458 "longer be processing messages. (entering purge mode)\n";
518 for (
auto& destid_and_dest : destinations_) {
519 auto& dest = *destid_and_dest.second;
524 cerr <<
"MessageLoggerScribe caught exception during summarize:\n" 528 cerr <<
"MessageLoggerScribe caught unknown exception type during " 529 "summarize. (Ignored)\n";
539 return isStarted.load();
546 if (isStarted.load()) {
569 if (isStarted.load()) {
582 string const& applicationName)
584 if (isStarted.load()) {
589 initGlobalVars(applicationName);
591 destinations_[
"cerr_early"s] = makePlugin_(
592 pluginFactory_,
"cerr",
"cerr_early", default_destination_config());
595 string msg{
"\nConfiguration error for destination: " +
609 "Exception from MessageLoggerScribe::configure",
612 isStarted.store(
true);
619 isStarted.store(
false);
635 for (
auto& category_and_destination : destinations_) {
636 category_and_destination.second->finish();
644 application_ = applicationName;
651 hostname_ = hostname;
658 hostaddr_ = hostaddr;
777 if (isStarted.load()) {
std::string bold_fontify(std::string const &s)
fhicl::OptionalDelegatedParameter destinations
ELseverityLevel severity() const
void SetIteration(string const &val)
void SetHostAddr(string const &hostaddr)
void EndMessageFacility()
std::string const & application() const
virtual void setPID(long)
string const & GetModuleName()
void make_ParameterSet(intermediate_table const &tbl, ParameterSet &ps)
static struct mf::FinalShutdown ensureShutdown
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
ELslProxy< ELhighestSeverityGen > constexpr ELhighestSeverity
virtual void setHostName(std::string const &)
void SetContextIteration(string const &val)
cet::coded_exception< errors::error, detail::translate > Exception
std::string const & idOverflow() const
bool isMessageProcessingSetUp()
std::vector< std::string > get_pset_names() const
void StartMessageFacility(fhicl::ParameterSet const &pset, string const &applicationName)
std::string const & hostaddr() const
ELextendedID const & xid() const
T get(std::string const &key) const
virtual void setHostAddr(std::string const &)
std::string const & id() const
std::string fullText() const
virtual void setApplication(std::string const &)
void SetHostName(string const &hostname)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
string const & GetHostName()
char const * what() const noexcept override
std::string value(boost::any const &)
bool get_if_present(T &t) const
string const & GetIteration()
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void SetContextSinglet(string const &val)
virtual void setReactedTo(bool)
bool erase(std::string const &key)
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
void LogErrorObj(ErrorObj *msg)
void SetModuleName(string const &val)
void SetApplicationName(string const &applicationName)
std::string const & hostname() const
cet::coded_exception< error, detail::translate > exception
std::string getSymbol() const
string const & GetApplicationName()
string const & GetHostAddr()