为什么在使用非静态记录器之前不会打印lazy_static slog :: Logger?

mag*_*esh 3 rust

如果我取消create_log,都logLOG打印在控制台上.没有它,什么也没有打印出来.到底是怎么回事?

#[macro_use]
extern crate slog;
extern crate slog_term;
extern crate slog_async;
#[macro_use]
extern crate lazy_static;

use slog::Drain;

lazy_static! {
    static ref LOG: slog::Logger = create_log();
}

fn create_log() -> slog::Logger {
    let decorator = slog_term::TermDecorator::new().force_plain().build();
    let drain = slog_term::CompactFormat::new(decorator).build().fuse();
    let drain = slog_async::Async::new(drain).build().fuse();
    slog::Logger::root(drain, o!())
}

fn main() {
    info!(LOG, "LOG");  // NOT printed unless next line is uncommented

    // let log = create_log();     // enables printing both log and LOG
    // info!(log, "log");
}
Run Code Online (Sandbox Code Playgroud)

She*_*ter 6

通过使用slog-async,您选择了:

slog-async允许构建Drains卸载处理到另一个线程.通常,序列化和IO操作可能足够慢,以至于它们可能使日志记录妨碍主代码的性能.将记录记录发送到另一个线程要快得多(球场为100ns).

您的代码注册了一个日志事件,该事件将被发送到另一个线程,然后立即退出.后台线程没有任何时间实际登录.

但是,通过在程序结束时进行睡眠,它"有效":

std::thread::sleep_ms(1000);
Run Code Online (Sandbox Code Playgroud)

为什么其他案例有效?我们再次转向文档,强调我的:

当使用std::process::exit退出代码终止进程时,注意不会调用析构函数是很重要的.这对slog_async很重要,因为它可以防止刷新异步消耗并丢弃尚未写入的消息.

lazy-static中的项目没有运行析构函数(如果它们是永远存在的话,它们什么时候会运行).

当您从main函数构造另一个记录器时,它将在堆栈上分配并将被删除.这会导致以前的日志消息也被刷新.