-
Notifications
You must be signed in to change notification settings - Fork 734
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
attributes: support arbitrary field expressions #672
Conversation
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
I think the docs also need to be updated. Will fix that. |
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Okay, merging #711 into this was a bit of a mess, but I've got all the tests passing again so it should be good. @davidbarsky, do you want to give it another look? I did change a few things while merging. |
I’ll take a look. |
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.
Looks good! Tests + new comments are nice.
## Motivation In PR #672, the `#[instrument]` attribute was rewritten to use a custom `syn` parser rather than using `syn::AttributeArgs`. This was primarily to allow the use of arbitrary expressions as fields, but it had the side benefit of also allowing more sophisticated error reporting. In particular, we were able to replace the previous behavior of silently ignoring unknown input with a compiler error, which has been requested a few times (see #772 and #727). However, emitting a compiler error for inputs that we previously allowed (even if they did nothing) is technically a breaking change --- see #773 (comment) and following comments. This means that the other new features added in #672 cannot be released until we release `tracing-subscriber` 0.2. ## Solution This branch avoids the breaking change by downgrading these errors to warnings. However, it isn't currently possible to emit a warning from a proc-macro on stable --- the `proc_macro::Diagnostic` API which would allow this requires a nightly feature. This branch hacks around this by generating a fake deprecated item with for each unrecognized token in the input, emitting the skipped item's parse error as the deprecation's `note`, and "using" the deprecated item. The deprecated warning is used here rather than other code that will emit compiler warnings, because it gives us a way to customize the warning output (via the `note` field). I've tried to make it fairly obvious that this is not a "real" deprecation. Sample output looks like this: ![Screenshot_20200707_153151](https://user-images.githubusercontent.com/2796466/86850948-fce0a780-c066-11ea-9b1c-5085c0fd43e0.png) Fixes #727 Fixes #772 Signed-off-by: Eliza Weisman <eliza@elizas.website>
Added - **attributes**: Support for arbitrary expressions as fields in `#[instrument]` (#672) - **attributes**: `#[instrument]` now emits a compiler warning when ignoring unrecognized input (#672, #786) - Improved documentation on using `tracing` in async code (#769) Changed - Updated `tracing-core` dependency to 0.1.11 Fixed - **macros**: Excessive monomorphization in macros, which could lead to longer compilation times (#787) - **log**: Compiler warnings in macros when `log` or `log-always` features are enabled (#753) - Compiler error when `tracing-core/std` feature is enabled but `tracing/std` is not (#760) Thanks to @nagisa for contributing to this release!
### Added - **attributes**: Support for arbitrary expressions as fields in `#[instrument]` (#672) - **attributes**: `#[instrument]` now emits a compiler warning when ignoring unrecognized input (#672, #786) - Improved documentation on using `tracing` in async code (#769) ### Changed - Updated `tracing-core` dependency to 0.1.11 ### Fixed - **macros**: Excessive monomorphization in macros, which could lead to longer compilation times (#787) - **log**: Compiler warnings in macros when `log` or `log-always` features are enabled (#753) - Compiler error when `tracing-core/std` feature is enabled but `tracing/std` is not (#760) Thanks to @nagisa, and everyone who contributed to the new `tracing-core` and `tracing-attributes` versions, for contributing to this release!
Motivation
Fields on spans generated by
#[instrument]
consist of the parametersto the
instrument
ed function, and a list of optional fields withliteral values passed in the
fields
argument of the attribute. Thecurrent API for additional user-defined fields is pretty limited, since
it only accepts literals (and doesn't accept dotted field names). It
would be nice to have an API for including additional fields with values
set by calling methods on
self
or on parameters, or by accessingvalues from parameters.
Solution
This branch extends the currently supported
fields
argument to allowproviding arbitrary expressions which are invoked within the function's
scope. This is a superset of the previous support for literal values
only. In addition, field names passed to
fields
may now contain dottedRust identifiers.
Implementing this required rewriting how arguments to the
#[instrument]
attribute are parsed. Previously, we usedsyn
'sAttributeArgs
type, which parses a comma-separated of "nested meta"items, consisting of
$ident($nested meta)
,$ident = $nested_meta
,paths, and literals. By replacing the use of
AttributeArgs
with ourown types implementing
syn::parse::Parse
, we can accept moreexpressions in the attribute arguments position. This also lets us
reject more invalid inputs at parse-time, which improves syntax error
reporting a bit.
One thing that's worth noting is that the current implementation will
generate an empty field when a field name is provided without an
=
and a value. This makes sense when only simple fields with literal
values are permitted. However, if we accept arbitrary expressions in the
macro, this is not the ideal behavior --- we would prefer to use the
same local variable shorthand as the function-like
tracing
macros.However, changing this now is a breaking change. Any code which uses a
name that doesn't exist in the current scope to declare an empty field
would fail to compile, because it attempts to reference a name that
doesn't exist. Instead, I left a comment noting that this is not the
ideal behavior and it should be changed next time we're ready to break
the proc macros.
Fixes: #650
Signed-off-by: Eliza Weisman eliza@buoyant.io