ELdestination.cc
Go to the documentation of this file.
2 // vim: set sw=2 expandtab :
3 
4 #include "cetlib/bold_fontify.h"
6 #include "fhiclcpp/types/Atom.h"
9 #include "fhiclcpp/types/Table.h"
13 
14 #include <bitset>
15 #include <cstddef>
16 #include <cstdio>
17 #include <functional>
18 #include <iomanip>
19 #include <limits>
20 #include <map>
21 #include <ostream>
22 #include <sstream>
23 #include <string>
24 
25 #include <sys/time.h>
26 #include <time.h>
27 
28 using namespace std;
29 using namespace std::string_literals;
30 
32  "ELdestination"s;
33 
34 namespace mf::service {
35 
36  ELdestination::Category::Config::~Config() = default;
37 
39  : limit{fhicl::Name{"limit"}, -1}
40  , reportEvery{fhicl::Name{"reportEvery"}, -1}
41  , timespan{fhicl::Name{"timespan"}, -1}
42  {}
43 
45  : limit{fhicl::Name{"limit"}, pset.get<int>("limit", -1)}
46  , reportEvery{fhicl::Name{"reportEvery"}, pset.get<int>("reportEvery", -1)}
47  , timespan{fhicl::Name{"timespan"}, pset.get<int>("timespan", -1)}
48  {}
49 
52  {
53  return R"(The 'limit' parameter is an integer after which the logger will start
54 to ignore messages of this category. Beyond the specified limit, an
55 occasional further message will appear, based on an exponential
56 fall-off. For example, if the limit is set to 5, and 100 messages of
57 this category are issued, then the destination containing this
58 configuration will log messages numbered 1, 2, 3, 4, 5, 10, 15, 25,
59 45, and 85. A limit of zero disables reporting any messages.)";
60  }
61 
64  {
65  return R"(The 'reportEvery' parameter is an integer n which logs only every nth
66 message. If the value is zero or less, then the report-every feature
67 is disabled.)";
68  }
69 
72  {
73  return R"(The 'timespan' parameter is an integer representing seconds. When a
74 limit is set, one can also specify that if no occurrences for that
75 particular category of messages have been seen in a period of time
76 (the timespan), then the count toward that limit is to be reset. For
77 example, if one wish to suppress most of the thousands of warnings of
78 some category expected at startup, but would like to know if another
79 one happens after a gap of ten minutes, one can set the timespan value
80 to 600. A value of zero or less disables the timespan functionality.)";
81  }
82 
85 
88  : limit_{}, reportEvery_{}, timespan_{}
89  {}
90 
93  : previousTimestamp_{}
94  , msgCount_{}
96  , limit_{}
97  , reportEvery_{}
98  , timespan_{}
99  {}
100 
103  : timestamp{fhicl::Name("timestamp"),
105  "The 'timestamp' parameter represents a format that can be "
106  "interpreted\n"
107  "by strftime. Allowed values include:\n\n"
108  " - \"none\" (suppress timestamp printing)\n"
109  " - \"default\" (format string shown below)\n"
110  " - \"default_ms\" (use millisecond precision)\n"
111  " - any user-specified format interpretable by strftime"),
112  "%d-%b-%Y %H:%M:%S %Z"}
113  , noLineBreaks{fhicl::Name("noLineBreaks"), false}
114  , lineLength{fhicl::Name{"lineLength"},
115  fhicl::Comment{"The following parameter is allowed only if "
116  "'noLineBreaks' has been set to 'false'."},
117  [this] { return !noLineBreaks(); },
118  80ull}
119  , wantModule{fhicl::Name("wantModule"), true}
120  , wantSubroutine{fhicl::Name("wantSubroutine"), true}
121  , wantText{fhicl::Name("wantText"), true}
122  , wantSomeContext{fhicl::Name("wantSomeContext"), true}
123  , wantSerial{fhicl::Name("wantSerial"), false}
124  , wantFullContext{fhicl::Name("wantFullContext"), false}
125  , wantTimeSeparate{fhicl::Name("wantTimeSeparate"), false}
126  , wantEpilogueSeparate{fhicl::Name("wantEpilogueSeparate"), false}
127  {}
128 
130 
132  : timeMethod_{0}, timeFmt_{}
133  {
134  auto const& value = config.timestamp();
135  bool const use_timestamp = (value != "none"s);
136  flags.set(TIMESTAMP, use_timestamp);
137  if (!use_timestamp) {
138  timeMethod_ = 0;
139  } else if (value == "default"s) {
140  timeMethod_ = 1;
141  timeFmt_ = "%d-%b-%Y %H:%M:%S %Z"s;
142  } else if (value == "default_ms"s) {
143  timeMethod_ = 2;
144  timeFmt_ = "%d-%b-%Y %H:%M:%S.%%03u %Z"s;
145  } else {
146  timeMethod_ = 1;
147  timeFmt_ = value;
148  }
149  lineLength = config.noLineBreaks() ? 32000ull : config.lineLength();
151  flags.set(MODULE, config.wantModule());
153  flags.set(TEXT, config.wantText());
155  flags.set(SERIAL, config.wantSerial());
159  }
160 
161  bool
163  {
164  return flags.test(FLAG);
165  }
166 
167  string
169  {
170  size_t constexpr SIZE{144};
171  string ret;
172  if (timeMethod_ == 0) {
173  return ret;
174  }
175  struct tm timebuf;
176  char ts[SIZE];
177  if (timeMethod_ == 1) {
178  strftime(
179  ts, sizeof(ts), timeFmt_.data(), localtime_r(&t.tv_sec, &timebuf));
180  ret = ts;
181  return ret;
182  }
183  char tmpts[SIZE];
184  strftime(
185  tmpts, sizeof(tmpts), timeFmt_.data(), localtime_r(&t.tv_sec, &timebuf));
186  snprintf(ts, sizeof(ts), tmpts, static_cast<unsigned>(t.tv_usec / 1000));
187  ret = ts;
188  return ret;
189  }
190 
192 
194  : n_{}
195  , aggregateN_{}
196  , ignoredFlag_{false}
197  , context1_{}
198  , context2_{}
199  , contextLast_{}
200  {}
201 
202  void
203  ELdestination::StatsCount::add(string const& context, bool const reactedTo)
204  {
205  if (reactedTo) {
206  ++n_;
207  }
208  ++aggregateN_;
209  ((n_ == 1) ? context1_ : (n_ == 2) ? context2_ : contextLast_) =
210  string(context, 0, 16);
211  if (!reactedTo) {
212  ignoredFlag_ = true;
213  }
214  }
215 
217 
219  : reset{fhicl::Name("reset"),
220  fhicl::Comment("Used for statistics destinations"),
221  false}
222  , resetStatistics{fhicl::Name("resetStatistics"), false}
223  {}
224 
225  ELdestination::Config::~Config() = default;
226 
228  : dest_type{fhicl::Name{"type"}}
229  , threshold{fhicl::Name{"threshold"},
231  "The 'threshold' parameter specifies the lowest severity "
232  "level of\n"
233  "messages that will be logged to the destination"},
234  "INFO"}
235  , format{fhicl::Name{"format"}}
236  , categories{fhicl::Name{"categories"},
238  R"(The 'categories' parameter (if provided) is a FHiCL table that
239 configures the behavior of logging to this destination for the specified
240 category. For example, if the following appears in C++ source code:
241 
242  mf::LogInfo{"Tracking"} << my_track.diagnostics();
243 
244 the category is 'Tracking', and its behavior can be specified via:
245 
246  categories: {
247  Tracking: {
248  limit: -1 # default
249  reportEvery: -1 # default
250  timespan: -1 # default
251  }
252  }
253 
254 Within the 'categories' table, it is permitted to specify a 'default'
255 category, which becomes the configuration for all message categories
256 that are not explicitly listed.
257 
258 Note the categories listed only customize the behavior of messages
259 that are logged specifically to this destination. Messages that are
260 routed to other destinations are not be affected.
261 
262 Category parameters
263 ===================
264 
266  "\n\n" + Category::Config::reportEvery_comment() + "\n\n" +
268  , outputStatistics{fhicl::Name{"outputStatistics"}, false}
269  , msgStatistics{}
270  {}
271 
273  : threshold_{pset.threshold()}
274  , format_{pset.format()}
276  , defaultReportEvery_{-1}
278  , categoryParams_{}
279  , xidLimiters_{}
280  , statsMap_{}
281  , outputStatistics_{pset.outputStatistics()}
282  , updatedStats_{false}
283  , reset_{pset.msgStatistics().reset() ||
284  pset.msgStatistics().resetStatistics()}
285  , charsOnLine_{}
286  {
287  vector<string> configuration_errors;
288  // Grab this destination's category configurations.
289  fhicl::ParameterSet cats_pset{};
290  pset.categories.get_if_present<fhicl::ParameterSet>(cats_pset);
291  // Grab the list of categories, removing the default category
292  // since it is handled specially.
293  auto const default_category_name = "default"s;
294  auto categories = cats_pset.get_pset_names();
295  auto erase_from =
296  remove_if(begin(categories), end(categories), [](auto const& category) {
297  return category == "default"s;
298  });
299  categories.erase(erase_from, categories.cend());
300  // Setup the default configuration for categories--this involves
301  // resetting the limits table according to the user-specified
302  // default configuration.
303  auto const& default_pset =
304  cats_pset.get<fhicl::ParameterSet>("default"s, {});
305  try {
307  defaultLimit_ = (default_params().limit() < 0) ?
308  numeric_limits<decltype(defaultLimit_)>::max() :
309  default_params().limit();
310  defaultReportEvery_ = default_params().reportEvery();
311  defaultTimespan_ = (default_params().timespan() < 0) ?
312  numeric_limits<decltype(defaultTimespan_)>::max() :
313  default_params().timespan();
314  }
315  catch (fhicl::detail::validationException const& e) {
316  string msg{"Category: "s + cet::bold_fontify("default"s) + "\n\n"s};
317  msg += e.what();
318  configuration_errors.push_back(move(msg));
319  }
320  // Now establish this destination's limit/reportEvery/timespan for
321  // each category, using the values of the possibly-specified
322  // default configuration when a given category is missing the
323  // fields.
324  for (auto const& category : categories) {
326  default_pset};
327  try {
328  category_params.validate(cats_pset.get<fhicl::ParameterSet>(category));
329  }
330  catch (fhicl::detail::validationException const& e) {
331  string msg{"Category: " + cet::bold_fontify(category) + "\n\n"};
332  msg += e.what();
333  configuration_errors.push_back(move(msg));
334  }
335 
336  if (category_params().limit() < 0) {
338  } else {
339  categoryParams_[category].limit_ = category_params().limit();
340  }
341  categoryParams_[category].reportEvery_ = category_params().reportEvery();
342  if (category_params().timespan() < 0) {
344  } else {
345  categoryParams_[category].timespan_ = category_params().timespan();
346  }
347  }
348  if (!configuration_errors.empty()) {
349  string msg{"The following categories were misconfigured:\n\n"};
350  for (auto const& error : configuration_errors) {
351  msg += error;
352  }
354  }
355  }
356 
357  string
359  {
360  if (c.substr(0, 4) != "Run:") {
361  return c;
362  }
363  istringstream is(c);
364  string runWord;
365  int run;
366  is >> runWord >> run;
367  if (!is) {
368  return c;
369  }
370  if (runWord != "Run:") {
371  return c;
372  }
373  string eventWord;
374  int event;
375  is >> eventWord >> event;
376  if (!is) {
377  return c;
378  }
379  if (eventWord != "Event:") {
380  return c;
381  }
382  ostringstream os;
383  os << run << "/" << event;
384  return os.str();
385  }
386 
387  void
389  string const& s,
390  bool const nl,
391  bool const preambleMode)
392  {
393  string const indent(6, ' ');
394  if (s.empty()) {
395  if (nl) {
396  os << '\n';
397  charsOnLine_ = 0UL;
398  }
399  return;
400  }
401  if (!preambleMode) {
402  os << s;
403  return;
404  }
405  char const first = s[0];
406  char const second = (s.length() < 2) ? '\0' : s[1];
407  char const last = (s.length() < 2) ? '\0' : s[s.length() - 1];
408  char const last2 = (s.length() < 3) ? '\0' : s[s.length() - 2];
409  // checking -2 because the very last char is sometimes a ' '
410  // inserted by ErrorLog::operator<<
411  // Accounts for newline @ the beginning of the string
412  if (first == '\n' || (charsOnLine_ + s.length()) > format_.lineLength) {
413  charsOnLine_ = 0UL;
414  if (second != ' ') {
415  os << ' ';
416  ++charsOnLine_;
417  }
418  if (first == '\n') {
419  os << s.substr(1);
420  } else {
421  os << s;
422  }
423  } else {
424  os << s;
425  }
426  if ((last == '\n') || (last2 == '\n')) {
427  os << indent;
428  if (last != ' ') {
429  os << ' ';
430  }
431  charsOnLine_ = indent.length() + 1UL;
432  }
433  if (nl) {
434  os << '\n';
435  charsOnLine_ = 0UL;
436  } else {
437  charsOnLine_ += s.length();
438  }
439  }
440 
441  void
442  ELdestination::fillPrefix(ostringstream& oss, ErrorObj const& msg)
443  {
444  if (msg.is_verbatim()) {
445  return;
446  }
447  auto const& xid = msg.xid();
448  charsOnLine_ = 0UL;
449  emitToken(oss, "%MSG"s, false, true);
450  emitToken(oss, xid.severity().getSymbol(), false, true);
451  emitToken(oss, " ", false, true);
452  emitToken(oss, xid.id(), false, true);
453  emitToken(oss, msg.idOverflow(), false, true);
454  emitToken(oss, ": ", false, true);
455  if (format_.want(SERIAL)) {
456  ostringstream s;
457  s << msg.serial();
458  emitToken(oss, "[serial #" + s.str() + "] ", false, true);
459  }
460  bool needAspace = true;
462  if (xid.module().length() + xid.subroutine().length() > 0) {
463  emitToken(oss, "\n", false, true);
464  needAspace = false;
465  } else if (format_.want(TIMESTAMP) && !format_.want(TIME_SEPARATE)) {
466  emitToken(oss, "\n", false, true);
467  needAspace = false;
468  }
469  }
470  if (format_.want(MODULE) && (xid.module().length() > 0)) {
471  if (needAspace) {
472  emitToken(oss, " ", false, true);
473  needAspace = false;
474  }
475  emitToken(oss, xid.module() + " ", false, true);
476  }
477  if (format_.want(SUBROUTINE) && (xid.subroutine().length() > 0)) {
478  if (needAspace) {
479  emitToken(oss, " ", false, true);
480  needAspace = false;
481  }
482  emitToken(oss, xid.subroutine() + "() ", false, true);
483  }
484  if (format_.want(TIMESTAMP)) {
485  if (format_.want(TIME_SEPARATE)) {
486  emitToken(oss, "\n", false, true);
487  needAspace = false;
488  }
489  if (needAspace) {
490  emitToken(oss, " ", false, true);
491  needAspace = false;
492  }
493  emitToken(oss, format_.timestamp(msg.timestamp()) + " ", false, true);
494  }
495  if (format_.want(SOME_CONTEXT)) {
496  if (needAspace) {
497  emitToken(oss, " ", false, true);
498  needAspace = false;
499  }
500  emitToken(oss, msg.context(), false, true);
501  }
502  }
503 
504  void
505  ELdestination::fillUsrMsg(ostringstream& oss, ErrorObj const& msg)
506  {
507  if (!format_.want(TEXT)) {
508  return;
509  }
510  // Determine if file and line should be included
511  if (!msg.is_verbatim()) {
512  if (!msg.filename().empty()) {
513  emitToken(oss, " "s);
514  emitToken(oss, msg.filename());
515  emitToken(oss, ":"s);
516  emitToken(oss, to_string(msg.lineNumber()));
517  }
518  // Check for user-requested line breaks
519  if (format_.want(NO_LINE_BREAKS)) {
520  emitToken(oss, " ==> ");
521  } else {
522  emitToken(oss, "", true);
523  }
524  }
525  // Print the contents.
526  for (auto const& val : msg.items()) {
527  emitToken(oss, val);
528  }
529  }
530 
531  void
532  ELdestination::fillSuffix(ostringstream& oss, ErrorObj const& msg)
533  {
534  if (!msg.is_verbatim() && !format_.want(NO_LINE_BREAKS)) {
535  emitToken(oss, "\n%MSG");
536  }
537  oss << '\n';
538  }
539 
540  void
541  ELdestination::routePayload(ostringstream const&, ErrorObj const&)
542  {}
543 
544  void
546  {
547  if (msg.xid().severity() < threshold_) {
548  if (outputStatistics_) {
549  statsMap_[msg.xid()].add(summarizeContext(msg.context()), false);
550  updatedStats_ = true;
551  }
552  return;
553  }
554  if (skipMsg(msg.xid())) {
555  if (outputStatistics_) {
556  statsMap_[msg.xid()].add(summarizeContext(msg.context()), false);
557  updatedStats_ = true;
558  }
559  return;
560  }
561  msg.setReactedTo(true);
562  ostringstream payload;
563  fillPrefix(payload, msg);
564  fillUsrMsg(payload, msg);
565  fillSuffix(payload, msg);
566  routePayload(payload, msg);
567  if (outputStatistics_) {
568  statsMap_[msg.xid()].add(summarizeContext(msg.context()), true);
569  updatedStats_ = true;
570  }
571  }
572 
573  string
575  {
576  ostringstream s;
577  int n{};
578  // ----- Summary part I:
579  //
580  bool ftnote{false};
581  struct part3 {
582  long n{}, t{};
584  for (auto const& [xid, count] : statsMap_) {
585  auto const& cat = xid.id();
586  // ----- Emit new part I header, if needed:
587  //
588  if (n == 0) {
589  s << "\n";
590  s << " type category sev module subroutine "
591  " count total\n"
592  << " ---- -------------------- -- ---------------- "
593  "---------------- ----- -----\n";
594  }
595  // ----- Emit detailed message information:
596  //
597  s
598  // Type
599  << right << setw(5) << ++n
600  << ' '
601  // Category
602  << left << setw(20) << cat.substr(0, 20)
603  << ' '
604  // Severity
605  << left << setw(2) << xid.severity().getSymbol()
606  << ' '
607  // Module
608  << left << setw(16) << xid.module().substr(0, 16)
609  << ' '
610  // Subroutine
611  << left << setw(16)
612  << xid.subroutine().substr(0, 16)
613  // Count
614  << right << setw(7) << count.n_ << left << setw(1)
615  << (count.ignoredFlag_ ? '*' : ' ')
616  // Total Count
617  << right << setw(8) << count.aggregateN_ << '\n';
618  ftnote = ftnote || count.ignoredFlag_;
619  // ----- Obtain information for Part III, below:
620  //
621  p3[xid.severity().getLevel()].n += count.n_;
622  p3[xid.severity().getLevel()].t += count.aggregateN_;
623  }
624  // ----- Provide footnote to part I, if needed:
625  //
626  if (ftnote) {
627  s << "\n* Some occurrences of this message were suppressed in all "
628  "logs, due to limits.\n";
629  }
630  // ----- Summary part II:
631  //
632  n = 0;
633  for (auto const& pr : statsMap_) {
634  auto const& xid = pr.first;
635  auto const& count = pr.second;
636  string const& cat = xid.id();
637  if (n == 0) {
638  s << '\n'
639  << " type category Examples: run/evt run/evt "
640  "run/evt\n"
641  << " ---- -------------------- ---------------- ---------------- "
642  "----------------\n";
643  }
644  s
645  // Type
646  << right << setw(5) << ++n
647  << ' '
648  // Category
649  << left << setw(20) << cat
650  << ' '
651  // Context1
652  << left << setw(16) << count.context1_.c_str()
653  << ' '
654  // Context2
655  << left << setw(16) << count.context2_.c_str()
656  << ' '
657  // ContextLast
658  << count.contextLast_ << '\n';
659  }
660  // ----- Summary part III:
661  //
662  s << '\n'
663  << "Severity # Occurrences Total Occurrences\n"
664  << "-------- ------------- -----------------\n";
665  for (int k = 0; k < ELseverityLevel::nLevels; ++k) {
666  if (p3[k].n != 0 || p3[k].t != 0) {
667  s
668  // Severity
669  << left << setw(8)
670  << ELseverityLevel{ELseverityLevel::ELsev_(k)}.getName().c_str()
671  // Occurrences
672  << right << setw(17)
673  << p3[k].n
674  // Total Occurrences
675  << right << setw(20) << p3[k].t << '\n';
676  }
677  }
678  return s.str();
679  }
680 
681  // Called only by MessageLoggerScribe::summarize()
682  // Called only by MessageLogger::LogStatistics()
683  void
685  {
687  ostringstream payload;
688  payload << "\n=============================================\n\n"
689  << "MessageLogger Summary\n"
690  << formSummary();
691  routePayload(payload, ErrorObj{ELzeroSeverity, "No ostream"s});
692  }
693  updatedStats_ = false;
694  if (reset_) {
696  resetLimiters();
697  }
698  }
699 
700  void
702  {}
703 
704  // Used only by MessageLoggerScribe to disable
705  // cerr_early once startup is complete.
706  void
708  {
709  threshold_ = sv;
710  }
711 
712  void
714  {
715  ErrorObj msg{ELwarning, "ELdestination"s};
716  msg << "Call to unimplemented flush()!";
717  log(msg);
718  }
719 
720  // A return value of true tells the destination
721  // to not log this message.
722  // Called by ELdestination log().
723  bool
725  {
726  auto xl_iter = xidLimiters_.find(xid);
727  if (xl_iter == xidLimiters_.end()) {
728  // Need to create and initialize a limiter for this xid.
729  int limit{defaultLimit_};
730  int reportEvery{defaultReportEvery_};
731  int timespan{defaultTimespan_};
732  // Does the category of this xid have explicit limits?
733  auto cp_iter = categoryParams_.find(xid.id());
734  if (cp_iter != categoryParams_.end()) {
735  // Category limits found, use them.
736  auto const& cp = cp_iter->second;
737  limit = (cp.limit_ < 0) ? defaultLimit_ : cp.limit_;
738  reportEvery =
739  (cp.reportEvery_ < 0) ? defaultReportEvery_ : cp.reportEvery_;
740  timespan = (cp.timespan_ < 0) ? defaultTimespan_ : cp.timespan_;
741  }
742  XidLimiter& limiter = xidLimiters_[xid];
743  limiter.previousTimestamp_ = time(0);
744  limiter.msgCount_ = 0;
745  limiter.skippedMsgCount_ =
746  reportEvery - 1; // So that the FIRST of the prescaled messages emerges
747  limiter.limit_ = limit;
748  limiter.reportEvery_ = reportEvery;
749  limiter.timespan_ = timespan;
750  xl_iter = xidLimiters_.find(xid);
751  }
752  XidLimiter& limiter = xl_iter->second;
753  time_t now = time(0);
754  // Has it been so long that we should restart counting toward the limit?
755  if ((limiter.timespan_ >= 0) &&
756  (difftime(now, limiter.previousTimestamp_) >= limiter.timespan_)) {
757  limiter.msgCount_ = 0;
758  if (limiter.reportEvery_ > 0) {
759  // So this message will be reacted to
760  limiter.skippedMsgCount_ = limiter.reportEvery_ - 1;
761  } else {
762  limiter.skippedMsgCount_ = 0;
763  }
764  }
765  limiter.previousTimestamp_ = now;
766  ++limiter.msgCount_;
767  ++limiter.skippedMsgCount_;
768  if (limiter.skippedMsgCount_ < limiter.reportEvery_) {
769  // Skip message.
770  return true;
771  }
772  if (limiter.limit_ == 0) {
773  // Zero limit - never react to this
774  // Skip message.
775  return true;
776  }
777  if ((limiter.limit_ < 0) || (limiter.msgCount_ <= limiter.limit_)) {
778  limiter.skippedMsgCount_ = 0;
779  // Accept message.
780  return false;
781  }
782  // Now we are over the limit - have we exceeded limit by 2^N * limit?
783  long diff = limiter.msgCount_ - limiter.limit_;
784  long r = diff / limiter.limit_;
785  if (r * limiter.limit_ != diff) {
786  // Not a multiple of limit - don't react
787  // Skip message.
788  return true;
789  }
790  if (r == 1) {
791  // Exactly twice limit - react
792  limiter.skippedMsgCount_ = 0;
793  // Accept message.
794  return false;
795  }
796  while (r > 1) {
797  if ((r & 1) != 0) {
798  // Not 2**msgCount_ times limit - don't react
799  // Skip message.
800  return true;
801  }
802  r >>= 1;
803  }
804  // If you never get an odd number till one, r is 2**msgCount_ so react
805  limiter.skippedMsgCount_ = 0;
806  // Accept message.
807  return false;
808  }
809 
810  void
812  {
813  statsMap_.clear();
814  }
815 
816  void
818  {
819  xidLimiters_.clear();
820  }
821 
822 } // namespace mf::service
int lineNumber() const
Definition: ErrorObj.cc:126
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
fhicl::Table< MsgFormatSettings::Config > format
ELseverityLevel severity() const
Definition: ELextendedID.cc:33
virtual void fillUsrMsg(std::ostringstream &, mf::ErrorObj const &msg)
bool skipMsg(ELextendedID const &)
void msg(const char *fmt,...)
Definition: message.cpp:107
timeval timestamp() const
Definition: ErrorObj.cc:73
fhicl::TableFragment< MsgStatistics::Config > msgStatistics
std::string string
Definition: nybbler.cc:12
void add(std::string const &context, bool reactedTo)
void emitToken(std::ostream &os, std::string const &s, bool nl=false, bool preambleMode=false)
ChannelGroupService::Name Name
error
Definition: include.cc:26
STL namespace.
fhicl::OptionalDelegatedParameter categories
virtual void fillSuffix(std::ostringstream &, mf::ErrorObj const &msg)
std::map< std::string const, CategoryParams > categoryParams_
virtual void log(mf::ErrorObj &)
tm
Definition: demo.py:21
std::list< std::string > const & items() const
Definition: ErrorObj.cc:79
std::string const & context() const
Definition: ErrorObj.cc:98
bool is_verbatim() const
Definition: ErrorObj.cc:91
fhicl::Atom< std::string > threshold
fhicl::Atom< unsigned long long > lineLength
std::string const & idOverflow() const
Definition: ErrorObj.cc:67
typename config_impl< T >::type Config
Definition: ModuleMacros.h:52
QTextStream & reset(QTextStream &s)
std::map< ELextendedID const, StatsCount > statsMap_
const double e
std::string summarizeContext(std::string const &)
ELslProxy< ELzeroSeverityGen > constexpr ELzeroSeverity
static Config * config
Definition: config.cpp:1054
std::void_t< T > n
ELextendedID const & xid() const
Definition: ErrorObj.cc:61
def move(depos, offset)
Definition: depos.py:107
ELslProxy< ELwarningGen > constexpr ELwarning
T get(std::string const &key) const
Definition: ParameterSet.h:271
std::string bold_fontify(std::string const &s)
Definition: bold_fontify.h:8
std::string const & filename() const
Definition: ErrorObj.cc:120
ELdestination(Config const &)
static int max(int a, int b)
ELseverityLevel threshold_
std::string const & id() const
Definition: ELextendedID.cc:27
int serial() const
Definition: ErrorObj.cc:55
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
fhicl::Atom< bool > outputStatistics
char const * what() const noexcept override
#define Comment
std::optional< T > get_if_present(std::string const &key) const
Definition: ParameterSet.h:224
virtual void fillPrefix(std::ostringstream &, mf::ErrorObj const &msg)
virtual void setReactedTo(bool)
Definition: ErrorObj.cc:177
MsgFormatSettings format_
void setThreshold(ELseverityLevel sv)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
std::map< ELextendedID const, XidLimiter > xidLimiters_
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
std::string nl(std::size_t i=1)
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
static QCString * s
Definition: config.cpp:1042
virtual void routePayload(std::ostringstream const &, mf::ErrorObj const &msg)