Public Member Functions | Private Member Functions | Private Attributes | List of all members
mf::service::MessageLoggerScribe Class Reference

#include <MessageLoggerScribe.h>

Inheritance diagram for mf::service::MessageLoggerScribe:
mf::service::AbstractMLscribe

Public Member Functions

 ~MessageLoggerScribe ()
 
 MessageLoggerScribe (std::string const &applicationName)
 
 MessageLoggerScribe (MessageLoggerScribe const &)=delete
 
MessageLoggerScribeoperator= (MessageLoggerScribe const &)=delete
 
void runCommand (OpCode opcode, void *operand) override
 
void setApplication (std::string const &application) override
 
void setHostName (std::string const &hostName) override
 
void setHostAddr (std::string const &hostAddr) override
 
void setPID (long pid) override
 
- Public Member Functions inherited from mf::service::AbstractMLscribe
 AbstractMLscribe ()=default
 
virtual ~AbstractMLscribe () noexcept=default
 
 AbstractMLscribe (AbstractMLscribe const &)=delete
 
AbstractMLscribeoperator= (AbstractMLscribe const &)=delete
 
virtual void setApplication (std::string const &application[[gnu::unused]])
 
virtual void setHostName (std::string const &hostName[[gnu::unused]])
 
virtual void setHostAddr (std::string const &hostAddr[[gnu::unused]])
 
virtual void setPID (long pid[[gnu::unused]])
 

Private Member Functions

void log (ErrorObj *errorobj_p)
 
void triggerStatisticsSummaries ()
 
void configure_errorlog (std::unique_ptr< MessageLoggerQ::Config > &&dests_config)
 
void fetchDestinations (std::unique_ptr< MessageLoggerQ::Config > dests_config)
 
void makeDestinations (fhicl::ParameterSet const &dests, ELdestConfig::dest_config const config)
 
std::vector< std::stringparseCategories (std::string const &s)
 
std::string createId (std::set< std::string > &existing_ids, std::string const &type, std::string const &filename, fhicl::ParameterSet const &pset={}, bool const should_throw=true)
 
bool duplicateDestination (std::string const &output_id, ELdestConfig::dest_config const config, bool const should_throw)
 
std::unique_ptr< ELdestinationmakePlugin_ (cet::BasicPluginFactory &pluginFactory, std::string const &libspec, std::string const &psetname, fhicl::ParameterSet const &pset)
 

Private Attributes

ELadministrator admin_
 
cet::BasicPluginFactory pluginFactory_ {"mfPlugin"}
 
cet::BasicPluginFactory pluginStatsFactory_ {"mfStatsPlugin"}
 
ELdestinationearlyDest_
 
bool cleanSlateConfiguration_ {true}
 
bool active_ {true}
 
std::atomic< bool > purgeMode_ {false}
 
std::atomic< int > count_ {0}
 
std::atomic< bool > messageBeingSent_ {false}
 
tbb::concurrent_queue< ErrorObj * > waitingMessages_ {}
 

Detailed Description

Definition at line 25 of file MessageLoggerScribe.h.

Constructor & Destructor Documentation

mf::service::MessageLoggerScribe::~MessageLoggerScribe ( )

Definition at line 79 of file MessageLoggerScribe.cc.

80  {
81  // If there are any waiting message, finish them off
82  ErrorObj* errorobj_p = nullptr;
83  while (waitingMessages_.try_pop(errorobj_p)) {
84  if (!purgeMode_) {
85  for (auto const& cat : parseCategories(errorobj_p->xid().id())) {
86  errorobj_p->setID(cat);
87  admin_.log(*errorobj_p); // route the message text
88  }
89  }
90  delete errorobj_p;
91  }
92  admin_.finish();
93  }
std::vector< std::string > parseCategories(std::string const &s)
tbb::concurrent_queue< ErrorObj * > waitingMessages_
mf::service::MessageLoggerScribe::MessageLoggerScribe ( std::string const &  applicationName)

