01、spdlog源码阅读——registry注册表

这篇具有很好参考价值的文章主要介绍了01、spdlog源码阅读——registry注册表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

注册表具有唯一标识,用于管理多个日志文章来源地址https://www.toymoban.com/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>;
    // 拷贝构造函数进行删除(delete)的声明。这意味着该类的拷贝构造函数被禁用,不允许进行拷贝构造。
    registry(const registry &) = delete;
    // 这意味着该类的赋值运算符重载被禁用,不允许进行对象之间的赋值操作。
    registry &operator=(const registry &) = delete;

    // 向全局的日志器注册表中注册一个新的日志器。
    void register_logger(std::shared_ptr<logger> new_logger);
    // 初始化一个新的日志器并将其设置为【全局默认日志器】。
    void initialize_logger(std::shared_ptr<logger> new_logger);
    // 通过名称获取logger
    std::shared_ptr<logger> get(const std::string &logger_name);
    // 获取默认的全局日志器。
    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.
    // 获取默认的全局日志器的裸指针(raw pointer)。
    // 裸指针是指向对象的普通指针,不包含智能指针的管理功能,需要手动管理对象的生命周期。
    logger *get_default_raw();

    // set default logger.
    // default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
    // 设置新的默认全局日志器
    void set_default_logger(std::shared_ptr<logger> new_default_logger);

    // 设置日志器的线程池。
    // 通过设置日志器的线程池,可以让日志器在后台线程中执行写入日志的操作,从而减少主线程的阻塞时间,提高程序的性能和响应性。
    // 如果日志记录是同步进行的(默认情况下),日志消息的写入操作会在主线程中直接完成,可能会对程序的性能产生影响。
    // 而设置了线程池后,日志消息的写入操作将在后台线程中进行,不会阻塞主线程的执行。
    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
    // 设置日志器的日志消息格式化器
    // 日志消息格式化器是用于将日志消息的内容按照特定的格式进行格式化的组件
    // 通过设置日志器的格式化器,可以自定义日志消息输出的样式,例如包含时间戳、日志级别、日志内容等信息,并将格式化后的日志消息写入到输出目标(如控制台、文件等)。
    void set_formatter(std::unique_ptr<formatter> formatter);

    // 启用日志器的回溯(backtrace)功能。
    void enable_backtrace(size_t n_messages);

    // 关闭日志器的回溯(backtrace)功能。
    void disable_backtrace();

    // 设置日志的级别
    void set_level(level::level_enum log_level);

    // 日志器的日志刷新级别。
    // 日志刷新级别指定了日志器在哪个日志级别及以上时需要立即刷新日志消息。
    // 如果调用 flush_on(spdlog::level::err),它会设置日志器在 err(错误)级别及以上时立即刷新日志消息。
    // 这意味着处于 err、critical 和 off 级别的日志消息将在写入后立即刷新,而低于这些级别的日志消息(例如 info 或 debug)可能会被缓冲以提高效率。
    void flush_on(level::level_enum log_level);

    // 设置定时刷新日志的时间间隔。
    // 支持不同类型的时间间隔。Rep 和 Period 是时间间隔类型的模板参数,用于指定时间间隔的数值和时间单位。
    // std::chrono::duration 是 C++ 标准库中的时间间隔类模板,用于表示一段时间。
    // std::lock_guard<std::mutex> lock(flusher_mutex_);这是一个互斥锁 std::mutex 的锁保护,用于保证在设置定时器时,其他线程不会同时进行刷新操作。
    // 回调函数是 this->flush_all(),表示要执行日志器的刷新操作。
    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(); };
        // 这是一个定时器的成员变量,用于设置定时器,并将回调函数和时间间隔传递给 periodic_worker 构造函数。
        // periodic_worker 是 spdlog 库中的一个类,用于创建周期性定时器。
        periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
    }

    // 设置错误处理函数(Error Handler)。
    // 这是一个函数指针或函数对象参数,用于表示错误处理函数。错误处理函数是一个用户定义的函数,用于处理在 spdlog 库中可能发生的错误情况
    // using err_handler = std::function<void(const std::string &err_msg)>;是一个函数对象类型,用于表示一个接受 const std::string & 类型参数的无返回值函数。
    void set_error_handler(err_handler handler);

    // 对所有已注册的日志器应用一个指定的函数。
    // 对所有已创建的日志器进行一些特定的操作,例如更改日志器的配置、设置日志级别等。
    void apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun);

    // 将所有已注册的日志器的缓冲日志消息刷新到输出目标。
    void flush_all();

    // 从日志器注册表中移除指定名称的日志器。
    void drop(const std::string &logger_name);

    // 从日志器注册表中移除所有日志器。
    void drop_all();

    // clean all resources and threads started by the registry
    // 关闭所有已注册的日志器并释放相关资源。
    void shutdown();

    // 获取一个递归互斥锁(recursive mutex)对象的引用。
    // 递归互斥锁是一种特殊类型的互斥锁,允许同一线程多次对互斥锁进行加锁,而不会导致死锁。
    std::recursive_mutex &tp_mutex();

    // 指定是否启用自动注册日志器功能。
    // 为true时,通过 spdlog::create 创建的日志器将自动注册到全局的日志器注册表中,方便后续的查找和使用。
    // 为false时,通过 spdlog::create 创建的日志器将不会自动注册到日志器注册表中,需要手动调用其他函数(如 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.
    // 可以同时设置多个日志器的日志级别,并可以设置全局的日志级别。这样可以方便地统一管理多个日志器的日志级别,并灵活地控制日志输出的详细程度。
    // using log_levels = std::unordered_map<std::string, level::level_enum>;多个日志级别配置,map类型
    void set_levels(log_levels levels, level::level_enum *global_level);

    // 获取日志器注册表的单例实例。
    // 日志器注册表是全局唯一的,为了方便使用,spdlog 使用了单例模式,即只允许存在一个注册表实例。
    static registry &instance();

    // 根据环境变量设置日志器的日志级别。
    // 使用环境变量来配置日志级别具有灵活性,因为它允许在不修改代码的情况下更改日志级别。
    // 通过在运行时设置环境变量,可以动态地调整日志输出的详细程度,方便在不同的场景或部署环境下进行日志记录。
    void apply_logger_env_levels(std::shared_ptr<logger> new_logger);

