4 #include "cetlib/PluginTypeDeducer.h" 42 ELdestination::Category::Config::~Config() {}
44 ELdestination::Category::Config::Config()
53 pset.get<
int>(
"reportEvery", -1)}
60 return R
"(The 'limit' parameter is an integer after which the logger will start 61 to ignore messages of this category. Beyond the specified limit, an 62 occasional further message will appear, based on an exponential 63 fall-off. For example, if the limit is set to 5, and 100 messages of 64 this category are issued, then the destination containing this 65 configuration will log messages numbered 1, 2, 3, 4, 5, 10, 15, 25, 66 45, and 85. A limit of zero disables reporting any messages.)"; 72 return R
"(The 'reportEvery' parameter is an integer n which logs only every nth 73 message. If the value is zero or less, then the report-every feature 80 return R
"(The 'timespan' parameter is an integer representing seconds. When a 81 limit is set, one can also specify that if no occurrences for that 82 particular category of messages have been seen in a period of time 83 (the timespan), then the count toward that limit is to be reset. For 84 example, if one wish to suppress most of the thousands of warnings of 85 some category expected at startup, but would like to know if another 86 one happens after a gap of ten minutes, one can set the timespan value 87 to 600. A value of zero or less disables the timespan functionality.)"; 103 : previousTimestamp_{} 116 "The 'timestamp' parameter represents a format that can be " 118 "by strftime. Allowed values include:\n\n" 119 " - \"none\" (suppress timestamp printing)\n" 120 " - \"default\" (format string shown below)\n" 121 " - \"default_ms\" (use millisecond precision)\n" 122 " - any user-specified format interpretable by strftime"),
123 "%d-%b-%Y %H:%M:%S %Z"}
127 "'noLineBreaks' has been set to 'false'."},
145 auto const&
value = config.timestamp();
146 bool const use_timestamp = (
value !=
"none"s);
148 if (!use_timestamp) {
150 }
else if (
value ==
"default"s) {
153 }
else if (
value ==
"default_ms"s) {
155 timeFmt_ =
"%d-%b-%Y %H:%M:%S.%%03u %Z"s;
160 lineLength = config.noLineBreaks() ? 32000ull : config.lineLength();
175 return flags.test(FLAG);
181 size_t constexpr SIZE{144};
190 ts,
sizeof(ts),
timeFmt_.data(), localtime_r(&t.tv_sec, &timebuf));
198 localtime_r(&t.tv_sec, &timebuf));
199 snprintf(ts,
sizeof(ts), tmpts, static_cast<unsigned>(t.tv_usec / 1000));
223 string(context, 0, 16);
244 "The 'threshold' parameter specifies the lowest severity " 246 "messages that will be logged to the destination"},
251 R
"(The 'categories' parameter (if provided) is a FHiCL table that 252 configures the behavior of logging to this destination for the specified 253 category. For example, if the following appears in C++ source code: 255 mf::LogInfo{"Tracking"} << my_track.diagnostics(); 257 the category is 'Tracking', and its behavior can be specified via: 262 reportEvery: -1 # default 263 timespan: -1 # default 267 Within the 'categories' table, it is permitted to specify a 'default' 268 category, which becomes the configuration for all message categories 269 that are not explicitly listed. 271 Note the categories listed only customize the behavior of messages 272 that are logged specifically to this destination. Messages that are 273 routed to other destinations are not be affected. 296 ,
reset_{pset.msgStatistics().reset() ||
297 pset.msgStatistics().resetStatistics()}
300 vector<string> configuration_errors;
306 auto const default_category_name =
"default"s;
307 auto categories = cats_pset.get_pset_names();
309 remove_if(
begin(categories),
end(categories), [](
auto const& category) {
310 return category ==
"default"s;
312 categories.erase(erase_from, categories.cend());
316 auto const& default_pset =
322 default_params().limit();
326 default_params().timespan();
331 configuration_errors.push_back(move(msg));
337 for (
auto const& category : categories) {
341 category_params.validate_ParameterSet(
347 configuration_errors.push_back(move(msg));
354 if (category_params().limit() < 0) {
360 category_params().reportEvery();
361 if (category_params().timespan() < 0) {
368 if (!configuration_errors.empty()) {
369 string msg{
"The following categories were misconfigured:\n\n"};
370 for (
auto const&
error : configuration_errors) {
380 if (c.substr(0, 4) !=
"Run:") {
386 is >> runWord >> run;
390 if (runWord !=
"Run:") {
395 is >> eventWord >> event;
399 if (eventWord !=
"Event:") {
403 os << run <<
"/" << event;
411 bool const preambleMode)
425 char const first = s[0];
426 char const second = (s.length() < 2) ?
'\0' : s[1];
427 char const last = (s.length() < 2) ?
'\0' : s[s.length() - 1];
428 char const last2 = (s.length() < 3) ?
'\0' : s[s.length() - 2];
446 if ((last ==
'\n') || (last2 ==
'\n')) {
467 auto const& xid = msg.
xid();
470 emitToken(oss, xid.severity().getSymbol(),
false,
true);
478 emitToken(oss,
"[serial #" + s.str() +
"] ",
false,
true);
480 bool needAspace =
true;
482 if (xid.module().length() + xid.subroutine().length() > 0) {
495 emitToken(oss, xid.module() +
" ",
false,
true);
502 emitToken(oss, xid.subroutine() +
"() ",
false,
true);
546 for (
auto const& val : msg.
items()) {
582 ostringstream payload;
605 auto const& xid = pr.first;
606 auto const& count = pr.second;
607 auto const& cat = xid.id();
612 s <<
" type category sev module subroutine " 614 <<
" ---- -------------------- -- ---------------- " 615 "---------------- ----- -----\n";
621 <<
right << setw(5) << ++
n 624 <<
left << setw(20) << cat.substr(0, 20)
627 <<
left << setw(2) << xid.severity().getSymbol()
630 <<
left << setw(16) << xid.module().substr(0, 16)
634 << xid.subroutine().substr(0, 16)
636 <<
right << setw(7) << count.n_ <<
left << setw(1)
637 << (count.ignoredFlag_ ?
'*' :
' ')
639 <<
right << setw(8) << count.aggregateN_ <<
'\n';
640 ftnote = ftnote || count.ignoredFlag_;
643 p3[xid.severity().getLevel()].n += count.n_;
644 p3[xid.severity().getLevel()].t += count.aggregateN_;
649 s <<
"\n* Some occurrences of this message were suppressed in all " 650 "logs, due to limits.\n";
655 for (
auto const& pr : statsMap_) {
656 auto const& xid = pr.first;
657 auto const& count = pr.second;
658 string const& cat = xid.id();
661 <<
" type category Examples: run/evt run/evt " 663 <<
" ---- -------------------- ---------------- ---------------- " 664 "----------------\n";
668 <<
right << setw(5) << ++
n 671 <<
left << setw(20) << cat
674 <<
left << setw(16) << count.context1_.c_str()
677 <<
left << setw(16) << count.context2_.c_str()
680 << count.contextLast_ <<
'\n';
685 <<
"Severity # Occurrences Total Occurrences\n" 686 <<
"-------- ------------- -----------------\n";
688 if (p3[k].
n != 0 || p3[k].t != 0) {
697 <<
right << setw(20) << p3[k].t <<
'\n';
709 ostringstream payload;
710 payload <<
"\n=============================================\n\n" 711 <<
"MessageLogger Summary\n" 738 msg <<
"Call to unimplemented flush()!";
758 auto const& cp = cp_iter->second;
776 time_t now = time(0);
795 if (limiter.
limit_ == 0) {
807 long r = diff / limiter.
limit_;
808 if (r * limiter.
limit_ != diff) {
fhicl::Table< MsgFormatSettings::Config > format
ELseverityLevel severity() const
fhicl::Atom< bool > resetStatistics
virtual void fillUsrMsg(std::ostringstream &, mf::ErrorObj const &msg)
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
bool skipMsg(ELextendedID const &)
static std::string limit_comment()
static std::string const value
timeval timestamp() const
fhicl::TableFragment< MsgStatistics::Config > msgStatistics
void add(std::string const &context, bool reactedTo)
void emitToken(std::ostream &os, std::string const &s, bool nl=false, bool preambleMode=false)
fhicl::OptionalDelegatedParameter categories
virtual void fillSuffix(std::ostringstream &, mf::ErrorObj const &msg)
std::map< std::string const, CategoryParams > categoryParams_
virtual void log(mf::ErrorObj &)
fhicl::Atom< int > timespan
std::list< std::string > const & items() const
std::string bold_fontify(std::string const &s)
static std::string timespan_comment()
std::string const & context() const
fhicl::Atom< std::string > threshold
fhicl::Atom< int > reportEvery
std::string const & idOverflow() const
std::map< ELextendedID const, StatsCount > statsMap_
std::string summarizeContext(std::string const &)
ELslProxy< ELzeroSeverityGen > constexpr ELzeroSeverity
ELextendedID const & xid() const
static std::string reportEvery_comment()
ELslProxy< ELwarningGen > constexpr ELwarning
T get(std::string const &key) const
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
std::string indent(std::size_t const i)
std::string const & filename() const
bool get_if_present(std::string const &key, T &value) const
ELdestination(Config const &)
ELseverityLevel threshold_
std::string const & id() const
fhicl::Atom< bool > outputStatistics
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
char const * what() const noexcept override
std::string value(boost::any const &)
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
std::string formSummary()
virtual void fillPrefix(std::ostringstream &, mf::ErrorObj const &msg)
virtual void setReactedTo(bool)
MsgFormatSettings format_
void setThreshold(ELseverityLevel sv)
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
std::map< ELextendedID const, XidLimiter > xidLimiters_
time_t previousTimestamp_
std::string nl(std::size_t i=1)
virtual void routePayload(std::ostringstream const &, mf::ErrorObj const &msg)
Event finding and building.