Definition at line 60 of file MessageLoggerScribe.cc.

61  : admin_ {
62  applicationName
63  }
64  , earlyDest_{admin_.attach("cerr_early",
66  "cerr",
67  "cerr_early",
69  {}
71  {
72  std::string msg{"\nConfiguration error for destination: " +
73  detail::bold_fontify("cerr_early") + "\n\n"};
74  msg += e.what();
75  throw Exception(errors::Configuration) << msg;
76  }
std::string string
Definition: nybbler.cc:12
cet::BasicPluginFactory pluginFactory_
std::enable_if_t< std::is_base_of< ELdestination, DEST >::value, ELdestination & > attach(std::string const &outputId, std::unique_ptr< DEST > &&dest)
std::string bold_fontify(std::string const &s)
Definition: bold_fontify.h:9
cet::coded_exception< errors::error, detail::translate > Exception
Definition: exception.h:16
const double e
std::unique_ptr< ELdestination > makePlugin_(cet::BasicPluginFactory &pluginFactory, std::string const &libspec, std::string const &psetname, fhicl::ParameterSet const &pset)
char const * what() const noexcept override
mf::service::MessageLoggerScribe::MessageLoggerScribe ( MessageLoggerScribe const &  )
delete

Member Function Documentation

void mf::service::MessageLoggerScribe::configure_errorlog ( std::unique_ptr< MessageLoggerQ::Config > &&  dests_config)
private

Definition at line 222 of file MessageLoggerScribe.cc.

224  {
225  if (admin_.destinations().size() > 1) {
226  LogWarning("multiLogConfig")
227  << "The message logger has been configured multiple times";
228  cleanSlateConfiguration_ = false;
229  }
230 
231  fetchDestinations(std::move(config));
232  } // MessageLoggerScribe::configure_errorlog()
MaybeLogger_< ELseverityLevel::ELsev_warning, false, true, detail::ConditionalLogger > LogWarning
Definition: MessageLogger.h:58
destination_collection_t const & destinations() const
void fetchDestinations(std::unique_ptr< MessageLoggerQ::Config > dests_config)
std::string mf::service::MessageLoggerScribe::createId ( std::set< std::string > &  existing_ids,
std::string const &  type,
std::string const &  filename,
fhicl::ParameterSet const &  pset = {},
bool const  should_throw = true 
)
private

Definition at line 391 of file MessageLoggerScribe.cc.

396  {
397  std::string output_id{type};
398  if (!cet::search_all(std::vector<std::string>{"cout", "cerr", "syslog"},
399  type)) {
400  output_id += ":" + pset.get<std::string>("filename", file_name);
401  }
402 
403  // Emplace and check that output_id doesn't already exist
404  if (!existing_ids.emplace(output_id).second) {
405  // Current usage case is to NOT throw for ordinary
406  // destinations, but to throw for statistics destinations.
407  if (should_throw) {
409  << "\n"
410  << " Output identifier: \"" << output_id << "\""
411  << " already specified within ordinary/statistics block in FHiCL "
412  "file"
413  << "\n";
414  }
415  }
416 
417  return output_id;
418  }
std::string string
Definition: nybbler.cc:12
cet::coded_exception< errors::error, detail::translate > Exception
Definition: exception.h:16
bool search_all(FwdCont const &, Datum const &)
bool mf::service::MessageLoggerScribe::duplicateDestination ( std::string const &  output_id,
ELdestConfig::dest_config const  config,
bool const  should_throw 
)
private

Definition at line 422 of file MessageLoggerScribe.cc.

426  {
427  std::string config_str;
428  switch (configuration) {
430  config_str = "MessageLogger";
431  break;
433  config_str = "MessageLogger Statistics";
434  break;
435  }
436 
437  auto dest_pr = admin_.destinations().find(output_id);
438  if (dest_pr == admin_.destinations().end())
439  return false;
440 
441  // For duplicate destinations
442  std::string const hrule{"\n=============================================="
443  "============================== \n"};
444  std::ostringstream except_msg, orig_config_msg;
445  except_msg << hrule << "\n Duplicate name for a " << config_str
446  << " destination: \"" << output_id << "\"";
447  orig_config_msg
448  << "\n Only original configuration instructions are used. \n"
449  << hrule;
450 
451  //------------------------------------------------------------------
452  // Handle statistics case where duplicate destinations are okay
453  //------------------------------------------------------------------
454 
455  // If user specifies the destination twice and the configuration
456  // is STATISTICS, then the ELdestination.userWantsStats_ flag
457  // needs to be set to 'true' so that statistics are output.
458 
460  dest_pr->second->userWantsStats();
461  return true; // don't emit warning for statistics
462  }
463 
464  // Emit error message for everything else
466 
467  if (should_throw) {
469  << except_msg.str();
470  } else
471  LogError("duplicateDestination")
472  << except_msg.str() << orig_config_msg.str();
473 
474  } else { // !cleanSlateConfiguration_
475  LogWarning("duplicateDestination")
476  << except_msg.str() << orig_config_msg.str();
477  }
478 
479  return true;
480  }
MaybeLogger_< ELseverityLevel::ELsev_warning, false, true, detail::ConditionalLogger > LogWarning
Definition: MessageLogger.h:58
std::string string
Definition: nybbler.cc:12
cet::coded_exception< errors::error, detail::translate > Exception
Definition: exception.h:16
destination_collection_t const & destinations() const
MaybeLogger_< ELseverityLevel::ELsev_error, false, true, detail::AlwaysLogger > LogError
Definition: MessageLogger.h:66
void mf::service::MessageLoggerScribe::fetchDestinations ( std::unique_ptr< MessageLoggerQ::Config dests_config)
private

