mirror of
https://github.com/tokio-rs/tracing.git
synced 2025-09-30 06:20:38 +00:00
tracing: add support literals for field names (#790)
## Motivation Some opentracing systems use fields with : in the names, which are not legal rust identifiers. We could special case :, but then we have complicated double-nested patterns (repeated idents separated by : and a nested repeat separated by .), and this may by a case of always being one-step-behind as more cases turn up; so this patch instead just gets in front and lets users put in whatever they want: as they are not rust identifiers, they miss out on some niceness. ## Solution This permits : in field names but also potentially anything stringifiable, which may be overly liberal. Signed-off-by: Robert Collins <robert.collins@cognite.com>
This commit is contained in:
parent
8195a32718
commit
32cf418c3b
@ -133,7 +133,7 @@ use tracing::{debug, error, info, span, warn, Level};
|
||||
|
||||
// the `#[tracing::instrument]` attribute creates and enters a span
|
||||
// every time the instrumented function is called. The span is named after the
|
||||
// the function or method. Paramaters passed to the function are recorded as fields.
|
||||
// the function or method. Parameters passed to the function are recorded as fields.
|
||||
#[tracing::instrument]
|
||||
pub fn shave(yak: usize) -> Result<(), Box<dyn Error + 'static>> {
|
||||
// this creates an event at the DEBUG level with two fields:
|
||||
|
@ -10,6 +10,8 @@ This directory contains a collection of examples that demonstrate the use of the
|
||||
`slog-term`'s `Compact` formatter.
|
||||
- **tracing-attributes**:
|
||||
+ `attrs-basic`: A simple example of the `#[instrument]` attribute.
|
||||
+ `attrs-literal-field-names`: Demonstrates using literal field names rather
|
||||
than rust tokens..
|
||||
+ `attrs-args`: An example implementing a simple recursive calculation of
|
||||
Fibonacci numbers, to demonstrate how the `#[instrument]` attribute can
|
||||
record function arguments.
|
||||
|
22
examples/examples/attrs-literal-field-names.rs
Normal file
22
examples/examples/attrs-literal-field-names.rs
Normal file
@ -0,0 +1,22 @@
|
||||
#![deny(rust_2018_idioms)]
|
||||
|
||||
use tracing::{debug, span, Level};
|
||||
use tracing_attributes::instrument;
|
||||
|
||||
#[instrument]
|
||||
#[inline]
|
||||
fn suggest_band() -> String {
|
||||
debug!("Suggesting a band.");
|
||||
String::from("Wild Pink")
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let subscriber = tracing_subscriber::fmt()
|
||||
.with_env_filter("attrs_literal_field_names=trace")
|
||||
.finish();
|
||||
tracing::subscriber::with_default(subscriber, || {
|
||||
let span = span!(Level::TRACE, "get_band_rec", "guid:x-request-id" = "abcdef");
|
||||
let _enter = span.enter();
|
||||
suggest_band();
|
||||
});
|
||||
}
|
@ -287,6 +287,19 @@
|
||||
//! # }
|
||||
//!```
|
||||
//!
|
||||
//! Fields with names that are not Rust identifiers, or with names that are Rust reserved words,
|
||||
//! may be created using quoted string literals. However, this may not be used with the local
|
||||
//! variable shorthand.
|
||||
//! ```
|
||||
//! # use tracing::{span, Level};
|
||||
//! # fn main() {
|
||||
//! // records an event with fields whose names are not Rust identifiers
|
||||
//! // - "guid:x-request-id", containing a `:`, with the value "abcdef"
|
||||
//! // - "type", which is a reserved word, with the value "request"
|
||||
//! span!(Level::TRACE, "api", "guid:x-request-id" = "abcdef", "type" = "request");
|
||||
//! # }
|
||||
//!```
|
||||
//!
|
||||
//! The `?` sigil is shorthand that specifies a field should be recorded using
|
||||
//! its [`fmt::Debug`] implementation:
|
||||
//! ```
|
||||
|
@ -1959,6 +1959,48 @@ macro_rules! valueset {
|
||||
$next,
|
||||
)
|
||||
};
|
||||
|
||||
// Handle literal names
|
||||
(@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = ?$val:expr, $($rest:tt)*) => {
|
||||
$crate::valueset!(
|
||||
@ { $($out),*, (&$next, Some(&debug(&$val) as &Value)) },
|
||||
$next,
|
||||
$($rest)*
|
||||
)
|
||||
};
|
||||
(@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = %$val:expr, $($rest:tt)*) => {
|
||||
$crate::valueset!(
|
||||
@ { $($out),*, (&$next, Some(&display(&$val) as &Value)) },
|
||||
$next,
|
||||
$($rest)*
|
||||
)
|
||||
};
|
||||
(@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = $val:expr, $($rest:tt)*) => {
|
||||
$crate::valueset!(
|
||||
@ { $($out),*, (&$next, Some(&$val as &Value)) },
|
||||
$next,
|
||||
$($rest)*
|
||||
)
|
||||
};
|
||||
(@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = ?$val:expr) => {
|
||||
$crate::valueset!(
|
||||
@ { $($out),*, (&$next, Some(&debug(&$val) as &Value)) },
|
||||
$next,
|
||||
)
|
||||
};
|
||||
(@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = %$val:expr) => {
|
||||
$crate::valueset!(
|
||||
@ { $($out),*, (&$next, Some(&display(&$val) as &Value)) },
|
||||
$next,
|
||||
)
|
||||
};
|
||||
(@ { $(,)* $($out:expr),* }, $next:expr, $k:literal = $val:expr) => {
|
||||
$crate::valueset!(
|
||||
@ { $($out),*, (&$next, Some(&$val as &Value)) },
|
||||
$next,
|
||||
)
|
||||
};
|
||||
|
||||
// Remainder is unparseable, but exists --- must be format args!
|
||||
(@ { $(,)* $($out:expr),* }, $next:expr, $($rest:tt)+) => {
|
||||
$crate::valueset!(@ { (&$next, Some(&format_args!($($rest)+) as &Value)), $($out),* }, $next, )
|
||||
@ -2017,6 +2059,17 @@ macro_rules! fieldset {
|
||||
$crate::fieldset!(@ { $($out),*, $crate::__tracing_stringify!($($k).+) } $($rest)*)
|
||||
};
|
||||
|
||||
// Handle literal names
|
||||
(@ { $(,)* $($out:expr),* } $k:literal = ?$val:expr, $($rest:tt)*) => {
|
||||
$crate::fieldset!(@ { $($out),*, $k } $($rest)*)
|
||||
};
|
||||
(@ { $(,)* $($out:expr),* } $k:literal = %$val:expr, $($rest:tt)*) => {
|
||||
$crate::fieldset!(@ { $($out),*, $k } $($rest)*)
|
||||
};
|
||||
(@ { $(,)* $($out:expr),* } $k:literal = $val:expr, $($rest:tt)*) => {
|
||||
$crate::fieldset!(@ { $($out),*, $k } $($rest)*)
|
||||
};
|
||||
|
||||
// Remainder is unparseable, but exists --- must be format args!
|
||||
(@ { $(,)* $($out:expr),* } $($rest:tt)+) => {
|
||||
$crate::fieldset!(@ { "message", $($out),*, })
|
||||
|
@ -262,6 +262,22 @@ fn error_span_with_parent() {
|
||||
error_span!(parent: &p, "bar",);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn span_with_non_rust_symbol() {
|
||||
span!(Level::TRACE, "non-rust", "guid:x-request-id" = ?"abcdef", "more {}", 42);
|
||||
span!(Level::TRACE, "non-rust", "guid:x-request-id" = %"abcdef", "more {}", 51);
|
||||
span!(
|
||||
Level::TRACE,
|
||||
"non-rust",
|
||||
"guid:x-request-id" = "abcdef",
|
||||
"more {}",
|
||||
60
|
||||
);
|
||||
span!(Level::TRACE, "non-rust", "guid:x-request-id" = ?"abcdef");
|
||||
span!(Level::TRACE, "non-rust", "guid:x-request-id" = %"abcdef");
|
||||
span!(Level::TRACE, "non-rust", "guid:x-request-id" = "abcdef");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn event() {
|
||||
event!(Level::DEBUG, foo = ?3, bar.baz = %2, quux = false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user