Add register_or_replace(logger) to atomically replace logger in registry

This commit is contained in:
gabime
2025-05-08 15:33:08 +03:00
parent 5dc6cec466
commit 78e19d66d3
5 changed files with 33 additions and 1 deletions

View File

@@ -54,6 +54,11 @@ SPDLOG_INLINE void registry::register_logger(std::shared_ptr<logger> 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) {
std::lock_guard<std::mutex> lock(logger_map_mutex_);
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) {
auto logger_name = new_logger->name();
auto &logger_name = new_logger->name();
throw_if_exists_(logger_name);
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 spdlog

View File

@@ -31,6 +31,7 @@ public:
registry &operator=(const registry &) = delete;
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);
std::shared_ptr<logger> get(const std::string &logger_name);
std::shared_ptr<logger> default_logger();
@@ -105,6 +106,7 @@ private:
void throw_if_exists_(const std::string &logger_name);
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);
std::mutex logger_map_mutex_, flusher_mutex_;
std::recursive_mutex tp_mutex_;

View File

@@ -59,6 +59,10 @@ SPDLOG_INLINE void register_logger(std::shared_ptr<logger> 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) {
details::registry::instance().apply_all(fun);
}

View File

@@ -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));
// 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);
// 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
// Example:
// spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) {l->flush();});

View File

@@ -25,6 +25,18 @@ TEST_CASE("explicit register", "[registry]") {
}
#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]") {
spdlog::drop_all();
auto logger = std::make_shared<spdlog::logger>(tested_logger_name,