-
Notifications
You must be signed in to change notification settings - Fork 721
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
Add support for visiting floating point values #1507
Conversation
@maxburke mind merging |
@hawkw done! |
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.
overall, this looks good to me. it would be nice to add some tests, but it's not a hard blocker.
we should also add f64
to the list of primitive types in the docs here:
tracing/tracing-core/src/field.rs
Line 19 in 373a77f
//! (`i64`, `u64`, `bool`, and `&str`) or using a `fmt::Display` or `fmt::Debug` |
@@ -197,6 +212,13 @@ impl<'a> field::Visit for SpanAttributeVisitor<'a> { | |||
self.record(KeyValue::new(field.name(), value)); | |||
} | |||
|
|||
/// Set attributes on the underlying OpenTelemetry [`Span`] from `i64` values. |
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 think this should say
/// Set attributes on the underlying OpenTelemetry [`Span`] from `i64` values. | |
/// Set attributes on the underlying OpenTelemetry [`Span`] from `f64` values. |
pub enum MockValue { | ||
F64(f64), |
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.
minor nit, but since the test support code now handles f64
values, we should probably also add some tests that actually try to record f64
s...
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.
Where would be the best place to put these? I looked for example in the tracing-core/src/field.rs but most of the tests there were calling record_debug
directly.
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.
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.
After taking a closer look at this, I noticed there are some issues with the way we implement Ord
and Eq
for types that contain f64
values, which may be NaN
. Since NaN
s are never equal and don't have a total ordering, these comparisons are not technically correct.
I left some comments on how we should probably change this.
@@ -36,14 +36,23 @@ pub(crate) struct MatchVisitor<'a> { | |||
inner: &'a SpanMatch, | |||
} | |||
|
|||
#[derive(Debug, Clone, PartialOrd, Ord, Eq, PartialEq)] | |||
#[derive(Debug, Clone, PartialOrd, PartialEq)] |
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.
the manual implementation of Ord
for a type that derives PartialOrd
triggers a clippy lint: https://github.com/tokio-rs/tracing/runs/3363637695#step:4:753
I think we need to add a manual PartialOrd
impl as well, to fix the clippy lint.
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.
👍
@@ -275,6 +286,15 @@ impl SpanMatch { | |||
} | |||
|
|||
impl<'a> Visit for MatchVisitor<'a> { | |||
fn record_f64(&mut self, field: &Field, value: f64) { | |||
match self.inner.fields.get(field) { | |||
Some((ValueMatch::F64(ref e), ref matched)) if value == *e => { |
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.
We probably need special behavior for NaN
values here. Two NaN
s will never be equal to each other. However, a user may want to write a filter configuration that enables all spans where a particular value is a NaN
. Therefore, we probably want to change this behavior.
I would probably change this by adding a separate ValueMatch::NaN
type, and change the parser to return that instead if s.parse::<f64>()
returns a value where is_nan() == true
. Then, in this method, we would add another match arm like
Some((ValueMatch::NaN, ref matched)) if value.is_nan() => {
matched.store(true, Release);
}
This way, users can match any NaN
value by writing filters like {foo=NaN}
, which is probably the desired behavior.
This also avoids the problem of NaNs in the Ord
impl breaking the total ordering for ValueMatch
es. Since no ValueMatch::F64
variants will be created with NaN
values, we actually can rely on the ordering of ValueMatch::F64
s being total. We would probably want to add a (debug?) assertion in that case that the values are not actually NaN, to ensure no NaN values sneak in accidentally.
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.
@hawkw I had a question for this particular code location, unrelated to the NaN support. Should this method here perform an equality compare against the matching value, or should it do an epsilon compare?
Clippy warns against doing an equality compare but I'm not sure it feels right to be doing an epsilon compare here.
Thoughts?
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.
It's probably best to do an epsilon compare here. In most cases, I think the user will be looking for values that are logically "equal" to the provided decimal number, rather than looking for floating-point values whose bit patterns are exactly equal.
Either way, it's probably worth documenting how floats are compared in the documentation for EnvFilter
, whether we do an exact comparison or an epsilon comparison.
impl Ord for ValueMatch { | ||
fn cmp(&self, other: &Self) -> Ordering { | ||
self.partial_cmp(other).unwrap() | ||
} | ||
} |
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.
This isn't really correct, because there's nothing stopping the ValueMatch::F64
case from containing NaN
values, and NaN
s don't have a total order.
The total ordering is required because ValueMatch
es are stored in a BTreeMap
, so we can't just remove the Ord
implementation. Instead, what I think we should do is make some additional changes to ensure that ValueMatch::F64
variants will never contain NaN
values, as I discussed in other comments. I think if we make those changes, we can then implement Ord
for ValueMatch
if we add an assertion when comparing ValueMatch::F64
variants that check that they aren't NaN
(or expect
the result of the partial_cmp
comparison). For every other variant, the Ord
impl can just call that type's Ord::cmp
.
I would expect the implementation to look something like this:
impl Ord for ValueMatch { | |
fn cmp(&self, other: &Self) -> Ordering { | |
self.partial_cmp(other).unwrap() | |
} | |
} | |
impl Ord for ValueMatch { | |
fn cmp(&self, other: &Self) -> Ordering { | |
use ValueMatch::*; | |
match (self, other) { | |
(Bool(this), Bool(that)) => this.cmp(that), | |
(Bool(_), _) => Ordering::Less, | |
(F64(this), F64(that)) => this.partial_cmp(that).expect("`ValueMatch::F64` may not contain `NaN` values"), | |
(F64(_), Bool(_)) => Ordering::Greater, | |
(F64(_), _) => Ordering::Less, | |
(NaN, NaN) => Ordering::Equal, | |
(NaN, Bool(_)) | (NaN, F64(_)) => Ordering::Greater, | |
(NaN _) => Ordering::Less, | |
(U64(this), U64(that)) => this.cmp(that), | |
(U64(_), Bool(_)) | (U64(_), F64(_)) | (U64(_), NaN) => Ordering::Greater, | |
(U64(_), _) => Ordering::Less, | |
(I64(this), I64(that)) => this.cmp(that), | |
(I64(_), Bool(_)) | (I64(_), F64(_)) | (I64(_), NaN), (I64(_), U64(_)) => Ordering::Greater, | |
(I64(_), _) => Ordering::Less, | |
(Pat(this), Pat(that)) => this.cmp(that), | |
(Pat(_), _) => Ordering::Greater, | |
} | |
} | |
} | |
impl PartialOrd for ValueMatch { | |
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | |
Some(self.cmp(other)) | |
} | |
} |
or similar.
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.
👍
U64(u64), | ||
I64(i64), | ||
Pat(Box<MatchPattern>), | ||
} | ||
|
||
impl Eq for ValueMatch {} |
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.
Similarly to Ord
, the Eq
implementation is only correct if we ensure there are no NaN
values present in the ValueMatch::F64
variant. See my comment on the Ord
impl for details.
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.
👍
@@ -29,6 +30,8 @@ pub enum MockValue { | |||
Any, | |||
} | |||
|
|||
impl Eq for MockValue {} |
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.
This is only correct if we ensure no NaN
values are present in the F64
case.
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.
👍
@hawkw I think this all make sense. Update incoming |
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.
Overall, this looks good! I commented on whether we should use epsilon comparisons in EnvFilter
(we probably should).
@@ -275,6 +286,15 @@ impl SpanMatch { | |||
} | |||
|
|||
impl<'a> Visit for MatchVisitor<'a> { | |||
fn record_f64(&mut self, field: &Field, value: f64) { | |||
match self.inner.fields.get(field) { | |||
Some((ValueMatch::F64(ref e), ref matched)) if value == *e => { |
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.
It's probably best to do an epsilon compare here. In most cases, I think the user will be looking for values that are logically "equal" to the provided decimal number, rather than looking for floating-point values whose bit patterns are exactly equal.
Either way, it's probably worth documenting how floats are compared in the documentation for EnvFilter
, whether we do an exact comparison or an epsilon comparison.
pub enum MockValue { | ||
F64(f64), |
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.
Any other things you'd like me to tidy up, @hawkw ? I extended a couple tests to validate the floating point values pass through with out being formatted. |
Nope, this looks good to me! Thanks! |
## Motivation Tracing is a really useful framework but a lack of floating point value support for the core visitors means these get coerced unnecessarily to strings. ## Solution This change adds support for floating point (`f64`) visitors.
## Motivation Tracing is a really useful framework but a lack of floating point value support for the core visitors means these get coerced unnecessarily to strings. ## Solution This change adds support for floating point (`f64`) visitors.
# 0.1.20 (September 12, 2021) This release adds support for `f64` as one of the `tracing-core` primitive field values, allowing floating-point values to be recorded as typed values rather than with `fmt::Debug`. Additionally, it adds `NoSubscriber`, a `Subscriber` implementation that does nothing. ### Added - **subscriber**: `NoSubscriber`, a no-op `Subscriber` implementation ([#1549]) - **field**: Added `Visit::record_f64` and support for recording floating-point values ([#1507]) Thanks to new contributors @jsgf and @maxburke for contributing to this release! [#1549]: #1549 [#1507]: #1507
# 0.2.21 (September 12, 2021) This release introduces the [`Filter`] trait, a new API for [per-layer filtering][plf]. This allows controlling which spans and events are recorded by various layers individually, rather than globally. In addition, it adds a new [`Targets`] filter, which provides a lighter-weight version of the filtering provided by [`EnvFilter`], as well as other smaller API improvements and fixes. ### Deprecated - **registry**: `SpanRef::parent_id`, which cannot properly support per-layer filtering. Use `.parent().map(SpanRef::id)` instead. ([#1523]) ### Fixed - **layer** `Context` methods that are provided when the `Subscriber` implements `LookupSpan` no longer require the "registry" feature flag ([#1525]) - **layer** `fmt::Debug` implementation for `Layered` no longer requires the `S` type parameter to implement `Debug` ([#1528]) ### Added - **registry**: `Filter` trait, `Filtered` type, `Layer::with_filter` method, and other APIs for per-layer filtering ([#1523]) - **filter**: `FilterFn` and `DynFilterFn` types that implement global (`Layer`) and per-layer (`Filter`) filtering for closures and function pointers ([#1523]) - **filter**: `Targets` filter, which implements a lighter-weight form of `EnvFilter`-like filtering ([#1550]) - **env-filter**: Added support for filtering on floating-point values ([#1507]) - **layer**: `Layer::on_layer` callback, called when layering the `Layer` onto a `Subscriber` ([#1523]) - **layer**: `Layer` implementations for `Box<L>` and `Arc<L>` where `L: Layer` ([#1536]) - **layer**: `Layer` implementations for `Box<dyn Layer<S> + Send + Sync + 'static>` and `Arc<dyn Layer<S> + Send + Sync + 'static>` ([#1536]) - A number of small documentation fixes and improvements ([#1553], [#1544], [#1539], [#1524]) Special thanks to new contributors @jsgf and @maxburke for contributing to this release! [`Filter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/trait.Filter.html [`plf`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/index.html#per-layer-filtering [`Targets`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.Targets.html [`EnvFilter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.EnvFilter.html [#1507]: #1507 [#1523]: #1523 [#1524]: #1524 [#1525]: #1525 [#1528]: #1528 [#1539]: #1539 [#1544]: #1544 [#1550]: #1550 [#1553]: #1553
# 0.2.21 (September 12, 2021) This release introduces the [`Filter`] trait, a new API for [per-layer filtering][plf]. This allows controlling which spans and events are recorded by various layers individually, rather than globally. In addition, it adds a new [`Targets`] filter, which provides a lighter-weight version of the filtering provided by [`EnvFilter`], as well as other smaller API improvements and fixes. ### Deprecated - **registry**: `SpanRef::parent_id`, which cannot properly support per-layer filtering. Use `.parent().map(SpanRef::id)` instead. ([#1523]) ### Fixed - **layer** `Context` methods that are provided when the `Subscriber` implements `LookupSpan` no longer require the "registry" feature flag ([#1525]) - **layer** `fmt::Debug` implementation for `Layered` no longer requires the `S` type parameter to implement `Debug` ([#1528]) ### Added - **registry**: `Filter` trait, `Filtered` type, `Layer::with_filter` method, and other APIs for per-layer filtering ([#1523]) - **filter**: `FilterFn` and `DynFilterFn` types that implement global (`Layer`) and per-layer (`Filter`) filtering for closures and function pointers ([#1523]) - **filter**: `Targets` filter, which implements a lighter-weight form of `EnvFilter`-like filtering ([#1550]) - **env-filter**: Added support for filtering on floating-point values ([#1507]) - **layer**: `Layer::on_layer` callback, called when layering the `Layer` onto a `Subscriber` ([#1523]) - **layer**: `Layer` implementations for `Box<L>` and `Arc<L>` where `L: Layer` ([#1536]) - **layer**: `Layer` implementations for `Box<dyn Layer<S> + Send + Sync + 'static>` and `Arc<dyn Layer<S> + Send + Sync + 'static>` ([#1536]) - A number of small documentation fixes and improvements ([#1553], [#1544], [#1539], [#1524]) Special thanks to new contributors @jsgf and @maxburke for contributing to this release! [`Filter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/trait.Filter.html [`plf`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/index.html#per-layer-filtering [`Targets`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.Targets.html [`EnvFilter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.EnvFilter.html [#1507]: #1507 [#1523]: #1523 [#1524]: #1524 [#1525]: #1525 [#1528]: #1528 [#1539]: #1539 [#1544]: #1544 [#1550]: #1550 [#1553]: #1553
# 0.1.20 (September 12, 2021) This release adds support for `f64` as one of the `tracing-core` primitive field values, allowing floating-point values to be recorded as typed values rather than with `fmt::Debug`. Additionally, it adds `NoSubscriber`, a `Subscriber` implementation that does nothing. ### Added - **subscriber**: `NoSubscriber`, a no-op `Subscriber` implementation ([#1549]) - **field**: Added `Visit::record_f64` and support for recording floating-point values ([#1507]) Thanks to new contributors @jsgf and @maxburke for contributing to this release! [#1549]: #1549 [#1507]: #1507
# 0.2.21 (September 12, 2021) This release introduces the [`Filter`] trait, a new API for [per-layer filtering][plf]. This allows controlling which spans and events are recorded by various layers individually, rather than globally. In addition, it adds a new [`Targets`] filter, which provides a lighter-weight version of the filtering provided by [`EnvFilter`], as well as other smaller API improvements and fixes. ### Deprecated - **registry**: `SpanRef::parent_id`, which cannot properly support per-layer filtering. Use `.parent().map(SpanRef::id)` instead. ([#1523]) ### Fixed - **layer** `Context` methods that are provided when the `Subscriber` implements `LookupSpan` no longer require the "registry" feature flag ([#1525]) - **layer** `fmt::Debug` implementation for `Layered` no longer requires the `S` type parameter to implement `Debug` ([#1528]) ### Added - **registry**: `Filter` trait, `Filtered` type, `Layer::with_filter` method, and other APIs for per-layer filtering ([#1523]) - **filter**: `FilterFn` and `DynFilterFn` types that implement global (`Layer`) and per-layer (`Filter`) filtering for closures and function pointers ([#1523]) - **filter**: `Targets` filter, which implements a lighter-weight form of `EnvFilter`-like filtering ([#1550]) - **env-filter**: Added support for filtering on floating-point values ([#1507]) - **layer**: `Layer::on_layer` callback, called when layering the `Layer` onto a `Subscriber` ([#1523]) - **layer**: `Layer` implementations for `Box<L>` and `Arc<L>` where `L: Layer` ([#1536]) - **layer**: `Layer` implementations for `Box<dyn Layer>` and `Arc<dyn Layer>` ([#1536]) - A number of small documentation fixes and improvements ([#1553], [#1544], [#1539], [#1524]) Special thanks to new contributors @jsgf and @maxburke for contributing to this release! [`Filter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/trait.Filter.html [plf]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/index.html#per-layer-filtering [`Targets`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.Targets.html [`EnvFilter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.EnvFilter.html [#1507]: #1507 [#1523]: #1523 [#1524]: #1524 [#1525]: #1525 [#1528]: #1528 [#1539]: #1539 [#1544]: #1544 [#1550]: #1550 [#1553]: #1553
# 0.2.21 (September 12, 2021) This release introduces the [`Filter`] trait, a new API for [per-layer filtering][plf]. This allows controlling which spans and events are recorded by various layers individually, rather than globally. In addition, it adds a new [`Targets`] filter, which provides a lighter-weight version of the filtering provided by [`EnvFilter`], as well as other smaller API improvements and fixes. ### Deprecated - **registry**: `SpanRef::parent_id`, which cannot properly support per-layer filtering. Use `.parent().map(SpanRef::id)` instead. ([#1523]) ### Fixed - **layer** `Context` methods that are provided when the `Subscriber` implements `LookupSpan` no longer require the "registry" feature flag ([#1525]) - **layer** `fmt::Debug` implementation for `Layered` no longer requires the `S` type parameter to implement `Debug` ([#1528]) ### Added - **registry**: `Filter` trait, `Filtered` type, `Layer::with_filter` method, and other APIs for per-layer filtering ([#1523]) - **filter**: `FilterFn` and `DynFilterFn` types that implement global (`Layer`) and per-layer (`Filter`) filtering for closures and function pointers ([#1523]) - **filter**: `Targets` filter, which implements a lighter-weight form of `EnvFilter`-like filtering ([#1550]) - **env-filter**: Added support for filtering on floating-point values ([#1507]) - **layer**: `Layer::on_layer` callback, called when layering the `Layer` onto a `Subscriber` ([#1523]) - **layer**: `Layer` implementations for `Box<L>` and `Arc<L>` where `L: Layer` ([#1536]) - **layer**: `Layer` implementations for `Box<dyn Layer>` and `Arc<dyn Layer>` ([#1536]) - A number of small documentation fixes and improvements ([#1553], [#1544], [#1539], [#1524]) Special thanks to new contributors @jsgf and @maxburke for contributing to this release! [`Filter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/trait.Filter.html [plf]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/index.html#per-layer-filtering [`Targets`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.Targets.html [`EnvFilter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.EnvFilter.html [#1507]: #1507 [#1523]: #1523 [#1524]: #1524 [#1525]: #1525 [#1528]: #1528 [#1539]: #1539 [#1544]: #1544 [#1550]: #1550 [#1553]: #1553
# 0.1.27 (September 13, 2021) This release adds a new [`Span::or_current`] method to aid in efficiently propagating span contexts to spawned threads or tasks. Additionally, it updates the [`tracing-core`] version to [0.1.20] and the [`tracing-attributes`] version to [0.1.16], ensuring that a number of new features in those crates are present. ### Fixed - **instrument**: Added missing `WithSubscriber` implementations for futures and other types ([#1424]) ### Added - `Span::or_current` method, to help with efficient span context propagation ([#1538]) - **attributes**: add `skip_all` option to `#[instrument]` ([#1548]) - **attributes**: record primitive types as primitive values rather than as `fmt::Debug` ([#1378]) - **core**: `NoSubscriber`, a no-op `Subscriber` implementation ([#1549]) - **core**: Added `Visit::record_f64` and support for recording floating-point values ([#1507], [#1522]) - A large number of documentation improvements and fixes ([#1369], [#1398], [#1435], [#1442], [#1524], [#1556]) Thanks to new contributors @dzvon and @mbergkvist, as well as @teozkr, @maxburke, @LukeMathWalker, and @jsgf, for contributing to this release! [`Span::or_current`]: https://docs.rs/tracing/0.1.27/tracing/struct.Span.html#method.or_current [`tracing-core`]: https://crates.io/crates/tracing-core [`tracing-attributes`]: https://crates.io/crates/tracing-attributes [`tracing-core`]: https://crates.io/crates/tracing-core [0.1.20]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.20 [0.1.16]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.16 [#1424]: #1424 [#1538]: #1538 [#1548]: #1548 [#1378]: #1378 [#1507]: #1507 [#1522]: #1522 [#1369]: #1369 [#1398]: #1398 [#1435]: #1435 [#1442]: #1442
# 0.1.27 (September 13, 2021) This release adds a new [`Span::or_current`] method to aid in efficiently propagating span contexts to spawned threads or tasks. Additionally, it updates the [`tracing-core`] version to [0.1.20] and the [`tracing-attributes`] version to [0.1.16], ensuring that a number of new features in those crates are present. ### Fixed - **instrument**: Added missing `WithSubscriber` implementations for futures and other types (#1424) ### Added - `Span::or_current` method, to help with efficient span context propagation (#1538) - **attributes**: add `skip_all` option to `#[instrument]` (#1548) - **attributes**: record primitive types as primitive values rather than as `fmt::Debug` (#1378) - **core**: `NoSubscriber`, a no-op `Subscriber` implementation (#1549) - **core**: Added `Visit::record_f64` and support for recording floating-point values (#1507, #1522) - A large number of documentation improvements and fixes (#1369, #1398, #1435, #1442, #1524, #1556) Thanks to new contributors @dzvon and @mbergkvist, as well as @teozkr, @maxburke, @LukeMathWalker, and @jsgf, for contributing to this release! [`Span::or_current`]: https://docs.rs/tracing/0.1.27/tracing/struct.Span.html#method.or_current [`tracing-core`]: https://crates.io/crates/tracing-core [`tracing-attributes`]: https://crates.io/crates/tracing-attributes [`tracing-core`]: https://crates.io/crates/tracing-core [0.1.20]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.20 [0.1.16]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.16
# 0.1.3 (February 4, 2022) This release adds *experimental* support for recording structured field values using the [`valuable`] crate. See [this blog post][post] for details on `valuable`. Note that `valuable` support currently requires `--cfg tracing_unstable`. See the documentation for details. ### Added - **valuable**: Experimental support for serializing user-defined types using [`valuable`] and [`valuable-serde`] ([#1862]) - Support for serializing `f64` values ([#1507]) ### Fixed - Fixed incorrect size hint in `SerializeFieldSet` ([#1333]) - A number of documentation fixes Thanks to @akinnane and @maxburke for contributing to this release! [`valuable`]: https://crates.io/crates/valuable [`valuable-serde`]: https://crates.io/crates/valuable-serde [post]: https://tokio.rs/blog/2021-05-valuable [#1862]: #1862 [#1507]: #1507 [#1333]: #1333 (I also noticed there was a missing changelog entry for v0.1.2, so I fixed that while I was here)
# 0.1.3 (February 4, 2022) This release adds *experimental* support for recording structured field values using the [`valuable`] crate. See [this blog post][post] for details on `valuable`. Note that `valuable` support currently requires `--cfg tracing_unstable`. See the documentation for details. ### Added - **valuable**: Experimental support for serializing user-defined types using [`valuable`] and [`valuable-serde`] ([#1862]) - Support for serializing `f64` values ([#1507]) ### Fixed - Fixed incorrect size hint in `SerializeFieldSet` ([#1333]) - A number of documentation fixes Thanks to @akinnane and @maxburke for contributing to this release! [`valuable`]: https://crates.io/crates/valuable [`valuable-serde`]: https://crates.io/crates/valuable-serde [post]: https://tokio.rs/blog/2021-05-valuable [#1862]: #1862 [#1507]: #1507 [#1333]: #1333 (I also noticed there was a missing changelog entry for v0.1.2, so I fixed that while I was here)
## Motivation Tracing is a really useful framework but a lack of floating point value support for the core visitors means these get coerced unnecessarily to strings. ## Solution This change adds support for floating point (`f64`) visitors.
# 0.1.20 (September 12, 2021) This release adds support for `f64` as one of the `tracing-core` primitive field values, allowing floating-point values to be recorded as typed values rather than with `fmt::Debug`. Additionally, it adds `NoSubscriber`, a `Subscriber` implementation that does nothing. ### Added - **subscriber**: `NoSubscriber`, a no-op `Subscriber` implementation ([tokio-rs#1549]) - **field**: Added `Visit::record_f64` and support for recording floating-point values ([tokio-rs#1507]) Thanks to new contributors @jsgf and @maxburke for contributing to this release! [tokio-rs#1549]: tokio-rs#1549 [tokio-rs#1507]: tokio-rs#1507
# 0.2.21 (September 12, 2021) This release introduces the [`Filter`] trait, a new API for [per-layer filtering][plf]. This allows controlling which spans and events are recorded by various layers individually, rather than globally. In addition, it adds a new [`Targets`] filter, which provides a lighter-weight version of the filtering provided by [`EnvFilter`], as well as other smaller API improvements and fixes. ### Deprecated - **registry**: `SpanRef::parent_id`, which cannot properly support per-layer filtering. Use `.parent().map(SpanRef::id)` instead. ([tokio-rs#1523]) ### Fixed - **layer** `Context` methods that are provided when the `Subscriber` implements `LookupSpan` no longer require the "registry" feature flag ([tokio-rs#1525]) - **layer** `fmt::Debug` implementation for `Layered` no longer requires the `S` type parameter to implement `Debug` ([tokio-rs#1528]) ### Added - **registry**: `Filter` trait, `Filtered` type, `Layer::with_filter` method, and other APIs for per-layer filtering ([tokio-rs#1523]) - **filter**: `FilterFn` and `DynFilterFn` types that implement global (`Layer`) and per-layer (`Filter`) filtering for closures and function pointers ([tokio-rs#1523]) - **filter**: `Targets` filter, which implements a lighter-weight form of `EnvFilter`-like filtering ([tokio-rs#1550]) - **env-filter**: Added support for filtering on floating-point values ([tokio-rs#1507]) - **layer**: `Layer::on_layer` callback, called when layering the `Layer` onto a `Subscriber` ([tokio-rs#1523]) - **layer**: `Layer` implementations for `Box<L>` and `Arc<L>` where `L: Layer` ([tokio-rs#1536]) - **layer**: `Layer` implementations for `Box<dyn Layer>` and `Arc<dyn Layer>` ([tokio-rs#1536]) - A number of small documentation fixes and improvements ([tokio-rs#1553], [tokio-rs#1544], [tokio-rs#1539], [tokio-rs#1524]) Special thanks to new contributors @jsgf and @maxburke for contributing to this release! [`Filter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/trait.Filter.html [plf]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/layer/index.html#per-layer-filtering [`Targets`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.Targets.html [`EnvFilter`]: https://docs.rs/tracing-subscriber/0.2.21/tracing_subscriber/filter/struct.EnvFilter.html [tokio-rs#1507]: tokio-rs#1507 [tokio-rs#1523]: tokio-rs#1523 [tokio-rs#1524]: tokio-rs#1524 [tokio-rs#1525]: tokio-rs#1525 [tokio-rs#1528]: tokio-rs#1528 [tokio-rs#1539]: tokio-rs#1539 [tokio-rs#1544]: tokio-rs#1544 [tokio-rs#1550]: tokio-rs#1550 [tokio-rs#1553]: tokio-rs#1553
# 0.1.27 (September 13, 2021) This release adds a new [`Span::or_current`] method to aid in efficiently propagating span contexts to spawned threads or tasks. Additionally, it updates the [`tracing-core`] version to [0.1.20] and the [`tracing-attributes`] version to [0.1.16], ensuring that a number of new features in those crates are present. ### Fixed - **instrument**: Added missing `WithSubscriber` implementations for futures and other types (tokio-rs#1424) ### Added - `Span::or_current` method, to help with efficient span context propagation (tokio-rs#1538) - **attributes**: add `skip_all` option to `#[instrument]` (tokio-rs#1548) - **attributes**: record primitive types as primitive values rather than as `fmt::Debug` (tokio-rs#1378) - **core**: `NoSubscriber`, a no-op `Subscriber` implementation (tokio-rs#1549) - **core**: Added `Visit::record_f64` and support for recording floating-point values (tokio-rs#1507, tokio-rs#1522) - A large number of documentation improvements and fixes (tokio-rs#1369, tokio-rs#1398, tokio-rs#1435, tokio-rs#1442, tokio-rs#1524, tokio-rs#1556) Thanks to new contributors @dzvon and @mbergkvist, as well as @teozkr, @maxburke, @LukeMathWalker, and @jsgf, for contributing to this release! [`Span::or_current`]: https://docs.rs/tracing/0.1.27/tracing/struct.Span.html#method.or_current [`tracing-core`]: https://crates.io/crates/tracing-core [`tracing-attributes`]: https://crates.io/crates/tracing-attributes [`tracing-core`]: https://crates.io/crates/tracing-core [0.1.20]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.20 [0.1.16]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.16
# 0.1.3 (February 4, 2022) This release adds *experimental* support for recording structured field values using the [`valuable`] crate. See [this blog post][post] for details on `valuable`. Note that `valuable` support currently requires `--cfg tracing_unstable`. See the documentation for details. ### Added - **valuable**: Experimental support for serializing user-defined types using [`valuable`] and [`valuable-serde`] ([tokio-rs#1862]) - Support for serializing `f64` values ([tokio-rs#1507]) ### Fixed - Fixed incorrect size hint in `SerializeFieldSet` ([tokio-rs#1333]) - A number of documentation fixes Thanks to @akinnane and @maxburke for contributing to this release! [`valuable`]: https://crates.io/crates/valuable [`valuable-serde`]: https://crates.io/crates/valuable-serde [post]: https://tokio.rs/blog/2021-05-valuable [tokio-rs#1862]: tokio-rs#1862 [tokio-rs#1507]: tokio-rs#1507 [tokio-rs#1333]: tokio-rs#1333 (I also noticed there was a missing changelog entry for v0.1.2, so I fixed that while I was here)
Motivation
Tracing is a really useful framework but a lack of floating point value support for the core visitors means these get coerced unnecessarily to strings.
Solution
This change adds support for floating point (f64) visitors.