如果我取消注释create_log
,则log
和LOG
都会打印在控制台上。没有它,什么也没有打印出来。发生了什么事?
#[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");
}
答案 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
终止带有退出代码的进程时,注意不会调用析构函数是很重要的。这对于slog_async很重要,因为它会防止刷新异步消耗并丢弃尚未写入的消息。
lazy-static do not have their destructors run中的项目(他们什么时候才能永远活着)。
当您从main
函数构造另一个记录器时,它将在堆栈上分配并将被删除。这会导致以前的日志消息也被刷新。