注冊表具有唯一標(biāo)識(shí),用于管理多個(gè)日志文章來源地址http://www.zghlxwxcb.cn/news/detail-616083.html
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
// Loggers registry of unique name->logger pointer
// An attempt to create a logger with an already existing name will result with spdlog_ex exception.
// If user requests a non existing logger, nullptr will be returned
// This class is thread safe
#include <spdlog/common.h>
#include <spdlog/details/periodic_worker.h>
#include <chrono>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include <mutex>
namespace spdlog {
class logger;
namespace details {
class thread_pool;
class SPDLOG_API registry
{
public:
using log_levels = std::unordered_map<std::string, level::level_enum>;
// 拷貝構(gòu)造函數(shù)進(jìn)行刪除(delete)的聲明。這意味著該類的拷貝構(gòu)造函數(shù)被禁用,不允許進(jìn)行拷貝構(gòu)造。
registry(const registry &) = delete;
// 這意味著該類的賦值運(yùn)算符重載被禁用,不允許進(jìn)行對象之間的賦值操作。
registry &operator=(const registry &) = delete;
// 向全局的日志器注冊表中注冊一個(gè)新的日志器。
void register_logger(std::shared_ptr<logger> new_logger);
// 初始化一個(gè)新的日志器并將其設(shè)置為【全局默認(rèn)日志器】。
void initialize_logger(std::shared_ptr<logger> new_logger);
// 通過名稱獲取logger
std::shared_ptr<logger> get(const std::string &logger_name);
// 獲取默認(rèn)的全局日志器。
std::shared_ptr<logger> default_logger();
// Return raw ptr to the default logger.
// To be used directly by the spdlog default api (e.g. spdlog::info)
// This make the default API faster, but cannot be used concurrently with set_default_logger().
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
// 獲取默認(rèn)的全局日志器的裸指針(raw pointer)。
// 裸指針是指向?qū)ο蟮钠胀ㄖ羔?,不包含智能指針的管理功能,需要手?dòng)管理對象的生命周期。
logger *get_default_raw();
// set default logger.
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
// 設(shè)置新的默認(rèn)全局日志器
void set_default_logger(std::shared_ptr<logger> new_default_logger);
// 設(shè)置日志器的線程池。
// 通過設(shè)置日志器的線程池,可以讓日志器在后臺(tái)線程中執(zhí)行寫入日志的操作,從而減少主線程的阻塞時(shí)間,提高程序的性能和響應(yīng)性。
// 如果日志記錄是同步進(jìn)行的(默認(rèn)情況下),日志消息的寫入操作會(huì)在主線程中直接完成,可能會(huì)對程序的性能產(chǎn)生影響。
// 而設(shè)置了線程池后,日志消息的寫入操作將在后臺(tái)線程中進(jìn)行,不會(huì)阻塞主線程的執(zhí)行。
void set_tp(std::shared_ptr<thread_pool> tp);
// 獲取線程池
std::shared_ptr<thread_pool> get_tp();
// Set global formatter. Each sink in each logger will get a clone of this object
// 設(shè)置日志器的日志消息格式化器
// 日志消息格式化器是用于將日志消息的內(nèi)容按照特定的格式進(jìn)行格式化的組件
// 通過設(shè)置日志器的格式化器,可以自定義日志消息輸出的樣式,例如包含時(shí)間戳、日志級別、日志內(nèi)容等信息,并將格式化后的日志消息寫入到輸出目標(biāo)(如控制臺(tái)、文件等)。
void set_formatter(std::unique_ptr<formatter> formatter);
// 啟用日志器的回溯(backtrace)功能。
void enable_backtrace(size_t n_messages);
// 關(guān)閉日志器的回溯(backtrace)功能。
void disable_backtrace();
// 設(shè)置日志的級別
void set_level(level::level_enum log_level);
// 日志器的日志刷新級別。
// 日志刷新級別指定了日志器在哪個(gè)日志級別及以上時(shí)需要立即刷新日志消息。
// 如果調(diào)用 flush_on(spdlog::level::err),它會(huì)設(shè)置日志器在 err(錯(cuò)誤)級別及以上時(shí)立即刷新日志消息。
// 這意味著處于 err、critical 和 off 級別的日志消息將在寫入后立即刷新,而低于這些級別的日志消息(例如 info 或 debug)可能會(huì)被緩沖以提高效率。
void flush_on(level::level_enum log_level);
// 設(shè)置定時(shí)刷新日志的時(shí)間間隔。
// 支持不同類型的時(shí)間間隔。Rep 和 Period 是時(shí)間間隔類型的模板參數(shù),用于指定時(shí)間間隔的數(shù)值和時(shí)間單位。
// std::chrono::duration 是 C++ 標(biāo)準(zhǔn)庫中的時(shí)間間隔類模板,用于表示一段時(shí)間。
// std::lock_guard<std::mutex> lock(flusher_mutex_);這是一個(gè)互斥鎖 std::mutex 的鎖保護(hù),用于保證在設(shè)置定時(shí)器時(shí),其他線程不會(huì)同時(shí)進(jìn)行刷新操作。
// 回調(diào)函數(shù)是 this->flush_all(),表示要執(zhí)行日志器的刷新操作。
template<typename Rep, typename Period>
void flush_every(std::chrono::duration<Rep, Period> interval)
{
std::lock_guard<std::mutex> lock(flusher_mutex_);
auto clbk = [this]() { this->flush_all(); };
// 這是一個(gè)定時(shí)器的成員變量,用于設(shè)置定時(shí)器,并將回調(diào)函數(shù)和時(shí)間間隔傳遞給 periodic_worker 構(gòu)造函數(shù)。
// periodic_worker 是 spdlog 庫中的一個(gè)類,用于創(chuàng)建周期性定時(shí)器。
periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
}
// 設(shè)置錯(cuò)誤處理函數(shù)(Error Handler)。
// 這是一個(gè)函數(shù)指針或函數(shù)對象參數(shù),用于表示錯(cuò)誤處理函數(shù)。錯(cuò)誤處理函數(shù)是一個(gè)用戶定義的函數(shù),用于處理在 spdlog 庫中可能發(fā)生的錯(cuò)誤情況
// using err_handler = std::function<void(const std::string &err_msg)>;是一個(gè)函數(shù)對象類型,用于表示一個(gè)接受 const std::string & 類型參數(shù)的無返回值函數(shù)。
void set_error_handler(err_handler handler);
// 對所有已注冊的日志器應(yīng)用一個(gè)指定的函數(shù)。
// 對所有已創(chuàng)建的日志器進(jìn)行一些特定的操作,例如更改日志器的配置、設(shè)置日志級別等。
void apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun);
// 將所有已注冊的日志器的緩沖日志消息刷新到輸出目標(biāo)。
void flush_all();
// 從日志器注冊表中移除指定名稱的日志器。
void drop(const std::string &logger_name);
// 從日志器注冊表中移除所有日志器。
void drop_all();
// clean all resources and threads started by the registry
// 關(guān)閉所有已注冊的日志器并釋放相關(guān)資源。
void shutdown();
// 獲取一個(gè)遞歸互斥鎖(recursive mutex)對象的引用。
// 遞歸互斥鎖是一種特殊類型的互斥鎖,允許同一線程多次對互斥鎖進(jìn)行加鎖,而不會(huì)導(dǎo)致死鎖。
std::recursive_mutex &tp_mutex();
// 指定是否啟用自動(dòng)注冊日志器功能。
// 為true時(shí),通過 spdlog::create 創(chuàng)建的日志器將自動(dòng)注冊到全局的日志器注冊表中,方便后續(xù)的查找和使用。
// 為false時(shí),通過 spdlog::create 創(chuàng)建的日志器將不會(huì)自動(dòng)注冊到日志器注冊表中,需要手動(dòng)調(diào)用其他函數(shù)(如 spdlog::register_logger)將其注冊
void set_automatic_registration(bool automatic_registration);
// set levels for all existing/future loggers. global_level can be null if should not set.
// 可以同時(shí)設(shè)置多個(gè)日志器的日志級別,并可以設(shè)置全局的日志級別。這樣可以方便地統(tǒng)一管理多個(gè)日志器的日志級別,并靈活地控制日志輸出的詳細(xì)程度。
// using log_levels = std::unordered_map<std::string, level::level_enum>;多個(gè)日志級別配置,map類型
void set_levels(log_levels levels, level::level_enum *global_level);
// 獲取日志器注冊表的單例實(shí)例。
// 日志器注冊表是全局唯一的,為了方便使用,spdlog 使用了單例模式,即只允許存在一個(gè)注冊表實(shí)例。
static registry &instance();
// 根據(jù)環(huán)境變量設(shè)置日志器的日志級別。
// 使用環(huán)境變量來配置日志級別具有靈活性,因?yàn)樗试S在不修改代碼的情況下更改日志級別。
// 通過在運(yùn)行時(shí)設(shè)置環(huán)境變量,可以動(dòng)態(tài)地調(diào)整日志輸出的詳細(xì)程度,方便在不同的場景或部署環(huán)境下進(jìn)行日志記錄。
void apply_logger_env_levels(std::shared_ptr<logger> new_logger);
private:
registry();
~registry();
// 用于檢查是否存在指定名稱的日志器,并在存在時(shí)拋出異常。
// 通過調(diào)用 throw_if_exists_ 函數(shù),并傳遞一個(gè)日志器的名稱作為參數(shù),可以檢查注冊表中是否已經(jīng)存在具有相同名稱的日志器。
// 如果存在,該函數(shù)會(huì)拋出異常,提示名稱沖突,防止創(chuàng)建重名的日志器。
void throw_if_exists_(const std::string &logger_name);
// 將指定的日志器注冊到日志器注冊表中。
void register_logger_(std::shared_ptr<logger> new_logger);
// 從配置中設(shè)置日志器的日志級別。
bool set_level_from_cfg_(logger *logger);
// 對日志器注冊表進(jìn)行線程同步的互斥鎖。對日志器刷新操作進(jìn)行線程同步的互斥鎖。
std::mutex logger_map_mutex_, flusher_mutex_;
// 遞歸互斥鎖對象的聲明。
std::recursive_mutex tp_mutex_;
// 日志無序映射
std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
// 保存多個(gè)日志器的名稱及對應(yīng)的日志級別。
log_levels log_levels_;
// formatter 是一個(gè)抽象基類,用于控制日志消息的格式化方式
// 獨(dú)占指針
// 由于 std::unique_ptr 具有獨(dú)占性,即同一時(shí)刻只有一個(gè) std::unique_ptr 可以擁有一個(gè)資源
// 因此 formatter_ 對象可以確保在其生命周期內(nèi),只有一個(gè)智能指針持有 formatter 對象。
// 這樣可以避免多個(gè)指針同時(shí)對同一個(gè)資源進(jìn)行管理,確保資源的正確釋放。
std::unique_ptr<formatter> formatter_;
// 全局日志級別變量的聲明和初始化。默認(rèn)為info
spdlog::level::level_enum global_log_level_ = level::info;
// 日志級別變量的聲明和初始化。flush_level_ 變量用于控制日志的刷新行為。
level::level_enum flush_level_ = level::off;
// 錯(cuò)誤處理器變量的聲明。
err_handler err_handler_;
// 線程池
std::shared_ptr<thread_pool> tp_;
// periodic_worker表示一個(gè)周期性任務(wù)的執(zhí)行器。
// 在 spdlog 中,periodic_worker 類型可能表示一個(gè)周期性的定時(shí)任務(wù)執(zhí)行器,用于定期執(zhí)行某個(gè)操作。
std::unique_ptr<periodic_worker> periodic_flusher_;
// 默認(rèn)日志
std::shared_ptr<logger> default_logger_;
// 是否自動(dòng)注冊,默認(rèn)true
bool automatic_registration_ = true;
// 回溯級別默認(rèn)為0
size_t backtrace_n_messages_ = 0;
};
} // namespace details
} // namespace spdlog
#ifdef SPDLOG_HEADER_ONLY
# include "registry-inl.h"
#endif
文章來源:http://www.zghlxwxcb.cn/news/detail-616083.html
到了這里,關(guān)于01、spdlog源碼閱讀——registry注冊表的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!