log4rs学习笔记

902 阅读10分钟

log4rs是Rust生态系统中功能强大且灵活的日志库,支持通过配置文件或代码来定制日志行为。配置文件可以使用多种格式,如YamlJsonToml。本文将详细介绍log4rs的各个配置项及其含义。

我们将主要以Yaml配置为例进行说明,涵盖以下主要部分:

image.png

一、全局配置项

全局配置项用于设置影响整个日志系统的参数

refresh_rate

描述:指定配置文件自动刷新(重新加载)的时间间隔,当配置文件发生更改时,log4rs会根据此间隔重新加载配置,以实现动态更新日志配置的效果。

格式:

refresh_rate: <duration>

示例:

refresh_rate: 30 seconds

支持的时间单位:

  • nanoseconds
  • microseconds
  • milliseconds
  • seconds
  • minutes
  • hours

注意:

  • 如果未设置refresh_rate,则配置文件不会自动刷新。
  • 配置文件发生更改时,log4rs会在下一个refresh_rate间隔到达时重新加载配置。

二、Appenders(输出器)

Appenders定义了日志的输出目标,如控制台、文件等,每个Appender都可以配置不同的编码器、过滤器和特定于该类型的参数。

2.1 ConsoleAppender(控制台输出器)

描述:将日志输出到标准输出(stdout)或标准错误(stderr)。

配置项:

  • kind:固定为console,表示控制台输出。
  • target:输出目标,取值为stdout(默认)或者stderr
  • encoder:定义日志消息的格式。

示例:

appenders:
  stdout:
    kind: console
    target: stdout
    encoder:
      pattern: "{d} - {l} - {m}{n}"

解释:

  • stdout:Appender的名称,可在Logger中引用。
  • pattern:指定日志的输出格式,详见3.1 PatternEncoder

2.2 FileAppender(文件输出器)

描述:将日志输出到指定的文件中。

配置项:

  • kind:固定为file,表示文件输出。
  • path:日志文件的路径。
  • append:是否以追加模式写入文件,默认为true
  • encoder:定义日志消息的格式。
  • buffered:是否启用缓冲写入,默认为false
  • buffer_size:缓冲区大小(字节),默认为8192,仅在buffered: true时有效。

示例:

appenders:
  file_appender:
    kind: file
    path: "logs/app.log"
    append: true
    buffered: true
    buffer_size: 8192
    encoder:
      pattern: "{d} - {l} - {m}{n}"

解释:

  • path:指定日志文件的存放路径。
  • append:为 true 时,新日志将追加到文件末尾;为 false 时,将覆盖文件。
  • buffered:启用后,日志将先写入缓冲区,再批量写入文件,提高性能。
  • buffer_size:指定缓冲区大小。

2.3 RollingFileAppender(滚动文件输出器)

描述:将日志输出到文件,并在满足特定条件时自动滚动(创建新文件并备份旧文件),适用于需要控制日志文件大小或数量的场景。

配置项:

  • kind:固定为rolling_file,表示文件输出。
  • path:当前活动日志文件的路径。
  • append:是否以追加模式写入文件,默认为true
  • encoder:定义日志消息的格式。
  • policy:定义滚动策略,包括触发器(何时滚动)和滚动器(如何处理旧日志)。

policy配置项:

  • trigger:定义滚动触发条件。
  • roller:定义滚动行为。

示例:

appenders:
  rolling_file_appender:
    kind: rolling_file
    path: "logs/app.log"
    append: true
    encoder:
      pattern: "{d} - {l} - {m}{n}"
    policy:
      trigger:
        kind: size
        limit: 10 mb
      roller:
        kind: fixed_window
        base: 1
        count: 5
        pattern: "logs/app.{}.log"
        compress: true

解释

  • trigger:当日志文件大小达到 10 MB 时触发滚动。
  • roller:使用固定窗口策略,保留最近的 5 个日志文件,文件名按照 app.1.logapp.5.log 命名,超过数量的旧日志将被删除。compress: true 表示滚动的日志文件将被压缩(gzip 格式)。

支持的 Trigger 类型

  1. SizeTrigger
  • kind: "size"
  • limit: 文件大小限制,支持单位如 kbmbgb

示例:

trigger:
  kind: size
  limit: 100 mb

2. CompoundTrigger:组合多个触发器,任意一个触发即滚动。

  • kind: "compound"
  • triggers: 触发器列表。

示例:

trigger:
  kind: compound
  triggers:
    - kind: size
      limit: 100 mb
    - kind: age
      age: 1 day

3. AgeTrigger

  • kind: "age"
  • age: 文件最大年龄。
trigger:
  kind: age
  age: 1 day

支持的 Roller 类型

  1. FixedWindowRoller
  • kind: "fixed_window"
  • base: 起始编号。
  • count: 保留的文件数量。
  • pattern: 滚动文件的命名模式,使用 {} 作为占位符。
  • compress: 是否压缩滚动文件,默认为 false

示例:

