如何将一组跟踪订阅者合并为一个?

Net*_*ave 6 rust rust-tracing

假设我有一个返回 a 的函数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(())
}
Run Code Online (Sandbox Code Playgroud)
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>`
Run Code Online (Sandbox Code Playgroud)

kmd*_*eko 4

我认为这从根本上与 aSubscriber的处理任务不一致。我认为s的模块文档Layer说得很清楚:

\n
\n

Subscriber中的特征代表tracing-core使用仪器所需的完整功能集tracing。这意味着单个Subscriber实例是收集跟踪的完整策略的独立实现;但这也意味着该Subscriber特质不能轻易地与其他特质组合Subscriber

\n

特别是,Subscribers 负责生成span ID 并将其分配给span。由于这些 ID 必须在当前跟踪的上下文中唯一标识一个跨度,这意味着在任何时间点 \xe2\x80\x94 对于给定线程可能只有一个跨度,Subscriber否则,将没有跨度的权威来源身份证。

\n

另一方面,大多数SubscriberTrait\xe2\x80\x99s 功能是可组合的:任意数量的订阅者都可以观察事件、跨度进入和退出等,前提是跨度 ID 具有单一的权威来源。该Layer特质代表了该Subscriber行为的可组合子集;它可以观察事件和跨度,但不分配 ID。

\n
\n

因此,如果可能的话,尝试将您的日志配置推广到Layers 而不是Subscribers。甚至已经有了一个impl Layer for Vec<L> where L: Layer实现。

\n

我认为这种可表达性和可组合性是大多数相关箱子被实现为Layers 而不是s的原因Subscriber。甚至其中一些被列为“实现订阅者”的也使用层(例如tracing-gelf或tracing-forest)。

\n