rust 如何有条件地使用跟踪编写器non_blocking而不是stdout?

wtzytmuj  于 2023-01-02  发布在  其他
关注(0)|答案(1)|浏览(136)

我使用下面的代码来初始化我的跟踪。
我只想在某些情况下使用non_blocking编写器,否则我只需要使用stdout编写器。
如何避免以下错误?

use tracing_appender::non_blocking;
use tracing_log::LogTracer;
use tracing_subscriber::{fmt::Layer, prelude::*, EnvFilter, Registry};

pub fn init(tracing: &Tracing) -> non_blocking::WorkerGuard {
    LogTracer::init().expect("init LogTracer");

    let (non_blocking, non_blocking_guard) = non_blocking(std::io::stdout());

    let base_layer;

    if tracing.blocking {
        base_layer = Layer::default().with_writer(std::io::stdout);
    } else {
        base_layer = Layer::default().with_writer(non_blocking);
    }

    let mut layers = Vec::new();

    layers.push(if tracing.pretty {
        base_layer.pretty().with_file(false).boxed()
    } else {
        base_layer.json().boxed()
    });

    let registry = Registry::default()
        .with(EnvFilter::from(&tracing.level))
        .with(layers);

    tracing::subscriber::set_global_default(registry).unwrap();

    non_blocking_guard
}

错误:

error[E0308]: mismatched types
    |
18  |         base_layer = Layer::default().with_writer(non_blocking);
    |                                       ----------- ^^^^^^^^^^^^ expected fn item, found struct `tracing_appender::non_blocking::NonBlocking`
    |                                       |
    |                                       arguments to this function are incorrect
    |
    = note: expected fn item `fn() -> std::io::Stdout {std::io::stdout}`
                found struct `tracing_appender::non_blocking::NonBlocking`
note: associated function defined here
    |
177 |     pub fn with_writer<W2>(self, make_writer: W2) -> Layer<S, N, E, W2>
    |            ^^^^^^^^^^^
o8x7eapl

o8x7eapl1#

你可以使用BoxMakeWriter来删除writer的具体类型,以便以后统一它们。

use tracing_subscriber::fmt::writer::BoxMakeWriter;

let writer = if tracing.blocking {
    BoxMakeWriter::new(std::io::stdout)
} else {
    BoxMakeWriter::new(non_blocking)
};

let layer = if tracing.pretty {
    Layer::default()
        .with_writer(writer)
        .pretty()
        .with_file(false)
        .boxed()
} else {
    Layer::default()
        .with_writer(writer)
        .json()
        .boxed()
};

let registry = Registry::default()
    .with(EnvFilter::from(&tracing.level))
    .with(layer);

注意:你不需要创建一个层的矢量;可以直接使用.boxed()的结果。

相关问题