#spans #tracing #tracing-subscriber #record #parent #subscriber

tracing-record-hierarchical

从子 tracing::Span 的上下文中记录父 tracing::Span 字段

2个版本

0.1.1 2023年12月4日
0.1.0 2023年10月10日

#386性能分析

Download history 82/week @ 2024-03-13 56/week @ 2024-03-20 61/week @ 2024-03-27 145/week @ 2024-04-03 88/week @ 2024-04-10 94/week @ 2024-04-17 43/week @ 2024-04-24 33/week @ 2024-05-01 63/week @ 2024-05-08 133/week @ 2024-05-15 142/week @ 2024-05-22 28/week @ 2024-05-29 49/week @ 2024-06-05 73/week @ 2024-06-12 72/week @ 2024-06-19 40/week @ 2024-06-26

每月245次 下载

MIT/Apache

30KB
508

tracing-record-hierarchical

crates.io Rust 1.70+ Unsafe Forbidden CI Rust docs

API文档 | 变更日志

从子 tracing::Span 的上下文中记录父 tracing::Span 字段。

动机

处理 Spantracing 的嵌套层次结构中的复杂关系可能会变得相当繁琐。当需要为树中较高层的 Span 字段记录新值时,用户别无选择,只能以某种方式重构他们的代码以允许这样做。这包括

  1. 从子 Span::record 中提取

    fn called_from_withing_a_span() {
        let id = 42;
        tracing::Span::current().record("id", id);
    
        tracing::info_span!("child").in_scope(|| {
            // ...
        })
    }
    

    • 它们之间有另一个 "层" 的 Span 时;
    • 需要记录的值在函数中计算(你可能仍然可以通过从 in_scope 闭包中返回来解决这个问题);
    • 父级 Span 位于另一个你无法控制的crate中。
  2. 将父级 Span 带到子级

    fn parent() {
        let parent_span = tracing::info_span!(
             "parent",
             id = tracing::field::Empty,
        );
        let _entered = parent_span.enter();
        child(parent_span.clone());
    }
    
    #[tracing::instrument(skip_all)]
    fn child(parent_span: tracing::Span) {
        let id = 42;
        parent_span.record("id", id);
    }
    

    我们必须使用 *_span! 宏构建一个 parent Span,并将其传递给子级。

这些解决方案不够便捷。此外,在某些情况下根本无法使用。

概述

该crate添加了一个 HierarchicalRecord Layer 和一个 SpanExt trait,其中包含一个 record_hierarchical() 方法,可以作为 Span::record 方法的直接替换。

用法

HierarchicalRecord Layer 添加到你的 subscriber

# use tracing_subscriber::prelude::*;
use tracing_record_hierarchical::HierarchicalRecord;

fn init_tracing() {
    tracing_subscriber::registry()
        .with(HierarchicalRecord::default())
        .init();
}

无论何时您需要使用 Span::record 将值记录到父级 Span 的字段中,请调用 record_hierarchical() 方法,或者调用一个抛出异常的 must_record_hierarchical() 版本。

use tracing_record_hierarchical::SpanExt as _;

#[tracing::instrument(fields(foo = tracing::field::Empty))]
fn foo() {
    bar();
}

#[tracing::instrument]
fn bar() {
    tracing::Span::current()
        // This walks up the hierarchy of `Span`s from the `span` the method 
        // was called on (`current()` in this example) to the "root" `Span`. 
        // If some `Span` in the hierarchy has the `foo` field, the provided 
        // value will be recorded there. If none of the `Span`s in the 
        // hierarchy has this field, a panic will occur.
        .must_record_hierarchical("foo", 42);
}
#
# fn main() {
#     use tracing_subscriber::prelude::*;
#     use tracing_record_hierarchical::HierarchicalRecord;
# 
#     tracing_subscriber::registry().with(HierarchicalRecord::default()).init();
# 
#     foo();
# }

许可证

版权所有 © 2023 Instrumentisto 团队,https://github.com/instrumentisto

根据您的选择,受Apache License, Version 2.0MIT license 许可证。

除非您明确声明,否则任何旨在包含在此crate中并由您提交的贡献,根据Apache-2.0 license 定义,都应如上所述双重许可,不附加任何其他条款或条件。

依赖项

~1.4–2MB
~38K SLoC