From d171c552842b957255e524ab9ea6802bbf73c90c Mon Sep 17 00:00:00 2001 From: nojhan Date: Sun, 18 Oct 2020 15:42:24 +0200 Subject: [PATCH] fix: depth mark, feat: more levels, feat: level_of - fix: the depth mark was not configurable, - rename the "quiet" level as "critical", - add the "note" log level, - adds `level_of` to ease user input of log levels, - explaing log levels semantics in the readme. --- README.md | 44 +++++++++++++++++++++++++++++++--------- clutchlog/clutchlog.h | 47 +++++++++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 233eaf9..b17ab76 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,12 @@ A shortcut function can be used to filter all at once: log.location(file, func, line); // Defaults to any, second and last parameters being optional. ``` +Strings may be used to set up the threshold, using `level_of`: +```cpp +log.threshold( log.level_of("XDebug") ); // You have to know the exact string. +``` +Note that the case of the log levels strings matters (see below). + Output Configuration -------------------- @@ -173,10 +179,17 @@ Output style The output can be colored differently depending on the log level. ```cpp // Print error messages in bold red: -log.style(clutchlog::level::error, - clutchlog::fmt( - clutchlog::fmt::fg::red, - clutchlog::fmt::typo::bold)); +log.style(clutchlog::level::error, // First, the log level. + clutchlog::fmt::fg::red, // Then the styles, in any order... + clutchlog::fmt::typo::bold); +``` + +Or, if you want to declare some semantics beforehand: +```cpp +// Print warning messages in bold magenta: +using fmt = clutchlog::fmt; +fmt warn(fmt::fg::magenta, fmt::typo::bold); +log.style(clutchlog::level::magenta, warn); ``` Using the `clutchlog::fmt` class, you can style: @@ -220,7 +233,7 @@ format << "{level}: " log.format(format.str()); ``` Note: messages at the "quiet", "error" and "warning" log levels are colored by default. -You may want to set their style to `none` if you want to cleanly insert colors in the format template. +You may want to set their style to `none` if you want to stay in control of inserted colors in the format template. Disabled calls @@ -276,6 +289,22 @@ log.dump(clutchlog::level::xdebug, cont.begin(), cont.end(), CLUTCHLOC, "dumped_ log.dump(clutchlog::level::xdebug, cont.begin(), cont.end(), "main.cpp", "main", 122, "dumped.dat", "\n\n"); ``` +Log level semantics +=================== + +Log levels use a classical semantics for a human skilled in the art, in decreasing order of importance: + +- *Critical*: an error which cannot be recovered. For instance, something which will make a server stop right here. +- *Error*: an error which invalidates a function, but may still be recovered. For example, a bad user input which will make a server reset its state, but not crash. +- *Warning*: something that is strange, but is probably legit. For example a default parameter is set because the user forgot to indicate its preference. +- *Progress*: the state at which computation currently is. +- *Note*: some state worth noting to understand what's going on. +- *Info*: any information which would help ensuring that everything is going well. +- *Debug*: data which would help debugging the program if there was a bug later on. +- *XDebug*: debugging information which would be heavy to read. + +Note: the log levels constants are lower case (for example: `clutchlog::level:xdebug`), but their string representation is not (e.g. "XDebug", this should be taken into account when using `level_of`). + Limitations =========== @@ -314,8 +343,3 @@ ctest There's a script which tests all the build types combinations: `./build_all.sh`. - -How to -====== - - diff --git a/clutchlog/clutchlog.h b/clutchlog/clutchlog.h index 1a4bd0a..37e69ba 100644 --- a/clutchlog/clutchlog.h +++ b/clutchlog/clutchlog.h @@ -134,7 +134,7 @@ class clutchlog } //! Available log levels. - enum level {quiet=0, error=1, warning=2, progress=3, info=4, debug=5, xdebug=6}; + enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7}; /** }@ High-level API */ @@ -244,9 +244,9 @@ class clutchlog { std::ostringstream os; this->print_on(os); - fmt end(fmt::typo::reset); + fmt reset(fmt::typo::reset); os << msg; - end.print_on(os); + reset.print_on(os); return os.str(); } }; // fmt class @@ -263,20 +263,22 @@ class clutchlog clutchlog() : // system, main, log _strip_calls(5), - _level_words({ - {level::quiet ,"Quiet"}, + _level_word({ + {level::critical,"Critical"}, {level::error ,"Error"}, {level::warning ,"Warning"}, {level::progress,"Progress"}, + {level::note ,"Note"}, {level::info ,"Info"}, {level::debug ,"Debug"}, {level::xdebug ,"XDebug"} }), _level_fmt({ - {level::quiet ,fmt(fmt::bg::red, fmt::typo::underline)}, + {level::critical,fmt(fmt::fg::red, fmt::typo::underline)}, {level::error ,fmt(fmt::fg::red, fmt::typo::bold)}, {level::warning ,fmt(fmt::fg::magenta, fmt::typo::bold)}, {level::progress,fmt()}, + {level::note ,fmt()}, {level::info ,fmt()}, {level::debug ,fmt()}, {level::xdebug ,fmt()} @@ -292,11 +294,17 @@ class clutchlog _in_file(".*"), _in_func(".*"), _in_line(".*") - {} + { + // Reverse the level->word map into a word->level map. + for(auto& lw : _level_word) { + _word_level[lw.second] = lw.first; + } + } protected: const size_t _strip_calls; - const std::map _level_words; + const std::map _level_word; + std::map _word_level; std::map _level_fmt; std::string _format_log; std::string _format_dump; @@ -416,8 +424,20 @@ class clutchlog line(in_line); } + template + void style(level stage, FMT... styles) { this->style(stage,fmt(styles...)); } void style(level stage, fmt style) { _level_fmt.at(stage) = style; } - fmt style(level stage) const { return _level_fmt.at(stage); } + fmt style(level stage) const { return _level_fmt.at(stage); } + + level level_of(const std::string name) + { + const auto ilevel = _word_level.find(name); + if( ilevel != std::end(_word_level)) { + return ilevel->second; + } else { + throw std::out_of_range("'" + name + "' is not a valid log level name"); + } + } /** }@ Configuration */ @@ -520,8 +540,8 @@ class clutchlog format = replace(format, "\\{func\\}", func); format = replace(format, "\\{line\\}", line); - format = replace(format, "\\{level\\}", _level_words.at(stage)); - std::string letter(1, _level_words.at(stage).at(0)); // char -> string + format = replace(format, "\\{level\\}", _level_word.at(stage)); + std::string letter(1, _level_word.at(stage).at(0)); // char -> string format = replace(format, "\\{level_letter\\}", letter); #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1 @@ -530,7 +550,7 @@ class clutchlog std::ostringstream chevrons; for(size_t i = _strip_calls; i < depth; ++i) { - chevrons << ">"; + chevrons << _depth_mark; } format = replace(format, "\\{depth_marks\\}", chevrons.str()); #endif @@ -626,7 +646,7 @@ class clutchlog { public: static clutchlog& logger() { } - enum level {quiet=0, error=1, warning=2, progress=3, info=4, debug=5, xdebug=6}; + enum level {critical=0, error=1, warning=2, progress=3, note=4, info=5, debug=6, xdebug=7}; class fmt { public: enum class fg { black, red, green, yellow, blue, magenta, cyan, white, none } fore; @@ -695,6 +715,7 @@ class clutchlog #pragma GCC diagnostic pop void style(level, fmt) { } fmt style(level) const { } + level level_of(const std::string) { } public: std::string replace( const std::string&,