parent
cb5e28add8
commit
c45080fc8e
3 changed files with 165 additions and 15 deletions
52
README.md
52
README.md
|
|
@ -200,12 +200,15 @@ Available tags are:
|
|||
- `{file}`: the current file (absolute path),
|
||||
- `{func}`: the current function,
|
||||
- `{line}`: the current line number,
|
||||
- `{level_fmt}`: the format of the current level (i.e. configured with `clutchlog::style`).
|
||||
- `{level_fmt}`: the style of the current level (i.e. configured with `clutchlog::style`),
|
||||
- `{filehash_fmt}`: a style for file names, which is value-dependant (see `clutchlog::filehash_styles`),
|
||||
- `{funchash_fmt}`: a style for function names, which is value-dependant (see `clutchlog::funchash_styles`).
|
||||
|
||||
Some tags are only available on POSIX operating systems as of now:
|
||||
- `{name}`: the name of the current binary,
|
||||
- `{depth}`: the current depth of the call stack,
|
||||
- `{depth_marks}`: as many chevrons `>` as there is calls in the stack,
|
||||
- `{depth_fmt}`: a style depending on the current depth value (see `clutchlog::depth_styles`),
|
||||
- `{hfill}`: Inserts a sequence of characters that will stretch to fill the space available
|
||||
in the current terminal, between the rightmost and leftmost part of the log message.
|
||||
|
||||
|
|
@ -220,10 +223,12 @@ clutchlog will not put the location-related tags in the message formats
|
|||
(i.e. `{name}`, `{func}`, and `{line}`) when not in Debug builds.
|
||||
|
||||
|
||||
Output style
|
||||
------------
|
||||
Output Styling
|
||||
--------------
|
||||
|
||||
Output lines can be colored differently depending on the log level.
|
||||
Output lines can be styled differently depending on their content.
|
||||
|
||||
For example, output lines can be colored differently depending on the log level.
|
||||
```cpp
|
||||
// Print error messages in bold red:
|
||||
log.style(level::error, // First, the log level.
|
||||
|
|
@ -251,7 +256,8 @@ depending on the types of arguments passed to styling functions:
|
|||
- `clutchlog::fg::none` and `clutchlog::bg::none` can be passed in all modes.
|
||||
|
||||
For example, all the following lines encode
|
||||
a bright red foreground for the critical level:
|
||||
a bright red foreground for the critical level
|
||||
(see the "Colors" section below):
|
||||
```cpp
|
||||
log.style(level:critical,
|
||||
fmt::fg::red); // 16-colors mode.
|
||||
|
|
@ -371,6 +377,42 @@ log.style(level::info, fg::none, 100,0,0, typo::bold); // No color over bold dar
|
|||
```
|
||||
|
||||
|
||||
### Value-dependant Format Tags
|
||||
|
||||
Some tags can be used to change the style of (part of) the output line,
|
||||
|
||||
*depending on its content*.
|
||||
The `{filehash_fmt}` and `{funchash_fmt}` will introduce a styling sequence
|
||||
which depends on the current file name, and function name respectively.
|
||||
The chosen style is chosen at random among the candidate ones,
|
||||
but will always be the same for each value.
|
||||
|
||||
The set of candidate styles can be configured with `clutchlog::filehash_styles`
|
||||
and `clutchlog::funchash_styles`, which both take a vector of `clutchlog::fmt`
|
||||
objects as argument:
|
||||
```cpp
|
||||
// Either one or the other color for filenames:
|
||||
log.filehash_styles( { fmt(fg::red), fmt(fg::yellow) } );
|
||||
// This would fix the function name style to a single one:
|
||||
log.funchash_styles( { fmt(typo::bold) } );
|
||||
// Works with any `fmt` constructor
|
||||
// (here, shades of blues in 256-colors mode):
|
||||
log.funchash_styles( { fmt(33), fmt(27), fmt(39), fmt(45) } );
|
||||
```
|
||||
|
||||
The same idea applies to `{depth_fmt}`.
|
||||
However, if `clutchlog::depth_styles` is configured,
|
||||
then the styles are chosen *in order*.
|
||||
That is, a depth of 1 would lead to the first style being chosen.
|
||||
If the current depth of the stack is larger than the number of configured
|
||||
styles, then the last one is used.
|
||||
For example:
|
||||
```cpp
|
||||
// Increasingly darker depth level colors (using the 256-colors mode).
|
||||
log.depth_styles({ fmt(255), fmt(250), fmt(245), fmt(240), fmt(235) });
|
||||
```
|
||||
|
||||
|
||||
Advanced Usage
|
||||
==============
|
||||
|
||||
|
|
|
|||
|
|
@ -810,6 +810,16 @@ class clutchlog
|
|||
this->print_on(os);
|
||||
return os.str();
|
||||
}
|
||||
|
||||
static fmt hash( const std::string& str, const std::vector<fmt> domain = {})
|
||||
{
|
||||
size_t h = std::hash<std::string>{}(str);
|
||||
if(domain.size() == 0) {
|
||||
return fmt(static_cast<short>(h % 256));
|
||||
} else {
|
||||
return fmt(domain[h % domain.size()]);
|
||||
}
|
||||
}
|
||||
}; // fmt class
|
||||
|
||||
/** @} */
|
||||
|
|
@ -872,6 +882,10 @@ class clutchlog
|
|||
_in_file(".*"),
|
||||
_in_func(".*"),
|
||||
_in_line(".*")
|
||||
// Empty vectors by default:
|
||||
// _filehash_fmts
|
||||
// _funchash_fmts
|
||||
// _depth_fmts
|
||||
{
|
||||
// Reverse the level->word map into a word->level map.
|
||||
for(auto& lw : _level_word) {
|
||||
|
|
@ -926,9 +940,16 @@ class clutchlog
|
|||
/** Current line location filter. */
|
||||
std::regex _in_line;
|
||||
|
||||
/** List of candidate format objects for value-dependant file name styling. */
|
||||
std::vector<fmt> _filehash_fmts;
|
||||
/** List of candidate format objects for value-dependant function name styling. */
|
||||
std::vector<fmt> _funchash_fmts;
|
||||
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
/** Maximum buffer size for backtrace message. */
|
||||
static const size_t _max_buffer = 4096;
|
||||
/** Ordered list of format objects for value-dependant depth styling. */
|
||||
std::vector<fmt> _depth_fmts;
|
||||
#endif
|
||||
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
|
||||
|
|
@ -974,11 +995,11 @@ class clutchlog
|
|||
size_t strip_calls() const {return _strip_calls;}
|
||||
#endif
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
|
||||
//! Set the character for the stretching hfill marker.
|
||||
//! Set the character for the stretching `{hfill}` template tag marker.
|
||||
void hfill_mark(const char mark) {_hfill_char = mark;}
|
||||
//! Get the character for the stretching hfill marker.
|
||||
//! Get the character for the stretching `{hfill}` template tag marker.
|
||||
char hfill_mark() const {return _hfill_char;}
|
||||
//! Set the style for the stretching hfill marker, with a `fmt` object.
|
||||
//! Set the style for the stretching `{hfill}` template tag marker, with a `fmt` object.
|
||||
void hfill_style(fmt style) {_hfill_fmt = style;}
|
||||
/** Set the style for the stretching hfill marker.
|
||||
*
|
||||
|
|
@ -986,17 +1007,42 @@ class clutchlog
|
|||
*/
|
||||
template<class ... FMT>
|
||||
void hfill_style(FMT... styles) { this->hfill_style(fmt(styles...)); }
|
||||
//! Get the character for the stretching hfill marker.
|
||||
//! Get the character for the stretching `{hfill}` template tag marker.
|
||||
fmt hfill_style() const {return _hfill_fmt;}
|
||||
//! Set the maximum width for which to hfill. */
|
||||
//! Set the maximum width for which to `{hfill}`.
|
||||
void hfill_max(const size_t nmax) {_hfill_max = nmax;}
|
||||
//! Get the maximum width for which to hfill. */
|
||||
//! Get the maximum width for which to `{hfill}`.
|
||||
size_t hfill_max() {return _hfill_max;}
|
||||
//! Set the minimum width at which to hfill. */
|
||||
//! Set the minimum width at which to `{hfill}`.
|
||||
void hfill_min(const size_t nmin) {_hfill_min = nmin;}
|
||||
//! Get the minimum width at which to hfill. */
|
||||
//! Get the minimum width at which to `{hfill}`.
|
||||
size_t hfill_min() {return _hfill_min;}
|
||||
#endif
|
||||
/** Set the candidate styles for value-dependant file name formatting.
|
||||
*
|
||||
* Style will be chosen based on the hash value of the filename
|
||||
* among the candidate ones.
|
||||
*
|
||||
* See the `{filehash_fmt}` template tag.
|
||||
*/
|
||||
void filehash_styles(std::vector<fmt> styles) {_filehash_fmts = styles;}
|
||||
/** Set the candidate styles for value-dependant function name formatting.
|
||||
*
|
||||
* Style will be chosen based on the hash value of the filename
|
||||
* among the candidate ones.
|
||||
*
|
||||
* See the `{funchash_fmt}` template tag.
|
||||
*/
|
||||
void funchash_styles(std::vector<fmt> styles) {_funchash_fmts = styles;}
|
||||
/** Set the styles for value-dependant depth formatting.
|
||||
*
|
||||
* The given list should be ordered, styles will be applied
|
||||
* for the corresponding depth level. If the actual depth is
|
||||
* larger than the number of styles, the last one is used.
|
||||
*
|
||||
* See the `{depth_fmt}` template tag.
|
||||
*/
|
||||
void depth_styles(std::vector<fmt> styles) {_depth_fmts = styles;}
|
||||
|
||||
//! Set the log level (below which logs are not printed) with an identifier.
|
||||
void threshold(level l) {_stage = l;}
|
||||
|
|
@ -1238,17 +1284,26 @@ class clutchlog
|
|||
row = replace(row, "\\{level_short\\}", _level_short.at(stage));
|
||||
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||
size_t actual_depth = depth - _strip_calls;
|
||||
row = replace(row, "\\{name\\}", name);
|
||||
row = replace(row, "\\{depth\\}", depth - _strip_calls);
|
||||
row = replace(row, "\\{depth\\}", actual_depth);
|
||||
|
||||
std::ostringstream chevrons;
|
||||
for(size_t i = _strip_calls; i < depth; ++i) {
|
||||
chevrons << _depth_mark;
|
||||
}
|
||||
row = replace(row, "\\{depth_marks\\}", chevrons.str());
|
||||
#endif
|
||||
|
||||
if(_depth_fmts.size() == 0) {
|
||||
row = replace(row, "\\{depth_fmt\\}", fmt(actual_depth % 256).str() );
|
||||
} else {
|
||||
row = replace(row, "\\{depth_fmt\\}",
|
||||
_depth_fmts[std::min(actual_depth,_depth_fmts.size()-1)].str() );
|
||||
}
|
||||
#endif
|
||||
row = replace(row, "\\{level_fmt\\}", _level_fmt.at(stage).str());
|
||||
row = replace(row, "\\{filehash_fmt\\}", fmt::hash(file, _filehash_fmts).str() );
|
||||
row = replace(row, "\\{funchash_fmt\\}", fmt::hash(func, _funchash_fmts).str() );
|
||||
|
||||
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
|
||||
// hfill is replaced last to allow for correct line width estimation.
|
||||
|
|
@ -1490,6 +1545,7 @@ class clutchlog
|
|||
friend std::ostream& operator<<(std::ostream&, const fmt&) {}
|
||||
std::string operator()( const std::string&) const {}
|
||||
std::string str() const {}
|
||||
static fmt hash( const std::string&, const std::vector<fmt>) {}
|
||||
};
|
||||
public:
|
||||
clutchlog(clutchlog const&) = delete;
|
||||
|
|
@ -1534,6 +1590,9 @@ class clutchlog
|
|||
void hfill_max(const size_t) {}
|
||||
size_t hfill_max() {}
|
||||
#endif
|
||||
void filehash_styles(std::vector<fmt> ) {}
|
||||
void funchash_styles(std::vector<fmt> ) {}
|
||||
void depth_styles(std::vector<fmt>) {}
|
||||
|
||||
void threshold(level) {}
|
||||
void threshold(const std::string&) {}
|
||||
|
|
|
|||
49
tests/t-hash-color.cpp
Normal file
49
tests/t-hash-color.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
#include "../clutchlog/clutchlog.h"
|
||||
|
||||
void deepcall()
|
||||
{
|
||||
CLUTCHLOG(warning,"at depth 4");
|
||||
}
|
||||
|
||||
void subsubsubcall()
|
||||
{
|
||||
CLUTCHLOG(warning,"at depth 3");
|
||||
deepcall();
|
||||
}
|
||||
|
||||
void subsubcall()
|
||||
{
|
||||
CLUTCHLOG(warning,"at depth 2");
|
||||
subsubsubcall();
|
||||
}
|
||||
|
||||
void subcall()
|
||||
{
|
||||
CLUTCHLOG(warning,"at depth 1");
|
||||
subsubcall();
|
||||
}
|
||||
|
||||
int main(/*const int argc, char* argv[]*/)
|
||||
{
|
||||
auto& log = clutchlog::logger();
|
||||
using fmt = clutchlog::fmt;
|
||||
using typo = clutchlog::fmt::typo;
|
||||
|
||||
fmt reset(typo::reset);
|
||||
std::ostringstream tpl;
|
||||
tpl << "{level_fmt}Having a {level} {filehash_fmt}within {file} {funchash_fmt}calling {func} {depth_fmt}at level {depth}"
|
||||
<< reset << " : {msg}\n";
|
||||
log.format(tpl.str());
|
||||
log.threshold(clutchlog::level::xdebug);
|
||||
|
||||
log.filehash_styles( {fmt(fmt::fg::red), fmt(fmt::fg::yellow)} );
|
||||
log.funchash_styles( {fmt(fmt::fg::green), fmt(fmt::fg::blue),
|
||||
fmt(fmt::fg::bright_green), fmt(fmt::fg::bright_blue), fmt(fmt::fg::magenta)} );
|
||||
log.depth_styles( {fmt(255),fmt(250),fmt(245),fmt(240)} );
|
||||
|
||||
CLUTCHLOG(warning,"in main");
|
||||
subcall();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue