Boost.Log v2 : 5.设计概要

Boost.Log是一款模块化和高扩展性的日志库,支持窄字符和宽字符日志,具备收集层、处理层及路由层三层抽象。日志记录可通过多种类型的Logger完成,并允许用户自定义Logger。LogRecord的生成涉及属性(Attribute)与属性值(Attributevalue),并经过过滤(Logfilter)、格式化(Logformatter)等步骤最终传递给日志接收器(LogSink)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计概要

Boost.Log的设计致力于模块化和高扩展性。她同时支持窄字符和宽字符日志。窄字符和宽字符logger的功能类似,故以下文档大都只对窄字符接口展开描述。

日志库由3层抽象组成:日志数据收集层,收集数据处理层,中心路由层(连接收集层和处理层)。如下图所示:
Boost.Log设计示意图
图中箭头代表数据流向 – 从应用程序(左侧)流到终端存储设备(如果有的话,在右侧)。其中存储设备是可选的,因为日志处理的结果也许是执行一些动作而非把信息保存在某处。比如,您的程序运行处于危险状态,可以发出一个特殊的日志,在系统托盘区显示一个提示框并发出报警音, dang~。日志库有个非常重要的特点:收集数据、处理数据的过程和数据本身的组成是无关的。这个特点意味着库用户不但可以进行传统的记录日志,还可以给最终用户标记重要事件和积累统计数据。

Log Source

我们回到上面的图,左侧是您的应用程序发出的Log record,她们在logger的帮助下格式化数据并最终形成Logs。日志库提供许多不同类型的logger,而且你也可以自己构造logger来做扩展。Logger被设计成一系列独立特征的混合体,这些独立的特征可以任意组合。您可以简单开发些私有特征然后把她们倒进这锅汤里。构造好的logger可以嵌入应用程序类或者作为全局变量使用。这2种做法各有利弊。把logger嵌入某个类可以实现按类实例区分日志,从函数式编程的角度而言,全局变量的用法提供了更简单的访问途径。

总体来说,日志库对logger的用法不做要求,能写日志就行。更通俗一点词log source则定义了一个实体,这个实体构造出log record从而开启日志之旅。其他的log source也许还会包含从子应用中捕获的数据或者网络数据,但logger无疑是最常见的一种log source

AttributeAttribute value

要发起日志功能log source就要传输所有和log record相关的数据给logging core。这些数据或者更精确的说数据的捕获逻辑是以一系列我们称之为”attribute*的东西展现的。每一个attribute基本上都是一个函数,其返回值称为attribute value,这些attribute value才是下一阶段的处理对象。一个attribute的例子是返回当前时间的函数。她的返回值(具体的时间点)就是attribute value

有3种类型的attribute集合:

  • 全局型
  • 线程特有型
  • 源特有型

    从上图中我们可以看出前2个集合是由logging core维护的,不需要由log source传递就能启动日志。全局型attribute会附加在所有创建的log record上。显然,所谓线程特有型attribute只会附加在注册她们的线程产生的log record上。源特有型attribute是有启动日志的源维护的,她们只会附加在由特定的源产生的log record上。

当一个源启动日志时,这3中类型的attribute集合产生的attribute value都会被获取。这些attribute value组成一个命名的单一集合,然后做进一步处理。您可以向集合里增加更多attribute value,这些attribute value只会附加在特定的log record上,不会和log sourcelogging core绑定。需要注意的是,相同名称的attribute是可以出现在多个attribute集合中的。有优先级来解决名字冲突:全局型attribute的优先级最低,源特有型的优先级最高,低优先级的attribute在名字冲突中时会被舍弃。

Logging coreLog filter

attribute value组装完成后,logging core决定这个log record要不要交给sink做进一步处理。这个过程称之为filtering。有2层filtering可用:全局filteringlogging core中首先被使用,她们可用快速的移除无用的log recordsink特有filtering随后被使用,每个sink有自己的特有filteringsink特有filtering可用把log record导向不同的sink。值得注意的是,此时已经知道log record来自哪个log source已经变得没有意义了,filtering操作只依赖附加在log record中的attribute value

要注意,对于给定的log recordfiltering操作只会做一次。显然只有filtering开始之前就附加在log record中的attribute value才会参与filtering。其他一些attribute value例如log record信息,是典型的在filtering之后才附加进log record的;这些attribute value是无法参与filtering,她们只会在log formatterlog sink中使用。

Log Sink, Log formatter

如果一个log record通过filtering到达至少一个log sink,这个log record就被认为是可消费的。如果log sink支持格式化输出,在这时日志消息的格式化过程就开始。格式化后的消息和她对应的attribute value一起传给接受了log recordlog sink。注意,格式化过程是基于log sink执行的,所以不同的log sink可以自己定义的格式输出log record

也许您已然发现上图中的log sink由2部分组成:前端和后端。这种划分是为了抽取log sink的通用功能到前端,例如filteringlog formatter和线程同步机制。log sink前端就提供这些库,用户通常不用再去实现她们了。而后端通常是扩展库功能之地。log sink的后端才是真正处理log record的。她们可以是存文件的log sink;她们可以是把log record发往其他处理节点的log sink;她们也可以是上文中提及的弹出提示工具条的log sink – 随你怎么叫吧。最常用的log sink后端在日志库里已经有所提供。

处理上述的主流功能外,日志库还提供了各种各样的辅助工具,比如attributeformatterfiltering的支持,lambda表达式和一些库初始化的辅助类。在《详情描述》一章您会找到关于她们的描述。但是对于日志库的新手,我们还是推荐您从《指南》一章开始。


翻译:Lanser@youkuaiyun.com
声明:本文旨在技术交流,可以转载,但如果是商业用途请务必和原作者确认。本人保留追诉权利。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值