首页 > 其他分享 >easylogging++的那些事(三)总体设计

easylogging++的那些事(三)总体设计

时间:2022-11-23 21:49:18浏览次数:65  
标签:框架 ++ 总体设计 easylogging 格式 日志 Logger

目录

上一篇文章我们介绍了 easylogging++的 ,今天我们开始介绍 easylogging++的总体设计。

一、日志框架的需求分析

    谈 easylogging++的总体设计之前,我们先假设现在需要开发一个日志框架,按照软件开发的流程,我们首进行需求分析。需求分为功能性需求和非功能性需求,日志框架的功能性需求就是日志框架要实现的功能,即规范应用程序日志记录过程,将处理日志记录这件事情的过程标准化。当想要捕获程序的运行时信息时,日志框架首先要发出要记录的信息,然后格式化这些信息,最后决定将它出到哪里。一般情况下,会输出到文件中,但是也可以将其输出到控制台、数据库,或者任何能够接收数据地方。
    通过上面的描述,我们可以得出 日志框架的功能性需求:

  • 日志内容:多种日志类型的支持
  • 日志格式的管理:日志格式的配置
  • 日志输出地的管理

    再说说 日志框架的非功能性需求:

  • 易用性
    日志框架否易集成、易插拔、跟业务代码是否松耦合、提供的接口是否够灵活等等有的时候,文档写得好坏甚至都有可能决定一个框架是否受欢迎。

  • 性能
    由于日志记录是很频繁的,我们不希望日志框架本身的代码执行效率,对业务系统有太多性能上的影响。

  • 扩展性
    可以在不修改框架源码,甚至不拿到框架源码的情况下,为框架扩展新的功能。这就有点类似给框架开发插件。

  • 容错性
    日志记录异常不能对正常的业务逻辑造成影响。

二、easylogging++的需求分析

功能性需求

1、日志内容: 多种日志类型的支持

    easylogging++将日志分为两种:用户日志和 syslog 日志,而用户日志又可分为普通日志和 verbose 日志。其中普通日志又可以细分为 带 errno 错误信息的和 不带 errno 错误信息。

2、日志格式的管理: 日志格式的配置

    easylogging++可以通过三种方式来配置:

  1. 命令行参数
  2. 通过相应的 API 以字符串形式来配置
  3. 通过加载配置文件

3、日志输出地的管理

    默认 easylogging++提供了对于控制台和文件输出这两种输出地的管理,其他方式可以通过注册相应的 LogDispatchCallback 回调来实现。github 上提供了通过 boost 实现的网络发送日志的 demo

非功能性需求

1、易用性

  • 官方文档很清晰。
  • 目前仅仅包含一个头文件和一个 cc 文件,很容易集成。
  • 接口易于使用,提供了流式接口和类似 printf 的接口以及大量相关的日志记录宏。

2、性能

    目前网上没有看到相关的性能评测数据,这里就不做过多说明,从源码上面能看的到的有四点:

  • 流式输出
  • 复用文件流
  • 支持日志缓存
  • 异步日志支持(实验性功能,由同步日志改为异步日志会出现崩溃问题)

3、扩展性

  • 提供了不同类型的回调注册机制
        1) 注册相应的 LogDispatchCallback 回调来实现日志输出事件的跟踪
        2) 注册相应的 PerformanceTrackingCallback 回调实现自定义的性能跟踪
        3) 注册相应的 LoggerRegistrationCallback 回调实现日志记录器注册事件的跟踪
        4) 支持日志旋转功能(源码当中这里实现的日志旋转后会截断日志文件的动作确实在实际项目中一般不这么用)
        5) 注册自定义的崩溃处理器以及堆栈跟踪
  • 灵活的日志格式配置方式,同时还支持自定义日志格式解析器,通过 CustomFormatSpecifier 类实现
  • STL, QT, BOOST, wxWidgets 相关数据类型直接输出到日志的支持以及兼容第三方类型直接日志输出支持

4、容错性

  • easylogging++支持线程安全。
  • 记录日志时,内部已经捕获了所有的异常,不让异常对正常的业务逻辑造成影响。

三、easylogging++的框架设计

