日志库的一般设计思路

日志库的设计,一般而言要抓住最核心的一条,就是日志从产生到到达最终目的地期间的处理流程。一般而言,为了设计一个灵活可扩展,可配置的日志库,主要将日志库分为4个部分去设计,分别是:记录器、过滤器、格式化器、输出器四部分。

  • 记录器:负责产生日志记录的原始信息,比如(原始信息,日志等级,时间,记录的位置)等等信息。
  • 过滤器:负责按指定的过滤条件过滤掉我们不需要的日志(比如按日志等级过滤)。
  • 格式化器:负责对原始日志信息按照我们想要的格式去格式化。
  • 输出器:负责将将要进行记录的日志(一般经过过滤器及格式化器的处理后)记录到日志目的地(例如:输出到文件中)

下面以一条日志的生命周为例说明日志库是怎么工作的。
一条日志的生命周期:
1. 产生。info!(“log information.”);
2. 经过记录器。记录器去获取日志发生的时间,位置,线程信息等等信息,会有一个数据结构去存储你需要的信息(例如:msg:”log information.”,time:2018-3-20 10:00:00,level:info,location:main.rs:3 lines)
3. 经过过滤器。决定是否记录(例如,过滤条件设为info级一下的过滤掉,这里条日志信息等级是info,满足条件,继续。)
4. 经过格式化器。假设我们想输出为“2018-3-22 10:00:00 [info] log information.”
5. 到输出器。例如输出到文件中,我们就将这条信息写到文件上(File::write(….);).
6. 这条日志信息生命结束了。

根据这四部分,去组成日志库的核功能。在具体实现上,可能要要设计一个核心处理器,负责读取日志配置文件,根据配置文件中的配置条件去构建相应的代码等等工作。

伪代码实现:

  1. 从配置文件中读取配置(可通过序列化或其他方式),生成Config。
  2. LoggerBuilder根据Config去构造Logger。
  3. 由Logger实现日志库的核心功能。

//配置
struct Config{
    level:Level,
    ...
}

//Logger建造者
struct LoggerBuilder{
    ...
}

//Logger
struct Logger{
    record:Recorder,
    filter:Filter,
    formater:Formater,
    output:Output,
}

fern,rust实现的一个日志库,基本就是这种思路。log4rs,rust实现的一个复杂可配置的日志库,也基本是上面这种模式,只不过每一部分的实现更加复杂,灵活,多样。

猜你喜欢

转载自blog.csdn.net/s_lisheng/article/details/79654542