日志配置

启用每个模块的日志级别

log-badge env_logger-badge cat-debugging-badge

创建两个模块:foo 和其嵌套的 foo::bar,日志记录指令分别由 RUST_LOG 环境变量控制。


mod foo {
    mod bar {
        pub fn run() {
            log::warn!("[bar] warn");
            log::info!("[bar] info");
            log::debug!("[bar] debug");
        }
    }

    pub fn run() {
        log::warn!("[foo] warn");
        log::info!("[foo] info");
        log::debug!("[foo] debug");
        bar::run();
    }
}

fn main() {
    env_logger::init();
    log::warn!("[root] warn");
    log::info!("[root] info");
    log::debug!("[root] debug");
    foo::run();
}

RUST_LOG 环境变量控制 env_logger 的输出。模块声明采用逗号分隔各项,格式类似于 path::to::module=log_level。按如下方式运行 test 应用程序:

RUST_LOG="warn,test::foo=info,test::foo::bar=debug" ./test

将日志等级 log::Level 的默认值设置为 warn,将模块 foo 和其嵌套的模块 foo::bar 的日志等级设置为 infodebug

WARN:test: [root] warn
WARN:test::foo: [foo] warn
INFO:test::foo: [foo] info
WARN:test::foo::bar: [bar] warn
INFO:test::foo::bar: [bar] info
DEBUG:test::foo::bar: [bar] debug

用自定义环境变量设置日志记录

log-badge env_logger-badge cat-debugging-badge

Builder 配置日志记录。

Builder::parseRUST_LOG 语法的形式解析 MY_APP_LOG 环境变量的内容。然后,Builder::init 初始化记录器。所有这些步骤通常由 env_logger::init 在内部完成。


use std::env;
use env_logger::Builder;

fn main() {
    Builder::new()
        .parse(&env::var("MY_APP_LOG").unwrap_or_default())
        .init();

    log::info!("informational message");
    log::warn!("warning message");
    log::error!("this is an error {}", "message");
}

在日志信息中包含时间戳

log-badge env_logger-badge chrono-badge cat-debugging-badge

使用 Builder 创建自定义记录器配置。每个日志项调用 Local::now 以获取本地时区中的当前 DateTime,并使用 DateTime::formatstrftime::specifiers 来格式化最终日志中使用的时间戳。

如下实例调用 Builder::format 设置一个闭包,该闭包用时间戳、Record::level 和正文(Record::args)对每个信息文本进行格式化。

use std::io::Write;
use chrono::Local;
use env_logger::Builder;
use log::LevelFilter;

fn main() {
    Builder::new()
        .format(|buf, record| {
            writeln!(buf,
                "{} [{}] - {}",
                Local::now().format("%Y-%m-%dT%H:%M:%S"),
                record.level(),
                record.args()
            )
        })
        .filter(None, LevelFilter::Info)
        .init();

    log::warn!("warn");
    log::info!("info");
    log::debug!("debug");
}

stderr 输入将含有:

2017-05-22T21:57:06 [WARN] - warn
2017-05-22T21:57:06 [INFO] - info

将信息记录到自定义位置

log-badge log4rs-badge cat-debugging-badge

log4rs 将日志输出配置到自定义位置。log4rs 可以使用外部 YAML 文件或生成器配置。

使用文件附加器 log4rs::append::file::FileAppender 创建日志配置,文件附加器定义日志记录的目标位置。日志配置使用 log4rs::encode::pattern 中的自定义模式进行编码,将配置项分配给 log4rs::config::Config,并设置默认的日志等级 log::LevelFilter

use error_chain::error_chain;

use log::LevelFilter;
use log4rs::append::file::FileAppender;
use log4rs::encode::pattern::PatternEncoder;
use log4rs::config::{Appender, Config, Root};

error_chain! {
    foreign_links {
        Io(std::io::Error);
        LogConfig(log4rs::config::Errors);
        SetLogger(log::SetLoggerError);
    }
}

fn main() -> Result<()> {
    let logfile = FileAppender::builder()
        .encoder(Box::new(PatternEncoder::new("{l} - {m}\n")))
        .build("log/output.log")?;

    let config = Config::builder()
        .appender(Appender::builder().build("logfile", Box::new(logfile)))
        .build(Root::builder()
                   .appender("logfile")
                   .build(LevelFilter::Info))?;

    log4rs::init_config(config)?;

    log::info!("Hello, world!");

    Ok(())
}