Definition at line 236 of file MessageLoggerScribe.cc.

238  {
239  fhicl::ParameterSet dest_psets;
240  fhicl::ParameterSet ordinaryDests;
241  if (!config->destinations.get_if_present(dest_psets)) {
242  dest_psets = default_destinations_config();
243  }
244  ordinaryDests = dest_psets;
245  ordinaryDests.erase("statistics");
246 
247  // Dial down the early destination once the ordinary
248  // destinations are filled.
250 
251  auto statDests = dest_psets.get<fhicl::ParameterSet>(
252  "statistics", default_statistics_config(ordinaryDests));
253 
254  // Initialize universal suppression variables
258 
261  }
ELslProxy< ELhighestSeverityGen > constexpr ELhighestSeverity
static bool warningAlwaysSuppressed
Definition: MessageDrop.h:77
T get(std::string const &key) const
Definition: ParameterSet.h:231
static bool debugAlwaysSuppressed
Definition: MessageDrop.h:73
static bool infoAlwaysSuppressed
Definition: MessageDrop.h:75
bool erase(std::string const &key)
void setThreshold(ELseverityLevel sv)
void makeDestinations(fhicl::ParameterSet const &dests, ELdestConfig::dest_config const config)
void mf::service::MessageLoggerScribe::log ( ErrorObj errorobj_p)
private

Definition at line 194 of file MessageLoggerScribe.cc.

195  {
196  bool expected = false;
197  std::unique_ptr<ErrorObj> obj(errorobj_p);
198  if (messageBeingSent_.compare_exchange_strong(expected, true)) {
199  // Process the current message.
200  for (auto const& cat : parseCategories(errorobj_p->xid().id())) {
201  errorobj_p->setID(cat);
202  admin_.log(*errorobj_p); // route the message text
203  }
204  // process any waiting messages
205  errorobj_p = nullptr;
206  while (!purgeMode_ && waitingMessages_.try_pop(errorobj_p)) {
207  obj.reset(errorobj_p);
208  for (auto const& cat : parseCategories(errorobj_p->xid().id())) {
209  errorobj_p->setID(cat);
210  admin_.log(*errorobj_p); // route the message text
211  }
212  }
213  messageBeingSent_.store(false);
214  } else {
215  obj.release();
216  waitingMessages_.push(errorobj_p);
217  }
218  }
const char expected[]
Definition: Exception_t.cc:22
std::vector< std::string > parseCategories(std::string const &s)
tbb::concurrent_queue< ErrorObj * > waitingMessages_
void mf::service::MessageLoggerScribe::makeDestinations ( fhicl::ParameterSet const &  dests,
ELdestConfig::dest_config const  config 
)
private

