mirror of
https://github.com/tokio-rs/tracing.git
synced 2025-09-28 13:31:52 +00:00
tracing: add record_all!
macro for recording multiple values in one call (#3227)
## Motivation Currently, Span.record_all() is part of the public API and accepts ValueSet as a parameter. However, constructing a ValueSet is both verbose and undocumented, making it not so practical. ## Solution To make recording multiple values easier, we introduce a new macro: record_all!, which wraps the Span.record_all() function. As we don't intend anyone to call Span.record_all() directly, we hide it from the documentation. We reference the new macro from Span.record() doc comment instead. The new record_all! macro supports optional formatting sigils % and ?, ensuring a consistent DevEx with the other value-recording macros. Co-authored-by: Hayden Stainsby <hds@caffeineconcepts.com>
This commit is contained in:
parent
37caa910ac
commit
0a5dc8e950
@ -130,6 +130,36 @@ macro_rules! span {
|
||||
};
|
||||
}
|
||||
|
||||
/// Records multiple values on a span in a single call. As with recording
|
||||
/// individual values, all fields must be declared when the span is created.
|
||||
///
|
||||
/// This macro supports two optional sigils:
|
||||
/// - `%` uses the Display implementation.
|
||||
/// - `?` uses the Debug implementation.
|
||||
///
|
||||
/// For more details, see the [top-level documentation][lib].
|
||||
///
|
||||
/// [lib]: tracing/#recording-fields
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use tracing::{field, info_span, record_all};
|
||||
/// let span = info_span!("my span", field1 = field::Empty, field2 = field::Empty, field3 = field::Empty).entered();
|
||||
/// record_all!(span, field1 = ?"1", field2 = %"2", field3 = 3);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! record_all {
|
||||
($span:expr, $($fields:tt)*) => {
|
||||
if let Some(meta) = $span.metadata() {
|
||||
$span.record_all(&$crate::valueset!(
|
||||
meta.fields(),
|
||||
$($fields)*
|
||||
));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Constructs a span at the trace level.
|
||||
///
|
||||
/// [Fields] and [attributes] are set using the same syntax as the [`span!`]
|
||||
|
@ -1182,6 +1182,11 @@ impl Span {
|
||||
/// span.record("parting", "you will be remembered");
|
||||
/// ```
|
||||
///
|
||||
/// <div class="example-wrap" style="display:inline-block">
|
||||
/// <pre class="ignore" style="white-space:normal;font:inherit;">
|
||||
/// **Note**: To record several values in just one call, see the [`record_all!`](crate::record_all!) macro.
|
||||
/// </pre></div>
|
||||
///
|
||||
/// [`field::Empty`]: super::field::Empty
|
||||
/// [`Metadata`]: super::Metadata
|
||||
pub fn record<Q: field::AsField + ?Sized, V: field::Value>(
|
||||
@ -1203,6 +1208,7 @@ impl Span {
|
||||
}
|
||||
|
||||
/// Records all the fields in the provided `ValueSet`.
|
||||
#[doc(hidden)]
|
||||
pub fn record_all(&self, values: &field::ValueSet<'_>) -> &Self {
|
||||
let record = Record::new(values);
|
||||
if let Some(ref inner) = self.inner {
|
||||
|
@ -7,7 +7,8 @@ use std::thread;
|
||||
|
||||
use tracing::{
|
||||
error_span,
|
||||
field::{debug, display},
|
||||
field::{debug, display, Empty},
|
||||
record_all,
|
||||
subscriber::with_default,
|
||||
Level, Span,
|
||||
};
|
||||
@ -612,6 +613,50 @@ fn record_new_values_for_fields() {
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
/// Tests record_all! macro, which is a wrapper for Span.record_all().
|
||||
/// Placed here instead of tests/macros.rs, because it uses tracing_mock, which
|
||||
/// requires std lib. Other macro tests exclude std lib to verify the macros do
|
||||
/// not dependend on it.
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn record_all_macro_records_new_values_for_fields() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span()
|
||||
.named("foo")
|
||||
.with_fields(expect::field("bar")),
|
||||
)
|
||||
.record(
|
||||
expect::span().named("foo"),
|
||||
expect::field("bar")
|
||||
.with_value(&5)
|
||||
.and(expect::field("baz").with_value(&"BAZ"))
|
||||
.and(expect::field("qux").with_value(&display("qux")))
|
||||
.and(expect::field("quux").with_value(&debug("QuuX")))
|
||||
.only(),
|
||||
)
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let span = tracing::span!(
|
||||
Level::TRACE,
|
||||
"foo",
|
||||
bar = 1,
|
||||
baz = 2,
|
||||
qux = Empty,
|
||||
quux = Empty
|
||||
);
|
||||
record_all!(span, bar = 5, baz = "BAZ", qux = %"qux", quux = ?"QuuX");
|
||||
span.in_scope(|| {})
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn new_span_with_target_and_log_level() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user