Merge branch 'master' of github.com:nojhan/clutchlog
This commit is contained in:
commit
0fc2b0cc23
2 changed files with 111 additions and 42 deletions
62
README.md
62
README.md
|
|
@ -7,7 +7,14 @@ Clutchlog — versatile (de)clutchable logging
|
||||||
- [Project page on Github](https://github.com/nojhan/clutchlog)
|
- [Project page on Github](https://github.com/nojhan/clutchlog)
|
||||||
- [Documentation](https://nojhan.github.io/clutchlog/)
|
- [Documentation](https://nojhan.github.io/clutchlog/)
|
||||||
|
|
||||||

|
<p align="center">
|
||||||
|
<img
|
||||||
|
alt"Clutchlog logo"
|
||||||
|
src="https://raw.githubusercontent.com/nojhan/clutchlog/master/docs/clutchlog_logo.svg"
|
||||||
|
width="400"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
|
||||||
[TOC]
|
[TOC]
|
||||||
|
|
||||||
Features
|
Features
|
||||||
|
|
@ -77,23 +84,6 @@ API documentation
|
||||||
=================
|
=================
|
||||||
|
|
||||||
|
|
||||||
Log level semantics
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Log levels use a classical semantics for a human skilled in the art, in decreasing order of importance:
|
|
||||||
|
|
||||||
- *Critical*: an error that cannot be recovered. For instance, something which will make a server stop right here.
|
|
||||||
- *Error*: an error that invalidates a function, but may still be recovered. For example, a bad user input that 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 that would help ensuring that everything is going well.
|
|
||||||
- *Debug*: data that would help debugging the program if there was a bug later on.
|
|
||||||
- *XDebug*: debugging information that 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 `threshold` or `level_of`).
|
|
||||||
|
|
||||||
|
|
||||||
Calls
|
Calls
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
@ -128,6 +118,23 @@ CLUTCHDUMP(debug, vec, "test_{n}.dat");
|
||||||
Note that if you pass a file name without the `{n}` tag, the file will be overwritten as is.
|
Note that if you pass a file name without the `{n}` tag, the file will be overwritten as is.
|
||||||
|
|
||||||
|
|
||||||
|
Log level semantics
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Log levels use a classical semantics for a human skilled in the art, in decreasing order of importance:
|
||||||
|
|
||||||
|
- *Critical*: an error that cannot be recovered. For instance, something which will make a server stop right here.
|
||||||
|
- *Error*: an error that invalidates a function, but may still be recovered. For example, a bad user input that 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 that would help ensuring that everything is going well.
|
||||||
|
- *Debug*: data that would help debugging the program if there was a bug later on.
|
||||||
|
- *XDebug*: debugging information that 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 `threshold` or `level_of`).
|
||||||
|
|
||||||
|
|
||||||
Location filtering
|
Location filtering
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
@ -234,7 +241,16 @@ and its default with the `CLUTCHLOG_DEFAULT_HFILL_MARK` macro:
|
||||||
log.hfill_mark(CLUTCHLOG_DEFAULT_HFILL_MARK); // Defaults to '.'.
|
log.hfill_mark(CLUTCHLOG_DEFAULT_HFILL_MARK); // Defaults to '.'.
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: if the system detects no terminal, only a single fill character is inserted.
|
Clutchlog measures the width of the standard error channel.
|
||||||
|
If it is redirected, it may be measured as very large.
|
||||||
|
Thus, the `hfill_max` accessors allow to set a maximum width (in number of characters).
|
||||||
|
```cpp
|
||||||
|
log.hfill_max(CLUTCHLOG_DEFAULT_HFILL_MAX); // Defaults to 300.
|
||||||
|
```
|
||||||
|
Note: clutchlog will select the minimum between `hfill_max`
|
||||||
|
and the measured number of columns in the terminal,
|
||||||
|
so that you may use `hfill_max` as a way to constraint the output width
|
||||||
|
in any cases.
|
||||||
|
|
||||||
|
|
||||||
## Stack Depth
|
## Stack Depth
|
||||||
|
|
@ -306,6 +322,12 @@ log.format(format.str());
|
||||||
Note: messages at the "critical", "error" and "warning" log levels are colored by default.
|
Note: messages at the "critical", "error" and "warning" log levels are colored by default.
|
||||||
You may want to set their style to `none` if you want to stay in control of inserted 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.
|
||||||
|
|
||||||
|
The horizontal filling line (the `{hfill}` tag) can be configured separately with `hfill_style`,
|
||||||
|
for example:
|
||||||
|
```cpp
|
||||||
|
log.hfill_style(clutchlog::fmt::fg::black);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
Disabled calls
|
Disabled calls
|
||||||
--------------
|
--------------
|
||||||
|
|
@ -318,7 +340,7 @@ by setting the `WITH_CLUTCHLOG` preprocessor variable.
|
||||||
|
|
||||||
When the `NDEBUG` preprocessor variable is set (e.g. in `Release` build),
|
When the `NDEBUG` preprocessor variable is set (e.g. in `Release` build),
|
||||||
clutchlog will do its best to allow the compiler to optimize out any calls
|
clutchlog will do its best to allow the compiler to optimize out any calls
|
||||||
for log levels that are under or equal to `progress`.
|
for log levels that are under `progress`.
|
||||||
|
|
||||||
You can change this behavior at compile time by setting the
|
You can change this behavior at compile time by setting the
|
||||||
`CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG` preprocessor variable
|
`CLUTCHLOG_DEFAULT_DEPTH_BUILT_NODEBUG` preprocessor variable
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef __CLUTCHLOG_H__
|
|
||||||
#define __CLUTCHLOG_H__
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#ifndef CLUTCHLOG_H
|
||||||
|
#define CLUTCHLOG_H
|
||||||
|
|
||||||
/** @file */
|
/** @file */
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
|
|
@ -257,10 +257,23 @@ class clutchlog
|
||||||
#endif // CLUTCHLOG_HFILL_MARK
|
#endif // CLUTCHLOG_HFILL_MARK
|
||||||
//! Default character used as a filling for right-align the right part of messages with "{hfill}".
|
//! Default character used as a filling for right-align the right part of messages with "{hfill}".
|
||||||
static inline char default_hfill_char = CLUTCHLOG_HFILL_MARK;
|
static inline char default_hfill_char = CLUTCHLOG_HFILL_MARK;
|
||||||
|
|
||||||
|
|
||||||
|
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
|
||||||
|
#ifndef CLUTCHLOG_HFILL_MAX
|
||||||
|
#define CLUTCHLOG_HFILL_MAX 300
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
//! Default maximum number of character used as a filling for right-align the right part of messages with "{hfill}".
|
||||||
|
static inline unsigned short default_hfill_max = CLUTCHLOG_HFILL_MAX;
|
||||||
|
|
||||||
|
// NOTE: there is no CLUTCHLOG_HFILL_STYLE for defaulting,
|
||||||
|
// but you can still set `hfill_style(...)` on the logger singleton.
|
||||||
/* @} */
|
/* @} */
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** @name High-level API
|
/** @name High-level API
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
|
|
@ -435,12 +448,16 @@ class clutchlog
|
||||||
}),
|
}),
|
||||||
_format_log(clutchlog::default_format),
|
_format_log(clutchlog::default_format),
|
||||||
_format_dump(clutchlog::dump_default_format),
|
_format_dump(clutchlog::dump_default_format),
|
||||||
_hfill_char(clutchlog::default_hfill_char),
|
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
|
||||||
|
_hfill_char(clutchlog::default_hfill_char),
|
||||||
|
_hfill_fmt(fmt::fg::none),
|
||||||
|
_hfill_max(clutchlog::default_hfill_max),
|
||||||
|
#endif
|
||||||
_out(&std::clog),
|
_out(&std::clog),
|
||||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||||
_depth(std::numeric_limits<size_t>::max() - _strip_calls),
|
_depth(std::numeric_limits<size_t>::max() - _strip_calls),
|
||||||
_depth_mark(clutchlog::default_depth_mark),
|
_depth_mark(clutchlog::default_depth_mark),
|
||||||
#endif
|
#endif
|
||||||
_stage(level::error),
|
_stage(level::error),
|
||||||
_in_file(".*"),
|
_in_file(".*"),
|
||||||
_in_func(".*"),
|
_in_func(".*"),
|
||||||
|
|
@ -452,8 +469,8 @@ class clutchlog
|
||||||
}
|
}
|
||||||
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
|
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
|
||||||
struct winsize w;
|
struct winsize w;
|
||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
ioctl(STDERR_FILENO, TIOCGWINSZ, &w);
|
||||||
_nb_columns = w.ws_col;
|
_nb_columns = std::min(w.ws_col, default_hfill_max);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -470,16 +487,22 @@ class clutchlog
|
||||||
std::string _format_log;
|
std::string _format_log;
|
||||||
/** Current format of the file output. */
|
/** Current format of the file output. */
|
||||||
std::string _format_dump;
|
std::string _format_dump;
|
||||||
/** Character for filling. */
|
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL
|
||||||
char _hfill_char;
|
/** Character for filling. */
|
||||||
|
char _hfill_char;
|
||||||
|
/** Style of the filling. */
|
||||||
|
fmt _hfill_fmt;
|
||||||
|
/** Maximum number of fill char. */
|
||||||
|
unsigned short _hfill_max;
|
||||||
|
#endif
|
||||||
/** Standard output. */
|
/** Standard output. */
|
||||||
std::ostream* _out;
|
std::ostream* _out;
|
||||||
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
#if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1
|
||||||
/** Current stack depth (above which logs are not printed). */
|
/** Current stack depth (above which logs are not printed). */
|
||||||
size_t _depth;
|
size_t _depth;
|
||||||
/** Current depth mark. */
|
/** Current depth mark. */
|
||||||
std::string _depth_mark;
|
std::string _depth_mark;
|
||||||
#endif
|
#endif
|
||||||
/** Current log level. */
|
/** Current log level. */
|
||||||
level _stage;
|
level _stage;
|
||||||
/** Current file location filter. */
|
/** Current file location filter. */
|
||||||
|
|
@ -541,6 +564,20 @@ class clutchlog
|
||||||
void hfill_mark(const char mark) {_hfill_char = mark;}
|
void hfill_mark(const char mark) {_hfill_char = mark;}
|
||||||
//! Get the character for the stretching hfill marker.
|
//! Get the character for the stretching hfill marker.
|
||||||
char hfill_mark() const {return _hfill_char;}
|
char hfill_mark() const {return _hfill_char;}
|
||||||
|
//! Set the style for the stretching hfill marker, with a `fmt` object.
|
||||||
|
void hfill_style(fmt style) {_hfill_fmt = style;}
|
||||||
|
/** Set the style for the stretching hfill marker.
|
||||||
|
*
|
||||||
|
* This version accept style arguments as if they were passed to `clutchlog::fmt`.
|
||||||
|
*/
|
||||||
|
template<class ... FMT>
|
||||||
|
void style(FMT... styles) { this->hfill_style(fmt(styles...)); }
|
||||||
|
//! Get the character for the stretching hfill marker.
|
||||||
|
fmt hfill_style() const {return _hfill_fmt;}
|
||||||
|
//! Set the maximum number of hfill characters. */
|
||||||
|
void hfill_max(const size_t nmax) {_hfill_max = nmax;}
|
||||||
|
//! Get the maximum number of hfill characters. */
|
||||||
|
unsigned short hfill_max() {return _hfill_max;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! Set the log level (below which logs are not printed) with an identifier.
|
//! Set the log level (below which logs are not printed) with an identifier.
|
||||||
|
|
@ -800,15 +837,19 @@ class clutchlog
|
||||||
if(right_len+left_len > _nb_columns) {
|
if(right_len+left_len > _nb_columns) {
|
||||||
// The right part would go over the terminal width: add a new line.
|
// The right part would go over the terminal width: add a new line.
|
||||||
const std::string hfill(std::max((size_t)0, _nb_columns-right_len), _hfill_char);
|
const std::string hfill(std::max((size_t)0, _nb_columns-right_len), _hfill_char);
|
||||||
format = replace(format, "\\{hfill\\}", "\n"+hfill);
|
const std::string hfill_styled = _hfill_fmt(hfill);
|
||||||
|
format = replace(format, "\\{hfill\\}", "\n"+hfill_styled);
|
||||||
} else {
|
} else {
|
||||||
// There is some space in between left and right parts.
|
// There is some space in between left and right parts.
|
||||||
const std::string hfill(std::max((size_t)0, _nb_columns - (right_len+left_len)), _hfill_char);
|
const std::string hfill(std::max((size_t)0, _nb_columns - (right_len+left_len)), _hfill_char);
|
||||||
format = replace(format, "\\{hfill\\}", hfill);
|
const std::string hfill_styled = _hfill_fmt(hfill);
|
||||||
|
format = replace(format, "\\{hfill\\}", hfill_styled);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We don't know the terminal width.
|
// We don't know the terminal width.
|
||||||
format = replace(format, "\\{hfill\\}", _hfill_char);
|
const std::string hfill(1, _hfill_char);
|
||||||
|
const std::string hfill_styled = _hfill_fmt(hfill);
|
||||||
|
format = replace(format, "\\{hfill\\}", hfill_styled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -967,12 +1008,16 @@ class clutchlog
|
||||||
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
|
#if CLUTCHLOG_HAVE_UNIX_SYSIOCTL == 1
|
||||||
void hfill_mark(const char) {}
|
void hfill_mark(const char) {}
|
||||||
char hfill_mark() const {}
|
char hfill_mark() const {}
|
||||||
|
void hfill_fmt(fmt) {}
|
||||||
|
fmt hfill_fmt() const {}
|
||||||
|
void hfill_max(const size_t) {}
|
||||||
|
unsigned short hfill_max() {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void threshold(level) {}
|
void threshold(level) {}
|
||||||
void threshold(const std::string&) {}
|
void threshold(const std::string&) {}
|
||||||
level threshold() const {}
|
level threshold() const {}
|
||||||
const std::map<std::string,level> levels() const {};
|
const std::map<std::string,level> levels() const {}
|
||||||
level level_of(const std::string) {}
|
level level_of(const std::string) {}
|
||||||
|
|
||||||
void file(std::string) {}
|
void file(std::string) {}
|
||||||
|
|
@ -988,6 +1033,8 @@ class clutchlog
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
template<class ... FMT>
|
||||||
|
void style(level, FMT...) {}
|
||||||
void style(level, fmt) {}
|
void style(level, fmt) {}
|
||||||
fmt style(level) const {}
|
fmt style(level) const {}
|
||||||
public:
|
public:
|
||||||
|
|
@ -1042,4 +1089,4 @@ class clutchlog
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif // WITH_CLUTCHLOG
|
#endif // WITH_CLUTCHLOG
|
||||||
|
|
||||||
#endif // __CLUTCHLOG_H__
|
#endif // CLUTCHLOG_H
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue