36 ELdestination::Category::Config::~Config() =
default;
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.)"; 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 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.)"; 93 : previousTimestamp_{}
105 "The 'timestamp' parameter represents a format that can be " 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"}
116 "'noLineBreaks' has been set to 'false'."},
135 bool const use_timestamp = (
value !=
"none"s);
137 if (!use_timestamp) {
139 }
else if (
value ==
"default"s) {
142 }
else if (
value ==
"default_ms"s) {
144 timeFmt_ =
"%d-%b-%Y %H:%M:%S.%%03u %Z"s;
164 return flags.test(FLAG);
170 size_t constexpr SIZE{144};
179 ts,
sizeof(ts),
timeFmt_.data(), localtime_r(&t.tv_sec, &timebuf));
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));
210 string(context, 0, 16);
231 "The 'threshold' parameter specifies the lowest severity " 233 "messages that will be logged to the destination"},
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: 242 mf::LogInfo{"Tracking"} << my_track.diagnostics(); 244 the category is 'Tracking', and its behavior can be specified via: 249 reportEvery: -1 # default 250 timespan: -1 # default 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. 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. 283 ,
reset_{pset.msgStatistics().reset() ||
284 pset.msgStatistics().resetStatistics()}
287 vector<string> configuration_errors;
293 auto const default_category_name =
"default"s;
294 auto categories = cats_pset.get_pset_names();
299 categories.erase(erase_from, categories.cend());
303 auto const& default_pset =
318 configuration_errors.push_back(
move(
msg));
324 for (
auto const&
category : categories) {
333 configuration_errors.push_back(
move(
msg));
336 if (category_params().limit() < 0) {
342 if (category_params().timespan() < 0) {
348 if (!configuration_errors.empty()) {
349 string msg{
"The following categories were misconfigured:\n\n"};
350 for (
auto const&
error : configuration_errors) {
360 if (c.substr(0, 4) !=
"Run:") {
366 is >> runWord >>
run;
370 if (runWord !=
"Run:") {
375 is >> eventWord >>
event;
379 if (eventWord !=
"Event:") {
383 os << run <<
"/" <<
event;
391 bool const preambleMode)
393 string const indent(6,
' ');
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];
426 if ((last ==
'\n') || (last2 ==
'\n')) {
447 auto const& xid = msg.
xid();
450 emitToken(oss, xid.severity().getSymbol(),
false,
true);
458 emitToken(oss,
"[serial #" + s.str() +
"] ",
false,
true);
460 bool needAspace =
true;
462 if (xid.module().length() + xid.subroutine().length() > 0) {
475 emitToken(oss, xid.module() +
" ",
false,
true);
482 emitToken(oss, xid.subroutine() +
"() ",
false,
true);
526 for (
auto const&
val : msg.
items()) {
562 ostringstream payload;
585 auto const& cat = xid.id();
590 s <<
" type category sev module subroutine " 592 <<
" ---- -------------------- -- ---------------- " 593 "---------------- ----- -----\n";
602 <<
left <<
setw(20) << cat.substr(0, 20)
605 <<
left <<
setw(2) << xid.severity().getSymbol()
608 <<
left <<
setw(16) << xid.module().substr(0, 16)
612 << xid.subroutine().substr(0, 16)
615 << (
count.ignoredFlag_ ?
'*' :
' ')
618 ftnote = ftnote ||
count.ignoredFlag_;
621 p3[xid.severity().getLevel()].n +=
count.n_;
622 p3[xid.severity().getLevel()].t +=
count.aggregateN_;
627 s <<
"\n* Some occurrences of this message were suppressed in all " 628 "logs, due to limits.\n";
633 for (
auto const& pr : statsMap_) {
634 auto const& xid = pr.first;
635 auto const&
count = pr.second;
636 string const& cat = xid.id();
639 <<
" type category Examples: run/evt run/evt " 641 <<
" ---- -------------------- ---------------- ---------------- " 642 "----------------\n";
658 <<
count.contextLast_ <<
'\n';
663 <<
"Severity # Occurrences Total Occurrences\n" 664 <<
"-------- ------------- -----------------\n";
666 if (p3[
k].
n != 0 || p3[
k].
t != 0) {
687 ostringstream payload;
688 payload <<
"\n=============================================\n\n" 689 <<
"MessageLogger Summary\n" 716 msg <<
"Call to unimplemented flush()!";
736 auto const& cp = cp_iter->second;
772 if (limiter.
limit_ == 0) {
784 long r = diff / limiter.
limit_;
785 if (r * limiter.
limit_ != diff) {
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
fhicl::Atom< bool > resetStatistics
virtual void fillUsrMsg(std::ostringstream &, mf::ErrorObj const &msg)
bool skipMsg(ELextendedID const &)
static std::string limit_comment()
void msg(const char *fmt,...)
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)
ChannelGroupService::Name Name
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
static std::string timespan_comment()
std::string const & context() const
fhicl::Atom< std::string > threshold
fhicl::Atom< int > reportEvery
std::string const & idOverflow() const
typename config_impl< T >::type Config
QTextStream & reset(QTextStream &s)
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::string bold_fontify(std::string const &s)
std::string const & filename() const
ELdestination(Config const &)
static int max(int a, int b)
ELseverityLevel threshold_
std::string const & id() const
Q_EXPORT QTSManip setw(int w)
fhicl::Atom< bool > outputStatistics
char const * what() const noexcept override
std::string formSummary()
std::optional< T > get_if_present(std::string const &key) const
virtual void fillPrefix(std::ostringstream &, mf::ErrorObj const &msg)
virtual void setReactedTo(bool)
MsgFormatSettings format_
void setThreshold(ELseverityLevel sv)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
std::map< ELextendedID const, XidLimiter > xidLimiters_
time_t previousTimestamp_
second_as<> second
Type of time stored in seconds, in double precision.
std::string nl(std::size_t i=1)
std::string to_string(ModuleType const mt)
virtual void routePayload(std::ostringstream const &, mf::ErrorObj const &msg)