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.
This commit is contained in:
parent
a93411c4f6
commit
d171c55284
2 changed files with 68 additions and 23 deletions
44
README.md
44
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
|
||||
======
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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,std::string> _level_words;
|
||||
const std::map<level,std::string> _level_word;
|
||||
std::map<std::string,level> _word_level;
|
||||
std::map<level,fmt> _level_fmt;
|
||||
std::string _format_log;
|
||||
std::string _format_dump;
|
||||
|
|
@ -416,8 +424,20 @@ class clutchlog
|
|||
line(in_line);
|
||||
}
|
||||
|
||||
template<class ... FMT>
|
||||
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&,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue