diff --git a/example/ex1/ex1.cpp b/example/ex1/ex1.cpp index 60922607..db0ce39e 100644 --- a/example/ex1/ex1.cpp +++ b/example/ex1/ex1.cpp @@ -3,7 +3,7 @@ using namespace xo; void A(int x) { - XO_SCOPE(log); + XO_SCOPE(log, info); log("x:", x); } diff --git a/example/ex2/ex2.cpp b/example/ex2/ex2.cpp index 3d246f0e..016fe177 100644 --- a/example/ex2/ex2.cpp +++ b/example/ex2/ex2.cpp @@ -6,7 +6,7 @@ using namespace xo; int fib(int n) { - scope log(XO_SSETUP0(), ":n ", n); + scope log(XO_ENTER0(info), ":n ", n); int retval = 1; @@ -26,7 +26,7 @@ main(int argc, char ** argv) { int n = 4; - scope log(XO_SSETUP0(), ":n ", 4); + scope log(XO_ENTER0(info), ":n ", 4); int fn = fib(n); diff --git a/example/ex3/ex3.cpp b/example/ex3/ex3.cpp index a0507147..0d9121dc 100644 --- a/example/ex3/ex3.cpp +++ b/example/ex3/ex3.cpp @@ -6,7 +6,7 @@ using namespace xo; int fib(int n) { - scope log(XO_ENTER0(), tag("n", n)); + scope log(XO_ENTER0(info), tag("n", n)); int retval = 1; @@ -21,6 +21,7 @@ fib(int n) { int main(int argc, char ** argv) { + log_config::min_log_level = log_level::info; log_config::time_enabled = true; log_config::time_local_flag = true; log_config::style = FS_Streamlined; @@ -34,12 +35,12 @@ main(int argc, char ** argv) { int n = 4; - scope log(XO_ENTER0(), ":n ", 4); + scope log(XO_ENTER0(info), ":n ", 4); int fn = fib(n); - log(tag("n", n)); - log("<-", xtag("fib(n)", fn)); + log && log(tag("n", n)); + log && log("<-", xtag("fib(n)", fn)); } /* ex3/ex3.cpp */ diff --git a/include/nestlog/log_config.hpp b/include/nestlog/log_config.hpp index fa0d3902..b0a3780e 100644 --- a/include/nestlog/log_config.hpp +++ b/include/nestlog/log_config.hpp @@ -2,6 +2,7 @@ #pragma once +#include "log_level.hpp" #include "function.hpp" #include "nestlog/color.hpp" #include @@ -10,6 +11,8 @@ namespace xo { /* Tag here b/c we want header-only library */ template struct log_config_impl { + /* display log messages with severity >= .log_level */ + static log_level min_log_level; /* true to log local time */ static bool time_enabled; /* true to log time-of-day in local coords; false for UTC coords */ @@ -41,6 +44,10 @@ namespace xo { static std::uint32_t code_location_color; }; /*log_config_impl*/ + template + log_level + log_config_impl::min_log_level = log_level::default_level; + template bool log_config_impl::time_enabled = 1; diff --git a/include/nestlog/log_level.hpp b/include/nestlog/log_level.hpp new file mode 100644 index 00000000..f5d5f4db --- /dev/null +++ b/include/nestlog/log_level.hpp @@ -0,0 +1,42 @@ +/* @file log_level.hpp */ + +#include + +namespace xo { + enum class log_level : std::uint32_t { + /* control log message severity + * silent > severe > error > warning > info > chatty + */ + chatty, + info, + warning, + error, + severe, + silent, + + default_level = error + }; /*log_level*/ + + inline bool + operator>(log_level x, log_level y) { + return (static_cast(x) > static_cast(y)); + } + + inline bool + operator>=(log_level x, log_level y) { + return (static_cast(x) >= static_cast(y)); + } + + inline bool + operator<(log_level x, log_level y) { + return (static_cast(x) < static_cast(y)); + } + + inline bool + operator<=(log_level x, log_level y) { + return (static_cast(x) <= static_cast(y)); + } + +} /*namespace xo*/ + +/* end log_level.hpp */ diff --git a/include/nestlog/scope.hpp b/include/nestlog/scope.hpp index 848e9d4e..f15515df 100644 --- a/include/nestlog/scope.hpp +++ b/include/nestlog/scope.hpp @@ -16,16 +16,16 @@ namespace xo { template class state_impl; -# define XO_ENTER0() xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__) -# define XO_ENTER1(debug_flag) xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__, debug_flag) +# define XO_ENTER0(lvl) xo::scope_setup(xo::log_level::lvl, xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__) +# define XO_ENTER1(lvl, debug_flag) xo::scope_setup(xo::log_level::lvl, xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__, debug_flag) //# define XO_SSETUP0() xo::scope_setup(__FUNCTION__) -# define XO_SSETUP0() xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__) +//# define XO_SSETUP0(lvl) xo::scope_setup(xo::log_level::lvl, xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__) /* throw exception if condition not met*/ # define XO_EXPECT(f,msg) if(!(f)) { throw std::runtime_error(msg); } /* establish scope using current function name */ -# define XO_SCOPE(name) xo::scope name(xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__)) +# define XO_SCOPE(name, lvl) xo::scope name(xo::scope_setup(xo::log_level::lvl, xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__)) /* like XO_SCOPE(name), but also set enabled flag */ # define XO_SCOPE2(name, debug_flag) xo::scope name(xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__, debug_flag)) # define XO_SCOPE_DISABLED(name) xo::scope name(xo::scope_setup(xo::log_config::style, __PRETTY_FUNCTION__, __FILE__, __LINE__, false)) @@ -35,17 +35,21 @@ namespace xo { * use to disambiguate setup from other arguments */ struct scope_setup { - scope_setup(function_style style, std::string_view name1, std::string_view name2, - std::string_view file, std::uint32_t line, bool enabled_flag) - : style_{style}, name1_{name1}, name2_{name2}, file_{file}, line_{line}, enabled_flag_{enabled_flag} {} - scope_setup(function_style style, std::string_view name1, std::string_view file, std::uint32_t line, bool enabled_flag) - : scope_setup(style, name1, "", file, line, enabled_flag) {} - scope_setup(function_style style, std::string_view name1, std::string_view file, std::uint32_t line) - : scope_setup(style, name1, file, line, true /*enabled_flag*/) {} + scope_setup(log_level level, function_style style, std::string_view name1, std::string_view name2, + std::string_view file, std::uint32_t line) + : log_level_{level}, style_{style}, name1_{name1}, name2_{name2}, file_{file}, line_{line} {} + scope_setup(log_level level, function_style style, + std::string_view name1, std::string_view file, std::uint32_t line) + : scope_setup(level, style, name1, "" /*name2*/, file, line) {} + + bool is_enabled() const { return (this->log_level_ >= log_config::min_log_level); } //static scope_setup literal(std::string_view name1, bool enabled_flag = true) { return scope_setup(FS_Literal, name1, enabled_flag); } //static scope_setup literal(std::string_view name1, std::string_view name2, bool enabled_flag = true) { return scope_setup(FS_Literal, name1, name2, enabled_flag); } + /* threshold level for logging -- write messages with severity >= this level */ + log_level log_level_ = log_level::error; + /* FS_Pretty | FS_Streamlined | FS_Simple */ function_style style_ = FS_Pretty; std::string_view name1_ = "<.name1>"; std::string_view name2_ = "<.name2>"; @@ -53,8 +57,6 @@ namespace xo { std::string_view file_ = "<.file>"; /* __LINE__ */ std::uint32_t line_ = 0; - /* true iff output enabled for this scope */ - bool enabled_flag_ = false; }; /*scope_setup*/ /* nesting logger @@ -182,9 +184,9 @@ namespace xo { name2_{std::move(setup.name2_)}, file_{std::move(setup.file_)}, line_{setup.line_}, - finalized_{!setup.enabled_flag_} + finalized_{!(setup.is_enabled())} { - if(setup.enabled_flag_) { + if(setup.is_enabled()) { state_impl_type * logstate = basic_scope::require_thread_local_state(); std::ostream & os = logstate2stream(logstate); diff --git a/include/nestlog/time.hpp b/include/nestlog/time.hpp index 04344195..1d93dd26 100644 --- a/include/nestlog/time.hpp +++ b/include/nestlog/time.hpp @@ -1,4 +1,4 @@ -/* @file Time.hpp */ +/* @file time.hpp */ #pragma once @@ -359,4 +359,4 @@ namespace std { } /*namespace chrono*/ } /*namespace std*/ -/* end Time.hpp */ +/* end time.hpp */