private:
    registry();
    ~registry();
    // 用于检查是否存在指定名称的日志器,并在存在时抛出异常。
    // 通过调用 throw_if_exists_ 函数,并传递一个日志器的名称作为参数,可以检查注册表中是否已经存在具有相同名称的日志器。
    // 如果存在,该函数会抛出异常,提示名称冲突,防止创建重名的日志器。
    void throw_if_exists_(const std::string &logger_name);
    // 将指定的日志器注册到日志器注册表中。
    void register_logger_(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_;
    // 日志无序映射
    std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
    // 保存多个日志器的名称及对应的日志级别。
    log_levels log_levels_;
    // formatter 是一个抽象基类,用于控制日志消息的格式化方式
    // 独占指针
    // 由于 std::unique_ptr 具有独占性,即同一时刻只有一个 std::unique_ptr 可以拥有一个资源
    // 因此 formatter_ 对象可以确保在其生命周期内,只有一个智能指针持有 formatter 对象。
    // 这样可以避免多个指针同时对同一个资源进行管理,确保资源的正确释放。
    std::unique_ptr<formatter> formatter_;
    // 全局日志级别变量的声明和初始化。默认为info
    spdlog::level::level_enum global_log_level_ = level::info;
    // 日志级别变量的声明和初始化。flush_level_ 变量用于控制日志的刷新行为。
    level::level_enum flush_level_ = level::off;
    // 错误处理器变量的声明。
    err_handler err_handler_;
    // 线程池
    std::shared_ptr<thread_pool> tp_;
    // periodic_worker表示一个周期性任务的执行器。
    // 在 spdlog 中,periodic_worker 类型可能表示一个周期性的定时任务执行器,用于定期执行某个操作。
    std::unique_ptr<periodic_worker> periodic_flusher_;
    // 默认日志
    std::shared_ptr<logger> default_logger_;
    // 是否自动注册,默认true
    bool automatic_registration_ = true;
    // 回溯级别默认为0
    size_t backtrace_n_messages_ = 0;
};

} // namespace details
} // namespace spdlog