Definition at line 265 of file MessageLoggerScribe.cc.

268  {
269  std::set<std::string> ids;
270 
271  std::vector<std::string> config_errors;
272  for (auto const& psetname : dests.get_pset_names()) {
273 
274  // Retrieve the destination pset object.
275  auto dest_pset = dests.get<fhicl::ParameterSet>(psetname);
276 
277  // If the provided parameter set is empty, replace its
278  // configuration with the default one.
279  if (dest_pset.is_empty()) {
280  dest_pset = default_destination_config();
281  }
282 
283  // Grab the destination type and filename.
284  // FIXME: This should only be part of the configuration
285  // validation!
286  std::string dest_type{};
287  if (!dest_pset.get_if_present("type", dest_type)) {
289  << "No 'type' specified for destination '" << psetname << "'.\n";
290  }
292 
293  bool const throw_on_duplicate_id =
295  std::string const& outputId =
296  createId(ids, dest_type, psetname, dest_pset, throw_on_duplicate_id);
297 
298  // Use previously defined configuration of duplicated destination
300  outputId, configuration, no_throw_on_clean_slate))
301  continue;
302 
303  std::string const& libspec = dest_type;
304  auto& plugin_factory = configuration == ELdestConfig::STATISTICS ?
307 
308  // attach the current destination, keeping a control handle to it:
309  try {
310  ELdestination& dest = admin_.attach(
311  outputId,
312  makePlugin_(plugin_factory, libspec, psetname, dest_pset));
313 
314  // Suppress the desire to do an extra termination summary just because
315  // of end-of-job info message for statistics jobs
317  dest.noTerminationSummary();
318  }
319  catch (fhicl::detail::validationException const& e) {
320  std::string msg{"Configuration error for destination: " +
321  detail::bold_fontify(psetname) + "\n\n"};
322  msg += e.what();
323  config_errors.push_back(std::move(msg));
324  }
325  }
326 
327  if (!config_errors.empty()) {
328  std::string msg{"\nThe following messagefacility destinations have "
329  "configuration errors:\n\n"};
330  constexpr cet::HorizontalRule rule{60};
331  msg += rule('=');
332  msg += "\n\n";
333  auto start = cbegin(config_errors);
334  msg += *start;
335  ++start;
336  for (auto it = start, e = cend(config_errors); it != e; ++it) {
337  msg += rule('-');
338  msg += "\n\n";
339  msg += *it;
340  }
341  msg += rule('=');
342  msg += "\n\n";
343  throw Exception(errors::Configuration) << msg;
344  }
345  } // make_destinations()
std::string string
Definition: nybbler.cc:12
void checkType(std::string const &type, dest_config const configuration)
cet::BasicPluginFactory pluginFactory_
std::enable_if_t< std::is_base_of< ELdestination, DEST >::value, ELdestination & > attach(std::string const &outputId, std::unique_ptr< DEST > &&dest)
list dests
Define destination.
std::string bold_fontify(std::string const &s)
Definition: bold_fontify.h:9
std::string createId(std::set< std::string > &existing_ids, std::string const &type, std::string const &filename, fhicl::ParameterSet const &pset={}, bool const should_throw=true)
cet::coded_exception< errors::error, detail::translate > Exception
Definition: exception.h:16
const double e
cet::BasicPluginFactory pluginStatsFactory_
std::unique_ptr< ELdestination > makePlugin_(cet::BasicPluginFactory &pluginFactory, std::string const &libspec, std::string const &psetname, fhicl::ParameterSet const &pset)
char const * what() const noexcept override
start
Definition: test.py:4
bool duplicateDestination(std::string const &output_id, ELdestConfig::dest_config const config, bool const should_throw)
std::unique_ptr< ELdestination > mf::service::MessageLoggerScribe::makePlugin_ ( cet::BasicPluginFactory pluginFactory,
std::string const &  libspec,
std::string const &  psetname,
fhicl::ParameterSet const &  pset 
)
private

