-
Notifications
You must be signed in to change notification settings - Fork 857
Support constant expressions as instrument field names #3158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
acd38e1 to
a2c17f3
Compare
tracing-attributes/tests/fields.rs
Outdated
| }); | ||
| } | ||
|
|
||
| // TODO(#3158): To be consistent with event! and span! macros, the argument's value should be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a test for the panic here, to ensure that this check doesn't get accidentally removed at some point in the future. It may be necessary to move the test to a "ui" test to validate the compiler error message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I no longer think adding a panic or deduplication logic for constant expressions is feasible at compile time. Every solution I tested incurs a runtime cost, as constant expressions need to be evaluated first, and then every value needs to be compared against each other.
Given that the impact of not doing it is "just" duplicated fields reported, and is limited to people newly opting into braced constant expressions, I don't expect this to cause much problem.
I updated the docs to explain this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Expanding on the previous message with more details:
The panic solution worked at compile time because it was fully integrated inside a constant context, which I learned recently the compiler is happy to execute. But I understand this is less than ideal from a user perspective, as it introduces a breaking change.
On the other hand, a new FieldSet::new_checked constructor would be very hard to surface, as it would force to duplicate a lot of the code, including the span! macro, at which point the code becomes unmaintainable.
I would prefer to implement deduplication, but this remained out of reach after many attempts.
- The existing deduplication code in expand.rs occurs during macro expansion, while constant evaluation by the compiler only happens at a later stage.
- Another point at which this could be implemented is around
FieldSetcreation, but given thatValueSetis created in a totally unrelated part of the code and the two need to stay in sync, it seems impossible to keep them aligned as duplicated fields are removed. - I have stayed away from runtime deduplication, as this is an undesirable cost to pay for something that should only be checked statically.
It'll be possible to do a follow-up PR to add deduplication when someone hopefully figures it out.
|
@nico-incubiq , are you still planning to work on this? |
I'd like to pick this back up yes.
|
ecd0231 to
41724a9
Compare
41724a9 to
aab1ff3
Compare
e709479 to
4f01b67
Compare
|
This is ready for review again when someone has time 🙏🏼 |
hds
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small docs nit. Otherwise, this looks good now!
Co-authored-by: Hayden Stainsby <[email protected]>
303c2c5 to
b007e5b
Compare
|
Thanks @hds, I merged your change and rebased off the latest |
|
@nico-incubiq run. Just a rustfmt failure (small one). |
|
Fixed |
hds
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all your work on this PR!
# 0.1.31 (November 30, 2025) ### Added - Support constant expressions as instrument field names ([#3158]) [#3158]: https://github.com/tokio-rs/tracing/pull/#3158
# 0.1.42 (November 30, 2025) ### Added - **attributes**: Support constant expressions as instrument field names ([#3158]) - **core**: Improve code generation at trace points significantly ([#3398]) ### Fixed - Fix perf regression when `release_max_level_*` not set ([#3373]) - Use imported instead of fully qualified path ([#3374]) - Make `valueset` macro sanitary ([#3382]) ### Documented - **core**: Add missing `dyn` keyword in `Visit` documentation code sample ([#3387]) [#3158]: https://github.com/tokio-rs/tracing/pull/#3158 [#3373]: https://github.com/tokio-rs/tracing/pull/#3373 [#3374]: https://github.com/tokio-rs/tracing/pull/#3374 [#3382]: https://github.com/tokio-rs/tracing/pull/#3382 [#3387]: https://github.com/tokio-rs/tracing/pull/#3387 [#3398]: https://github.com/tokio-rs/tracing/pull/#3398
# 0.1.31 (November 30, 2025) ### Added - Support constant expressions as instrument field names ([#3158]) [#3158]: https://github.com/tokio-rs/tracing/pull/#3158
# 0.1.31 (November 26, 2025) ### Added - Support constant expressions as instrument field names ([#3158]) [#3158]: https://github.com/tokio-rs/tracing/pull/#3158
# 0.1.31 (November 26, 2025) ### Added - Support constant expressions as instrument field names ([#3158]) [#3158]: https://github.com/tokio-rs/tracing/pull/#3158
# 0.1.42 (November 26, 2025) ### Added - **attributes**: Support constant expressions as instrument field names ([#3158]) - **core**: Improve code generation at trace points significantly ([#3398]) ### Changed - `tracing-core`: updated to 0.1.35 ([#3414]) - `tracing-attributes`: updated to 0.1.31 ([#3417]) ### Fixed - Fix perf regression when `release_max_level_*` not set ([#3373]) - Use imported instead of fully qualified path ([#3374]) - Make `valueset` macro sanitary ([#3382]) ### Documented - **core**: Add missing `dyn` keyword in `Visit` documentation code sample ([#3387]) [#3158]: https://github.com/tokio-rs/tracing/pull/#3158 [#3373]: https://github.com/tokio-rs/tracing/pull/#3373 [#3374]: https://github.com/tokio-rs/tracing/pull/#3374 [#3382]: https://github.com/tokio-rs/tracing/pull/#3382 [#3387]: https://github.com/tokio-rs/tracing/pull/#3387 [#3398]: https://github.com/tokio-rs/tracing/pull/#3398 [#3414]: https://github.com/tokio-rs/tracing/pull/#3414 [#3417]: https://github.com/tokio-rs/tracing/pull/#3417
# 0.1.42 (November 26, 2025) ### Added - **attributes**: Support constant expressions as instrument field names ([#3158]) - Add `record_all!` macro for recording multiple values in one call ([#3227]) - **core**: Improve code generation at trace points significantly ([#3398]) ### Changed - `tracing-core`: updated to 0.1.35 ([#3414]) - `tracing-attributes`: updated to 0.1.31 ([#3417]) ### Fixed - Fix "name / parent" variant of `event!` ([#2983]) - Remove 'r#' prefix from raw identifiers in field names ([#3130]) - Fix perf regression when `release_max_level_*` not set ([#3373]) - Use imported instead of fully qualified path ([#3374]) - Make `valueset` macro sanitary ([#3382]) ### Documented - **core**: Add missing `dyn` keyword in `Visit` documentation code sample ([#3387]) [#2983]: https://github.com/tokio-rs/tracing/pull/#2983 [#3130]: https://github.com/tokio-rs/tracing/pull/#3130 [#3158]: https://github.com/tokio-rs/tracing/pull/#3158 [#3227]: https://github.com/tokio-rs/tracing/pull/#3227 [#3373]: https://github.com/tokio-rs/tracing/pull/#3373 [#3374]: https://github.com/tokio-rs/tracing/pull/#3374 [#3382]: https://github.com/tokio-rs/tracing/pull/#3382 [#3387]: https://github.com/tokio-rs/tracing/pull/#3387 [#3398]: https://github.com/tokio-rs/tracing/pull/#3398 [#3414]: https://github.com/tokio-rs/tracing/pull/#3414 [#3417]: https://github.com/tokio-rs/tracing/pull/#3417
# 0.1.42 (November 26, 2025) ### Important The [`Span::record_all`] method has been removed from the documented API. It was always unsuable via the documented API as it requried a `ValueSet` which has no publically documented constructors. The method remains, but should not be used outside of `tracing` macros. ### Added - **attributes**: Support constant expressions as instrument field names ([#3158]) - Add `record_all!` macro for recording multiple values in one call ([#3227]) - **core**: Improve code generation at trace points significantly ([#3398]) ### Changed - `tracing-core`: updated to 0.1.35 ([#3414]) - `tracing-attributes`: updated to 0.1.31 ([#3417]) ### Fixed - Fix "name / parent" variant of `event!` ([#2983]) - Remove 'r#' prefix from raw identifiers in field names ([#3130]) - Fix perf regression when `release_max_level_*` not set ([#3373]) - Use imported instead of fully qualified path ([#3374]) - Make `valueset` macro sanitary ([#3382]) ### Documented - **core**: Add missing `dyn` keyword in `Visit` documentation code sample ([#3387]) [#2983]: https://github.com/tokio-rs/tracing/pull/#2983 [#3130]: https://github.com/tokio-rs/tracing/pull/#3130 [#3158]: https://github.com/tokio-rs/tracing/pull/#3158 [#3227]: https://github.com/tokio-rs/tracing/pull/#3227 [#3373]: https://github.com/tokio-rs/tracing/pull/#3373 [#3374]: https://github.com/tokio-rs/tracing/pull/#3374 [#3382]: https://github.com/tokio-rs/tracing/pull/#3382 [#3387]: https://github.com/tokio-rs/tracing/pull/#3387 [#3398]: https://github.com/tokio-rs/tracing/pull/#3398 [#3414]: https://github.com/tokio-rs/tracing/pull/#3414 [#3417]: https://github.com/tokio-rs/tracing/pull/#3417 [`Span::record_all`]: https://docs.rs/tracing/0.1.41/tracing/struct.Span.html#method.record_all
# 0.1.42 (November 26, 2025) ### Important The [`Span::record_all`] method has been removed from the documented API. It was always unsuable via the documented API as it requried a `ValueSet` which has no publically documented constructors. The method remains, but should not be used outside of `tracing` macros. ### Added - **attributes**: Support constant expressions as instrument field names ([#3158]) - Add `record_all!` macro for recording multiple values in one call ([#3227]) - **core**: Improve code generation at trace points significantly ([#3398]) ### Changed - `tracing-core`: updated to 0.1.35 ([#3414]) - `tracing-attributes`: updated to 0.1.31 ([#3417]) ### Fixed - Fix "name / parent" variant of `event!` ([#2983]) - Remove 'r#' prefix from raw identifiers in field names ([#3130]) - Fix perf regression when `release_max_level_*` not set ([#3373]) - Use imported instead of fully qualified path ([#3374]) - Make `valueset` macro sanitary ([#3382]) ### Documented - **core**: Add missing `dyn` keyword in `Visit` documentation code sample ([#3387]) [#2983]: https://github.com/tokio-rs/tracing/pull/#2983 [#3130]: https://github.com/tokio-rs/tracing/pull/#3130 [#3158]: https://github.com/tokio-rs/tracing/pull/#3158 [#3227]: https://github.com/tokio-rs/tracing/pull/#3227 [#3373]: https://github.com/tokio-rs/tracing/pull/#3373 [#3374]: https://github.com/tokio-rs/tracing/pull/#3374 [#3382]: https://github.com/tokio-rs/tracing/pull/#3382 [#3387]: https://github.com/tokio-rs/tracing/pull/#3387 [#3398]: https://github.com/tokio-rs/tracing/pull/#3398 [#3414]: https://github.com/tokio-rs/tracing/pull/#3414 [#3417]: https://github.com/tokio-rs/tracing/pull/#3417 [`Span::record_all`]: https://docs.rs/tracing/0.1.41/tracing/struct.Span.html#method.record_all
Motivation
The
#[instrument]proc macro only allows setting field names as identifiers, which is not on par with other macros such asspan!orevent!that allow constant expressions. Using constants for example can ensure consistency across a project for the field names used.This addresses #2969, which was already mentioned in this comment here on #2617 (note that "classic macros" mentioned there already work, there are tests attesting of it).
I also updated the doc block to mention field values can be any arbitrary expressions, which was implemented by #672 but never updated.
Solution
I updated the instrument proc macro to allow constant expressions (const, const fn, literal str, ...) as field names, using the same syntax as #2617, enclosed in curly braces.
Notes
swould be used instead of a function argumentsin the span). As far as I'm aware this is not possible to implement for constant expressions, as the compiler doesn't allow to evaluate constants at build time (MIRI might be a solution but that seems complicated, and https://rustc-dev-guide.rust-lang.org/const-eval seems experimental). It's a minor inconsistency; in this scenario, the code would panic immediately at startup, and the workaround is as simple as skipping the function argument.