#ifdef SPDLOG_HEADER_ONLY
#    include "registry-inl.h"
#endif

到了这里,关于01、spdlog源码阅读——registry注册表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Windows基础】注册表

    注册表是Windows操作系统、硬件设备以及客户应用程序得以正常运行和保存设置的 核心\\\"数据库\\\" ,也可以说是一个非常巨大的 树状分层结构 的 数据库系统 注册表记录了用户安装在计算机上的软件和每个程序的相互关联信息,它包括了计算机的硬件配置,包括自动配置的即插

    2024年02月04日
    浏览(54)
  • 玩转注册表

           很多人都认识注册表,但是几乎没人搞懂过注册表。我来带大家玩转注册表,做这篇文章就想记录一下注册表里的一些路径(难找,记不住!),本文中我会介绍一些实用的利用注册表进行内网权限维持的一个思路和方法。没学网安的,会更了解注册表;大佬就复习

    2024年02月05日
    浏览(42)
  • MFC 注册表

    2024年02月08日
    浏览(41)
  • Reg注册表读写

    在Windows 95及其后继版本中,采用了一种叫做“注册表”的数据库来统一进行管理,将各种信息资源集中起来并存储各种配置信息。按照这一原则,Windows各版本中都采用了将应用程序和计算机系统全部配置信息容纳在一起的注册表,用来管理应用程序和文件的关联、硬件设备

    2024年02月09日
    浏览(37)
  • Unity 注册表操作

    内容将会持续更新,有错误的地方欢迎指正,谢谢!   Unity 注册表操作       TechX 坚持将创新的科技带给世界! 拥有更好的学习体验 —— 不断努力,不断进步,不断探索 TechX —— 心探索、心进取! 助力快速掌握 Registry 注册表操作 为初学者节省宝贵的学习时间,避免困惑

    2024年02月02日
    浏览(38)
  • Windows注册表清理

    伴随着系统运行时间不断增长,我们的电脑 注册表 中累积了许多垃圾文件。这些垃圾文件都是我们平常安装与卸载程序所留下的无用注册表信息,时间一长,垃圾文件与信息越来越多,我们电脑的运行速度越来越慢。 ​ 而且部分软件由于删除方式不对,导致一些残留注册表

    2024年02月08日
    浏览(47)
  • 深入注册表监控

    注册表是windows的重要数据库,存放了很多重要的信息以及一些应用的设置,对注册表进行监控并防止篡改是十分有必要的。在64位系统下微软提供了 CmRegisterCallback 这个回调函数来实时监控注册表的操作,那么既然这里微软提供了这么一个方便的接口,病毒木马自然也会利用

    2024年02月08日
    浏览(37)
  • Windows技巧之注册表

    介绍 注册表是Windows操作系统中的一个核心数据库,其中存放着各种参数,直接控制着Windows的启动、硬件驱动程序的装载以及一些Windows应用程序的运行,从而在整个系统中起着核心作用。这些作用包括了软、硬件的相关配置和状态信息,比如注册表中保存有应用程序和资源管

    2023年04月08日
    浏览(43)
  • DOS下操作注册表

    下面以彻底关闭window10 操作为背景,通过命令行对注册表进行操作. 执行命令需要管理员权限 如果目录中存在空格 需要双引号 hklm为 HKEY_LOCAL_MACHINE 的缩写 查询: QUERY 添加: ADD 删除: DELETE 复制: COPY 保存: SAVE /t 表示 类型 如下 /v 表示 键名 效果如下图 /d 表示 键值 效果如

    2024年02月10日
    浏览(40)
  • 【Windows注册表内容详解】

    一、什么是注册表 注册表是windows操作系统、硬件设备以及客户应用程序得以正常运行和保存设置的核心“数据库”,也可以说是一个非常巨大的树状分层结构的数据库系统。 注册表记录了用户安装在计算机上的软件和每个程序的相互关联信息,它包括了计算机的硬件配置,

    2024年02月09日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包