roller:
  kind: fixed_window
  base: 1
  count: 5
  pattern: "logs/app.{}.log"
  compress: true

2. DeleteRoller

  • kind: "delete"
  • keep: 保留的文件数量。
  • pattern: 匹配要删除的文件模式。

示例:

roller:
  kind: delete
  keep: 3
  pattern: "logs/app.*.log"

2.4 其他Appender类型

log4rs 还支持其他类型的 Appender,例如:

  1. SyslogAppender:将日志发送到系统日志(syslog)。

配置示例:

appenders:
  syslog_appender:
    kind: syslog
    facility: local0
    hostname: localhost
    process: my_app
    encoder:
      pattern: "{d} - {l} - {m}{n}"

2. ElasticsearchAppender:将日志发送到 Elasticsearch。

配置示例:

appenders:
  es_appender:
    kind: elasticsearch
    url: "http://localhost:9200"
    index: "app_logs"
    encoder:
      kind: json

注意:某些特殊的 Appender 可能需要额外的依赖或特性支持,请在使用前查看相应的文档。

三、Encoders(编码器)

Encoders 定义了日志消息的格式,即日志输出时的内容和排版。

3.1 PatternEncoder(模式编码器)

描述:通过指定格式模式字符串,灵活地定义日志输出的格式。

配置项

  • pattern: 格式字符串,包含占位符,用于指定日志的输出格式。

常用占位符

  • {d}:日期时间;可选格式:{d(%Y-%m-%d %H:%M:%S)}
  • {l}:日志级别(如 INFO、ERROR)。
  • {m}:日志消息内容。
  • {M}:触发日志的函数名。
  • {f}:触发日志的文件名。
  • {L}:触发日志的行号。
  • {t}:当前线程名。
  • {T}:制表符。
  • {n}:换行符。
  • {h(m)}:高亮内容(用于控制台输出)。

示例:

encoder:
  pattern: "{d(%Y-%m-%d %H:%M:%S)} [{t}] {l} {M} - {m}{n}"

输出效果示例:

2023-08-30 12:34:56 [main] INFO my_function - This is a log message

解释

  • {d(%Y-%m-%d %H:%M:%S)} :格式化日期时间。
  • [{t}] :线程名,放在方括号内。
  • {l} :日志级别。
  • {M} :函数名。
  • - {m}{n} :日志消息内容,后跟换行符。

3.2 JsonEncoder(JSON编码器)

描述:将日志消息编码为 JSON 格式,便于日志的结构化处理和分析。

配置项

  • kind: 固定为 "json",表示使用 JSON 编码器。
  • fields: 指定要包含的字段和格式。
  • timestamp: 日期时间的格式。

示例

encoder:
  kind: json
  timestamp:
    format: "%Y-%m-%dT%H:%M:%S%.3fZ"
  fields:
    time: "{d}"
    level: "{l}"
    thread: "{t}"
    file: "{f}"
    line: "{L}"
    message: "{m}"

输出效果示例

{
  "time": "2023-08-30T12:34:56.789Z",
  "level": "INFO",
  "thread": "main",
  "file": "src/main.rs",
  "line": 42,
  "message": "This is a log message"
}

解释

  • timestamp.format:指定时间戳的格式。
  • fields:定义 JSON 对象中的字段及其对应的值。
  • 各字段的占位符:与 PatternEncoder 中的占位符一致。

四、Filters(过滤器)

Filters 用于根据特定条件过滤日志消息,控制哪些日志被输出,哪些被忽略。

4.1 ThresholdFilter(阈值过滤器)

描述:根据日志级别过滤日志消息,只有满足指定级别的日志才会被输出。

配置项

  • kind: 固定为 "threshold",表示阈值过滤器。
  • level: 日志级别,只有大于等于此级别的日志才会被输出。

支持的日志级别

  • off
  • error
  • warn
  • info
  • debug
  • trace

示例

filters:
  - kind: threshold
    level: warn

应用到Appender

appenders:
  console_appender:
    kind: console
    encoder:
      pattern: "{d} - {l} - {m}{n}"
    filters:
      - kind: threshold
        level: warn

解释

  • 只有级别为 warnerror 的日志会通过此 Appender 输出。

4.2 其他过滤器类型

log4rs 支持自定义过滤器,或者通过扩展实现更多过滤器。以下是一个示例:

RegexFilter(正则表达式过滤器)

描述:根据日志消息内容匹配正则表达式,决定是否输出日志。

配置项

  • kind: 固定为 "regex"
  • regex: 正则表达式字符串。
  • strategy: 策略,accept_on_matchtrue 时,匹配成功的日志将被输出。

示例

yaml
复制代码
filters:
  - kind: regex
    regex: "ERROR_CODE_[0-9]+"
    strategy: accept_on_match

解释

  • 只有日志消息中包含匹配 "ERROR_CODE_[0-9]+" 正则表达式的日志才会被输出。

注意:要使用自定义过滤器,可能需要在代码中进行额外的注册和实现。