Definition at line 484 of file MessageLoggerScribe.cc.

488  {
489  std::unique_ptr<ELdestination> result;
490  try {
491  auto const pluginType = plugin_factory.pluginType(libspec);
493  result = plugin_factory.makePlugin<std::unique_ptr<ELdestination>>(
494  libspec, psetname, pset);
495  } else {
496  throw Exception(errors::Configuration, "MessageLoggerScribe: ")
497  << "unrecognized plugin type " << pluginType << "for plugin "
498  << libspec << ".\n";
499  }
500  }
501  catch (cet::exception const& e) {
502  throw Exception(errors::Configuration, "MessageLoggerScribe: ", e)
503  << "Exception caught while processing plugin spec.\n";
504  }
505  return result;
506  } //
cet::coded_exception< errors::error, detail::translate > Exception
Definition: exception.h:16
const double e
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
MessageLoggerScribe& mf::service::MessageLoggerScribe::operator= ( MessageLoggerScribe const &  )
delete
vstring mf::service::MessageLoggerScribe::parseCategories ( std::string const &  s)
private

Definition at line 349 of file MessageLoggerScribe.cc.

350  {
351  vstring cats;
352  using namespace std::string_literals;
353  // Note: This algorithm assigns, as desired, one null category if it
354  // encounters an empty categories string
355 
356  auto const npos = s.length();
357  decltype(s.length()) i{};
358 
359  while (i <= npos) {
360 
361  if (i == npos) {
362  cats.push_back(std::string());
363  return cats;
364  }
365 
366  auto const j = s.find('|', i);
367  std::string cat = cet::trim_copy(s.substr(i, j - i), " \t\n"s);
368  cats.push_back(cat);
369  i = j;
370  while ((i < npos) && (s[i] == '|'))
371  ++i;
372  // the above handles cases of || and also | at end of string
373  }
374  return cats;
375  }
std::string string
Definition: nybbler.cc:12
std::string trim_copy(std::string source, std::string const &t=" ")
Definition: trim.h:66
std::vector< std::string > vstring
static const double s
Definition: Units.h:99
void mf::service::MessageLoggerScribe::runCommand ( OpCode  opcode,
void *  operand 
)
overridevirtual

Implements mf::service::AbstractMLscribe.

Definition at line 97 of file MessageLoggerScribe.cc.

