Add register_or_replace(logger) to atomically replace logger in registry

register-replace-logger
gabime 4 months ago
parent 5dc6cec466
commit 78e19d66d3

@ -54,6 +54,11 @@ SPDLOG_INLINE void registry::register_logger(std::shared_ptr<logger> new_logger)
register_logger_(std::move(new_logger)); register_logger_(std::move(new_logger));
} }
SPDLOG_INLINE void registry::register_or_replace(std::shared_ptr<logger> new_logger) {
std::lock_guard<std::mutex> lock(logger_map_mutex_);
register_or_replace_(std::move(new_logger));
}
SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr<logger> new_logger) { SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr<logger> new_logger) {
std::lock_guard<std::mutex> lock(logger_map_mutex_); std::lock_guard<std::mutex> lock(logger_map_mutex_);
new_logger->set_formatter(formatter_->clone()); new_logger->set_formatter(formatter_->clone());
@ -252,10 +257,14 @@ SPDLOG_INLINE void registry::throw_if_exists_(const std::string &logger_name) {
} }
SPDLOG_INLINE void registry::register_logger_(std::shared_ptr<logger> new_logger) { SPDLOG_INLINE void registry::register_logger_(std::shared_ptr<logger> new_logger) {
auto logger_name = new_logger->name(); auto &logger_name = new_logger->name();
throw_if_exists_(logger_name); throw_if_exists_(logger_name);
loggers_[logger_name] = std::move(new_logger); loggers_[logger_name] = std::move(new_logger);
} }
SPDLOG_INLINE void registry::register_or_replace_(std::shared_ptr<logger> new_logger) {
loggers_[new_logger->name()] = std::move(new_logger);
}
} // namespace details } // namespace details
} // namespace spdlog } // namespace spdlog

@ -31,6 +31,7 @@ public:
registry &operator=(const registry &) = delete; registry &operator=(const registry &) = delete;
void register_logger(std::shared_ptr<logger> new_logger); void register_logger(std::shared_ptr<logger> new_logger);
void register_or_replace(std::shared_ptr<logger> new_logger);
void initialize_logger(std::shared_ptr<logger> new_logger); void initialize_logger(std::shared_ptr<logger> new_logger);
std::shared_ptr<logger> get(const std::string &logger_name); std::shared_ptr<logger> get(const std::string &logger_name);
std::shared_ptr<logger> default_logger(); std::shared_ptr<logger> default_logger();
@ -105,6 +106,7 @@ private:
void throw_if_exists_(const std::string &logger_name); void throw_if_exists_(const std::string &logger_name);
void register_logger_(std::shared_ptr<logger> new_logger); void register_logger_(std::shared_ptr<logger> new_logger);
void register_or_replace_(std::shared_ptr<logger> new_logger);
bool set_level_from_cfg_(logger *logger); bool set_level_from_cfg_(logger *logger);
std::mutex logger_map_mutex_, flusher_mutex_; std::mutex logger_map_mutex_, flusher_mutex_;
std::recursive_mutex tp_mutex_; std::recursive_mutex tp_mutex_;

@ -59,6 +59,10 @@ SPDLOG_INLINE void register_logger(std::shared_ptr<logger> logger) {
details::registry::instance().register_logger(std::move(logger)); details::registry::instance().register_logger(std::move(logger));
} }
SPDLOG_INLINE void register_or_replace(std::shared_ptr<logger> logger) {
details::registry::instance().register_or_replace(std::move(logger));
}
SPDLOG_INLINE void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun) { SPDLOG_INLINE void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun) {
details::registry::instance().apply_all(fun); details::registry::instance().apply_all(fun);
} }

@ -91,8 +91,13 @@ inline void flush_every(std::chrono::duration<Rep, Period> interval) {
SPDLOG_API void set_error_handler(void (*handler)(const std::string &msg)); SPDLOG_API void set_error_handler(void (*handler)(const std::string &msg));
// Register the given logger with the given name // Register the given logger with the given name
// Will throw if a logger with the same name already exists.
SPDLOG_API void register_logger(std::shared_ptr<logger> logger); SPDLOG_API void register_logger(std::shared_ptr<logger> logger);
// Register the given logger with the given name
// Will replace any the existing logger with the same name if exists.
SPDLOG_API void register_or_replace(std::shared_ptr<logger> logger);
// Apply a user-defined function on all registered loggers // Apply a user-defined function on all registered loggers
// Example: // Example:
// spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) {l->flush();}); // spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) {l->flush();});

@ -25,6 +25,18 @@ TEST_CASE("explicit register", "[registry]") {
} }
#endif #endif
TEST_CASE("register_or_replace", "[registry]") {
spdlog::drop_all();
auto logger1 = std::make_shared<spdlog::logger>(tested_logger_name,
std::make_shared<spdlog::sinks::null_sink_st>());
spdlog::register_logger(logger1);
REQUIRE(spdlog::get(tested_logger_name) == logger1);
auto logger2 = std::make_shared<spdlog::logger>(tested_logger_name, std::make_shared<spdlog::sinks::null_sink_st>());
spdlog::register_or_replace(logger2);
REQUIRE(spdlog::get(tested_logger_name) == logger2);
}
TEST_CASE("apply_all", "[registry]") { TEST_CASE("apply_all", "[registry]") {
spdlog::drop_all(); spdlog::drop_all();
auto logger = std::make_shared<spdlog::logger>(tested_logger_name, auto logger = std::make_shared<spdlog::logger>(tested_logger_name,

Loading…
Cancel
Save