spdlog中的异步日志方案

日志方案

同步日志方案:立即输出日志记录的方案才能继续执行其他任务。

异步日志方案:先抛出一个日志记录的任务到某个地方,不马上执行打印也不影响往下执行其他任务。

二者关键区别是产生日志记录并调用相关的日志任务接口之后,是否需要马上打印才能往下执行其他任务。

使用多线程的日志方案不一定是异步日志,多线程也能通过锁实现日志的串行打印。

使用单线程的也不一定是同步日志方案,也有可能通过网络通信将日志异步地抛给其他节点完成打印日志的任务。

Spdlog介绍

Spdlog是性能极高的C++日志库。

Spdlog的特点

零成本抽象:spdlog主要编程语言是C++,C++的设计理念之一就是零成本抽象。零成本抽象主要通过内联函数和模板实现。抽象意思是先放置一个大致的框架在代码中,等到真正使用的时候稍加输入和调用就能迅速地构建出要使用的复杂实例或数据结构,不用从0开始编写。零成本指的是相比起用C语言从0开始构建的实例,性能成本几乎一样,没有额外的资源开销,同时大大减少了开发成本。

可异步进行日志记录:把日志信息发送到线程池异步地进行处理,减少对主线程的影响。用户可以自定义线程的个数与队列的大小。如果队列已满可选:抛弃部分日志或者阻塞。

高效格式化:类似python的.format方法。

Spdlog的输出控制

Spdlog日志级别日志级别非spdlog独有,由低到高(重要等级从轻到重):trace、debug、info、warn、error、critical。

Spdlog多种输出目标:可以把日志输出到控制台、文件或者远程服务器。

格式化输出:类似python的.format方法。

Spdlog抽象模型

Registry管理logger/async logger, logger/async logger管理并输出到sink,sink把日志按某种格式输出到目的地,async logger需要依赖一个thread pool。

spd各部件主要功能

用伪代码介绍

Register:

register是一个全局的单例。如果没有显式地创建,一般在创建logger的时候会自动创建。

Spdlog::register_logger(std::shared_ptr<logger> new_logger) //把logger配置到register中去进行管理

Spdlog::get(logger_name) #获取logger

Logger:

如果没有显式地创建而是直接调用spd相关的输出函数,会自动创建默认参数的logger。

Flush策略 #指定sink把日志刷到目的地的方式

Logger->log(…) #输入日志到sink

Set_level #设置日志级别,只有大于等于设置的level才能输出出去

Async logger:

Logger->log(…) #在异步日志中仅仅是发布一个消息到线程池

Sink:

Set_level #自定义日志级别

Set_pattern #自定义日志格式

Set_formatter #补充Set_pattern的功能

Spdlog的使用

安装

方法一

方法二

初级应用

把日志按默认格式输出到控制台,背后会按默认参数创建logger和register并完成注册。

创建logger

Spdlog工厂方法创建

工厂方法的目的:屏蔽复杂的创建对象的流程。

工厂设计模式:有多个具体工厂类继承自一个抽象类,有多个具体产品类继承自另一个抽象类。每个具体工厂类里放置对应的具体产品生产类,只要创建了一个具体工厂实例就能调用具体的产品生产、使用等相关函数。

Spdlog里由很多头文件,不同的头文件里的有不同的“工厂”。

比如daily_file_sink.h指向的是把不同的日期的日志分开记录的“工厂”,hourly_file_sink是把每小时的日志分开记录的“工厂”,mongo_sink.h是把日志写到mongo数据库的“工厂”,ratating_file_sink.h是把日志文件按大小或者条数分割的“工厂”。

需要导入相关的头文件才能实现具体的“工厂”。用相应的头文件里的函数就能实现工厂的实力并“生产”对应的“产品”了。

Mt:multigthread。St:single thread。

这里的stdout_color_mt主要做了几件事情:

  1. 生成了一个对应的patten formatter(日志的输出格式)
  2. 基于默认的sink创建了一个logger,因为logger创建需要sink参数。
  3. 给logger起了一个名字“console”。
  4. 把logger注册到register。Register没有显式地创建,而是在logger创建的时候自动创建的单例。

在工厂模式的封装下,这些复杂的步骤和流程都被隐藏了。

手工方法创建

把工厂模式下被隐藏的步骤全部由自己显式书写,在这种模式下更方便设置多个日志的输出sink,参考sink模块。

创建sink

常规sink

如图创建两个sink,都将其绑定到logger上,于是logger可以输出日志到终端和文件上。

自定义pattern

sink2被修改了输出格式。

%^:表示日志级别的起始颜色标记。这个占位符可以用于在彩色控制台输出中设置日志级别的颜色。
%l:表示日志级别的占位符。它将被替换为实际的日志级别,例如 "info"、"error" 等。
%$:表示日志级别的结束颜色标记。这个占位符用于终止彩色控制台输出中的日志级别颜色。
%v:表示日志消息的占位符。它将被替换为实际的日志消息内容。