98  {
99  switch (opcode) {
100  default: {
101  assert(false); // can't happen (we certainly hope!)
102  break;
103  }
104  case END_THREAD: {
105  break;
106  }
107  case LOG_A_MESSAGE: {
108  auto errorobj_p = static_cast<ErrorObj*>(operand);
109  try {
110  if (active_ && !purgeMode_) {
111  log(errorobj_p);
112  }
113  }
114  catch (cet::exception const& e) {
115  ++count_;
116  std::cerr << "MessageLoggerScribe caught " << count_
117  << " cet::exceptions, text = \n"
118  << e.what() << "\n";
119 
120  if (count_ > 25) {
121  std::cerr << "MessageLogger will no longer be processing "
122  << "messages due to errors (entering purge mode).\n";
123  purgeMode_ = true;
124  }
125  }
126  catch (...) {
127  std::cerr << "MessageLoggerScribe caught an unknown exception and "
128  << "will no longer be processing "
129  << "messages. (entering purge mode)\n";
130  purgeMode_ = true;
131  }
132  break;
133  }
134  case CONFIGURE: {
135  auto config = std::unique_ptr<MessageLoggerQ::Config>(
136  static_cast<MessageLoggerQ::Config*>(operand));
137  configure_errorlog(std::move(config));
138  break;
139  }
140  case SUMMARIZE: {
141  assert(operand == nullptr);
142  try {
144  }
145  catch (cet::exception const& e) {
146  std::cerr << "MessageLoggerScribe caught exception "
147  << "during summarize:\n"
148  << e.what() << "\n";
149  }
150  catch (...) {
151  std::cerr << "MessageLoggerScribe caught unkonwn exception type "
152  << "during summarize. (Ignored)\n";
153  }
154  break;
155  }
156  case SHUT_UP: {
157  assert(operand == nullptr);
158  active_ = false;
159  break;
160  }
161  case FLUSH_LOG_Q: {
162  break;
163  }
164  } // switch
165 
166  } // MessageLoggerScribe::runCommand(opcode, operand)
void configure_errorlog(std::unique_ptr< MessageLoggerQ::Config > &&dests_config)
const double e
void log(ErrorObj *errorobj_p)
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void mf::service::MessageLoggerScribe::setApplication ( std::string const &  application)
override

Definition at line 169 of file MessageLoggerScribe.cc.

170  {
171  admin_.setApplication(application);
172  }
void setApplication(std::string const &application)
void mf::service::MessageLoggerScribe::setHostAddr ( std::string const &  hostAddr)
override

Definition at line 181 of file MessageLoggerScribe.cc.

182  {
183  admin_.hostaddr_ = hostAddr;
184  }
void mf::service::MessageLoggerScribe::setHostName ( std::string const &  hostName)
override

Definition at line 175 of file MessageLoggerScribe.cc.

176  {
177  admin_.hostname_ = hostName;
178  }
void mf::service::MessageLoggerScribe::setPID ( long  pid)
override

Definition at line 187 of file MessageLoggerScribe.cc.

void mf::service::MessageLoggerScribe::triggerStatisticsSummaries ( )
private

Definition at line 379 of file MessageLoggerScribe.cc.

380  {
381  for (auto& idDestPair : admin_.destinations()) {
382  auto& dest = *idDestPair.second;
383  dest.summary();
384  if (dest.resetStats())
385  dest.wipe();
386  }
387  }
destination_collection_t const & destinations() const

Member Data Documentation

bool mf::service::MessageLoggerScribe::active_ {true}
private

Definition at line 67 of file MessageLoggerScribe.h.

ELadministrator mf::service::MessageLoggerScribe::admin_
private

Definition at line 62 of file MessageLoggerScribe.h.

bool mf::service::MessageLoggerScribe::cleanSlateConfiguration_ {true}
private

Definition at line 66 of file MessageLoggerScribe.h.

std::atomic<int> mf::service::MessageLoggerScribe::count_ {0}
private

Definition at line 69 of file MessageLoggerScribe.h.

ELdestination& mf::service::MessageLoggerScribe::earlyDest_
private

Definition at line 65 of file MessageLoggerScribe.h.

std::atomic<bool> mf::service::MessageLoggerScribe::messageBeingSent_ {false}
private

Definition at line 70 of file MessageLoggerScribe.h.

cet::BasicPluginFactory mf::service::MessageLoggerScribe::pluginFactory_ {"mfPlugin"}
private

Definition at line 63 of file MessageLoggerScribe.h.

cet::BasicPluginFactory mf::service::MessageLoggerScribe::pluginStatsFactory_ {"mfStatsPlugin"}
private

Definition at line 64 of file MessageLoggerScribe.h.

std::atomic<bool> mf::service::MessageLoggerScribe::purgeMode_ {false}
private

Definition at line 68 of file MessageLoggerScribe.h.

tbb::concurrent_queue<ErrorObj*> mf::service::MessageLoggerScribe::waitingMessages_ {}
private

Definition at line 71 of file MessageLoggerScribe.h.


The documentation for this class was generated from the following files: