Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:24:43

0001 // Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
0002 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
0003 
0004 #pragma once
0005 
0006 #ifndef SPDLOG_HEADER_ONLY
0007 #    include <spdlog/details/registry.h>
0008 #endif
0009 
0010 #include <spdlog/common.h>
0011 #include <spdlog/details/periodic_worker.h>
0012 #include <spdlog/logger.h>
0013 #include <spdlog/pattern_formatter.h>
0014 
0015 #ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
0016 // support for the default stdout color logger
0017 #    ifdef _WIN32
0018 #        include <spdlog/sinks/wincolor_sink.h>
0019 #    else
0020 #        include <spdlog/sinks/ansicolor_sink.h>
0021 #    endif
0022 #endif // SPDLOG_DISABLE_DEFAULT_LOGGER
0023 
0024 #include <chrono>
0025 #include <functional>
0026 #include <memory>
0027 #include <string>
0028 #include <unordered_map>
0029 
0030 namespace spdlog {
0031 namespace details {
0032 
0033 SPDLOG_INLINE registry::registry()
0034     : formatter_(new pattern_formatter())
0035 {
0036 
0037 #ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
0038     // create default logger (ansicolor_stdout_sink_mt or wincolor_stdout_sink_mt in windows).
0039 #    ifdef _WIN32
0040     auto color_sink = std::make_shared<sinks::wincolor_stdout_sink_mt>();
0041 #    else
0042     auto color_sink = std::make_shared<sinks::ansicolor_stdout_sink_mt>();
0043 #    endif
0044 
0045     const char *default_logger_name = "";
0046     default_logger_ = std::make_shared<spdlog::logger>(default_logger_name, std::move(color_sink));
0047     loggers_[default_logger_name] = default_logger_;
0048 
0049 #endif // SPDLOG_DISABLE_DEFAULT_LOGGER
0050 }
0051 
0052 SPDLOG_INLINE registry::~registry() = default;
0053 
0054 SPDLOG_INLINE void registry::register_logger(std::shared_ptr<logger> new_logger)
0055 {
0056     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0057     register_logger_(std::move(new_logger));
0058 }
0059 
0060 SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr<logger> new_logger)
0061 {
0062     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0063     new_logger->set_formatter(formatter_->clone());
0064 
0065     if (err_handler_)
0066     {
0067         new_logger->set_error_handler(err_handler_);
0068     }
0069 
0070     // set new level according to previously configured level or default level
0071     auto it = log_levels_.find(new_logger->name());
0072     auto new_level = it != log_levels_.end() ? it->second : global_log_level_;
0073     new_logger->set_level(new_level);
0074 
0075     new_logger->flush_on(flush_level_);
0076 
0077     if (backtrace_n_messages_ > 0)
0078     {
0079         new_logger->enable_backtrace(backtrace_n_messages_);
0080     }
0081 
0082     if (automatic_registration_)
0083     {
0084         register_logger_(std::move(new_logger));
0085     }
0086 }
0087 
0088 SPDLOG_INLINE std::shared_ptr<logger> registry::get(const std::string &logger_name)
0089 {
0090     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0091     auto found = loggers_.find(logger_name);
0092     return found == loggers_.end() ? nullptr : found->second;
0093 }
0094 
0095 SPDLOG_INLINE std::shared_ptr<logger> registry::default_logger()
0096 {
0097     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0098     return default_logger_;
0099 }
0100 
0101 // Return raw ptr to the default logger.
0102 // To be used directly by the spdlog default api (e.g. spdlog::info)
0103 // This make the default API faster, but cannot be used concurrently with set_default_logger().
0104 // e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
0105 SPDLOG_INLINE logger *registry::get_default_raw()
0106 {
0107     return default_logger_.get();
0108 }
0109 
0110 // set default logger.
0111 // default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
0112 SPDLOG_INLINE void registry::set_default_logger(std::shared_ptr<logger> new_default_logger)
0113 {
0114     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0115     // remove previous default logger from the map
0116     if (default_logger_ != nullptr)
0117     {
0118         loggers_.erase(default_logger_->name());
0119     }
0120     if (new_default_logger != nullptr)
0121     {
0122         loggers_[new_default_logger->name()] = new_default_logger;
0123     }
0124     default_logger_ = std::move(new_default_logger);
0125 }
0126 
0127 SPDLOG_INLINE void registry::set_tp(std::shared_ptr<thread_pool> tp)
0128 {
0129     std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
0130     tp_ = std::move(tp);
0131 }
0132 
0133 SPDLOG_INLINE std::shared_ptr<thread_pool> registry::get_tp()
0134 {
0135     std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
0136     return tp_;
0137 }
0138 
0139 // Set global formatter. Each sink in each logger will get a clone of this object
0140 SPDLOG_INLINE void registry::set_formatter(std::unique_ptr<formatter> formatter)
0141 {
0142     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0143     formatter_ = std::move(formatter);
0144     for (auto &l : loggers_)
0145     {
0146         l.second->set_formatter(formatter_->clone());
0147     }
0148 }
0149 
0150 SPDLOG_INLINE void registry::enable_backtrace(size_t n_messages)
0151 {
0152     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0153     backtrace_n_messages_ = n_messages;
0154 
0155     for (auto &l : loggers_)
0156     {
0157         l.second->enable_backtrace(n_messages);
0158     }
0159 }
0160 
0161 SPDLOG_INLINE void registry::disable_backtrace()
0162 {
0163     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0164     backtrace_n_messages_ = 0;
0165     for (auto &l : loggers_)
0166     {
0167         l.second->disable_backtrace();
0168     }
0169 }
0170 
0171 SPDLOG_INLINE void registry::set_level(level::level_enum log_level)
0172 {
0173     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0174     for (auto &l : loggers_)
0175     {
0176         l.second->set_level(log_level);
0177     }
0178     global_log_level_ = log_level;
0179 }
0180 
0181 SPDLOG_INLINE void registry::flush_on(level::level_enum log_level)
0182 {
0183     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0184     for (auto &l : loggers_)
0185     {
0186         l.second->flush_on(log_level);
0187     }
0188     flush_level_ = log_level;
0189 }
0190 
0191 SPDLOG_INLINE void registry::set_error_handler(err_handler handler)
0192 {
0193     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0194     for (auto &l : loggers_)
0195     {
0196         l.second->set_error_handler(handler);
0197     }
0198     err_handler_ = std::move(handler);
0199 }
0200 
0201 SPDLOG_INLINE void registry::apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun)
0202 {
0203     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0204     for (auto &l : loggers_)
0205     {
0206         fun(l.second);
0207     }
0208 }
0209 
0210 SPDLOG_INLINE void registry::flush_all()
0211 {
0212     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0213     for (auto &l : loggers_)
0214     {
0215         l.second->flush();
0216     }
0217 }
0218 
0219 SPDLOG_INLINE void registry::drop(const std::string &logger_name)
0220 {
0221     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0222     loggers_.erase(logger_name);
0223     if (default_logger_ && default_logger_->name() == logger_name)
0224     {
0225         default_logger_.reset();
0226     }
0227 }
0228 
0229 SPDLOG_INLINE void registry::drop_all()
0230 {
0231     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0232     loggers_.clear();
0233     default_logger_.reset();
0234 }
0235 
0236 // clean all resources and threads started by the registry
0237 SPDLOG_INLINE void registry::shutdown()
0238 {
0239     {
0240         std::lock_guard<std::mutex> lock(flusher_mutex_);
0241         periodic_flusher_.reset();
0242     }
0243 
0244     drop_all();
0245 
0246     {
0247         std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
0248         tp_.reset();
0249     }
0250 }
0251 
0252 SPDLOG_INLINE std::recursive_mutex &registry::tp_mutex()
0253 {
0254     return tp_mutex_;
0255 }
0256 
0257 SPDLOG_INLINE void registry::set_automatic_registration(bool automatic_registration)
0258 {
0259     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0260     automatic_registration_ = automatic_registration;
0261 }
0262 
0263 SPDLOG_INLINE void registry::set_levels(log_levels levels, level::level_enum *global_level)
0264 {
0265     std::lock_guard<std::mutex> lock(logger_map_mutex_);
0266     log_levels_ = std::move(levels);
0267     auto global_level_requested = global_level != nullptr;
0268     global_log_level_ = global_level_requested ? *global_level : global_log_level_;
0269 
0270     for (auto &logger : loggers_)
0271     {
0272         auto logger_entry = log_levels_.find(logger.first);
0273         if (logger_entry != log_levels_.end())
0274         {
0275             logger.second->set_level(logger_entry->second);
0276         }
0277         else if (global_level_requested)
0278         {
0279             logger.second->set_level(*global_level);
0280         }
0281     }
0282 }
0283 
0284 SPDLOG_INLINE registry &registry::instance()
0285 {
0286     static registry s_instance;
0287     return s_instance;
0288 }
0289 
0290 SPDLOG_INLINE void registry::throw_if_exists_(const std::string &logger_name)
0291 {
0292     if (loggers_.find(logger_name) != loggers_.end())
0293     {
0294         throw_spdlog_ex("logger with name '" + logger_name + "' already exists");
0295     }
0296 }
0297 
0298 SPDLOG_INLINE void registry::register_logger_(std::shared_ptr<logger> new_logger)
0299 {
0300     auto logger_name = new_logger->name();
0301     throw_if_exists_(logger_name);
0302     loggers_[logger_name] = std::move(new_logger);
0303 }
0304 
0305 } // namespace details
0306 } // namespace spdlog