Skip to content

Commit 83895f9

Browse files
committed
feat: Span::record() to allow recording a value after the span was created.
1 parent bd6e3d7 commit 83895f9

File tree

4 files changed

+42
-8
lines changed

4 files changed

+42
-8
lines changed

gix-trace/src/disabled.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
#[derive(Clone)]
44
pub struct Span;
55

6+
impl Span {
7+
/// A no-op
8+
pub fn record<V>(&self, _field: &str, _value: V) -> &Self {
9+
self
10+
}
11+
}
12+
613
/// A macro to create a span.
714
#[macro_export]
815
macro_rules! span {

gix-trace/src/enabled.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
use tracing_core::{dispatcher::get_default as with_dispatcher, span::Id, Dispatch};
1+
use tracing_core::{dispatcher::get_default as with_dispatcher, span, span::Id, Dispatch};
22

33
// these are used later in macros.
44
pub use tracing_core::{field, metadata, Metadata};
55

66
/// An entered span which will exit on drop.
77
#[derive(Clone)]
88
pub struct Span {
9-
id: Option<(Id, Dispatch)>,
9+
id: Option<(Id, Dispatch, &'static Metadata<'static>)>,
1010
}
1111

1212
impl Span {
13-
#[allow(missing_docs)]
13+
/// Create a new span.
14+
///
15+
/// This constructor is typically invoked by the [`crate::span!`] macro.
1416
pub fn new(
1517
level: crate::Level,
1618
meta: &'static Metadata<'static>,
@@ -23,16 +25,40 @@ impl Span {
2325
let id = dispatch.new_span(&tracing_core::span::Attributes::new(meta, values));
2426
dispatch.enter(&id);
2527
Self {
26-
id: Some((id, dispatch.clone())),
28+
id: Some((id, dispatch.clone(), meta)),
2729
}
2830
})
2931
}
3032
}
33+
34+
/// Record a single `field` to take `value`.
35+
///
36+
/// Note that this silently fails if the field name wasn't mentioned when the span was created.
37+
pub fn record<V>(&self, field: &str, value: V) -> &Self
38+
where
39+
V: field::Value,
40+
{
41+
if let Some((_, _, meta)) = &self.id {
42+
let fields = meta.fields();
43+
if let Some(field) = fields.field(field) {
44+
self.record_all(&fields.value_set(&[(&field, Some(&value as &dyn field::Value))]));
45+
}
46+
}
47+
self
48+
}
49+
50+
fn record_all(&self, values: &field::ValueSet<'_>) -> &Self {
51+
if let Some((id, dispatch, _)) = &self.id {
52+
let record = span::Record::new(values);
53+
dispatch.record(id, &record);
54+
}
55+
self
56+
}
3157
}
3258

3359
impl Drop for Span {
3460
fn drop(&mut self) {
35-
if let Some((id, dispatch)) = self.id.take() {
61+
if let Some((id, dispatch, _meta)) = self.id.take() {
3662
dispatch.exit(&id);
3763
dispatch.try_close(id);
3864
}

gix-trace/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub const MAX_LEVEL: Level = Level::Coarse;
3535
mod enabled;
3636

3737
#[cfg(feature = "tracing")]
38-
pub use enabled::Span;
38+
pub use enabled::{field, Span};
3939

4040
impl Span {
4141
/// Execute `f` in with this span active, consuming it.
@@ -46,7 +46,7 @@ impl Span {
4646

4747
#[cfg(feature = "tracing")]
4848
#[doc(hidden)]
49-
pub use enabled::{field, metadata, MetaOnlyCallsite, Metadata};
49+
pub use enabled::{metadata, MetaOnlyCallsite, Metadata};
5050

5151
#[cfg(not(feature = "tracing"))]
5252
mod disabled;

gix-trace/tests/trace.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ fn span() {
44
let _x = span!(gix_trace::Level::Coarse, "hello");
55
let fourty_two = span!(gix_trace::Level::Coarse, "hello", x = "value", y = 42).into_scope(|| 42);
66
assert_eq!(fourty_two, 42);
7-
span!(target: "other", gix_trace::Level::Coarse, "hello", x = "value", y = 42);
7+
let span = span!(target: "other", gix_trace::Level::Coarse, "hello", x = "value", y = 42);
8+
span.record("y", "hello").record("x", 36);
89
}
910

1011
#[test]

0 commit comments

Comments
 (0)