自定义formmater

formmater一般和pattern一起使用,是对pattern的补充。

class my_formatter_flag是固定用法,不必深究,只需要关注小红圈里的自定义的text的值。formatter->add_flag<my_formatter_flag>('*') 是往pattern里插入了一个*,也就是占位符*,未来这个占位符会被替换成hct。

创建异步日志

如果,先创建了一个队列8292,线程数量为8的线程池。选择异步工厂的数据类型创建logger并导入线程池。最后一个参数表示:如果等待队列已满,覆盖队列里存在时间最长是日志事件。类似的还有:

block: 当日志消息队列已满时,调用线程将被阻塞,直到有空间来写入新的消息。这种策略可以确保不会丢失任何日志消息,但可能会导致调用线程的阻塞。

discard_log_msg: 当日志消息队列已满时,新的日志消息将被直接丢弃,而不进行任何处理。这可能会导致丢失部分日志消息。

discard_policy: 与 discard_log_msg 类似,当日志消息队列已满时,新的日志消息将被丢弃。但是,相比于 discard_log_msg,discard_policy 会尝试创建一个新的日志消息对象,以便在资源释放后可以重新使用。这样可以减少内存分配的开销。

设置flush策略

sink输出日志一般都是先输出到缓存的,什么时候把日志记录从缓冲区刷到磁盘中,我们可以为此设置策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/580769.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

若依报500异常,只有前端没有后端

1.在vue.config.js中target的网址为https://vue.ruoyi.vip, process.env.VUE_APP_BASE_API]: { target: https://vue.ruoyi.vip,}2.pathRewrite单引号中加入 /prod-api pathRewrite: { ^ process.env.VUE_APP_BASE_API]: /prod-api3.在.env.development中变更 VUE_APP_BASE…

【Python】Python 输出中文乱码问题解决

Python 中文乱码的解决方法 1. 理解编码和解码 Python的字符编码遵循Unicode标准,但在不同的操作系统和编程环境下会有不同的默认字符编码,导致中文输出出现乱码等问题。解决中文输出乱码的问题,需要先理解编码和解码的概念。 编码: 把字符转换成字节序列的过程。因为计算…

CMMI认证办理流程以及需要参与的人员

CMMI&#xff08;Capability Maturity Model Integration&#xff09;认证是衡量软件企业过程管理成熟度的一种标准&#xff0c;它由美国卡内基-梅隆大学软件工程研究中心与美国国防部共同开发。CMMI认证分为五个等级&#xff0c;从低到高依次为1级到5级。以下是办理CMMI证书的…

数据结构-汇总

时间复杂度-汇总 一、二叉树 1、树的结构-初期 2、二叉树的分类-平衡树-红黑树 二叉树的旋转-LL\RR\RL\LR 3、二叉树的旋转-高级一步到位 4、红黑树特征、删除、插入

test mock-01-什么是 mock? Mockito/EasyMock/PowerMock/JMockit/Spock mock 框架对比

拓展阅读 test 之 jmockit-01-overview jmockit-01-test 之 jmockit 入门使用案例 mockito-01-overview mockito 简介及入门使用 PowerMock Mock Server ChaosBlade-01-测试混沌工程平台整体介绍 jvm-sandbox 入门简介 单元测试中的 mock 单元测试是一种验证代码单元&…

K8S网络类型

k8s的网络类型 k8s的通信模式 1 pod内部之间容器与容器之间的通信&#xff0c;在同一个pod中容器是共享资源和网络&#xff0c;使用同一个网络命名空间&#xff0c;可以直接通信 2 同一个node节点之内&#xff0c;不同pod之间的通信&#xff0c;每个pod都有一个全局的真实ip地…

AI 领域代币市场趋势:探索最热门投资领域的前沿动向

作者&#xff1a;lesleyfootprint.network 数据源&#xff1a;Token Sector Dashboard ChatGPT 的热潮点燃了 AI 领域&#xff0c;AI 与区块链技术的融合成为市场关注的焦点。因为区块链的一个显著特征是它能够在链上安全地存储大量数据&#xff0c;这与 AI 模型对数据的密集…

mysql面试题:索引(B+树、聚集索引、二级索引、回表查询、覆盖索引、超大分页查询、索引创建原则)

索引 概念 索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构(有序)。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构**&#xff08;B树&#xff09;**&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数据&am…

安装虚拟机在虚拟机里面安装WindowsServer2012与步骤

目录 一、VMware介绍 1.1、概念讲解 1.2、VMware虚拟机的安装讲解 1.3、具体操作步骤 二、虚拟机安装WindowsServer2012演示 2.1、在虚拟机里配置具体步骤 (相当于制作启动U盘) 2.2、安装windows server2012步骤演示 三、Windows Server2012激活步骤演示 四、思维导…

