Reputation: 42678
I need to instrument spans with different names dynamically. How can I create a tracing span with dynamic naming?
use tracing; // 0.1.22
fn main() {
let name: &'static str = "foo bar";
let span = tracing::span!(tracing::Level::TRACE, name);
let span_handle = span.enter();
tracing::info!("Hello, world!");
drop(span_handle);
}
error[E0435]: attempt to use a non-constant value in a constant
--> src/main.rs:5:54
|
5 | let span = tracing::span!(tracing::Level::TRACE, name);
| ^^^^ non-constant value
Upvotes: 9
Views: 3498
Reputation: 21
You can accomplish this by setting the otel.name
field on a span:
let span = tracing::Span::current();
let my_span_name = "Whatever I want the name to be".to_owned();
span.record("otel.name", my_span_name);
Upvotes: 2
Reputation: 11
To confirm what you're after, is it dynamic naming of your spans, ie. the name is decided at runtime? or do you just want to be able to declare the name of your spans in constants and use those when you create your spans?
If it's the former, then I don't believe you're able to, because the macro explicitly only accepts literals
. However if its the latter, you can work around it via basic macros.
macro_rules! prefix_name {
($name:literal) => {
concat!("prefix::", $name)
};
}
macro_rules! span_name {
() => {
"foo::bar"
};
}
Then you can use it below
fn main() {
let span = tracing::span!(tracing::Level::TRACE, prefix_name!("foo bar"));
let span_handle = span.enter();
tracing::info!("Hello, world!");
drop(span_handle);
let span = tracing::span!(tracing::Level::TRACE, span_name!());
let span_handle = span.enter();
tracing::info!("Hello, world!");
drop(span_handle);
}
To be honest I can only take a guess at why this works (so anyone who knows for sure, please feel free to correct me). But I would assume that macro expansion occurs prior to actually trying to compile the code. So by the time the compiler is trying to compile that span, the macro has already been expanded to the underlying literal.
Upvotes: 1
Reputation: 430270
Instead of attempting to set the span's name dynamically, add a field:
let value = "forty-two";
let span = tracing::span!(tracing::Level::TRACE, "foo bar", value = value);
From the docs:
A span consists of fields, user-defined key-value pairs of arbitrary data that describe the context the span represents
Upvotes: 4