Skip to content
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

Merged
merged 14 commits into from
May 23, 2020
Merged

Conversation

hawkw
Copy link
Member

@hawkw hawkw commented Apr 7, 2020

Motivation

Fields on spans generated by #[instrument] consist of the parameters
to the instrumented function, and a list of optional fields with
literal values passed in the fields argument of the attribute. The
current 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 accessing
values from parameters.

Solution

This branch extends the currently supported fields argument to allow
providing 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 dotted
Rust identifiers.

Implementing this required rewriting how arguments to the
#[instrument] attribute are parsed. Previously, we used syn's
AttributeArgs 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 our
own types implementing syn::parse::Parse, we can accept more
expressions 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

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>
@hawkw hawkw added kind/feature New feature or request crate/attributes Related to the `tracing-attributes` crate labels Apr 7, 2020
@hawkw hawkw requested review from carllerche and a team April 7, 2020 23:37
@hawkw hawkw self-assigned this Apr 7, 2020
@hawkw
Copy link
Member Author

hawkw commented Apr 7, 2020

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>
hawkw added 2 commits May 23, 2020 13:16
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
@hawkw
Copy link
Member Author

hawkw commented May 23, 2020

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.

@davidbarsky
Copy link
Member

I’ll take a look.

Copy link
Member

@davidbarsky davidbarsky left a 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.

hawkw added a commit that referenced this pull request Jul 8, 2020
## 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>
hawkw added a commit that referenced this pull request Jul 8, 2020
# 0.1.9 (July 8, 2020)

### Added

- Support for arbitrary expressions as fields in `#[instrument]` (#672)

### Changed

- `#[instrument]` now emits a compiler warning when ignoring 
  unrecognized input (#672, #786)

Fixes #785 

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
hawkw added a commit that referenced this pull request Jul 8, 2020
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!
hawkw added a commit that referenced this pull request Jul 8, 2020
### 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!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crate/attributes Related to the `tracing-attributes` crate kind/feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

instrument macro: provide way to include additional fields
2 participants