spdlog 基本结构分析
spdlog 基本结构分析
代码取自 V1.5.0, 代码堪称美学。
spdlog 是一个只有头文件的C++日志库,速度非常快,扩展性很强,更重要的是 社区活跃,文档齐全。
使用
- 参考官方的 example.
- {fmt} 的格式使用也需要熟悉一下,毕竟也进 C++20 了,什么垃圾流就快扫进历史的垃圾堆吧.
分析
这里选择了三个点来做分析:
- 提供的 日志格式 非常丰富,并且允许用户自定义需要的格式。
- 对日志文件的类型也做了充分扩展,支持控制台,普通文件,按大小滚动文件,按时间滚动文件,如果不能满足需要,可以自己扩展格式,见 spdlog/sinks/base_sink.h。
- 支持单/多线程,异步/同步,阻塞非阻塞模式。
spdlog 的代码结构如下:
spdlog
├─example 用法代码
├─include 实现目录
│ └─spdlog
│ ├─details 功能函数目录
│ ├─fmt {fmt} 库目录
│ ├─sinks 落地文件格式实现
│ └─*.h 异步模式,日志库接口等实现
├─src .cpp 文件,组成编译模块生成静态库使用
├─test 测试代码
基本逻辑结构如下:

有几个比较重要的文件:
- spdlog/spdlog.h 为日志库接口,提供日志宏的属性控制函数。
- spdlog/logger.h 为日志管理器,为前后端连接的枢纽。
- spdlog/async.h 为异步模式接口。
- spdlog/sinks/base_sink.h 为日志文件格式父类,后面所有的日志文件格式都是继承该类来实现不同功能。
- spdlog/sinks/registry.h 用于登记所有的logger,及一些默认的属性,如日志格式、日志写入等级。
spdlog 接口
spdlog 总体而言提供了日志接口
spdlog::debug(), 默认的日志对象,使用默认的日志信息格式,输出至 stdout。logger->debug(), 指定日志对象进行日志记录,输出至该日志对象对应的文件中。SPDLOG_LOGGER_DEBUG(logger), SPDLOG_DEBUG(), 使用宏对以上两种接口进行包装,产生的日志格式包含 文件、函数、行。
提供的一些落地的文件类型:
- 标准输出
- 带颜色的标准输出(默认)
- 基本文件
- 可设定时间的滚动文件
- 可设定大小的滚动文件
- 过滤重复的日志
- syslog 日志
这里简单提一下 sinks 的实现,所有落地文件的类型都是从 base_sink(忽略sink) 继承而来,提供了两个纯虚函数 sink_it_() 和 flush_(),这样一来,需要扩展的类型文件只需要实现两个函数,很大的简化了扩展的流程。而单/多线程通过模板来确定是否需要使用互斥量来保持同步,也算是比较有意思的一个实现了:
// 例子使用 base_file_sink
using basic_file_sink_mt = basic_file_sink<std::mutex>;
using basic_file_sink_st = basic_file_sink<details::null_mutex>;
struct null_mutex
{
void lock() const {}
void unlock() const {}
bool try_lock() const
{
return true;
}
};
template<typename Mutex>
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::log(const details::log_msg &msg)
{
std::lock_guard<Mutex> lock(mutex_);
sink_it_(msg);
}
如果需要使用多线程模式,就使用 std::mutex,如果是单线程,我们就不需要互斥来同步,这里实现一个空的互斥量类,就使得 log() 的代码完全不需要修改了,也提高了内聚性。
spdlog 默认使用同步模式,也可以设置异步模式,异步模式会创建一个线程池,线程池大小可以自行设置,默认为1,该线程池所有者为 details::registry::instance(). 后台的大小可以设置的 多生产者多消费者队列 默认为阻塞模式,也可以设置为非阻塞,不过这个非阻塞的处理非常简单粗暴,就是简单的丢弃最老的日志,推荐是不要这样设置滴,一般产生阻塞的情况大概是磁盘IO打满了,出现这个情况一般是别的地方出问题了。
details::registry 管理所有的日志对象
- 使用
<name, logger>将日志对象和其名称对应起来,后面使用的时候可以直接通过名称获取对应的日志对象。 - 保存全部日志对象的默认属性,可使用提供的属性控制接口改变所有的日志对象属性。
- 提供定时flush,spdlog 的文件操作具有缓冲区属性,为试日志信息及时落地,后台新生成一个flush线程,设置一个时间(单位:秒)定时唤醒一次进行 flush。
参考
- {fmt}, A modern formatting library. 现代化的格式化库,速度快,使用简单,已经确定进入 C++20.
spdlog 基本结构分析的更多相关文章
- Facebook的体系结构分析---外文转载
Facebook的体系结构分析---外文转载 From various readings and conversations I had, my understanding of Facebook's ...
- Android项目目录结构分析
Android项目目录结构分析 1.HelloWorld项目的目录结构1.1.src文件夹1.2.gen文件夹1.3.Android 2.1文件夹1.4.assets 1.5.res文件夹1.6.An ...
- 【转载】nedmalloc结构分析
原文:nedmalloc结构分析 nedmalloc是一个跨平台的高性能多线程内存分配库,很多库都使用它,例如:OGRE.现在我们来看看nedmalloc的实现 (以WIN32部分为例) 位操作 ...
- laravel5-目录结构分析
laravel5-目录结构分析 (2016-01-21 11:24:03) 转载▼ 一.环境配置: $ lsb_release -a No LSB modules are available. ...
- [Cocos2d-x for WP8学习笔记] HelloWorld结构分析
先来看一下目录结构: Assets:游戏资源文件,图片音频等,Resource文件夹也有类似功能 include:用于放置游戏头文件 Shaders:渲染器着色器文件(大雾) cocos2dorig. ...
- Sde表结构分析
原文 Sde表结构分析 今天开始想分析一下sde的表结构,希望能够弄明白sde一个要素类的每个Feature是如何存储的. 弄ArcSDE的人都知道,ArcSDE内一个要素类在关系数据库(以MS SQ ...
- Linux中断处理体系结构分析
Linux中断处理体系结构分析(一) 异常,就是可以打断CPU正常运行流程的一些事情,比如外部中断.未定义指令.试图修改只读的数据.执行swi指令(Software Interrupt Instruc ...
- PNG文件结构分析 ---Png解析
PNG文件结构分析 ---Png解析 为了实现更高级的应用,我们必须充分挖掘PNG的潜力. PNG的文件结构 根据PNG文件的定义来说,其文件头位置总是由位固定的字节来描述的: 十进制数 13 ...
- Android 虚拟机Dalvik、Android各种java包功能、Android相关文件类型、应用程序结构分析、ADB
Android虚拟机Dalvik Dalvik冲击 随着Google 的AndroidSDK 的发布,关于它的API 以及在移动电话领域所带来的预期影响这些方面的讨论不胜枚举.不过,其中的一个话题在J ...
随机推荐
- java异常处理格式
异常处理的5个关键字 try ,catch, finally throw, throws 我的总结: 捕获异常:先捕获小异常再捕获大异常. 程序是调出来的,不是写出来的:多测试是程序员的必修课. ...
- JOISC2014 Day2 E "交朋友" (思维+假的SCC)
传送门 题目描述 你是活跃在历史幕后的一名特工,为了世界和平而夜以继日地努力着. 这个世界有N个国家,编号为1..N; 你的目的是在这N个国家之间建立尽可能多的友好关系. 你为了制定一个特工工作的计划 ...
- Java中getBytes()方法--使用详解
getBytes()方法详解 在Java中,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组.这表示在不同的操作系统下,返回的东西不一样! 1. str.getByte ...
- 【t046】牛跳
Time Limit: 1 second Memory Limit: 128 MB [问题描述] John的奶牛们计划要跳到月亮上去.它们请魔法师配制了P(1 <= P <=150,000 ...
- 【u202】家庭作业
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分.每个作业的截止日期 ...
- H3C tracert命令的输出
- Linux 内核 ksets 之上的操作
对于初始化和设置, ksets 有一个接口非常类似于 kobjects. 下列函数存在: void kset_init(struct kset *kset); int kset_add(struct ...
- ZR提高失恋测4
ZR提高失恋测4 比赛链接 A (方便讨论,设读入的串为\(S,T\)答案串为\(A\)) 首先\(*\)只会有一个 这是这道题目中非常重要的一个结论 简单证明一下? 因为\(*\)可以代表所有的字符 ...
- Vue学习笔记-目录结构
1.采用脚手架构建的项目基本目录结构 可能会有些许差别,但是大致基本目录都差不多 2.项目入口(index.html,main.js,App.vue) 一般情况下,我们都习惯性将 index.html ...
- 牛客练习赛4 A Laptop
传送门:https://ac.nowcoder.com/acm/contest/16/A 题意: 每个物品有2个属性,求有多少个物品的两个属性完全小于另一个物品 题解: 求逆序对板子题 代码: /** ...