From 8923922f3076c827bce6275471e0e597b7398a00 Mon Sep 17 00:00:00 2001 From: gabime Date: Sun, 27 Sep 2020 02:08:24 +0300 Subject: [PATCH] Cleaned level loading from env var --- include/spdlog/cfg/argv.h | 3 +- include/spdlog/cfg/env.h | 3 +- include/spdlog/cfg/helpers-inl.h | 28 +++++++++++----- include/spdlog/cfg/helpers.h | 2 +- include/spdlog/details/registry-inl.h | 46 ++++++++++----------------- include/spdlog/details/registry.h | 6 ++-- tests/test_cfg.cpp | 11 ++++--- 7 files changed, 51 insertions(+), 48 deletions(-) diff --git a/include/spdlog/cfg/argv.h b/include/spdlog/cfg/argv.h index 49e2ff4d..36d9f1c4 100644 --- a/include/spdlog/cfg/argv.h +++ b/include/spdlog/cfg/argv.h @@ -30,8 +30,7 @@ inline void load_argv_levels(int argc, const char **argv) if (arg.find(spdlog_level_prefix) == 0) { auto levels_string = arg.substr(spdlog_level_prefix.size()); - auto levels = helpers::extract_levels(levels_string); - details::registry::instance().set_levels(std::move(levels)); + helpers::load_levels(levels_string); } } } diff --git a/include/spdlog/cfg/env.h b/include/spdlog/cfg/env.h index 68d84ab9..1f39ebbb 100644 --- a/include/spdlog/cfg/env.h +++ b/include/spdlog/cfg/env.h @@ -30,8 +30,7 @@ inline void load_env_levels() auto env_val = details::os::getenv("SPDLOG_LEVEL"); if (!env_val.empty()) { - auto levels = helpers::extract_levels(env_val); - details::registry::instance().set_levels(std::move(levels)); + helpers::load_levels(env_val); } } diff --git a/include/spdlog/cfg/helpers-inl.h b/include/spdlog/cfg/helpers-inl.h index 81768e4d..52a1a137 100644 --- a/include/spdlog/cfg/helpers-inl.h +++ b/include/spdlog/cfg/helpers-inl.h @@ -73,19 +73,22 @@ inline std::unordered_map extract_key_vals_(const std: continue; } auto kv = extract_kv_('=', token); - if (kv.first.empty()) - { - kv.first = "*"; - } rv[kv.first] = kv.second; } return rv; } -SPDLOG_INLINE std::unordered_map extract_levels(const std::string &input) +SPDLOG_INLINE void load_levels(const std::string &input) { + if (input.empty() || input.size() > 512) + { + return; + } + auto key_vals = extract_key_vals_(input); - std::unordered_map rv; + std::unordered_map levels; + level::level_enum global_level = level::info; + bool global_level_found = false; for (auto &name_level : key_vals) { @@ -97,9 +100,18 @@ SPDLOG_INLINE std::unordered_map extract { continue; } - rv[logger_name] = level; + if (logger_name.empty()) // no logger name indicate global level + { + global_level_found = true; + global_level = level; + } + else + { + levels[logger_name] = level; + } } - return rv; + + details::registry::instance().set_levels(std::move(levels), global_level_found ? &global_level : nullptr); } } // namespace helpers diff --git a/include/spdlog/cfg/helpers.h b/include/spdlog/cfg/helpers.h index 1f82b8fb..a795f39a 100644 --- a/include/spdlog/cfg/helpers.h +++ b/include/spdlog/cfg/helpers.h @@ -18,7 +18,7 @@ namespace helpers { // turn off all logging except for logger1: "off,logger1=debug" // turn off all logging except for logger1 and logger2: "off,logger1=debug,logger2=info" // -SPDLOG_API std::unordered_map extract_levels(const std::string &txt); +SPDLOG_API void load_levels(const std::string &txt); } // namespace helpers } // namespace cfg diff --git a/include/spdlog/details/registry-inl.h b/include/spdlog/details/registry-inl.h index c39fb46f..a60faabc 100644 --- a/include/spdlog/details/registry-inl.h +++ b/include/spdlog/details/registry-inl.h @@ -57,28 +57,6 @@ SPDLOG_INLINE void registry::register_logger(std::shared_ptr new_logger) register_logger_(std::move(new_logger)); } -// set level if this logger was configured in the cfg_levels_ -// return true if found and set -SPDLOG_INLINE bool registry::set_level_from_cfg_(logger *logger) -{ - if (cfg_levels_.empty()) - { - return false; - } - auto cfg_level_it = cfg_levels_.find(logger->name()); - if (cfg_level_it == cfg_levels_.end()) - { - // if logger name not found, set it anyway if "*" exists (i.e. all loggers) - cfg_level_it = cfg_levels_.find("*"); - } - if (cfg_level_it != cfg_levels_.end()) - { - logger->set_level(cfg_level_it->second); - return true; - } - return false; -} - SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr new_logger) { std::lock_guard lock(logger_map_mutex_); @@ -89,10 +67,10 @@ SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr new_logge new_logger->set_error_handler(err_handler_); } - if (!set_level_from_cfg_(new_logger.get())) - { - new_logger->set_level(global_log_level_); - } + // set new level according to previously configured level or default level + auto it = log_levels_.find(new_logger->name()); + auto new_level = it != log_levels_.end() ? it->second : global_log_level_; + new_logger->set_level(new_level); new_logger->flush_on(flush_level_); @@ -289,14 +267,24 @@ SPDLOG_INLINE void registry::set_automatic_registration(bool automatic_registrat automatic_registration_ = automatic_registration; } -SPDLOG_INLINE void registry::set_levels(std::unordered_map levels) +SPDLOG_INLINE void registry::set_levels(log_levels levels, level::level_enum *global_level) { std::lock_guard lock(logger_map_mutex_); - cfg_levels_ = std::move(levels); + log_levels_ = std::move(levels); + auto global_level_requested = global_level != nullptr; + global_log_level_ = global_level_requested ? *global_level : global_log_level_; for (auto &logger : loggers_) { - set_level_from_cfg_(logger.second.get()); + auto logger_entry = log_levels_.find(logger.first); + if (logger_entry != log_levels_.end()) + { + logger.second->set_level(logger_entry->second); + } + else if (global_level_requested) + { + logger.second->set_level(*global_level); + } } } diff --git a/include/spdlog/details/registry.h b/include/spdlog/details/registry.h index 89044fb0..d9b586a5 100644 --- a/include/spdlog/details/registry.h +++ b/include/spdlog/details/registry.h @@ -27,6 +27,7 @@ class periodic_worker; class SPDLOG_API registry { public: + using log_levels = std::unordered_map; registry(const registry &) = delete; registry &operator=(const registry &) = delete; @@ -79,7 +80,8 @@ public: void set_automatic_registration(bool automatic_registration); - void set_levels(std::unordered_map levels); + // set levels for all existing/future loggers. global_level can be null if should not set. + void set_levels(log_levels levels, level::level_enum *global_level); static registry &instance(); @@ -93,7 +95,7 @@ private: std::mutex logger_map_mutex_, flusher_mutex_; std::recursive_mutex tp_mutex_; std::unordered_map> loggers_; - std::unordered_map cfg_levels_; + log_levels log_levels_; std::unique_ptr formatter_; spdlog::level::level_enum global_log_level_ = level::info; level::level_enum flush_level_ = level::off; diff --git a/tests/test_cfg.cpp b/tests/test_cfg.cpp index 6deef387..ee21fc41 100644 --- a/tests/test_cfg.cpp +++ b/tests/test_cfg.cpp @@ -42,21 +42,23 @@ TEST_CASE("argv2", "[cfg]") auto l1 = spdlog::create("l1"); REQUIRE(l1->level() == spdlog::level::warn); REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace); - spdlog::set_level(spdlog::level::info); } TEST_CASE("argv3", "[cfg]") { + spdlog::set_level(spdlog::level::trace); + spdlog::drop("l1"); - const char *argv[] = {"ignore", "SPDLOG_LEVEL="}; + const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk_name=warn"}; load_argv_levels(2, argv); auto l1 = spdlog::create("l1"); - REQUIRE(l1->level() == spdlog::level::info); - REQUIRE(spdlog::default_logger()->level() == spdlog::level::info); + REQUIRE(l1->level() == spdlog::level::trace); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace); } TEST_CASE("argv4", "[cfg]") { + spdlog::set_level(spdlog::level::info); spdlog::drop("l1"); const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk"}; load_argv_levels(2, argv); @@ -66,6 +68,7 @@ TEST_CASE("argv4", "[cfg]") TEST_CASE("argv5", "[cfg]") { + spdlog::set_level(spdlog::level::info); spdlog::drop("l1"); const char *argv[] = {"ignore", "ignore", "SPDLOG_LEVEL=l1=warn,trace"}; load_argv_levels(3, argv);