Rust log4rs 架构分析

log4rs 是基于 Rust log 抽象的 logging API 的一个 log 库实现,这个 log 框架具备高可配置的能力。

log4rs 基本配置对象

appender

log4rs 的 appender 就是用来配置在哪里记录日志的,appender 有如下几种实现:

  • console: requires the console_appender feature.
  • file: requires the file_appender feature.
  • rolling_file: requires the rolling_file_appender feature and can be configured with the compound_policy:
    • compound: requires the compound_policy feature
      • Rollers
        • delete: requires the delete_roller feature
        • fixed_window: requires the fixed_window_roller feature
      • Triggers
        • size: requires the size_trigger feature

encoder

log4rs 的 encoder 负责将日志记录转换成对应的输出格式,appender 一般会包括 encoder,encoder 主要有两种实现:

  • pattern: requires the pattern_encoder feature
  • json: requires the json_encoder feature

filter

filter 跟 appender 是关联在一起的用来控制哪些日志会在关联的 appender 中记录,主要的实现:

  • threshold: requires the threshold_filter feature

logger

每条日志记录都是针对特定的 logger,logger 通过 target 字符串来做区分的,如下代码所示的日志记录宏定义指定了 target:

#[macro_export]
macro_rules! bpf_trace {
    ($($arg:tt)+) => (
        if $crate::logging::handler::Handle::is_inited() {
            log::log!(target: "pangolind::bpf", log::Level::Trace, $($arg)+)
        }
    )
}

:: 作为 target 字符串的分隔符,用了指定 logger 的父子关系,log level 如果没有指定则继承父 logger 的配置,每个 logger 可以指定一个 appender 集合,root logger 是所有 logger 的祖先。

log4rs 配置示例

# Scan this file for changes every 30 seconds
refresh_rate: 30 seconds
appenders:
  # An appender named "stdout" that writes to stdout
  stdout:
    kind: console
  # An appender named "requests" that writes to a file with a custom pattern encoder
  requests:
    kind: file
    path: "log/requests.log"
    encoder:
      pattern: "{d} - {m}{n}"
# Set the default logging level to "warn" and attach the "stdout" appender to the root
root:
  level: warn
  appenders:
    - stdout
loggers:
  # Raise the maximum log level for events sent to the "app::backend::db" logger to "info"
  app::backend::db:
    level: info
  # Route log events sent to the "app::requests" logger to the "requests" appender,
  # and *not* the normal appenders installed at the root
  app::requests:
    level: info
    appenders:
      - requests
    additive: false

log4rs 二次开发

log4rs 这个日志库有很强的配置能力,为 Rust 提供了非常灵活的 logging 能力。但是在使用过程中也发现了 log4rs 一些不足,主要是业务场景的支持方面有一些不足:

  • 配置文件格式适配,Rust 经常使用的 TOML 格式
  • 缺省配置支持
  • 支持异步多文件日志记录
  • 宏定义支持,例如多 target 的宏定义

我自己开发了一个 logging 模块,目前在公司内部使用不方便公开,后面有时间我打算搞一个开源版本,stay tune。

References

  1. log4rs/lib.rs