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

时间:2017-11-17 01:44:24

标签: 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");
}

1 个答案:

答案 0 :(得分:6)

使用slog-async,you have opted into

  

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

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

然而,通过在程序结束时进行睡眠,它可以正常运行":

std::thread::sleep_ms(1000);

为什么其他案例有效?我们再次turn to the docs,强调我的:

  

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

lazy-static do not have their destructors run中的项目(他们什么时候才能永远活着)。

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