2 releases
0.1.1 | Dec 4, 2023 |
---|---|
0.1.0 | Oct 10, 2023 |
#882 in Debugging
123 downloads per month
30KB
508 lines
tracing-record-hierarchical
Record parent tracing::Span
fields from inside child tracing::Span
's context.
Motivation
Dealing with the complex relationship in the hierarchy of nested Span
s in tracing
may become quite cumbersome. When faced with the need to record a new value for a field of a Span
higher in the tree, users have no choice but to refactor their code in some way to allow that. This includes:
-
Extracting a
Span::record
out of the childSpan
:fn called_from_withing_a_span() { let id = 42; tracing::Span::current().record("id", id); tracing::info_span!("child").in_scope(|| { // ... }) }
Which doesn't work when:
-
Bringing the parent
Span
to the child: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); }
We had to construct a
parent
Span
using*_span!
macro and pass it to the child.
Those workarounds are not ergonomic. Furthermore, in some cases cannot be used at all.
Overview
This crate adds a HierarchicalRecord
Layer
and a SpanExt
trait with the record_hierarchical()
method that can be used as a drop-in replacement for a Span::record
.
Usage
Add the HierarchicalRecord
Layer
to your subscriber:
# use tracing_subscriber::prelude::*;
use tracing_record_hierarchical::HierarchicalRecord;
fn init_tracing() {
tracing_subscriber::registry()
.with(HierarchicalRecord::default())
.init();
}
Whenever you're to use a Span::record
to record a value to a parent Span
's field, call the record_hierarchical()
method instead, or a panicking must_record_hierarchical()
version instead:
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();
# }
License
Copyright © 2023 Instrumentisto Team, https://github.com/instrumentisto
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Dependencies
~1.2–1.8MB
~33K SLoC