diff --git a/README.md b/README.md index f5afb5b..7ea244d 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ To configure the display, you indicate the three types of locations, for example ```cpp auto& log = clutchlog::logger(); log.depth(2); // Log functions called from "main" but not below. - log.threshold(clutchlog::level::info); // Log only "info", "warning", "error" or "critical" messages. + log.threshold("Info"); // Log only "info", "warning", "error" or "critical" messages. log.file("algebra/.*"); // Will match any file in the "algebra" directory. log.func("(mul|add|sub|div)"); // Will match "multiply", for instance. ``` @@ -72,6 +72,24 @@ allowing for the fast tracking of a bug across the execution. 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 ----- @@ -135,9 +153,9 @@ 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`: +Strings may be used to set up the threshold: ```cpp -log.threshold( log.level_of("XDebug") ); // You have to know the exact string. +log.threshold("Error"); // You have to know the exact —case sensitive— string. ``` Note that the case of the log levels strings matters (see below). @@ -305,6 +323,11 @@ 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"); ``` +You can access the identifier of log levels with `level_of`: +```cpp +log.threshold( log.level_of("XDebug") ); // You have to know the exact string. +``` + (De)clutch any function call ---------------------------- @@ -332,22 +355,6 @@ CLUTCHCODE(info, ); ``` -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 `level_of`). - Limitations =========== diff --git a/clutchlog/clutchlog.h b/clutchlog/clutchlog.h index c7e6cae..dc6ee4b 100644 --- a/clutchlog/clutchlog.h +++ b/clutchlog/clutchlog.h @@ -282,16 +282,16 @@ class clutchlog } /** Typographic style*/ style; //! Empty constructor, only useful for a no-op formatter. - fmt() : fore(fg::none), back(bg::none), style(typo::none) { } + fmt() : fore(fg::none), back(bg::none), style(typo::none) {} /** @name All combination of constructors with different parameters orders. * @{ */ - fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) { } - fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) { } - fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) { } - fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) { } - fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) { } - fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) { } + fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {} + fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {} + fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {} + fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {} + fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {} + fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {} /** @} */ protected: @@ -472,10 +472,28 @@ class clutchlog std::string depth_mark() const {return _depth_mark;} #endif - //! Set the log level below which logs are not printed. + //! Set the log level (below which logs are not printed) with an identifier. void threshold(level l) {_stage = l;} + //! Set the log level (below which logs are not printed) with a string. + void threshold(const std::string& l) {_stage = this->level_of(l);} //! Get the log level below which logs are not printed. level threshold() const {return _stage;} + //! Get the map of available log levels string representations toward their identifier. */ + const std::map& levels() const { return _word_level;} + + /** Return the log level tag corresponding to the given pre-configured name. + * + * @note This is case sensitive, see the pre-configured `_level_word`. + */ + 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"); + } + } //! Set the regular expression filtering the file location. void file(std::string file) {_in_file = file;} @@ -507,20 +525,6 @@ class clutchlog //! Get the configured fmt instance of the given log level. fmt style(level stage) const { return _level_fmt.at(stage); } - /** Return the log level tag corresponding to the given pre-configured name. - * - * @note This is case sensitive, see the pre-configured `_level_word`. - */ - 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"); - } - } - /** @} */ public: @@ -815,25 +819,25 @@ class clutchlog class clutchlog { public: - static clutchlog& logger() { } + static clutchlog& logger() {} 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; enum class bg { black, red, green, yellow, blue, magenta, cyan, white, none } back; enum class typo { reset, bold, underline, inverse, none } style; - fmt() : fore(fg::none), back(bg::none), style(typo::none) { } - fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) { } - fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) { } - fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) { } - fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) { } - fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) { } - fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) { } + fmt() : fore(fg::none), back(bg::none), style(typo::none) {} + fmt( fg f, bg b = bg::none, typo s = typo::none) : fore(f), back(b), style(s) {} + fmt( fg f, typo s , bg b = bg::none) : fore(f), back(b), style(s) {} + fmt( bg b, fg f = fg::none, typo s = typo::none) : fore(f), back(b), style(s) {} + fmt( bg b, typo s , fg f = fg::none) : fore(f), back(b), style(s) {} + fmt(typo s, fg f = fg::none, bg b = bg::none) : fore(f), back(b), style(s) {} + fmt(typo s, bg b , fg f = fg::none) : fore(f), back(b), style(s) {} protected: - std::ostream& print_on(std::ostream&) const { } + std::ostream& print_on(std::ostream&) const {} public: - friend std::ostream& operator<<(std::ostream&, const fmt&) { } - std::string operator()(const std::string&) const { } + friend std::ostream& operator<<(std::ostream&, const fmt&) {} + std::string operator()(const std::string&) const {} }; public: clutchlog(clutchlog const&) = delete; @@ -848,7 +852,7 @@ class clutchlog const std::string&, const size_t ) const - { } + {} public: void format(const std::string&) {} std::string format() const {} @@ -868,7 +872,10 @@ class clutchlog #endif void threshold(level) {} + void threshold(const std::string&) {} level threshold() const {} + const std::map levels() const {}; + level level_of(const std::string) {} void file(std::string) {} void func(std::string) {} @@ -881,25 +888,24 @@ class clutchlog const std::string& in_function=".*", const std::string& in_line=".*" ) - { } + {} #pragma GCC diagnostic pop - void style(level, fmt) { } - fmt style(level) const { } - level level_of(const std::string) { } + void style(level, fmt) {} + fmt style(level) const {} public: std::string replace( const std::string&, const std::string&, const std::string& ) const - { } + {} std::string replace( const std::string&, const std::string&, const size_t ) const - { } + {} std::string format( std::string, @@ -916,14 +922,14 @@ class clutchlog const size_t #endif ) const - { } + {} void log( const level&, const std::string&, const std::string&, const std::string&, size_t ) const - { } + {} template void dump( @@ -933,7 +939,7 @@ class clutchlog const std::string&, const std::string ) const - { } + {} }; #pragma GCC diagnostic pop #endif // WITH_CLUTCHLOG diff --git a/tests/t-log.cpp b/tests/t-log.cpp index 531e104..7bc709e 100644 --- a/tests/t-log.cpp +++ b/tests/t-log.cpp @@ -38,7 +38,9 @@ int main(/*const int argc, char* argv[]*/) #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1 log.depth(4); #endif - log.threshold(clutchlog::level::xdebug); + assert(log.levels().find("XDebug") != std::end(log.levels())); // contains + assert(log.levels().find("Xdebug") == std::end(log.levels())); // not contains + log.threshold("XDebug"); log.location(".*"); f(); @@ -62,7 +64,7 @@ int main(/*const int argc, char* argv[]*/) #if CLUTCHLOG_HAVE_UNIX_SYSINFO == 1 log.depth(99); #endif - log.threshold(clutchlog::level::debug); + log.threshold("Debug"); log.location(".*","(g|h)"); f(); }