easylogging++的所有与日志输出相关的信息都保存在 Storage 类中,日志库的入口类或者总的管理类,其中保存了这些信息:

  • RegisteredHitCounters 指定文件指定行的用于是否记录日志的计数器
  • RegisteredLoggers 注册的日志记录器的管理类
  • LoggingFlag 写日志时会用到的一些标志
  • VRegistry 详细日志相关配置的管理类(保存详细日志级别以及 vModule 相关信息)
  • AsyncLogQueue 异步日志队列(暂时保存日志)
  • IWorker 异步日志调度器(处理 AsyncLogQueue 中的日志)
  • CommandLineArgs 命令行参数解析器
  • PreRollOutCallback 日志回旋回调函数
  • LogDispatchCallback 所有注册的日志派发回调函数
  • PerformanceTrackingCallback 所有注册的性能跟踪回调函数
  • 线程信息容器(线程 ID 字符串 线程名称)
  • CustomFormatSpecifier 自定义日志格式指示器
  • Level 普通日志记录时的基准日志级别,大于这个级别才会记录普通日志

其中 RegisteredLoggers 管理的日志记录器类为 Logger,每个 Logger 实例保存了以下信息:

  • id: Logger 标识符,唯一标识一个 logger 实例
  • stringstream_t 每个 Logger 实例的字符串流,每条日志的信息会先写入这个字符串流
  • 应用程序名称
  • Configurations Logger 实例对应各个日志级别的配置项的字符串形式的值 Logger 实例对应的字符串形式的日志格式信息,比如是否启用配置项是字符串形式的 "true" 或者 "false"
  • TypedConfigurations Logger 实例对应各个日志级别的配置项的类型是程序运行时的实际类型,比如是否启用配置项是 bool
  • Logger 实例对应各个日志级别的写日志时未刷新累计的次数
  • LogStreamsReferenceMapPtr 文件名和对应文件流的映射关系容器(key-> 文件名,value-> 文件流)

easylogging++的总体设计就介绍到这里,下一篇我们开始分析主流程。

标签:框架,++,总体设计,easylogging,格式,日志,Logger
From: https://www.cnblogs.com/DesignLife/p/16903503.html

相关文章

  • easylogging++的那些事(二)宏定义
    上一篇文章我们简要介绍了easylogging++的主要功能。easylogging++中有很多特性是通过宏来控制的,今天我们就来聊聊这些宏:debug输出流宏定义ELPP_INTERNAL_DEBUGGING......
  • C++全栈开发学习路线图
    C语言基础与提高 C语言基础 指针、内存管理 变量、条件、字符串、数组、函数、结构体 C语言提高 多级指针的使用 接口的封......
  • 数据结构(二):括号匹配(C++,栈)
    好家伙,写题,题目代码在最后 来吧,  1.栈 栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一......
  • C++ 嵌入式实时操作系统调试心得
    1、如果设置了全局vector变量,然后在程序中一直pushback,如果是系统内存较小,运行一段时间后可能会崩溃;2、如果使用C语言编程采用动态内存,一定要在变量生存周期结束时对内存......
  • C++ --- 标准库std::max/std::min和window头文件中宏max/min冲突
    转载:https://blog.twofei.com/668/在包含了Windows.h的C++源代码中使用std::min/std::max会出现错误。intmain(){intx=std::max(0,1);inty=std......
  • C ++:树
    C++:树树的概念:所谓“树”是输就结构的一种,树大概可以分为两大类:有根树和无根树有根树使有一个确定的根节点,反之为无根树·子节点:从树根开始,通过树边向下扩展的节......
  • C++ 判断闰年简单代码
    闰年闰年分为普通闰年和世纪闰年1582年以来的置闰规则:普通闰年:公历年份是4的倍数,且不是100的倍数的,为闰年(如2004年、2020年等就是闰年)。世纪闰年:公历年份是整百数的......
  • 周六900C++班级-2022-11-19 01背包
    背包问题关系图  问题描述若有N件物品和一个最多能装重量为W的背包,一个物品只有两个属性:重量和价值。第i件物品的重量是weight[i],得到的价值是value[i]。假......
  • 用汇编的眼光看C++(之 总结篇)
       早在八月份的时候,就陆陆续续写了二十多篇用汇编语言看C++的博客内容。在此为了做一个概括,也为了朋友们看起来更方便,我们利用这么一篇博客对所有的文章做一个总结。如......
  • socket通信编程C++实现
    socket提供了套接字,以方便我们想读取文件一样进行网络进程间的数据通信。在网络通信中,套接字一定是成对出现的。一端的发送缓冲区对应对端的接收缓冲区。我们使用同一个文......