五、Loggers(记录器)

Loggers 用于为特定的模块或路径配置日志行为,允许针对不同的代码部分设置不同的日志级别和输出目标。

配置项

  • <logger_name>: Logger 的名称,通常为模块路径。

    • level: 该 Logger 的日志级别。
    • appenders: 关联的 Appender 列表。
    • additive: 是否继承父级 Logger 的 Appender,默认为 true

示例

yaml
复制代码
loggers:
  app::module_a:
    level: debug
    appenders:
      - file_appender
    additive: false

  app::module_b:
    level: info
    appenders:
      - console_appender

解释

  • app::module_a

    • 日志级别为 debug,日志将输出到 file_appender
    • additive: false 表示不继承父级 Logger 的 Appender,即只输出到指定的 Appender。
  • app::module_b

    • 日志级别为 info,日志将输出到 console_appender
    • 因为未指定 additive,默认为 true,会继承父级 Logger 的 Appender。

层级关系

  • Logger 名称按照模块路径层级划分,例如 app::module::submodule
  • 子模块会继承父模块的配置,除非设置了 additive: false

六、Root Logger(根记录器)

描述Root Logger 是日志系统的默认配置,用于处理未被其他 Logger 捕获的日志消息。

配置项

  • level: 根日志级别。
  • appenders: 关联的 Appender 列表。

示例

root:
  level: warn
  appenders:
    - console_appender

解释

  • 未被其他 Logger 处理的日志,将根据根 Logger 的配置输出。
  • 在此示例中,根 Logger 将输出级别为 warn 及以上的日志到 console_appender

七、完整示例

综合以上配置,给出一个完整的配置文件示例。

refresh_rate: 60 seconds

appenders:
  console_appender:
    kind: console
    target: stdout
    encoder:
      pattern: "{d(%Y-%m-%d %H:%M:%S)} [{l}] {t} - {m}{n}"

  file_appender:
    kind: file
    path: "logs/application.log"
    append: true
    encoder:
      pattern: "{d} - {l} - {M} - {m}{n}"
    filters:
      - kind: threshold
        level: info

  rolling_file_appender:
    kind: rolling_file
    path: "logs/rolling.log"
    encoder:
      pattern: "{d} - {l} - {m}{n}"
    policy:
      trigger:
        kind: size
        limit: 50 mb
      roller:
        kind: fixed_window
        base: 1
        count: 7
        pattern: "logs/rolling.{}.log"
        compress: true

loggers:
  my_app::database:
    level: error
    appenders:
      - file_appender
    additive: false

  my_app::services:
    level: debug
    appenders:
      - console_appender
      - rolling_file_appender

root:
  level: warn
  appenders:
    - console_appender

解释

  • 全局配置:配置文件每隔 60 秒自动刷新。

  • Appenders:

    • console_appender:将日志输出到标准输出,格式包含日期、级别、线程和消息。
    • file_appender:将日志输出到固定文件,过滤级别为 info 及以上。
    • rolling_file_appender:将日志输出到滚动文件,当文件大小达到 50 MB 时滚动,保留最近 7 个日志文件并压缩。
  • Loggers:

    • my_app::database:仅输出 error 级别的日志到 file_appender,不继承根 Logger 的配置。
    • my_app::services:输出 debug 及以上级别的日志到 console_appenderrolling_file_appender,同时继承根 Logger 的配置。
  • Root Logger:默认输出 warn 及以上级别的日志到 console_appender

八、动态配置和刷新

描述:通过设置 refresh_ratelog4rs 可以在运行时动态刷新配置,实现日志配置的热更新。

配置方法

refresh_rate: 30 seconds

工作原理

  • log4rs 会在指定的时间间隔检查配置文件的修改时间。
  • 如果检测到配置文件发生变化,将自动重新加载配置,无需重启应用程序。
  • 这对于需要在运行时调整日志级别、输出目标等场景非常有用。

注意事项

  • 确保配置文件的路径正确且可访问。
  • 配置文件的修改应保持格式正确,避免因配置错误导致日志系统异常。

九、总结

log4rs 提供了强大且灵活的日志配置能力,支持多种输出目标、格式和过滤策略。通过合理配置 appendersencodersfiltersloggers,可以满足各种复杂的日志需求。同时,动态刷新功能使得在运行时调整日志配置变得简单高效。

关键点回顾

  • 全局配置:控制配置文件刷新等全局行为。
  • Appenders:定义日志输出目标,如控制台、文件、滚动文件等。
  • Encoders:定义日志消息的格式,支持自定义模式和 JSON 等结构化格式。
  • Filters:根据条件过滤日志消息,控制日志的输出。
  • Loggers:针对不同的模块或路径配置日志行为,支持灵活的层级继承。
  • Root Logger:定义默认的日志行为,处理未被其他 Logger 捕获的日志。

通过以上配置项的组合和调整,log4rs 能够适应从简单到复杂的各种日志需求,为 Rust 应用程序提供可靠和高效的日志支持。