diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c905783..e1f9e405 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,9 +150,6 @@ set(SPDLOG_HEADERS "include/spdlog/spdlog.h" "include/spdlog/stopwatch.h" "include/spdlog/version.h" - "include/spdlog/cfg/argv.h" - "include/spdlog/cfg/env.h" - "include/spdlog/cfg/helpers.h" "include/spdlog/details/circular_q.h" "include/spdlog/details/file_helper.h" "include/spdlog/details/fmt_helper.h" @@ -197,7 +194,6 @@ set(SPDLOG_SRCS "src/logger.cpp" "src/pattern_formatter.cpp" "src/spdlog.cpp" - "src/cfg/helpers.cpp" "src/details/file_helper.cpp" "src/details/os_filesystem.cpp" "src/details/log_msg.cpp" diff --git a/example/example.cpp b/example/example.cpp index 57d269cb..32c4ff52 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -7,7 +7,6 @@ #include #include -void load_levels_example(); void stdout_logger_example(); void basic_example(); void rotating_example(); @@ -27,14 +26,10 @@ void custom_flags_example(); void file_events_example(); void replace_default_logger_example(); -#include "spdlog/cfg/env.h" // support for loading levels from the environment variable #include "spdlog/spdlog.h" #include "spdlog/version.h" int main(int, char *[]) { - // Log levels can be loaded from argv/env using "SPDLOG_LEVEL" - load_levels_example(); - SPDLOG_INFO("This message should be displayed.."); spdlog::info("Welcome to spdlog version {}.{}.{} !", SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH); spdlog::warn("Easy padding in numbers like {:08d}", 12); spdlog::critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); @@ -73,10 +68,7 @@ int main(int, char *[]) { file_events_example(); replace_default_logger_example(); - // Apply some function on all registered loggers - spdlog::apply_all([&](std::shared_ptr l) { l->info("End of example."); }); - - // Release all spdlog resources, and drop all loggers in the registry. + // Release all spdlog resources // This is optional (only mandatory if using windows + async log). spdlog::shutdown(); } @@ -123,17 +115,6 @@ void callback_example() { }); } -void load_levels_example() { - // Set the log level to "info" and mylogger to "trace": - // SPDLOG_LEVEL=info,mylogger=trace && ./example - // must #include "spdlog/cfg/env.h" - spdlog::cfg::load_env_levels(); - // or from command line: - // ./example SPDLOG_LEVEL=info,mylogger=trace - // #include "spdlog/cfg/argv.h" // for loading levels from argv - // spdlog::cfg::load_argv_levels(args, argv); -} - #include "spdlog/async.h" void async_example() { // Default thread pool settings can be modified *before* creating the async logger: diff --git a/include/spdlog/async.h b/include/spdlog/async.h index c8fa5168..db0dd98a 100644 --- a/include/spdlog/async.h +++ b/include/spdlog/async.h @@ -48,7 +48,6 @@ struct async_factory_impl { auto sink = std::make_shared(std::forward(args)...); auto new_logger = std::make_shared(std::move(logger_name), std::move(sink), std::move(tp), OverflowPolicy); - registry_inst.initialize_logger(new_logger); return new_logger; } }; diff --git a/include/spdlog/cfg/argv.h b/include/spdlog/cfg/argv.h deleted file mode 100644 index 556ab736..00000000 --- a/include/spdlog/cfg/argv.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) - -#pragma once -#include "./helpers.h" - -// -// Init log levels using each argv entry that starts with "SPDLOG_LEVEL=" -// -// set all loggers to debug level: -// example.exe "SPDLOG_LEVEL=debug" - -// set logger1 to trace level -// example.exe "SPDLOG_LEVEL=logger1=trace" - -// turn off all logging except for logger1 and logger2: -// example.exe "SPDLOG_LEVEL=off,logger1=debug,logger2=info" - -namespace spdlog { -namespace cfg { - -// search for SPDLOG_LEVEL= in the args and use it to init the levels -inline void load_argv_levels(int argc, const char **argv) { - const std::string spdlog_level_prefix = "SPDLOG_LEVEL="; - for (int i = 1; i < argc; i++) { - std::string arg = argv[i]; - if (arg.find(spdlog_level_prefix) == 0) { - auto levels_string = arg.substr(spdlog_level_prefix.size()); - helpers::load_levels(levels_string); - } - } -} - -inline void load_argv_levels(int argc, char **argv) { load_argv_levels(argc, const_cast(argv)); } - -} // namespace cfg -} // namespace spdlog diff --git a/include/spdlog/cfg/env.h b/include/spdlog/cfg/env.h deleted file mode 100644 index ff1f0c9b..00000000 --- a/include/spdlog/cfg/env.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) - -#pragma once -#include "../details/context.h" -#include "../details/os.h" -#include "./helpers.h" - -// -// Init levels and patterns from env variables SPDLOG_LEVEL -// Inspired from Rust's "env_logger" crate (https://crates.io/crates/env_logger). -// Note - fallback to "info" level on unrecognized levels -// -// Examples: -// -// set global level to debug: -// export SPDLOG_LEVEL=debug -// -// turn off all logging except for logger1: -// export SPDLOG_LEVEL="*=off,logger1=debug" -// - -// turn off all logging except for logger1 and logger2: -// export SPDLOG_LEVEL="off,logger1=debug,logger2=info" - -namespace spdlog { -namespace cfg { -inline void load_env_levels() { - auto env_val = details::os::getenv("SPDLOG_LEVEL"); - if (!env_val.empty()) { - helpers::load_levels(env_val); - } -} - -} // namespace cfg -} // namespace spdlog diff --git a/include/spdlog/cfg/helpers.h b/include/spdlog/cfg/helpers.h deleted file mode 100644 index c9acf7dd..00000000 --- a/include/spdlog/cfg/helpers.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) - -#pragma once - -#include - -#include "../common.h" - -namespace spdlog { -namespace cfg { -namespace helpers { -// -// Init levels from given string -// -// Examples: -// -// set global level to debug: "debug" -// 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 void load_levels(const std::string &input); -} // namespace helpers -} // namespace cfg -} // namespace spdlog diff --git a/include/spdlog/details/context.h b/include/spdlog/details/context.h index 45ebeba0..320f8413 100644 --- a/include/spdlog/details/context.h +++ b/include/spdlog/details/context.h @@ -33,7 +33,6 @@ public: context(const context &) = delete; context &operator=(const context &) = delete; - void initialize_logger(std::shared_ptr new_logger); std::shared_ptr default_logger(); // Return raw ptr to the default logger. @@ -51,53 +50,18 @@ public: std::shared_ptr get_tp(); - // Set global formatter. Each sink in each logger will get a clone of this object - void set_formatter(std::unique_ptr formatter); - - void set_level(level level); - - void flush_on(level level); - - void set_error_handler(err_handler handler); - - void apply_all(const std::function)> &fun); - - void flush_all(); - - void drop(const std::string &logger_name); - - void drop_all(); - - // clean all resources and threads started by the registry + // clean all resources void shutdown(); std::recursive_mutex &tp_mutex(); - void set_automatic_registration(bool automatic_registration); - - // set levels for all existing/future loggers. global_level can be null if should not set. - void set_levels(log_levels levels, level *global_level); - - void apply_logger_env_levels(std::shared_ptr new_logger); - private: context(); ~context(); - void throw_if_exists_(const std::string &logger_name); - void register_logger_(std::shared_ptr new_logger); - std::mutex logger_map_mutex_, flusher_mutex_; std::recursive_mutex tp_mutex_; - std::unordered_map> loggers_; - log_levels log_levels_; - std::unique_ptr formatter_; - spdlog::level global_log_level_ = level::info; - level flush_level_ = level::off; - err_handler err_handler_; std::shared_ptr tp_; - std::unique_ptr periodic_flusher_; std::shared_ptr default_logger_; - bool automatic_registration_ = true; }; } // namespace details diff --git a/include/spdlog/details/synchronous_factory.h b/include/spdlog/details/synchronous_factory.h index 391231e3..3aee14c6 100644 --- a/include/spdlog/details/synchronous_factory.h +++ b/include/spdlog/details/synchronous_factory.h @@ -15,7 +15,6 @@ struct synchronous_factory { static std::shared_ptr create(std::string logger_name, SinkArgs &&...args) { auto sink = std::make_shared(std::forward(args)...); auto new_logger = std::make_shared(std::move(logger_name), std::move(sink)); - details::context::instance().initialize_logger(new_logger); return new_logger; } }; diff --git a/include/spdlog/spdlog.h b/include/spdlog/spdlog.h index cede04c2..554ea7bd 100644 --- a/include/spdlog/spdlog.h +++ b/include/spdlog/spdlog.h @@ -10,7 +10,6 @@ #pragma once #include -#include #include #include #include @@ -24,75 +23,40 @@ namespace spdlog { using default_factory = synchronous_factory; -// Create and register a logger with a templated sink type -// The logger's level, formatter and flush level will be set according the -// global settings. -// +// Create a logger with a templated sink type // Example: // spdlog::create("logger_name", "dailylog_filename", 11, 59); template -inline std::shared_ptr create(std::string logger_name, SinkArgs &&...sink_args) { +std::shared_ptr create(std::string logger_name, SinkArgs &&...sink_args) { return default_factory::create(std::move(logger_name), std::forward(sink_args)...); } -// Initialize and register a logger, -// formatter and flush level will be set according the global settings. -// -// Useful for initializing manually created loggers with the global settings. -// -// Example: -// auto mylogger = std::make_shared("mylogger", ...); -// spdlog::initialize_logger(mylogger); -SPDLOG_API void initialize_logger(std::shared_ptr logger); +// Set formatter of the default logger. Each sink in each logger will get a clone of this object +SPDLOG_API void set_formatter(std::unique_ptr formatter); -// Return an existing logger or nullptr if a logger with such name doesn't -// exist. -// example: spdlog::get("my_logger")->info("hello {}", "world"); -SPDLOG_API std::shared_ptr get(const std::string &name); -SPDLOG_API std::shared_ptr get(std::string_view name); -SPDLOG_API std::shared_ptr get(const char *name); - -// Set global formatter. Each sink in each logger will get a clone of this object -SPDLOG_API void set_formatter(std::unique_ptr formatter); - -// Set global format string. +// Set format string of the default logger. // example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v"); SPDLOG_API void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local); -// Get global logging level +// Get logging level of the default logger SPDLOG_API level get_level(); -// Set global logging level +// Set logging level of the default logger SPDLOG_API void set_level(level level); // Determine whether the default logger should log messages with a certain level SPDLOG_API bool should_log(level level); -// Set global flush level +// Set flush level of the default logger. SPDLOG_API void flush_on(level level); -// Set global error handler + +// Set error handler for the default logger SPDLOG_API void set_error_handler(void (*handler)(const std::string &msg)); -// Register the given logger with the given name -SPDLOG_API void register_logger(std::shared_ptr logger); - -// Apply a user defined function on all registered loggers -// Example: -// spdlog::apply_all([&](std::shared_ptr l) {l->flush();}); -SPDLOG_API void apply_all(const std::function)> &fun); - -// Drop the reference to the given logger -SPDLOG_API void drop(const std::string &name); - -// Drop all references from the registry -SPDLOG_API void drop_all(); - -// stop any running threads started by spdlog and clean registry loggers +// calls context::shutdown() to perform final cleanups SPDLOG_API void shutdown(); -// Automatic registration of loggers when using spdlog::create() or spdlog::create_async -SPDLOG_API void set_automatic_registration(bool automatic_registration); // API for using default logger (stdout_color_mt), // e.g: spdlog::info("Message {}", 1); @@ -101,69 +65,61 @@ SPDLOG_API void set_automatic_registration(bool automatic_registration); // For example, to add another sink to it: // spdlog::default_logger()->sinks().push_back(some_sink); // -// The default logger can replaced using spdlog::set_default_logger(new_logger). +// The default logger can be replaced using spdlog::set_default_logger(new_logger). // For example, to replace it with a file logger. // // IMPORTANT: // The default API is thread safe (for _mt loggers), but: // set_default_logger() *should not* be used concurrently with the default API. -// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another. +// e.g. do not call set_default_logger() from one thread while calling spdlog::info() from another. -SPDLOG_API std::shared_ptr default_logger(); +SPDLOG_API std::shared_ptr default_logger(); -SPDLOG_API spdlog::logger *default_logger_raw(); +SPDLOG_API logger *default_logger_raw(); -SPDLOG_API void set_default_logger(std::shared_ptr default_logger); - -// Initialize logger level based on environment configs. -// -// Useful for applying SPDLOG_LEVEL to manually created loggers. -// -// Example: -// auto mylogger = std::make_shared("mylogger", ...); -// spdlog::apply_logger_env_levels(mylogger); -SPDLOG_API void apply_logger_env_levels(std::shared_ptr logger); +SPDLOG_API void set_default_logger(std::shared_ptr default_logger); template -inline void log(source_loc source, level lvl, format_string_t fmt, Args &&...args) { +void log(source_loc source, level lvl, format_string_t fmt, Args &&...args) { default_logger_raw()->log(source, lvl, fmt, std::forward(args)...); } template -inline void log(level lvl, format_string_t fmt, Args &&...args) { +void log(level lvl, format_string_t fmt, Args &&...args) { default_logger_raw()->log(lvl, fmt, std::forward(args)...); } inline void log(level lvl, std::string_view msg) { default_logger_raw()->log(lvl, msg); } + inline void log(source_loc loc, level lvl, std::string_view msg) { default_logger_raw()->log(loc, lvl, msg); } template -inline void trace(format_string_t fmt, Args &&...args) { +void trace(format_string_t fmt, Args &&...args) { log(level::trace, fmt, std::forward(args)...); } template -inline void debug(format_string_t fmt, Args &&...args) { +void debug(format_string_t fmt, Args &&...args) { log(level::debug, fmt, std::forward(args)...); } template -inline void info(format_string_t fmt, Args &&...args) { +void info(format_string_t fmt, Args &&...args) { log(level::info, fmt, std::forward(args)...); } template -inline void warn(format_string_t fmt, Args &&...args) { +void warn(format_string_t fmt, Args &&...args) { log(level::warn, fmt, std::forward(args)...); } template -inline void error(format_string_t fmt, Args &&...args) { +void error(format_string_t fmt, Args &&...args) { log(level::err, fmt, std::forward(args)...); } template -inline void critical(format_string_t fmt, Args &&...args) { +void critical(format_string_t fmt, Args &&...args) { log(level::critical, fmt, std::forward(args)...); } diff --git a/src/cfg/helpers.cpp b/src/cfg/helpers.cpp deleted file mode 100644 index 026cb222..00000000 --- a/src/cfg/helpers.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. -// Distributed under the MIT License (http://opensource.org/licenses/MIT) - -#include "spdlog/cfg/helpers.h" - -#include -#include -#include -#include - -#include "spdlog/details/context.h" - -namespace spdlog { -namespace cfg { -namespace helpers { - -// inplace convert to lowercase -inline std::string &to_lower_(std::string &str) { - std::transform(str.begin(), str.end(), str.begin(), - [](char ch) { return static_cast((ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch); }); - return str; -} - -// inplace trim spaces -inline std::string &trim_(std::string &str) { - const char *spaces = " \n\r\t"; - str.erase(str.find_last_not_of(spaces) + 1); - str.erase(0, str.find_first_not_of(spaces)); - return str; -} - -// return (name,value) trimmed pair from given "name=value" string. -// return empty string on missing parts -// "key=val" => ("key", "val") -// " key = val " => ("key", "val") -// "key=" => ("key", "") -// "val" => ("", "val") - -inline std::pair extract_kv_(char sep, const std::string &str) { - auto n = str.find(sep); - std::string k, v; - if (n == std::string::npos) { - v = str; - } else { - k = str.substr(0, n); - v = str.substr(n + 1); - } - return std::make_pair(trim_(k), trim_(v)); -} - -// return vector of key/value pairs from sequence of "K1=V1,K2=V2,.." -// "a=AAA,b=BBB,c=CCC,.." => {("a","AAA"),("b","BBB"),("c", "CCC"),...} -inline std::unordered_map extract_key_vals_(const std::string &str) { - std::string token; - std::istringstream token_stream(str); - std::unordered_map rv{}; - while (std::getline(token_stream, token, ',')) { - if (token.empty()) { - continue; - } - auto kv = extract_kv_('=', token); - rv[kv.first] = kv.second; - } - return rv; -} - -void load_levels(const std::string &input) { - if (input.empty() || input.size() > 512) { - return; - } - - auto key_vals = extract_key_vals_(input); - std::unordered_map levels; - level global_level = level::info; - bool global_level_found = false; - - for (auto &name_level : key_vals) { - const auto &logger_name = name_level.first; - auto level_name = to_lower_(name_level.second); - auto level = level_from_str(level_name); - // ignore unrecognized level names - if (level == level::off && level_name != "off") { - continue; - } - if (logger_name.empty()) // no logger name indicate global level - { - global_level_found = true; - global_level = level; - } else { - levels[logger_name] = level; - } - } - - details::context::instance().set_levels(std::move(levels), global_level_found ? &global_level : nullptr); -} - -} // namespace helpers -} // namespace cfg -} // namespace spdlog diff --git a/src/details/context.cpp b/src/details/context.cpp index d0da8eb9..dd8d1923 100644 --- a/src/details/context.cpp +++ b/src/details/context.cpp @@ -26,8 +26,7 @@ static constexpr size_t small_map_threshold = 10; namespace spdlog { namespace details { -context::context() - : formatter_(new pattern_formatter()) { +context::context() { #ifndef SPDLOG_DISABLE_DEFAULT_LOGGER // create default logger (ansicolor_stdout_sink_mt or wincolor_stdout_sink_mt in windows). #ifdef _WIN32 @@ -37,35 +36,13 @@ context::context() #endif const char *default_logger_name = ""; default_logger_ = std::make_shared(default_logger_name, std::move(color_sink)); - loggers_[default_logger_name] = default_logger_; #endif // SPDLOG_DISABLE_DEFAULT_LOGGER } context::~context() = default; -void context::initialize_logger(std::shared_ptr new_logger) { - std::lock_guard lock(logger_map_mutex_); - new_logger->set_formatter(formatter_->clone()); - - if (err_handler_) { - new_logger->set_error_handler(err_handler_); - } - - // 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_); - - if (automatic_registration_) { - register_logger_(std::move(new_logger)); - } -} - std::shared_ptr context::default_logger() { - std::lock_guard lock(logger_map_mutex_); return default_logger_; } @@ -78,10 +55,6 @@ logger *context::get_default_raw() const { return default_logger_.get(); } // set default logger. // default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map. void context::set_default_logger(std::shared_ptr new_default_logger) { - std::lock_guard lock(logger_map_mutex_); - if (new_default_logger != nullptr) { - loggers_[new_default_logger->name()] = new_default_logger; - } default_logger_ = std::move(new_default_logger); } @@ -95,129 +68,18 @@ std::shared_ptr context::get_tp() { return tp_; } -// Set global formatter. Each sink in each logger will get a clone of this object -void context::set_formatter(std::unique_ptr formatter) { - std::lock_guard lock(logger_map_mutex_); - formatter_ = std::move(formatter); - for (auto &l : loggers_) { - l.second->set_formatter(formatter_->clone()); - } -} - -void context::set_level(level level) { - std::lock_guard lock(logger_map_mutex_); - for (auto &l : loggers_) { - l.second->set_level(level); - } - global_log_level_ = level; -} - -void context::flush_on(level level) { - std::lock_guard lock(logger_map_mutex_); - for (auto &l : loggers_) { - l.second->flush_on(level); - } - flush_level_ = level; -} - -void context::set_error_handler(err_handler handler) { - std::lock_guard lock(logger_map_mutex_); - for (auto &l : loggers_) { - l.second->set_error_handler(handler); - } - err_handler_ = std::move(handler); -} - -void context::apply_all(const std::function)> &fun) { - std::lock_guard lock(logger_map_mutex_); - for (auto &l : loggers_) { - fun(l.second); - } -} - -void context::flush_all() { - std::lock_guard lock(logger_map_mutex_); - for (auto &l : loggers_) { - l.second->flush(); - } -} - -void context::drop(const std::string &logger_name) { - std::lock_guard lock(logger_map_mutex_); - auto is_default_logger = default_logger_ && default_logger_->name() == logger_name; - loggers_.erase(logger_name); - if (is_default_logger) { - default_logger_.reset(); - } -} - -void context::drop_all() { - std::lock_guard lock(logger_map_mutex_); - loggers_.clear(); - default_logger_.reset(); -} - // clean all resources and threads started by the registry void context::shutdown() { - { - std::lock_guard lock(flusher_mutex_); - periodic_flusher_.reset(); - } - - drop_all(); - - { - std::lock_guard lock(tp_mutex_); - tp_.reset(); - } + std::lock_guard lock(tp_mutex_); + tp_.reset(); } std::recursive_mutex &context::tp_mutex() { return tp_mutex_; } -void context::set_automatic_registration(bool automatic_registration) { - std::lock_guard lock(logger_map_mutex_); - automatic_registration_ = automatic_registration; -} - -void context::set_levels(log_levels levels, level *global_level) { - std::lock_guard lock(logger_map_mutex_); - 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_) { - 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); - } - } -} - context &context::instance() { static context s_instance; return s_instance; } -void context::apply_logger_env_levels(std::shared_ptr new_logger) { - std::lock_guard lock(logger_map_mutex_); - 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); -} - -void context::throw_if_exists_(const std::string &logger_name) { - if (loggers_.find(logger_name) != loggers_.end()) { - throw_spdlog_ex("logger with name '" + logger_name + "' already exists"); - } -} - -void context::register_logger_(std::shared_ptr new_logger) { - auto logger_name = new_logger->name(); - throw_if_exists_(logger_name); - loggers_[logger_name] = std::move(new_logger); -} - } // namespace details } // namespace spdlog diff --git a/src/spdlog.cpp b/src/spdlog.cpp index 60bcfdd5..d50122b0 100644 --- a/src/spdlog.cpp +++ b/src/spdlog.cpp @@ -12,10 +12,10 @@ namespace spdlog { -void initialize_logger(std::shared_ptr logger) { details::context::instance().initialize_logger(std::move(logger)); } + void set_formatter(std::unique_ptr formatter) { - details::context::instance().set_formatter(std::move(formatter)); + default_logger_raw()->set_formatter(std::move(formatter)); } void set_pattern(std::string pattern, pattern_time_type time_type) { @@ -26,24 +26,15 @@ level get_level() { return default_logger_raw()->log_level(); } bool should_log(level level) { return default_logger_raw()->should_log(level); } -void set_level(level level) { details::context::instance().set_level(level); } +void set_level(level level) { default_logger_raw()->set_level(level); } -void flush_on(level level) { details::context::instance().flush_on(level); } +void flush_on(level level) { default_logger_raw()->flush_on(level); } -void set_error_handler(void (*handler)(const std::string &msg)) { details::context::instance().set_error_handler(handler); } +void set_error_handler(void (*handler)(const std::string &msg)) { default_logger_raw()->set_error_handler(handler); } -void apply_all(const std::function)> &fun) { details::context::instance().apply_all(fun); } - -void drop(const std::string &name) { details::context::instance().drop(name); } - -void drop_all() { details::context::instance().drop_all(); } void shutdown() { details::context::instance().shutdown(); } -void set_automatic_registration(bool automatic_registration) { - details::context::instance().set_automatic_registration(automatic_registration); -} - std::shared_ptr default_logger() { return details::context::instance().default_logger(); } spdlog::logger *default_logger_raw() { return details::context::instance().get_default_raw(); } @@ -52,7 +43,4 @@ void set_default_logger(std::shared_ptr default_logger) { details::context::instance().set_default_logger(std::move(default_logger)); } -void apply_logger_env_levels(std::shared_ptr logger) { - details::context::instance().apply_logger_env_levels(std::move(logger)); -} } // namespace spdlog diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8a699fab..acd02d02 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -43,8 +43,7 @@ set(SPDLOG_UTESTS_SOURCES test_stdout_api.cpp test_create_dir.cpp test_custom_callbacks.cpp - test_cfg.cpp - test_time_point.cpp + test_time_point.cpp test_stopwatch.cpp test_circular_q.cpp test_ringbuffer_sink.cpp diff --git a/tests/test_async.cpp b/tests/test_async.cpp index 639b5e32..ad5f00c0 100644 --- a/tests/test_async.cpp +++ b/tests/test_async.cpp @@ -68,7 +68,6 @@ TEST_CASE("discard policy using factory ", "[async]") { } REQUIRE(test_sink->msg_counter() < messages); - spdlog::drop_all(); } TEST_CASE("flush", "[async]") { diff --git a/tests/test_cfg.cpp b/tests/test_cfg.cpp deleted file mode 100644 index 9cfec7b5..00000000 --- a/tests/test_cfg.cpp +++ /dev/null @@ -1,168 +0,0 @@ - -#include "includes.h" -#include "spdlog/cfg/argv.h" -#include "spdlog/cfg/env.h" -#include "test_sink.h" - -using spdlog::cfg::load_argv_levels; -using spdlog::cfg::load_env_levels; -using spdlog::sinks::test_sink_st; - -TEST_CASE("env", "[cfg]") { - spdlog::drop("l1"); - auto l1 = spdlog::create("l1"); -#ifdef CATCH_PLATFORM_WINDOWS - _putenv_s("SPDLOG_LEVEL", "l1=warn"); -#else - setenv("SPDLOG_LEVEL", "l1=warn", 1); -#endif - load_env_levels(); - REQUIRE(l1->log_level() == spdlog::level::warn); - spdlog::set_default_logger(spdlog::create("cfg-default")); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::info); -} - -TEST_CASE("argv1", "[cfg]") { - spdlog::drop("l1"); - const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn"}; - load_argv_levels(2, argv); - auto l1 = spdlog::create("l1"); - REQUIRE(l1->log_level() == spdlog::level::warn); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::info); -} - -TEST_CASE("argv2", "[cfg]") { - spdlog::drop("l1"); - const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn,trace"}; - load_argv_levels(2, argv); - auto l1 = spdlog::create("l1"); - REQUIRE(l1->log_level() == spdlog::level::warn); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::trace); -} - -TEST_CASE("argv3", "[cfg]") { - spdlog::set_level(spdlog::level::trace); - - spdlog::drop("l1"); - const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk_name=warn"}; - load_argv_levels(2, argv); - auto l1 = spdlog::create("l1"); - REQUIRE(l1->log_level() == spdlog::level::trace); - REQUIRE(spdlog::default_logger()->log_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); - auto l1 = spdlog::create("l1"); - REQUIRE(l1->log_level() == spdlog::level::info); -} - -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); - auto l1 = spdlog::create("l1"); - REQUIRE(l1->log_level() == spdlog::level::warn); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::trace); - spdlog::set_level(spdlog::level::info); -} - -TEST_CASE("argv6", "[cfg]") { - spdlog::set_level(spdlog::level::err); - const char *argv[] = {""}; - load_argv_levels(1, argv); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::err); - spdlog::set_level(spdlog::level::info); -} - -TEST_CASE("argv7", "[cfg]") { - spdlog::set_level(spdlog::level::err); - const char *argv[] = {""}; - load_argv_levels(0, argv); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::err); - spdlog::set_level(spdlog::level::info); -} - -TEST_CASE("level-not-set-test1", "[cfg]") { - spdlog::drop("l1"); - const char *argv[] = {"ignore", ""}; - load_argv_levels(2, argv); - auto l1 = spdlog::create("l1"); - l1->set_level(spdlog::level::trace); - REQUIRE(l1->log_level() == spdlog::level::trace); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::info); -} - -TEST_CASE("level-not-set-test2", "[cfg]") { - spdlog::drop("l1"); - spdlog::drop("l2"); - const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace"}; - - auto l1 = spdlog::create("l1"); - l1->set_level(spdlog::level::warn); - auto l2 = spdlog::create("l2"); - l2->set_level(spdlog::level::warn); - - load_argv_levels(2, argv); - - REQUIRE(l1->log_level() == spdlog::level::trace); - REQUIRE(l2->log_level() == spdlog::level::warn); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::info); -} - -TEST_CASE("level-not-set-test3", "[cfg]") { - spdlog::drop("l1"); - spdlog::drop("l2"); - const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace"}; - - load_argv_levels(2, argv); - - auto l1 = spdlog::create("l1"); - auto l2 = spdlog::create("l2"); - - REQUIRE(l1->log_level() == spdlog::level::trace); - REQUIRE(l2->log_level() == spdlog::level::info); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::info); -} - -TEST_CASE("level-not-set-test4", "[cfg]") { - spdlog::drop("l1"); - spdlog::drop("l2"); - const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace,warn"}; - - load_argv_levels(2, argv); - - auto l1 = spdlog::create("l1"); - auto l2 = spdlog::create("l2"); - - REQUIRE(l1->log_level() == spdlog::level::trace); - REQUIRE(l2->log_level() == spdlog::level::warn); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::warn); -} - -TEST_CASE("level-not-set-test5", "[cfg]") { - spdlog::drop("l1"); - spdlog::drop("l2"); - const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=junk,warn"}; - - load_argv_levels(2, argv); - - auto l1 = spdlog::create("l1"); - auto l2 = spdlog::create("l2"); - - REQUIRE(l1->log_level() == spdlog::level::warn); - REQUIRE(l2->log_level() == spdlog::level::warn); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::warn); -} - -TEST_CASE("restore-to-default", "[cfg]") { - spdlog::drop("l1"); - spdlog::drop("l2"); - const char *argv[] = {"ignore", "SPDLOG_LEVEL=info"}; - load_argv_levels(2, argv); - REQUIRE(spdlog::default_logger()->log_level() == spdlog::level::info); -} diff --git a/tests/test_custom_callbacks.cpp b/tests/test_custom_callbacks.cpp index 6bd92368..5f5a9d07 100644 --- a/tests/test_custom_callbacks.cpp +++ b/tests/test_custom_callbacks.cpp @@ -30,5 +30,4 @@ TEST_CASE("custom_callback_logger", "[custom_callback_logger]") { REQUIRE(lines[0] == ref_lines[0]); REQUIRE(lines[1] == ref_lines[1]); REQUIRE(lines[2] == ref_lines[2]); - spdlog::drop_all(); } diff --git a/tests/test_errors.cpp b/tests/test_errors.cpp index 25d0f335..db7d43fe 100644 --- a/tests/test_errors.cpp +++ b/tests/test_errors.cpp @@ -21,8 +21,7 @@ struct custom_ex {}; TEST_CASE("default_error_handler", "[errors]") { prepare_logdir(); spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); - - auto logger = spdlog::create("test-error", filename, true); + auto logger = spdlog::basic_logger_mt("test-error", filename); logger->set_pattern("%v"); logger->info(SPDLOG_FMT_RUNTIME("Test message {} {}"), 1); logger->info("Test message {}", 2); @@ -35,25 +34,23 @@ TEST_CASE("default_error_handler", "[errors]") { TEST_CASE("custom_error_handler", "[errors]") { prepare_logdir(); spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); - auto logger = spdlog::create("logger", filename, true); + auto logger = spdlog::basic_logger_mt("test-error", filename); logger->flush_on(spdlog::level::info); logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); logger->info("Good message #1"); - REQUIRE_THROWS_AS(logger->info(SPDLOG_FMT_RUNTIME("Bad format msg {} {}"), "xxx"), custom_ex); logger->info("Good message #2"); require_message_count(SIMPLE_LOG, 2); } TEST_CASE("default_error_handler2", "[errors]") { - spdlog::drop_all(); - auto logger = spdlog::create("failed_logger"); + + auto logger = std::make_shared("failed_logger", std::make_shared()); logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex); } TEST_CASE("flush_error_handler", "[errors]") { - spdlog::drop_all(); auto logger = spdlog::create("failed_logger"); logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); REQUIRE_THROWS_AS(logger->flush(), custom_ex); @@ -77,7 +74,6 @@ TEST_CASE("async_error_handler", "[errors]") { logger->info("Good message #1"); logger->info(SPDLOG_FMT_RUNTIME("Bad format msg {} {}"), "xxx"); logger->info("Good message #2"); - spdlog::drop("logger"); // force logger to drain the queue and shutdown } spdlog::init_thread_pool(128, 1); require_message_count(SIMPLE_ASYNC_LOG, 2); @@ -98,7 +94,6 @@ TEST_CASE("async_error_handler2", "[errors]") { ofs << err_msg; }); logger->info("Hello failure"); - spdlog::drop("failed_logger"); // force logger to drain the queue and shutdown } spdlog::init_thread_pool(128, 1); diff --git a/tests/test_file_logging.cpp b/tests/test_file_logging.cpp index 50a6baec..3ef4a3b4 100644 --- a/tests/test_file_logging.cpp +++ b/tests/test_file_logging.cpp @@ -12,13 +12,10 @@ TEST_CASE("simple_file_logger", "[simple_logger]") { prepare_logdir(); spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); - - auto logger = spdlog::create("logger", filename); + auto logger = spdlog::basic_logger_mt("logger", filename); logger->set_pattern("%v"); - logger->info("Test message {}", 1); logger->info("Test message {}", 2); - logger->flush(); require_message_count(SIMPLE_LOG, 2); using spdlog::details::os::default_eol; @@ -28,17 +25,14 @@ TEST_CASE("simple_file_logger", "[simple_logger]") { TEST_CASE("flush_on", "[flush_on]") { prepare_logdir(); spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); - - auto logger = spdlog::create("logger", filename); + auto logger = spdlog::basic_logger_mt("test-error", filename); logger->set_pattern("%v"); logger->set_level(spdlog::level::trace); logger->flush_on(spdlog::level::info); logger->trace("Should not be flushed"); REQUIRE(count_lines(SIMPLE_LOG) == 0); - logger->info("Test message {}", 1); logger->info("Test message {}", 2); - require_message_count(SIMPLE_LOG, 3); using spdlog::details::os::default_eol; REQUIRE(file_contents(SIMPLE_LOG) == spdlog::fmt_lib::format("Should not be flushed{}Test message 1{}Test message 2{}", @@ -70,9 +64,6 @@ TEST_CASE("rotating_file_logger2", "[rotating_logger]") { for (int i = 0; i < 10; ++i) { logger->info("Test message {}", i); } - // drop causes the logger destructor to be called, which is required so the - // next logger can rename the first output file. - spdlog::drop(logger->name()); } auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 2, true); diff --git a/tests/test_macros.cpp b/tests/test_macros.cpp index b0991eff..a02f6113 100644 --- a/tests/test_macros.cpp +++ b/tests/test_macros.cpp @@ -15,8 +15,7 @@ TEST_CASE("debug and trace w/o format string", "[macros]") { prepare_logdir(); spdlog::filename_t filename = SPDLOG_FILENAME_T(TEST_FILENAME); - - auto logger = spdlog::create("logger", filename); + auto logger = spdlog::basic_logger_mt("logger", filename); logger->set_pattern("%v"); logger->set_level(spdlog::level::trace); @@ -45,7 +44,7 @@ TEST_CASE("disable param evaluation", "[macros]") { } TEST_CASE("pass logger pointer", "[macros]") { - auto logger = spdlog::create("refmacro"); + auto logger = spdlog::null_logger_mt("refmacro"); auto &ref = *logger; SPDLOG_LOGGER_TRACE(&ref, "Test message 1"); SPDLOG_LOGGER_DEBUG(&ref, "Test message 2"); diff --git a/tests/test_misc.cpp b/tests/test_misc.cpp index 8b88062b..b2d6029d 100644 --- a/tests/test_misc.cpp +++ b/tests/test_misc.cpp @@ -90,8 +90,6 @@ TEST_CASE("clone-logger", "[clone]") { REQUIRE(test_sink->lines().size() == 2); REQUIRE(test_sink->lines()[0] == "Some message 1"); REQUIRE(test_sink->lines()[1] == "Some message 2"); - - spdlog::drop_all(); } TEST_CASE("clone async", "[clone]") { @@ -115,8 +113,6 @@ TEST_CASE("clone async", "[clone]") { REQUIRE(test_sink->lines().size() == 2); REQUIRE(test_sink->lines()[0] == "Some message 1"); REQUIRE(test_sink->lines()[1] == "Some message 2"); - - spdlog::drop_all(); } TEST_CASE("default logger API", "[default logger]") { @@ -150,7 +146,6 @@ TEST_CASE("default logger API", "[default logger]") { spdlog::set_level(spdlog::level::info); spdlog::debug("should not be logged"); REQUIRE(oss.str().empty()); - spdlog::drop_all(); spdlog::set_pattern("%v"); } diff --git a/tests/test_stdout_api.cpp b/tests/test_stdout_api.cpp index 92feb42f..4db6f218 100644 --- a/tests/test_stdout_api.cpp +++ b/tests/test_stdout_api.cpp @@ -16,7 +16,6 @@ TEST_CASE("stdout_st", "[stdout]") { l->warn("Test stdout_st"); l->error("Test stdout_st"); l->critical("Test stdout_st"); - spdlog::drop_all(); } TEST_CASE("stderr_st", "[stderr]") { @@ -28,7 +27,6 @@ TEST_CASE("stderr_st", "[stderr]") { l->warn("Test stderr_st"); l->error("Test stderr_st"); l->critical("Test stderr_st"); - spdlog::drop_all(); } TEST_CASE("stdout_mt", "[stdout]") { @@ -54,7 +52,6 @@ TEST_CASE("stdout_color_st", "[stdout]") { l->warn("Test stdout_color_st"); l->error("Test stdout_color_st"); l->critical("Test stdout_color_st"); - spdlog::drop_all(); } TEST_CASE("stdout_color_mt", "[stdout]") { @@ -67,7 +64,6 @@ TEST_CASE("stdout_color_mt", "[stdout]") { l->warn("Test stdout_color_mt"); l->error("Test stdout_color_mt"); l->critical("Test stdout_color_mt"); - spdlog::drop_all(); } TEST_CASE("stderr_color_st", "[stderr]") { @@ -75,7 +71,6 @@ TEST_CASE("stderr_color_st", "[stderr]") { l->set_pattern("%+"); l->set_level(spdlog::level::debug); l->debug("Test stderr_color_st"); - spdlog::drop_all(); } TEST_CASE("stderr_color_mt", "[stderr]") { @@ -85,5 +80,4 @@ TEST_CASE("stderr_color_mt", "[stderr]") { l->warn("Test stderr_color_mt"); l->error("Test stderr_color_mt"); l->critical("Test stderr_color_mt"); - spdlog::drop_all(); } diff --git a/tests/test_time_point.cpp b/tests/test_time_point.cpp index c4399189..b5e15a4c 100644 --- a/tests/test_time_point.cpp +++ b/tests/test_time_point.cpp @@ -31,5 +31,4 @@ TEST_CASE("time_point1", "[time_point log_msg]") { REQUIRE(lines[4] == lines[5]); REQUIRE(lines[6] == lines[7]); REQUIRE(lines[8] != lines[9]); - spdlog::drop_all(); } diff --git a/tests/utils.cpp b/tests/utils.cpp index cd594644..5a4a4d19 100644 --- a/tests/utils.cpp +++ b/tests/utils.cpp @@ -8,7 +8,6 @@ #endif void prepare_logdir() { - spdlog::drop_all(); #ifdef _WIN32 system("rmdir /S /Q test_logs"); #else