rust 如何将跟踪订阅服务器的集合合并为一个集合?

mrwjdhj3  于 2023-05-07  发布在  其他
关注(0)|答案(1)|浏览(127)

假设我有一个返回Vec<Box<dyn Subscriber>>的函数,我想将它们组合成一个单独的函数,并将其设置为默认订阅者。如何做到这一点?
我尝试做类似的事情,但我无法使类型匹配:

pub fn init_log(subscribers: Vec<Box<dyn Subscriber>>) -> Result<(), Error> {
    use tracing_subscriber::prelude::*;
    let mut layers: Vec<Box<dyn Layer<dyn Subscriber>>> = Vec::new();

    for subscriber in subscribers.iter().drain(..) {
        let layer: Box<dyn Layer<dyn Subscriber>> =
          Box::new(tracing_subscriber::layer::Identity::new().with_subscriber(subscriber));

        layers.push(layer);
    }

    let init_layer: Box<dyn Layer<dyn Subscriber>> =
        Box::new(tracing_subscriber::layer::Identity::new());

    let acc_subscriber: Layered<Box<dyn Layer<dyn Subscriber>>, _> =
        tracing_subscriber::fmt().finish().with(init_layer);
    
    let composed = layers
        .drain(..)
        .into_iter()
        .fold(acc_subscriber, |acc, layer| acc.with(layer));
    
    tracing::subscriber::set_global_default(composed);

    Ok(())
}
error[E0277]: the trait bound `Box<dyn tracing::Subscriber>: tracing::Subscriber` is not satisfied
  --> jormungandr\src\settings\logging.rs:97:85
   |
97 |                 Box::new(tracing_subscriber::layer::Identity::new().with_subscriber(subscriber));
   |                                                                                     ^^^^^^^^^^ the trait `tracing::Subscriber` is not implemented for `Box<dyn tracing::Subscriber>`
7eumitmz

7eumitmz1#

我认为这与Subscriber处理的任务根本不一致。我认为Layer s的module documentation清楚地说明了这一点:
tracing-core中的Subscriber trait表示使用tracing插装所需的完整功能集。这意味着单个Subscriber示例是完整的跟踪收集策略的自包含实现;但是这也意味着Subscriber特征不能容易地与其他Subscriber组合。
特别是,Subscriber s负责生成跨度ID并将其分配给跨度。由于这些ID必须在当前跟踪的上下文中唯一标识一个span,这意味着在任何时间点,给定线程可能只有一个Subscriber,否则,将没有span ID的权威来源。
另一方面,Subscriber trait的大部分功能都是可组合的:只要存在单个授权的跨度ID源,任何数量的订户都可以观察事件、跨度进入和退出等。Layer特征表示Subscriber行为的可组合子集;它可以观察事件和跨度,但不分配ID。
因此,如果可能的话,请尝试将日志配置一般化为Layer s,而不是Subscriber s。甚至已经有了impl Layer for Vec<L> where L: Layer的实现。
我认为这种可表达性和可组合性是大多数Related Crates被实现为Layer s而不是Subscriber s的原因。甚至一些被列为“实现订阅者”的应用程序也使用了层(如tracing-gelf或tracing-forest)。

相关问题