0%

【Rust】Rust配置日志记录

利用 logenv_logger来配置日志。

简介

Crate log

功能说明

log 提供了一个单独的日志记录 API,给出了日志库的一般抽象,后面具体的日志库需要基于这个抽象实现具体的实例。

日志请求由目标,级别和内容组成。目标是一个字符串,其默认为日志请求的位置的模块路径,尽管可能会覆盖默认值。记录器实现通常使用目标基于某些用户配置来过滤日志请求。

记录器实现

为了生成日志输出,必须使用与 log 兼容的日志记录器实现。有许多可用的实现可供选择,这里有一些常用的: - 精简版记录器: - env_logger - simple_logger - simplelog - pretty_env_logger - stderrlog - flexi_logger - 复杂且可配置的框架: - log4rs - fern - 专用适配: - syslog - slog-stdlog - systemd-journal-logger - android_log - win_dbg_logger - WebAssembly可用: - console_log - 动态库: - 构建在log之上的 FFI-safe wrapper 来初始化库。

日志分级

log的最基本的用法是通过5个宏来实现的。 定义如下:

1
2
3
4
5
6
7
8
#[repr(usize)]
pub enum Level {
Error,
Warn,
Info,
Debug,
Trace,
}
优先级error! > warn! > info! > debug! > trace!error!的优先级最高,trace!优先级最低。

Crate env_logger

env_logger 通过配置环境变量来实现日志记录器的功能。

应用示例

  1. 打印不同级别日志
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #[cfg(test)]
    mod logtests {
    #[test]
    fn test_log_default(){
    use log::{debug, error, warn, info};

    env_logger::init();

    debug!("debug message");
    info!("informational message");
    warn!("warning message");
    error!("error message");
    }
    }
    运行cargo test -- test_log_default进行测试,结果如下: 为什么无法看到 error 以下级别的日志呢? 从 env_logger 的源代码中有以下说明: >Log levels are controlled on a per-module basis, and by default all logging is disabled except for the error level.1

基于env_logger的工作模式,需要对 环境变量 RUST_LOG 进行预定义,对以上代码使用以下方式测试。 先设置环境变量 RUST_LOG ,然后运行测试,

1
2
$ set RUST_LOG=trace
$ cargo test -- test_log_default
结果如下:

  1. 采用本地时间作为时间戳 这时需要创建日志生成器 builder 中的 format 方法来完成输出格式的配置。

    1
    2


    运行set RUST_LOG=trace && cargo test -- test_log_localtime2 结果如下: 可以看出, 时间戳已经更改为本地时间,但是整个日志格式比较简陋。

  2. 输出格式美化 依照默认输出时的格式,在时间戳、级别、目标前后加入方括号。方括号表现为较高亮度,级别用不同颜色区别。

  • 对级别及方括号分别创建样式 Style
  • Style 中的 set_intense 方法用来设置高亮度
  • Style 中的 set_color 方法用来设置颜色,参数为 enum 类型
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #[non_exhaustive]
    pub enum Color {
    Black,
    Blue,
    Green,
    Red,
    Cyan,
    Magenta,
    Yellow,
    White,
    Ansi256(u8),
    Rgb(u8, u8, u8),
    }
  • Style 中的 set_bold 方法用来设置字体粗细
  • Style 中的 value 方法用来封装需要格式化的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#[test]
fn test_log_beautify(){
use log::{debug, error, warn, info, trace};
use env_logger::Builder;
use env_logger::fmt::Color;
use chrono::Local;
use std::io::Write;
use log::Level;

// 创建env_logger生成器, 也可直接写成env_logger::builder()
let mut builder = Builder::from_default_env();

builder
.format(|buf, record| {
let mut level_style = buf.style();
let mut brace_style = buf.style();
level_style.set_intense(true);
match record.level() {
Level::Trace => level_style.set_color(Color::Cyan).set_bold(true),
Level::Debug => level_style.set_color(Color::Blue).set_bold(true),
Level::Info => level_style.set_color(Color::Green).set_bold(true),
Level::Warn => level_style.set_color(Color::Yellow).set_bold(true),
Level::Error => level_style.set_color(Color::Red).set_bold(true),
};
brace_style.set_color(Color::Black).set_intense(true);
writeln!(buf, "{}{} {} {}{} {}",
brace_style.value("["),
Local::now().format("%Y-%m-%d %H:%M:%S%.3f"),
level_style.value(record.level()),
record.target(),
brace_style.value("]"),
record.args())
})
.init();

trace!("trace message");
debug!("debug message");
info!("informational message");
warn!("warning message");
error!("error message");
}

运行set RUST_LOG=trace && cargo test -- test_log_beautify 结果如下:

参考

  1. log 文档
  2. env_logger 文档

注释


  1. lib.rs - source (docs.rs), 第92行。↩︎

  2. 该命令可以在 cmd 下同时执行多条命令, 命令格式:command1 && command2 ,command1执行成后后才能执行command2。↩︎