golang并发安全-sync.map

sync.map解决的问题 golang 原生map是存在并发读写的问题&#xff0c;在并发读写时候会抛出异常 func main() {mT : make(map[int]int)g1 : []int{1, 2, 3, 4, 5, 6}g2 : []int{4, 5, 6, 7, 8, 9}go func() {for i : range g1 {mT[i] i}}()go func() {for i : range g2 {mT[…

【SpringBoot篇】优惠券秒杀 — 添加优惠劵操作(基本操作 | 一人仅一张券的操作)

文章目录 &#x1f354;发放优惠券&#x1f386;基本操作&#x1f384;数据库表&#x1f6f8;思路&#x1f339;代码实现 &#x1f386;完善后的操作&#x1f6f8;乐观锁&#x1f339;代码实现 &#x1f354;一人仅一张优惠券&#x1f6f8;思路&#x1f339;代码⭐代码分析 &am…

git远程操作,推送【push】,拉取【pull】,忽略特殊文件,配置别名,标签管理

文章目录 前言&#xff1a;新建远程仓库克隆推送【push】拉取【pull】 配置git忽略特殊文件给命令配置别名 标签管理理解标签创建标签操作标签 前言&#xff1a; 大家如果没有看过前几章git的基础操作的话&#xff0c;推荐先看一下&#xff0c;看完再来看这个远程操作&#xf…

【PHP】取出数组中的第一个元素

目录 1.使用 reset() 函数&#xff1a; 2.使用 array_shift() 函数&#xff1a; 在 PHP 中&#xff0c;可以使用 reset() 函数或者 array_shift() 函数来取出数组中的第一个元素。 1.使用 reset() 函数&#xff1a; $array [1, 2, 3, 4, 5]; $firstElement reset($array);…

2023年总结:反复纠结与成长的一年

前言 这是我第五年写年度总结&#xff1a; 《2022年总结&#xff1a;道阻且长&#xff0c;行则将至》 《2021年总结&#xff1a;前路有光&#xff0c;初心莫忘》 《2020年总结&#xff0c;所有努力只为一份期待》 《2019年总结&#xff0c;平凡的我仍在平凡的生活》 现在…

【超图】SuperMap iClient3D for WebGL/WebGPU —— 数据集合并缓存如何控制对象样式

作者&#xff1a;taco 最近在支持的过程中&#xff0c;遇到了一个新问题&#xff01;之前研究功能的时候竟然没有想到。通常我们控制单个对象的显隐、颜色、偏移的参数都是根据对象所在的图层以及对象单独的id来算的。那么问题来了&#xff0c;合并后的图层。他怎么控制单个对象…

gorm 使用sql方法

var users []User// 查询 执行用Scan 和Find 一样dbdb.Raw("select uid,user_name,age from Users").Scan(&users)//dbdb.Raw("select uid,user_name,age from Users").Find(&users)fmt.Println("Users",users)// 更新和删除.插入用 …

【Recruitment】

Network I)JD I)JD 1、英语听说读写熟练&#xff0c;有较强的英语沟通能力&#xff1b;2、丰富的网络项目管理和运维管理经验&#xff1b;3、有较强的沟通能力&#xff1b;4、有丰富的供应商管理经验&#xff1b;5、熟悉ITIL管理流程&#xff1b;6、有敏锐的发现问题的能力&am…

面试官:SpringBoot项目中,要如何1秒实现异步接口?

今年IT寒冬&#xff0c;大厂都裁员或者准备裁员&#xff0c;作为开猿节流主要目标之一&#xff0c;我们更应该时刻保持竞争力。为了抱团取暖&#xff0c;林老师开通了《知识星球》&#xff0c;并邀请我阿里、快手、腾讯等的朋友加入&#xff0c;分享八股文、项目经验、管理经验…

STM32逆变器方案

输入电压&#xff1a; 额定输入电压&#xff1a;DC110V 输入电压范围&#xff1a;DC77-137.5V 额定输出参数 电压&#xff1a;200V5%&#xff08;200VAC~240VAC 可调&#xff09; 频率&#xff1a; 42Hz0.5Hz&#xff08;35-50 可调&#xff09; 额定输出容量&#xff1a;1…

关于“Python”的核心知识点整理大全45

目录 15.4.6 绘制直方图 die_visual.py 注意 15.4.7 同时掷两个骰子 dice_visual.py 15.4.8 同时掷两个面数不同的骰子 different_dice.py 15.5 小结 第 16 章 16.1 CSV 文件格式 16.1.1 分析 CSV 文件头 highs_lows.py 注意 16.1.2 打印文件头及其位置 highs_l…