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

Feature/valuable integration #1608

Merged
merged 27 commits into from
Jan 21, 2022

Conversation

xd009642
Copy link
Contributor

@xd009642 xd009642 commented Oct 1, 2021

Start the initial integration of Valuable into tracing by adding it to the visit trait, implementing Value for Valuable and seeing if it all works. For further motivation see the tracking issue: #1570

For my own testing, I have a project with the following main.rs, I grabbed the Person and Address types from a valuable example:

use valuable::Valuable;
use tracing::{info, info_span};

#[derive(Valuable)]
pub struct Person {
    name: String,
    age: u32,
    addresses: Vec<Address>,
}

#[derive(Valuable)]
pub struct Address {
    street: String,
    city: String,
    zip: String,
}

fn blah(value: &(dyn Valuable + 'static)) -> tracing::Span {
    info_span!("span", v=value)
}

fn blahblah(person: &Person) -> tracing::Span {
    info_span!("span", v=person)
}

fn main() {

    let person = Person {
        name: "Daniel".to_string(),
        age: 28,
        addresses: vec![
            Address {
                street: "redacted".to_string(),
                city: "London".to_string(),
                zip: "redacted".to_string()
            }
        ]
    };

    blah(&person);
    blahblah(&person);
}

Currently blah works, but blahblah has a compilation error which I'm currently trying to resolve but I rarely touch macros in rust so any help would be appreciated:

error[E0277]: the trait bound `Person: tracing::Value` is not satisfied
  --> src/main.rs:23:5
   |
23 |     info_span!("span", v=person)
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `tracing::Value` is not implemented for `Person`
   |
   = note: required because of the requirements on the impl of `tracing::Value` for `&Person`
   = note: required for the cast to the object type `dyn tracing::Value`
   = note: this error originates in the macro `$crate::valueset` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `Person: tracing::Value` is not satisfied
  --> src/main.rs:41:5
   |
41 |     info_span!("Greeting", person=person);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `tracing::Value` is not implemented for `Person`
   |
   = note: required for the cast to the object type `dyn tracing::Value`
   = note: this error originates in the macro `$crate::valueset` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.
error: could not compile `tracing-valuable-test` due to 2 previous errors

@xd009642 xd009642 requested review from carllerche, davidbarsky, hawkw and a team as code owners October 1, 2021 17:41
@xd009642 xd009642 force-pushed the feature/valuable-integration branch from 5147657 to 7a2f3c5 Compare October 1, 2021 17:43
@xd009642
Copy link
Contributor Author

xd009642 commented Oct 1, 2021

Okay after some useful guidance from @hawkw on discord I've added a ValuableValue type (candidates for better names more than welcome). And the following minimal example compiles.

use valuable::Valuable;
use tracing::{info, info_span};

#[derive(Valuable)]
pub struct Person {
    name: String,
    age: u32,
    addresses: Vec<Address>,
}

#[derive(Valuable)]
pub struct Address {
    street: String,
    city: String,
    zip: String,
}

fn blah(value: &(dyn Valuable + 'static)) -> tracing::Span {
    info_span!("span", v=tracing::field::valuable(value))
}

fn blahblah(person: &Person) -> tracing::Span {
    info_span!("span", v=tracing::field::valuable(person))
}

fn main() {

    let person = Person {
        name: "Daniel".to_string(),
        age: 28,
        addresses: vec![
            Address {
                street: "redacted".to_string(),
                city: "London".to_string(),
                zip: "redacted".to_string()
            }
        ]
    };

    blah(&person);
    info_span!("Greeting", person=tracing::field::valuable(person));
    info!("Hello");
}

I haven't yet made any moves to gate it behind a cfg like RUSTFLAGS="--cfg tracing_unstable" as suggested in the tracking issue by @davidbarsky. I guess my only question for that would be should it still be an optional feature then or remove the feature entirely in favour of the cfg. Either way that should be a simple change so I figured i'd do that as part of the tidy up once everyone's happy with how it's currently looking and working

@hawkw
Copy link
Member

hawkw commented Oct 1, 2021

I guess my only question for that would be should it still be an optional feature then or remove the feature entirely in favour of the cfg.

Regardless of whether or not we add an unstable cfg, it should be an optional dependency. The goal is that the tracing_unstable cfg would be temporary, and it would eventually be removed. However, once the unstable cfg is removed, I think we would still want users to be able to determine whether or not the valuable dependency is enabled. So, if we add the cfg, we should still feature flag as well.

@hawkw hawkw marked this pull request as draft October 1, 2021 21:40
@hawkw
Copy link
Member

hawkw commented Oct 1, 2021

I'm going to try to give this a closer review this afternoon. However, I wanted to start by saying that we are not going to be able to merge this PR until there's a crates.io release of valuable. Since we can't publish new tracing releases if we have git dependencies, merging this PR would block publishing tracing releases until valuable is on crates.io.

Therefore, since this is currently blocked on a published valuable release, I'm marking this PR as a draft, since it can't be merged yet for reasons not directly related to the code change here.

cc @carllerche

@xd009642
Copy link
Contributor Author

xd009642 commented Oct 4, 2021

I've just added the config, missing debug implementation and missing doc comments for this PR. Pending any review comments and a valuable release to crates.io the only thing I can see that would need doing is an update to the CI so the valuable code is also tested. But not sure how thorough the checks should be (i.e. do we still care about MSRV for an unstable feature).

If I have time to do it I'll also work on playing around using this branch on a personal project and if anything of interest comes up or I push anything publicly I'll mention it 😄

Copy link
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I finally had a chance to give this a review, and overall it looks great. I commented on a few small things that I think we ought to change.

It would definitely also be nice to have some tests for this, and to flesh out the docs and examples somewhat, but that isn't strictly necessary until we can actually merge this PR (which is still blocked on an actual release of valuable). So, we can do that later --- for now, I think testing out the branch to make sure it's actually usable is probably the most important next step!

tracing-core/src/field.rs Outdated Show resolved Hide resolved
tracing-core/Cargo.toml Outdated Show resolved Hide resolved
tracing-core/src/field.rs Show resolved Hide resolved
tracing-core/src/field.rs Show resolved Hide resolved
tracing-core/src/field.rs Show resolved Hide resolved
tracing-core/src/field.rs Show resolved Hide resolved
#[cfg_attr(docsrs, doc(cfg(all(tracing_unstable, feature = "valuable"))))]
impl<T: valuable::Valuable> Value for ValuableValue<T> {
fn record(&self, key: &Field, visitor: &mut dyn Visit) {
visitor.record_value(key, &self.0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a potential thought, although i'm not sure whether or not it's necessary: valuable's list of primitive types has some overlaps with tracing's. we may want to consider doing something where we call Valuable::as_value, match on the result, and call the Visit type's record_$TY methods for tracing primitive types if the value is a tracing primitive? e.g.

Suggested change
visitor.record_value(key, &self.0)
match self.0.as_value() {
valuable::Value::I64(v) => visitor.record_i64(key, v),
valuable::Value::U64(v) => visitor.record_u64(key, v),
// ...
_ => visitor.record_value(key, &self.0)
}

I'm not totally sure if this is the right approach or not, but the thought process here is that visitors that are aware of Valuable will probably still implement the record_$TY methods for various tracing primitives as well, since a majority of the values recorded will not be Valuables. but, the visitor implementation could always handle the duplicated code itself...idk if this is worth doing here or not. probably worth testing it out in your own code and seeing how it feels...

tracing-core/src/field.rs Show resolved Hide resolved
tracing-core/src/field.rs Outdated Show resolved Hide resolved
@xd009642
Copy link
Contributor Author

xd009642 commented Oct 4, 2021

Oh yeah tests would be good, I guess I'll work out something with a custom visitor at some point to make sure the dispatch works correctly - unless there's any smart/more-important things to test with this. When I have some code using this branch I'll apply the unresolved suggested change and see what it's like with and without it

@hawkw
Copy link
Member

hawkw commented Oct 5, 2021

Another good way to test out that this actually works correctly would be writing a few quick examples in the examples/ dir. That way, we can demonstrate that it works, and when it's ready to merge, we'll already have some nice examples for users to learn how to use it.

@xd009642
Copy link
Contributor Author

xd009642 commented Oct 5, 2021

Added a very simple example, emphasis on very simple it just derives Valuable on a type adds it as a field to a span and then emits an event with the default format subscriber so you can see it printed out. I also cribbed the person/address example from valuable again with a lord of the rings reference because it was the first thing to come to mind that shouldn't covered by copyright wasn't my own name and address 😅

Clippy doesn't like the example without a main function though, so maybe attributes on everything is a nicer approach just for CI

@hawkw
Copy link
Member

hawkw commented Oct 5, 2021

Clippy doesn't like the example without a main function though, so maybe attributes on everything is a nicer approach just for CI

hmm, that's annoying. another option is to make a separate crate unstable-examples and put all the examples that require tracing-unstable (currently only the valuable ones) in that crate. then, we could build the unstable examples crate separately, and have it require the unstable feature to be enabled?

it may also be worth looking at what other crates in the ecosystem do for examples that require a cfg to be set?

as a side note, it looks like it's not just clippy; a missing main seems to actually be a compile error. so, we can't just slap an #[allow(clippy::no_main)] in that file, or something like that; the missing main function is a hard error, not an ignorable warning. :(

@hawkw hawkw changed the base branch from master to v0.1.x October 7, 2021 17:34
@hawkw hawkw changed the base branch from v0.1.x to master October 7, 2021 17:34
@hawkw
Copy link
Member

hawkw commented Oct 7, 2021

I just realized that this branch is based on master rather than v0.1.x, but this change is the v0.1 version of valuable support, so it should really be based on the v0.1.x branch.

I tried changing the base in the github UI, but this branch also contains a bunch of unrelated changes from master. @xd009642, would you mind rebasing this onto v0.1.x, dropping all the commits from master? It should hopefully rebase cleanly; you may want to use git rebase -i and drop all the commits that aren't part of the valuable integration change.

xd009642 and others added 7 commits January 20, 2022 00:18
The woes of trying to rush something in when tired
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
examples/examples/valuable.rs Outdated Show resolved Hide resolved
@hawkw hawkw enabled auto-merge (squash) January 21, 2022 21:07
@hawkw hawkw merged commit 5d08634 into tokio-rs:v0.1.x Jan 21, 2022
hawkw added a commit that referenced this pull request Feb 4, 2022
# 0.1.22 (February 3, 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

- **field**: Experimental support for recording field values using the
  [`valuable`] crate ([#1608], [#1888], [#1887])
- **field**: Added `ValueSet::record` method ([#1823])
- **subscriber**: `Default` impl for `NoSubscriber` ([#1785])
- **metadata**: New `Kind::HINT` to support the `enabled!` macro in
  `tracing` ([#1883], [#1891])
### Fixed

- Fixed a number of documentation issues ([#1665], [#1692], [#1737])

Thanks to @xd009642, @Skepfyr, @guswynn, @Folyd, and @mbergkvist for
contributing to this release!
hawkw added a commit that referenced this pull request Feb 4, 2022
# 0.1.22 (February 3, 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

- **field**: Experimental support for recording field values using the
  [`valuable`] crate ([#1608], [#1888], [#1887])
- **field**: Added `ValueSet::record` method ([#1823])
- **subscriber**: `Default` impl for `NoSubscriber` ([#1785])
- **metadata**: New `Kind::HINT` to support the `enabled!` macro in
  `tracing` ([#1883], [#1891])
### Fixed

- Fixed a number of documentation issues ([#1665], [#1692], [#1737])

Thanks to @xd009642, @Skepfyr, @guswynn, @Folyd, and @mbergkvist for
contributing to this release!

[`valuable`]: https://crates.io/crates/valuable
[post]: https://tokio.rs/blog/2021-05-valuable
[#1608]: #1608
[#1888]: #1888
[#1887]: #1887
[#1823]: #1823
[#1785]: #1785
[#1883]: #1883
[#1891]: #1891
[#1665]: #1665
[#1692]: #1692
[#1737]: #1737
hawkw added a commit that referenced this pull request Feb 4, 2022
# 0.1.30 (February 3rd, 2021)

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.

This release also adds a new `enabled!` macro for testing if a span or
event would be enabled.

### Added

- **field**: Experimental support for recording field values using the
  [`valuable`] crate ([#1608], [#1888], [#1887])
- `enabled!` macro for testing if a span or event is enabled ([#1882])

### Changed

- `tracing-core`: updated to [0.1.22][core-0.1.22]
- `tracing-attributes`: updated to [0.1.19][attributes-0.1.19]

### Fixed

- **log**: Fixed "use of moved value" compiler error when the "log"
  feature is enabled ([#1823])
- Fixed macro hygiene issues when used in a crate that defines its own
  `concat!` macro ([#1842])
- A very large number of documentation fixes and improvements.

Thanks to @@vlad-scherbina, @Skepfyr, @Swatinem, @guswynn, @teohhanhui,
@xd009642, @tobz, @d-e-s-o@0b01, and @nickelc for contributing to this
release!

[`valuable`]: https://crates.io/crates/valuable
[post]: https://tokio.rs/blog/2021-05-valuable
[core-0.1.22]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.22
[attributes-0.1.19]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.19
[#1608]: #1608
[#1888]: #1888
[#1887]: #1887
[#1882]: #1882
[#1823]: #1823
[#1842]: #1842
hawkw added a commit that referenced this pull request Feb 4, 2022
# 0.1.30 (February 3rd, 2021)

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.

This release also adds a new `enabled!` macro for testing if a span or
event would be enabled.

### Added

- **field**: Experimental support for recording field values using the
  [`valuable`] crate ([#1608], [#1888], [#1887])
- `enabled!` macro for testing if a span or event is enabled ([#1882])

### Changed

- `tracing-core`: updated to [0.1.22][core-0.1.22]
- `tracing-attributes`: updated to [0.1.19][attributes-0.1.19]

### Fixed

- **log**: Fixed "use of moved value" compiler error when the "log"
  feature is enabled ([#1823])
- Fixed macro hygiene issues when used in a crate that defines its own
  `concat!` macro ([#1842])
- A very large number of documentation fixes and improvements.

Thanks to @@vlad-scherbina, @Skepfyr, @Swatinem, @guswynn, @teohhanhui,
@xd009642, @tobz, @d-e-s-o@0b01, and @nickelc for contributing to this
release!

[`valuable`]: https://crates.io/crates/valuable
[post]: https://tokio.rs/blog/2021-05-valuable
[core-0.1.22]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.22
[attributes-0.1.19]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.19
[#1608]: #1608
[#1888]: #1888
[#1887]: #1887
[#1882]: #1882
[#1823]: #1823
[#1842]: #1842
kaffarell pushed a commit to kaffarell/tracing that referenced this pull request May 22, 2024
# 0.3.4 (Dec 23, 2021)

This release contains bugfixes for the `fmt` module, as well as documentation
improvements.

### Fixed

- **fmt**: Fixed `fmt` not emitting log lines when timestamp formatting fails
  ([tokio-rs#1689])
- **fmt**: Fixed double space before thread IDs with `Pretty` formatter
  ([tokio-rs#1778])
- Several documentation improvements ([tokio-rs#1608], [tokio-rs#1699], [tokio-rs#1701])

[tokio-rs#1689]: tokio-rs#1689
[tokio-rs#1778]: tokio-rs#1778
[tokio-rs#1608]: tokio-rs#1608
[tokio-rs#1699]: tokio-rs#1699
[tokio-rs#1701]: tokio-rs#1701

Thanks to new contributors @Swatinem and @rukai for contributing to this
release!
kaffarell pushed a commit to kaffarell/tracing that referenced this pull request May 22, 2024
This branch adds initial support for using the [`valuable`] crate as an
opt-in `Value` type in `tracing`. `valuable` provides a mechanism for
defining custom ways to record user-implemented types, as well as
structured recording of standard library data structures such as maps,
arrays, and sets.

For more details, see the tracking issue tokio-rs#1570.

In `tracing` v0.2, the intent is for `valuable` to replace the existing
`tracing_core::field::Value` trait. However, in v0.1.x, `valuable`
support must be added in a backwards-compatible way, so recording types
that implement `valuable::Valueable` currently requires opting in using
a `field::valuable` wrapper function.

Since this is the first release of `valuable` and the API is still
stabilizing, we don't want to tie `tracing-core`'s stability to
`valuable`'s. Therefore, the valuable dependency is feature-flagged
*and* also requires `RUSTFLAGS="--cfg tracing_unstable"`.

[`valuable`]: https://github.com/tokio-rs/valuable

Co-authored-by: Daniel McKenna <daniel@emotech.co>
Co-authored-by: David Barsky <me@davidbarsky.com>
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
kaffarell pushed a commit to kaffarell/tracing that referenced this pull request May 22, 2024
# 0.1.22 (February 3, 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

- **field**: Experimental support for recording field values using the
  [`valuable`] crate ([tokio-rs#1608], [tokio-rs#1888], [tokio-rs#1887])
- **field**: Added `ValueSet::record` method ([tokio-rs#1823])
- **subscriber**: `Default` impl for `NoSubscriber` ([tokio-rs#1785])
- **metadata**: New `Kind::HINT` to support the `enabled!` macro in
  `tracing` ([tokio-rs#1883], [tokio-rs#1891])
### Fixed

- Fixed a number of documentation issues ([tokio-rs#1665], [tokio-rs#1692], [tokio-rs#1737])

Thanks to @xd009642, @Skepfyr, @guswynn, @Folyd, and @mbergkvist for
contributing to this release!

[`valuable`]: https://crates.io/crates/valuable
[post]: https://tokio.rs/blog/2021-05-valuable
[tokio-rs#1608]: tokio-rs#1608
[tokio-rs#1888]: tokio-rs#1888
[tokio-rs#1887]: tokio-rs#1887
[tokio-rs#1823]: tokio-rs#1823
[tokio-rs#1785]: tokio-rs#1785
[tokio-rs#1883]: tokio-rs#1883
[tokio-rs#1891]: tokio-rs#1891
[tokio-rs#1665]: tokio-rs#1665
[tokio-rs#1692]: tokio-rs#1692
[tokio-rs#1737]: tokio-rs#1737
kaffarell pushed a commit to kaffarell/tracing that referenced this pull request May 22, 2024
# 0.1.30 (February 3rd, 2021)

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.

This release also adds a new `enabled!` macro for testing if a span or
event would be enabled.

### Added

- **field**: Experimental support for recording field values using the
  [`valuable`] crate ([tokio-rs#1608], [tokio-rs#1888], [tokio-rs#1887])
- `enabled!` macro for testing if a span or event is enabled ([tokio-rs#1882])

### Changed

- `tracing-core`: updated to [0.1.22][core-0.1.22]
- `tracing-attributes`: updated to [0.1.19][attributes-0.1.19]

### Fixed

- **log**: Fixed "use of moved value" compiler error when the "log"
  feature is enabled ([tokio-rs#1823])
- Fixed macro hygiene issues when used in a crate that defines its own
  `concat!` macro ([tokio-rs#1842])
- A very large number of documentation fixes and improvements.

Thanks to @@vlad-scherbina, @Skepfyr, @Swatinem, @guswynn, @teohhanhui,
@xd009642, @tobz, @d-e-s-o@0b01, and @nickelc for contributing to this
release!

[`valuable`]: https://crates.io/crates/valuable
[post]: https://tokio.rs/blog/2021-05-valuable
[core-0.1.22]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.22
[attributes-0.1.19]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.19
[tokio-rs#1608]: tokio-rs#1608
[tokio-rs#1888]: tokio-rs#1888
[tokio-rs#1887]: tokio-rs#1887
[tokio-rs#1882]: tokio-rs#1882
[tokio-rs#1823]: tokio-rs#1823
[tokio-rs#1842]: tokio-rs#1842
@@ -27,7 +27,7 @@ edition = "2018"
rust-version = "1.42.0"

[features]
default = ["std"]
default = ["std", "valuable/std"]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this causes cargo to download the valuable crate even though it isn't actually used without tracing_unstable

hawkw pushed a commit that referenced this pull request Jun 9, 2024
…`valuable` is used (#3002)

## Motivation

`tracing-core` adds a dependency on `valuable` anytime the `std` (or `default`) feature is enabled even when `valuable` is not meant to be used. This was pointed out by [this comment](#1608 (comment)).

## Solution

Only add the feature dependency when something enables `valuable`.

This does not apply to `master` as `valuable` support there is always on.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants