• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2023-07-09 01:14 Aet 隐藏边栏 |   抢沙发  37 
文章评分 4 次,平均分 5.0

接收器

  1. 接收器是实际将日志写入其目标的对象
  2. 每个接收器应该只负责单个目标(例如文件、控制台、数据库)
  3. 并且每个接收器都有自己的格式化程序对象的私有实例
  4. spdlog的接收器有_mt(多线程)或_st(单线程)后缀来指示线程安全

旋转接收器

  1. 当达到最大文件大小时,关闭文件,重命名它,然后创建一个新文件
  2. 最大文件大小和最大文件数都可以在构造函数中配置

每日接收器

简单文件接收器

标准输出接收器,标准错误接收器

空接收器

  1. 调试用

系统日志接收器

  1. POSIX syslog(3) 接收器将其日志发送到 syslog

系统接收器

dist_sink

  1. 将日志消息分发到其他接收器列表

msvc_sink

  1. Windows 调试接收器(使用 OutputDebugStringA 进行日志记录)

dup_filter_sink

  1. 重复消息删除接收器。如果前一条消息相同且已过去的时间小于max_skip_duration,则跳过该消息

环缓冲区接收器

  1. 环形缓冲区接收器将最新的日志消息保留在内存中

qt_sink

  1. 可以从 QTextBrowserQTextEdit 输出日志消息

自定义接收器

  1. 推荐的方法是继承base_sink类。这个类已经处理线程锁定,并且使得实现线程安全接收器变得非常容易

  1. 创建后添加

记录器注册表

  1. spdlog 维护已创建记录器的全局(每个进程)注册表
  2. 目的是让记录器可以从项目中的任何地方轻松访问,而无需传递它们
  3. 如果未找到记录器,则返回空共享指针

注册新的记录器

  1. 要注册手动创建的记录器(即不是由 spdlog.h 工厂函数创建的)

重名冲突

  1. 当尝试使用注册表中已存在的名称进行注册时,spdlog 将引发异常spdlog::spdlog_ex

从注册表中删除记录器

  1. drop函数可用于从注册表中删除记录器
  2. 如果不存在指向记录器的其他shared_ptr,则记录器将被关闭,并且其所有资源将被释放

异步日志记录

创建异步记录器

  1. 包含#include spdlog/async.h
  2. spdlog::async_factory模板参数

  1. spdlog::create_async<Sink>

  1. spdlog::create_async_nb<Sink>,创建一个永远不会阻塞完整队列的记录器

  1. 直接构造并使用全局线程池

  1. 直接构造并使用自定义线程池

满队列策略

  1. 当队列已满时,有两种选择:
    1. 阻止呼叫者,直到有更多空间(默认行为)
    2. 删除队列中最旧的消息并用新消息替换,而不是等待更多空间。使用create_async_nb工厂函数或spdlog::async_overflow_policy记录器的构造函数中的

spdlog的线程池

  1. 默认情况下,spdlog 创建一个队列大小为 8192 的全局线程池和 1 个工作线程,为所有异步记录器提供服务
  2. 所有队列槽位均在线程池构造中预先分配(每个槽位在 64 位系统上占用约 256 字节)
  3. 线程池大小和线程可以通过以下方式重置
    1. 这将删除旧的全局线程池(tp)并创建一个新的 tp - 这意味着任何使用旧 tp 的记录器将停止工作,因此建议在创建任何异步记录器之前调用它

  1. 如果不同的记录器必须有单独的队列,则可以创建不同的池实例并将它们传递给记录器

  1. 线程池有额外的构造函数,它们将回调作为参数。这些将由每个线程在创建之后和销毁之前执行

注意

  1. 默认情况下,spdlog 创建一个工作线程,它保留队列中消息的顺序
  2. 对于具有多个工作线程的线程池,消息可能会在出队后重新排序
  3. 如果要保持消息顺序,则在线程池中只创建一个工作线程

刷新策略

  1. 默认情况下,spdlog 会在认为合适时让底层 libc 刷新,以实现良好的性能

手动刷新

  1. 可以使用该logger->flush()函数指示记录器刷新其内容。记录器将依次调用flush()每个底层接收器上的函数
  2. 如果使用异步记录器,logger->flush()请将消息发布到请求刷新操作的队列,以便该函数立即返回

基于级别的自动刷新

  1. 可以设置触发自动刷新的最低日志级别
    1. 每当记录错误或更严重的消息时,这将触发刷新

基于间隔的定期刷新

  1. spdlog支持设置刷新间隔。这是由单个工作线程实现的,该线程定期在每个记录器上调用flush()
  2. 需要注意的是,仅在线程安全记录器上使用此选项,因为定期刷新发生在不同的线程中

默认记录器

  1. spdlog 创建一个默认的全局记录器(到标准输出、彩色和多线程)
  2. 直接调用即可轻松使用spdlog::info(..), spdlog::debug(..), etc
  3. 它的实例可以替换为任何其他记录器(shared_ptr)

异常相关

  1. Spdlog在记录时不会抛出异常(从版本39cdd08开始)
    1. 如果在记录期间发生错误,库将向 stderr 打印一条错误消息
    2. 为了避免屏幕上充斥着错误消息,每个记录器的速率限制为 1 条消息/分钟
  2. 它可能会在记录器或接收器的建造过程中抛出,因为它被认为是致命的

更改全局错误处理

对于特定的记录器

默认错误处理

  1. _default_err_handler将使用它来打印错误

动态库中使用spdlog

问题

  1. 由于 spdlog 仅包含标头,因此构建共享库并在主程序中使用它不会在它们之间共享注册表
  2. 这意味着对类似函数的调用spdlog::set_level(spdlog::level::level_enum::info)不会更改 DLL 中的记录器

解决

  1. 在两个注册表中注册记录器

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2023-07-23
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享