190 Commits

Author SHA1 Message Date
David Barsky
7f0cc09d0b docs: remove usage of 0.2 terminology (#2728) 2023-10-01 10:46:02 -07:00
Ethan Brierley
1771128aea core: allow ValueSets of any length (#2508)
## Motivation

Fixes: #1566

## Solution

This change removes the maximum of 32 fields limitation using const
generics.

Having this arbitrary restriction in place to prevent stack overflows
feels a little misplaced to me since stack size varies between
environments.
2023-10-01 10:46:02 -07:00
Eliza Weisman
e03a831d05 chore: fix new warnings in Rust 1.72.0 (#2700)
This branch fixes a handful of new warnings which have shown up after
updating to Rust 1.72.0.

This includes:

* `clippy::redundant_closure_call` in macros --- allowed because the
  macro sometimes calls a function that isn't a closure, and the closure
  is just used in the case where it's not a function.
* Unnecessary uses of `#` in raw string literals that don't contain `"`
  characters.
* Dead code warnings with specific feature flag combinations in
  `tracing-subscriber`.

In addition, I've fixed a broken RustDoc link that was making the
Netlify build sad.
2023-10-01 10:46:02 -07:00
Alexander Tesfamichael
1115777024 docs(field): remove duplicate wording (#2674) 2023-10-01 10:46:02 -07:00
Nikita Popov
e604f2414e core: ensure callsites in test have unique addresses (#2681)
The test relies on TEST_CALLSITE_1 and TEST_CALLSITE_2 to have
different addresses. However, as they are zero-sized types, this
is not guaranteed.

This fixes the test failure with LLVM 17 and certain optimization
options reported at https://github.com/rust-lang/rust/issues/114699.
2023-10-01 10:46:02 -07:00
Harry Barber
111ad87d3d tracing: use fully qualified names in macros for items exported from std prelude (#2621)
Currently, in many places, macros do not use fully qualified names for
items exported from the prelude. This means that naming collisions
(`struct Some`) or the removal of the std library prelude will cause
compilation errors.

- Identify and use fully qualified names in macros were we previously
  assumed the Rust std prelude. We use `::core` rather than `::std`.
- Add
  [`no_implicit_prelude`](https://doc.rust-lang.org/reference/names/preludes.html#the-no_implicit_prelude-attribute)
  to `tracing/tests/macros.rs`. I'm unsure if this is giving us good
  coverage - can we improve on this approach? I'm not confident I've
  caught everything.
2023-10-01 10:46:02 -07:00
Guillaume Desmottes
a65bb78ef4 core: fix typo in field docs (#2611)
Module `tracing::field` documentation is missing a word.

Fixing the typo by adding `event`.
; Conflicts:
;	tracing-core/src/field.rs
2023-06-19 06:26:02 -07:00
Eliza Weisman
bec82286e8
core: prepare to release v0.1.31 (#2594)
# 0.1.31 (May 11, 2023)

This release of `tracing-core` fixes a bug that caused threads which
call `dispatcher::get_default` _before_ a global default subscriber is
set to never see the global default once it is set. In addition, it
includes improvements for instrumentation performance in some cases,
especially when using a global default dispatcher.

### Fixed

- Fixed incorrect thread-local caching of `Dispatch::none` if
  `dispatcher::get_default` is called before
  `dispatcher::set_global_default` (#2593)

### Changed

- Cloning a `Dispatch` that points at a global default subscriber no
  longer requires an `Arc` reference count increment, improving
  performance substantially (#2593)
- `dispatcher::get_default` no longer attempts to access a thread local
  if the scoped dispatcher is not in use, improving performance when the
  default dispatcher is global (#2593)
- Added `#[inline]` annotations called by the `event!` and `span!`
  macros to reduce the size of macro-generated code and improve
  recording performance (#2555)

Thanks to new contributor @ldm0 for contributing to this release!
2023-05-11 16:22:12 -07:00
Eliza Weisman
fe9e91dc3e
core: remove thread local caching of the global default subscriber (#2593)
## Motivation

Currently, when a call to `dispatcher::get_default` occurs, `tracing`
will check the thread-local default dispatcher first. If a thread-local
scoped default is set, it is returned. Otherwise, the thread will then
check the global default. If a global default is present, it is then
cached in the thread local, so that subsequent calls do not need to
check the global default.

Unfortunately, this behavior results in issues if the scoped default is
accessed (e.g. using `get_default` or creating a new span) *prior* to a
global default being set. When `get_default` runs for the first time and
there is no global default, a `none` dispatcher is cached as the
thread-local default. This means that the thread will now behave as
though its default dispatcher is `None` until the scoped default is
overridden, even if a global default is then set later. This is quite
bad, and results in issues such as #2587, #2436, and #2411.

## Solution

This branch makes several changes to remove the use of the thread-local
caching of the global default dispatcher, and to lessen the performance
impact of doing so.

On the `master` (v0.2.x) branch, we track the number of scoped
dispatchers currently active, and use it to determine whether or not to
check thread-local storage at all. This optimization was introduced in
PR #1017. This branch backports a similar change to `v0.1.x`.

In addition, #1017 also changes the dispatcher module to represent a
`Dispatch` internally using an enum of either an `Arc` in the case where
the dispatcher is scoped, or a `&'static dyn Subscriber + Send + Sync`
reference when the dispatcher is the global default. This makes cloning
and constructing the global default cheaper, and also allows us to
change the `None` dispatcher into a static singleton. That means that
the use of a `None` dispatcher no longer requires an allocation and arc
reference bump, an issue which was previously resolved by locally
caching a `None` dispatcher. A side benefit of this change is that
*cloning* a `Dispatch` is substantially cheaper when the dispatcher is a
global default, as it's just an `&'static` reference and no `Arc` bump
is necessary. This will also make cloning a `Span` cheaper when the
global default dispatcher is in use.

Finally, because the overhead of getting the global default is
substantially reduced, we are able to change the scoped default
dispatcher's behavior to remove the caching entirely. This means that
the category of bugs involving the local cache becoming stale is
resolved entirely.

Fixes #2587
Fixes #2436
Fixes #2411
Closes #2592

## Performance Impact

This change results in a change in performance characteristics. Running
the benchmarks, we observe a significant improvement in performance in
most of the benchmarks that use the global default dispatcher, and a
noticeable decrease in performance for some benchmarks using the scoped
default. In my opinion, this performance change is acceptable, as a
global default dispatcher is the common case for most users, and is
generally expected to perform better than the scoped default. In
addition, resolving the variety of bugs that are caused by the local
caching of the default when using the scoped default dispatcher is worth
a performance cost when the scoped default is in use.

<details>
<summary>Benchmark results:</summary>

```
     Running benches/baseline.rs (target/release/deps/baseline-9b70733ce49582d2)
comparison/relaxed_load time:   [456.48 ps 456.55 ps 456.63 ps]
                        change: [+3.0281% +3.3135% +3.5664%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 10 outliers among 100 measurements (10.00%)
  5 (5.00%) high mild
  5 (5.00%) high severe
comparison/acquire_load time:   [438.98 ps 439.32 ps 439.76 ps]
                        change: [-0.3725% -0.2092% -0.0614%] (p = 0.01 < 0.05)
                        Change within noise threshold.
Found 12 outliers among 100 measurements (12.00%)
  2 (2.00%) high mild
  10 (10.00%) high severe
comparison/log          time:   [227.05 ps 227.14 ps 227.27 ps]
                        change: [+3.1351% +3.2984% +3.4537%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 14 outliers among 100 measurements (14.00%)
  5 (5.00%) high mild
  9 (9.00%) high severe
```
```
     Running benches/dispatch_get_clone.rs (target/release/deps/dispatch_get_clone-d4d6ca1f9895e432)
Dispatch::get_clone/none
                        time:   [8.3974 ns 8.4004 ns 8.4039 ns]
                        change: [-22.870% -22.796% -22.728%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 10 outliers among 100 measurements (10.00%)
  1 (1.00%) low severe
  1 (1.00%) low mild
  4 (4.00%) high mild
  4 (4.00%) high severe
Dispatch::get_clone/scoped
                        time:   [15.877 ns 15.959 ns 16.045 ns]
                        change: [+52.358% +52.943% +53.500%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 16 outliers among 100 measurements (16.00%)
  2 (2.00%) high mild
  14 (14.00%) high severe
Dispatch::get_clone/global
                        time:   [8.3962 ns 8.4000 ns 8.4054 ns]
                        change: [-19.126% -18.961% -18.817%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 15 outliers among 100 measurements (15.00%)
  2 (2.00%) low severe
  6 (6.00%) high mild
  7 (7.00%) high severe
```
```
     Running benches/dispatch_get_ref.rs (target/release/deps/dispatch_get_ref-6ce05749a0b1bf87)
Dispatch::get_ref/none  time:   [1.7551 ns 1.7564 ns 1.7579 ns]
                        change: [-51.858% -51.749% -51.644%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 10 outliers among 100 measurements (10.00%)
  3 (3.00%) low mild
  2 (2.00%) high mild
  5 (5.00%) high severe
Dispatch::get_ref/scoped
                        time:   [3.6341 ns 3.6365 ns 3.6397 ns]
                        change: [-2.6892% -2.5955% -2.4968%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 12 outliers among 100 measurements (12.00%)
  5 (5.00%) high mild
  7 (7.00%) high severe
Dispatch::get_ref/global
                        time:   [1.7668 ns 1.7686 ns 1.7713 ns]
                        change: [-52.697% -52.647% -52.603%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 7 outliers among 100 measurements (7.00%)
  2 (2.00%) high mild
  5 (5.00%) high severe
```
```
     Running benches/empty_span.rs (target/release/deps/empty_span-745c777d77b8b7ca)
empty_span/none         time:   [227.02 ps 227.10 ps 227.20 ps]
                        change: [-0.1729% -0.0705% +0.0495%] (p = 0.24 > 0.05)
                        No change in performance detected.
Found 10 outliers among 100 measurements (10.00%)
  5 (5.00%) high mild
  5 (5.00%) high severe
empty_span/scoped       time:   [218.51 ps 218.69 ps 218.90 ps]
                        change: [-0.7582% -0.6056% -0.4630%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 8 outliers among 100 measurements (8.00%)
  5 (5.00%) high mild
  3 (3.00%) high severe
empty_span/global       time:   [217.85 ps 218.15 ps 218.56 ps]
                        change: [-2.6528% -2.4341% -2.1602%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 8 outliers among 100 measurements (8.00%)
  4 (4.00%) high mild
  4 (4.00%) high severe
empty_span/baseline_struct
                        time:   [655.54 ps 656.09 ps 656.76 ps]
                        change: [-1.6595% -1.4125% -1.1776%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 7 outliers among 100 measurements (7.00%)
  5 (5.00%) high mild
  2 (2.00%) high severe
```
```
     Running benches/enter_span.rs (target/release/deps/enter_span-7fc1c2a69c076475)
enter_span/none         time:   [0.0000 ps 0.0000 ps 0.0000 ps]
                        change: [-43.600% +6.5764% +109.38%] (p = 0.86 > 0.05)
                        No change in performance detected.
Found 14 outliers among 100 measurements (14.00%)
  6 (6.00%) high mild
  8 (8.00%) high severe
enter_span/scoped       time:   [2.6513 ns 2.6567 ns 2.6641 ns]
                        change: [+0.3121% +1.9504% +3.4648%] (p = 0.01 < 0.05)
                        Change within noise threshold.
Found 9 outliers among 100 measurements (9.00%)
  2 (2.00%) high mild
  7 (7.00%) high severe
enter_span/global       time:   [3.2108 ns 3.2160 ns 3.2220 ns]
                        change: [+25.963% +26.742% +27.434%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 2 outliers among 100 measurements (2.00%)
  2 (2.00%) high mild
```
```
     Running benches/event.rs (target/release/deps/event-6742eef6ebe07aa4)
event/none              time:   [227.04 ps 227.18 ps 227.41 ps]
                        change: [-1.6751% -1.5743% -1.4711%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 13 outliers among 100 measurements (13.00%)
  6 (6.00%) high mild
  7 (7.00%) high severe
event/scoped            time:   [8.3849 ns 8.4335 ns 8.4888 ns]
                        change: [-3.4754% -3.0252% -2.6092%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  3 (3.00%) high mild
  2 (2.00%) high severe
event/scoped_recording  time:   [36.916 ns 37.022 ns 37.194 ns]
                        change: [+8.1054% +18.714% +30.381%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 10 outliers among 100 measurements (10.00%)
  1 (1.00%) low mild
  2 (2.00%) high mild
  7 (7.00%) high severe
event/global            time:   [6.9694 ns 7.1677 ns 7.3469 ns]
                        change: [-23.407% -21.940% -20.398%] (p = 0.00 < 0.05)
                        Performance has improved.
```
```
     Running benches/span_fields.rs (target/release/deps/span_fields-96dfd0a8a577dec6)
span_fields/none        time:   [3.5936 ns 3.6008 ns 3.6106 ns]
                        change: [+17.160% +17.776% +18.413%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 14 outliers among 100 measurements (14.00%)
  8 (8.00%) high mild
  6 (6.00%) high severe
span_fields/scoped      time:   [33.751 ns 33.765 ns 33.779 ns]
                        change: [+22.689% +22.873% +23.037%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 7 outliers among 100 measurements (7.00%)
  1 (1.00%) low mild
  4 (4.00%) high mild
  2 (2.00%) high severe
span_fields/scoped_recording
                        time:   [270.22 ns 270.55 ns 270.91 ns]
                        change: [+10.615% +10.827% +11.028%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 6 outliers among 100 measurements (6.00%)
  6 (6.00%) high mild
span_fields/global      time:   [28.337 ns 28.428 ns 28.527 ns]
                        change: [+3.0582% +3.3355% +3.6278%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 13 outliers among 100 measurements (13.00%)
  13 (13.00%) high mild
```
```
     Running benches/span_no_fields.rs (target/release/deps/span_no_fields-f8c7d7a84f720442)
span_no_fields/none     time:   [1.5467 ns 1.5507 ns 1.5553 ns]
                        change: [+12.966% +13.206% +13.434%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 8 outliers among 100 measurements (8.00%)
  7 (7.00%) high mild
  1 (1.00%) high severe
span_no_fields/scoped   time:   [17.796 ns 17.810 ns 17.826 ns]
                        change: [+1.0381% +1.1673% +1.2914%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 12 outliers among 100 measurements (12.00%)
  6 (6.00%) high mild
  6 (6.00%) high severe
span_no_fields/scoped_recording
                        time:   [30.397 ns 30.459 ns 30.524 ns]
                        change: [-0.8489% -0.6268% -0.3915%] (p = 0.00 < 0.05)
                        Change within noise threshold.
span_no_fields/global   time:   [12.747 ns 12.791 ns 12.844 ns]
                        change: [-27.930% -27.672% -27.386%] (p = 0.00 < 0.05)
                        Performance has improved.
```
```
     Running benches/span_repeated.rs (target/release/deps/span_repeated-03bfaaf4ecd13d36)
span_repeated/none      time:   [699.28 ns 699.84 ns 700.53 ns]
                        change: [+2.4125% +2.6359% +2.8862%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 9 outliers among 100 measurements (9.00%)
  7 (7.00%) high mild
  2 (2.00%) high severe
span_repeated/scoped    time:   [2.5029 µs 2.5057 µs 2.5090 µs]
                        change: [+4.5095% +4.6605% +4.8122%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 16 outliers among 100 measurements (16.00%)
  8 (8.00%) low mild
  6 (6.00%) high mild
  2 (2.00%) high severe
span_repeated/scoped_recording
                        time:   [5.0509 µs 5.0535 µs 5.0566 µs]
                        change: [+0.7346% +1.0724% +1.3718%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 13 outliers among 100 measurements (13.00%)
  6 (6.00%) high mild
  7 (7.00%) high severe
span_repeated/global    time:   [2.1264 µs 2.1272 µs 2.1282 µs]
                        change: [-11.213% -11.119% -11.031%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 10 outliers among 100 measurements (10.00%)
  5 (5.00%) high mild
  5 (5.00%) high severe
```

</details>
2023-05-11 15:48:57 -07:00
Donough Liu
63ae090515 tracing: inline methods to make macro-generated code smaller (#2555)
## Motivation

Make `tracing::event!` codegen smaller

## Solution

Add `inline` to several functions called by `tracing::event!`.

Simple example: https://github.com/ldm0/tracing_test

After inlining, executable size drops from 746kb to 697kb
(`cargo build --release + strip`), saves 50 bytes per `event!`.

Test environment:
```
toolchain: nightly-aarch64-apple-darwin
rustc-version: rustc 1.70.0-nightly (88fb1b922 2023-04-10)
```

There are also performance improvements in the benchmarks:

```
event/scoped [-40.689% -40.475% -40.228%]
event/scoped_recording [-14.972% -14.685% -14.410%]
event/global [-48.412% -48.217% -48.010%]
span_fields/scoped [-25.317% -24.876% -24.494%]
span_fields/global [-39.695% -39.488% -39.242%]
span_repeated/global [-27.514% -26.633% -25.298%]
static/baseline_single_threaded [-32.275% -32.032% -31.808%]
static/single_threaded [-29.628% -29.376% -29.156%]
static/enabled_one [-29.777% -29.544% -29.305%]
static/enabled_many [-30.901% -30.504% -30.140%]
dynamic/baseline_single_threaded [-20.157% -19.880% -19.603%]
```

I retried benchmark several times and the improvements seem to be fairly
stable.

raw log: https://gist.github.com/ldm0/6573935f4979d2645fbcf5bde7361386
2023-04-21 16:59:51 -07:00
David Barsky
45a2cea8bb subscriber: dim Compact targets, matching the default formatter (#2409)
Fixes https://github.com/tokio-rs/tracing/issues/2408

Just switch to use `dim`

Before:
![2022-12-08_13-58-40](https://user-images.githubusercontent.com/623453/206576169-63ee4e20-b56f-4c63-a9b3-80ba2e97eec9.png)
After:
![2022-12-08_13-55-36](https://user-images.githubusercontent.com/623453/206576055-878d360f-7b95-4e18-bc31-4fb6f1b71a3a.png)
Full mode for comparison:
![2022-12-08_13-55-48](https://user-images.githubusercontent.com/623453/206576054-6e38852c-cb3a-4b84-98e5-50463cdb5073.png)
; Conflicts:
;	tracing-subscriber/src/fmt/format/mod.rs
2023-04-21 16:59:51 -07:00
Luca Palmieri
6c55b66915 chore: Remove doc(html_root_url) attribute from all crates. (#2384)
Fixes #2383.
; Conflicts:
;	tracing-appender/src/lib.rs
;	tracing-attributes/src/lib.rs
;	tracing-core/src/lib.rs
;	tracing-error/src/lib.rs
;	tracing-futures/src/lib.rs
;	tracing-log/src/lib.rs
;	tracing-opentelemetry/src/lib.rs
;	tracing-serde/src/lib.rs
;	tracing-subscriber/src/lib.rs
;	tracing/src/lib.rs
2023-04-21 16:59:51 -07:00
Jeremy Fitzhardinge
b38122deff attributes: improve docs; tests for using Levels in #[instrument] (#2350)
This branch adds documentation and tests noting that the `#[instrument]`
macro accepts `tracing::Level` directly. Using `tracing::Level` directly
allows for IDE autocomplete and earlier detection of typos.

The documentation for tracing-attributes was also rewritten to remove
the usage of the second-person perspective, making it more consistent
with the rest of tracing's documentation.

Co-authored-by: David Barsky <me@davidbarsky.com>
; Conflicts:
;	tracing-attributes/Cargo.toml
;	tracing-attributes/src/lib.rs
2023-04-21 16:59:51 -07:00
keepsimple1
d2f47f1e3f
chore: fix clippy warnings for v0.1.x (#2552)
## Motivation

Clippy check fails in recent CI runs in v0.1.x branch PRs, for example
this run:
https://github.com/tokio-rs/tracing/actions/runs/4641107803/jobs/8215263838


Relevant error logs:
```
error: lint `const_err` has been removed: converted into hard error, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> for more information
   --> tracing-core/src/lib.rs:132:5
    |
132 |     const_err,
    |     ^^^^^^^^^
    |
    = note: `-D renamed-and-removed-lints` implied by `-D warnings`


error: deref which would be done by auto-deref
   --> tracing-core/src/dispatcher.rs:371:26
    |
371 |                 return f(&*entered.current());
    |                          ^^^^^^^^^^^^^^^^^^^ help: try this: `&entered.current()`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#explicit_auto_deref
    = note: `-D clippy::explicit-auto-deref` implied by `-D warnings`


error: deref which would be done by auto-deref
   --> tracing-core/src/dispatcher.rs:393:20
    |
393 |             Some(f(&*entered.current()))
    |                    ^^^^^^^^^^^^^^^^^^^ help: try this: `&entered.current()`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#explicit_auto_deref
```

## Solution

Fix the warnings based on the suggestions for Clippy.
2023-04-12 21:22:44 +00:00
Eliza Weisman
8b01ea9b9c
core: prepare to release v0.1.30 (#2339)
# 0.1.30 (October 6, 2022)

This release of `tracing-core` adds a new `on_register_dispatch` method
to the `Subscriber` trait to allow the `Subscriber` to perform
initialization after being registered as a `Dispatch`, and a
`WeakDispatch` type to allow a `Subscriber` to store its own `Dispatch`
without creating reference count cycles.

### Added

- `Subscriber::on_register_dispatch` method ([#2269])
- `WeakDispatch` type and `Dispatch::downgrade()` function ([#2293])

Thanks to @jswrenn for contributing to this release!

[#2269]: https://github.com/tokio-rs/tracing/pull/2269
[#2293]: https://github.com/tokio-rs/tracing/pull/2293
2022-10-06 10:52:01 -07:00
Jack Wrenn
37c2434f21
core: add Dispatch::downgrade() and WeakDispatch (#2293)
Allows `Subscriber`s and `Layer`s to stash their own `Dispatch` without
causing a memory leak.

## Motivation

Resolves a shortcoming of #2269: that it's impossible for `Subscriber`s
or `Layer`s to stash a copy of their own `Dispatch` without creating a
reference cycle that would prevent them from being dropped.

## Solution

Introduces `WeakDispatch` (analogous to `std::sync::Weak`) that holds a
weak pointer to a `Subscriber`. `WeakDispatch` can be created via
`Dispatch::downgrade`, and can be transformed into a `Dispatch` via
`WeakDispatch::upgrade`.

Co-authored-by: Eliza Weisman <eliza@buoyant.io>
2022-09-30 11:59:53 -07:00
Jack Wrenn
9fccc013c8 core: add {Subscriber,Layer}::on_register_dispatch (#2269)
The `on_register_dispatch` method is invoked when a `Subscriber` is
registered as a `Dispatch`. This method should be overridden to
perform actions upon the installation of a subscriber/layer;
for instance, to send a copy of the subscriber's `Dispatch` to a
worker thread.
2022-09-19 11:47:54 -07:00
Eliza Weisman
1413f042c3 chore: fix clippy::borrow_deref_ref lints (#2277)
This fixes new Clippy lints introduced in the latest Rust version.

* chore: fix `clippy::borrow_deref_ref` lints
* chore: fix `clippy::partial_eq_without_eq` lint
2022-09-19 11:47:54 -07:00
Eliza Weisman
275ededfc2
core: prepare to release v0.1.29 (#2256)
# 0.1.29 (July 29, 2022)

This release of `tracing-core` adds `PartialEq` and `Eq` implementations
for metadata types, and improves error messages when setting the global
default subscriber fails.

### Added

- `PartialEq` and `Eq` implementations for `Metadata` ([#2229])
- `PartialEq` and `Eq` implementations for `FieldSet` ([#2229])

### Fixed

- Fixed unhelpful `fmt::Debug` output for
  `dispatcher::SetGlobalDefaultError` ([#2250])
- Fixed compilation with `-Z minimal-versions` ([#2246])

Thanks to @jswrenn and @CAD97 for contributing to this release!

[#2229]: https://github.com/tokio-rs/tracing/pull/2229
[#2246]: https://github.com/tokio-rs/tracing/pull/2246
[#2250]: https://github.com/tokio-rs/tracing/pull/2250
2022-07-29 12:45:09 -07:00
Eliza Weisman
250cb5b3c1
core: give SetGlobalDefaultError a useful Debug impl (#2250)
## Motivation

When a global default dispatcher has already been set, the
`dispatch::set_global_default` function fails with a
`SetGlobalDefaultError`. The `fmt::Display` impl for this type includes
a message explaining that the error indicates that a global default has
already been set, but the `fmt::Debug` impl is derived, and just looks
like this:
```
SetGlobalDefaultError { _no_construct: () }
```
which isn't particularly helpful.

Unfortunately, when `unwrap()`ping or `expect()`ing a `Result`, the
`fmt::Debug` implementation for the error type is used, rather than
`fmt::Display`. This means that the error message will not explain to
the user why setting the global default dispatcher failed, which is a
bummer.

## Solution

This branch replaces the derived `Debug` impl with a manually
implemented one that prints the same message as the `Display` impl, but
formatted like a tuple struct with a single string field. This avoids
emitting `Debug` output that's *just* a textual human-readable message,
rather than looking like Rust code, but ensures the message is visible
to the user when writing code like
```rust
tracing::dispatch::set_global_default(foo).unwrap();
```

The mesasge now looks like:
```
SetGlobalDefaultError("a global default trace dispatcher has already been set")
```
which should be a bit easier to debug.
2022-07-29 11:27:33 -07:00
Christopher Durham
a3868af664
chore: fix minimal-versions correctness (#2246)
## Motivation

Fix minimal-versions failure.

## Solution

Upgrade all the dependencies to their most recent semver-compatible
version, adjusting back down as necessary for MSRV.

Essentially a cherry-pick of #2231, but redone by hand.

## Tests

- `cargo minimal-versions msrv verify -- cargo check --all-features`
- `cargo minimal-versions msrv verify -- cargo check --no-default-features`

## Methodology

- `cargo update && cargo upgrade --to-lockfile`
  - Identify [a bug](https://github.com/killercup/cargo-edit/issues/750) and manually resolve it
- loop; upgrade transitive deps
  - `cargo minimal-versions check --all-features`
  - Identify failing dep
  - `cargo minimal-versions tree -i dep --all-features`
  - Find the closest dependency leading to pulling in `dep`
  - `cargo add fixdep --optional` to force a more recent more-minimal-versions-correct version
- loop; downgrade to msrv
  - `cargo minimal-versions msrv verify -- cargo check --all-features`
  - Identify failing dep
  - `cargo minimal-versions tree -i dep --all-features`
  - Find the version that supports MSRV from lib.rs
  - `cargo upgrade dep@msrv`
2022-07-26 15:27:58 -07:00
Jack Wrenn
398a6ecf89 core: implement PartialEq, Eq for Metadata, FieldSet (#2229)
A `FieldSet` is equal to another `FieldSet` if they share the same
callsite and fields (provided in the same order). This ensures
that a `Field` applicable to one `FieldSet` is applicable to any
equal `FieldSet`. A `Metadata` is equal to another `Metadata` if
all of their contained metadata is exactly equal.

This change manually re-implements `PartialEq` and `Eq` for
`Metadata` and `FieldSet` to define their equality strictly in
terms of callsite equality. In debug builds, the equality of
these types' other fields is also checked.

Documentation is added to both `Metadata` and `FieldSet`
explaining this behavior.

The expectation that, in a well-behaving application, `Metadata`
and `FieldSet`s with equal callsites will be otherwise equal is
documented on `Callsite::metadata`. This is not a breaking change,
as previous releases did not define equality for `Metadata` or
`FieldSet`. The `Callsite` trait remains safe, as this expectation
is not (yet) a safety-critical property.
2022-07-20 11:59:58 -07:00
Eliza Weisman
542c34dcf0
chore: prepare to release tracing-core v0.1.28 (#2177)
# 0.1.28 (June 23, 2022)

This release of `tracing-core` adds new `Value` implementations,
including one for `String`, to allow recording `&String` as a value
without having to call `as_str()` or similar, and for 128-bit integers
(`i128` and `u128`). In addition, it adds new methods and trait
implementations for `Subscriber`s.

### Added

- `Value` implementation for `String` ([#2164])
- `Value` implementation for `u128` and `i28` ([#2166])
- `downcast_ref` and `is` methods for `dyn Subscriber + Sync`,
  `dyn Subscriber + Send`, and `dyn Subscriber + Send + Sync` ([#2160])
- `Subscriber::event_enabled` method to enable filtering based on
  `Event` field
  values ([#2008])
- `Subscriber` implementation for `Box<S: Subscriber + ?Sized>` and
  `Arc<S: Subscriber + ?Sized>` ([#2161])

Thanks to @jswrenn and @CAD97 for contributing to this release!

[#2164]: https://github.com/tokio-rs/tracing/pull/2164
[#2166]: https://github.com/tokio-rs/tracing/pull/2166
[#2160]: https://github.com/tokio-rs/tracing/pull/2160
[#2008]: https://github.com/tokio-rs/tracing/pull/2008
[#2161]: https://github.com/tokio-rs/tracing/pull/2161
2022-06-23 17:35:21 -07:00
Eliza Weisman
f7966bde76
core: remove vendored lazy_static on no-std (#2173)
Currently, `no_std` targets use a vendored version of `lazy_static` that
uses the `spin` crate's `Once` type, while the `std` target uses the
`once_cell` crate's `Lazy` type. This is unfortunate, as the
`lazy_static` macro has a different interface from the `Lazy` cell type.
This increases the amount of code that differs based on whether or not
`std` is enabled.

This branch removes the vendored `lazy_static` macro and replaces it
with a reimplementation of `once_cell::sync::Lazy` that uses
`spin::Once` rather than `once_cell::sync::OnceCell` as the inner "once
type". Now, all code can be written against a `Lazy` struct with the
same interface, regardless of whether or not `std` is enabled.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2022-06-22 22:43:25 +00:00
Christopher Durham
f42e7e6dd2 core, subscriber: add event_enabled to filter events on fields (#2008)
## Motivation

Allow filter layers to filter on the contents of events (see #2007).

## Solution

This branch adds a new `Subscriber::event_enabled` method, taking an
`Event` and returning `bool`. This is called before the
`Subscriber::event` method, and if it returns `false`,
`Subscriber::event` is not called.

For simple subscriber (e.g. not using `Layer`s), the `event_enabled`
method is not particulary necessary, as the subscriber can just skip the
`event` call. However, this branch also adds a new
`Layer::event_enabled` method, with the signature:
```rust
fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool;
```

This is called before `Layer::on_event`, and if `event_enabled`
returns `false`, `on_event` is not called (nor is `Subscriber::event`).
This allows filter `Layer`s to filter out an `Event` based on its
fields.

Closes #2007
2022-06-22 15:01:24 -07:00
David Barsky
d3eb109e45 core: add support for recording 128-bit integers (#2166)
## Motivation

I've received a request at work to record 128-bit integers and realized
that we should probably support recording them.

## Solution

Added two methods to the `Visit` trait, `record_i128` and `record_u128`.
However, I didn't add the size conversions present for 64-bit integers,
as 128-bit integers are, at this time, more specialized.
2022-06-22 15:01:24 -07:00
Jack Wrenn
374b646979 core: impl<S: Subscriber + ?Sized> Subscriber for Box<S>, Arc<S> (#2161)
These broader impls supersede the previous impls where the inner type was a
`dyn Subscriber`. With these generic impls, you no longer must (but
still can, if you wish) cast the inner type of a boxed or arc'd
subscriber to `dyn Subscriber` to use it as a `Subscriber`.
2022-06-22 15:01:24 -07:00
Eliza Weisman
3ad7f99f64 core: impl field::Value for String (#2164)
## Motivation

Currently, it is rather difficult to record `String`s as field values,
even though `&str` is a primitive `Value` type. For example, this code
does not currently compile:

```rust
let my_string = String::from("hello world!");
tracing::debug!(my_string);
```

Instead, it is necessary to explicitly call `String::as_str` or a
similar conversion method:

```rust
let my_string = String::from("hello world!");
tracing::debug!(my_string = my_string.as_str());
```

This is unfortunate, as it makes a fairly straightforward, commomplace
task (recording a `String` as a field) unnecessarily verbose.

## Solution

This branch adds an `impl Value for String` in `tracing-core`. The impl
simply calls `String::as_str` and then calls `record_str`. Because
`Value` takes an `&self`, and there are preexisting `impl<T: Value>
Value` for `&T` and `&mut T`, the string is not consumed, and `&String`
or `&mut String`s can also be used as `Value`s.

I've also added tests validating that this actually works.
2022-06-22 15:01:24 -07:00
Jack Wrenn
0d41b373e7 core, subscriber: more downcast_ref & is methods (#2160)
Adds inherent `downcast_ref` and `is` inherent methods to:
  - `dyn Subscriber + Send`
  - `dyn Subscriber + Sync`
  - `dyn Subscriber + Send + Sync`
  - `Layered`

These additional implementations reduce the circumstances in which one
must cast to `dyn Subscriber` (which, previously, was the only type for
which `downcast_ref` and `is` were available).
2022-06-22 15:01:24 -07:00
Eliza Weisman
d6699fe311
core: prepare to release v0.1.27 (#2155)
# 0.1.27 (June 7, 2022)

This release of `tracing-core` introduces a new `DefaultCallsite` type,
which can be used by instrumentation crates rather than implementing
their own callsite types. Using `DefaultCallsite` may offer reduced
overhead from callsite registration.

### Added

- `DefaultCallsite`, a pre-written `Callsite` implementation for use in
  instrumentation crates ([#2083])
- `ValueSet::len` and `Record::len` methods returning the number of
  fields in a `ValueSet` or `Record` ([#2152])

### Changed

- Replaced `lazy_static` dependency with `once_cell` ([#2147])

### Documented

- Added documentation to the `callsite` module ([#2088], [#2149])

Thanks to new contributors @jamesmunns and @james7132 for contributing
to this release!

[#2083]: https://github.com/tokio-rs/tracing/pull/2083
[#2152]: https://github.com/tokio-rs/tracing/pull/2152
[#2147]: https://github.com/tokio-rs/tracing/pull/2147
[#2088]: https://github.com/tokio-rs/tracing/pull/2088
[#2149]: https://github.com/tokio-rs/tracing/pull/2149
2022-06-07 14:18:32 -07:00
James Munns
2f23eccaca
core: add ValueSet::len and Record::len (#2152)
## Motivation

This PR adds two new accessor functions that are useful for creating a
structured serde implementation for tracing.

This is a sort of "distilled" version of
https://github.com/tokio-rs/tracing/pull/2113, based on the `v0.1.x`
branch.

As it is unlikely that "structured serde" will be 1:1 compatible with
the existing JSON-based `tracing-serde` (or at least - I'm not sure how
to do it in a reasonable amount of effort), these functions will allow
me to make a separate crate to hold me over until breaking formatting
changes are possible in `tracing-serde`.

CC @hawkw, as we've discussed this pretty extensively
2022-06-07 20:12:06 +00:00
James Liu
29b265dd9c core, subscriber: migrate from lazy_static to once_cell (#2147)
Replace `lazy_static` with `once_cell`. Fixes #2146.

## Motivation

`lazy_static!`, while a declarative macro, is a macro nonetheless. It
can add quite a bit of additional compilation time cost.
`once_cell::sync::Lazy` does the same thing with generics, and can be
used more flexibly (i.e. non-static lazily initialized values), and has
been proposed to be added to `std` (see linked issue).

I'm trying to reduce the compile time and dependency tree complexity of
a dependent project: [bevy](https://bevyengine.org), which is using
tracing. `lazy_static` and `once_cell` are both in our dependency tree
and both end up doing the same thing.

## Solution

Migrate to `once_cell`.
2022-06-07 10:01:02 -07:00
Eliza Weisman
a29fbc6a36
tracing-core: add documentation on DefaultCallsite (#2149)
This adds a small note on the use of `DefaultCallsite` to the
`tracing-core` docs. I wanted to take care of this before publishing a
new `tracing-core` release.
2022-06-06 11:11:05 -07:00
Eliza Weisman
befdca0adf core: document the callsite module (#2088)
Currently, there isn't a lot of documentation explaining what callsites
and registration are for, and how they work. There's some documentation
explaining this stuff, but it's all on the `register_callsite` *method*,
rather than in the `callsite` module itself. We should fix that.

This branch adds new documentation to `tracing-core`'s `callsite`
module. Hopefully this should shine some light on how this part of
tracing works.

Thanks to @JamesHallowell for fixing some typos!

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2022-04-26 16:23:03 -07:00
Eliza Weisman
45a5df1373
core: add a limited form of the linked-list callsite registry for v0.1.x (#2083)
## Motivation

Currently on `v0.1.x`, the global callsite registry is implemented as a
`Mutex<Vec<&'static dyn Callsite>>`. This has a few downsides:

* Every time a callsite is registered, the `Mutex` must be locked. This
  can cause a deadlock when a `register_callsite` implementation calls
  into code that _also_ registers a callsite. See #2020 for details.

* Registering callsites is relatively slow and forces the program to
  synchronize on the callsite registry (and not on *individual*
  callsites). This means that if two threads are both registering
  totally different callsites, both threads must wait for the lock.
  Although this overhead is amortized over the entire rest of the
  program, it does have an impact in short-running applications where
  any given callsite may only be hit once or twice.

* Memory allocation may occur while the registry is locked. This makes
  the use of `tracing` inside of memory allocators difficult or
  impossible.

On the `master` branch (v0.2.x), PR #988 rewrote the callsite registry
to use an intrusive atomic singly-linked list of `Callsite`s. This
removed the need for locking the callsite registry, and made it possible
to register callsites without ever allocating memory. Because the
callsite registry on v0.2 will *never* allocate, this also makes it
possible to compile `tracing-core` for `no_std` platforms without
requiring `liballoc`. Unfortunately, however, we cannot use an identical
implementation on v0.1.x, because using the intrusive linked-list
registry for *all* callsites requires a breaking change to the
`Callsite` trait (in order to add a way to get the callsite's
linked-list node), which we cannot make on v0.1.x.

## Solution

This branch adds a linked-list callsite registry for v0.1.x in a way
that allows us to benefit from *some* of the advantages of this approach
in a majority of cases. The trick is introducing a new `DefaultCallsite`
type in `tracing-core` that implements the `Callsite` trait. This type
can contain an intrusive list node, and *when a callsite is a
`DefaultCallsite`*, we can register it without having to push it to the
`Mutex<Vec<...>>`. The locked vec still _exists_, for `Callsite`s that
are *not* `DefaultCallsite`s, so we can't remove the `liballoc`
dependency, but in most cases, we can avoid the mutex and allocation.

Naturally, `tracing` has been updated to use the `DefaultCallsite` type
from `tracing-core`, so the `Vec` will only be used in the following
cases:

* User code has a custom implementation of the `Callsite` trait, which
  is [not terribly common][1].
* An older version of the `tracing` crate is in use.

This fixes the deadlock described in #2020 when `DefaultCallsite`s are
used. Additionally, it should reduce the performance impact and memory
usage of the callsite registry.

Furthermore, I've changed the subscriber registry so that a
`RwLock<Vec<dyn Dispatch>>` is only used when there actually are
multiple subscribers in use. When there's only a global default
subscriber, we can once again avoid locking for the registry of
subscribers. When the `std` feature is disabled, thread-local scoped
dispatchers are unavailable, so the single global subscriber will always
be used on `no_std`.

We can make additional changes, such as the ones from #2020, to _also_
resolve potential deadlocks when non-default callsites are in use, but
since this branch rewrites a lot of the callsite registry code, that
should probably be done in a follow-up.

[1]: https://cs.github.com/?scopeName=All+repos&scope=&q=%28%2Fimpl+.*Callsite%2F+AND+language%3Arust%29+NOT+%28path%3A%2Ftracing%2F**+OR+path%3A%2Ftracing-*%2F**+OR+path%3A%2Ftokio-trace*%2F**%29%29

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2022-04-22 16:11:08 +00:00
Benjamin Herr
c8a2bb2d79
docs: more intra-doc links (#2077)
* docs: `cargo intraconv` for more intra-doc links

... also it deleted some redundant ones, and it got some things wrong,
and it was gonna delete some of the cross-crate docs.rs links we can't
do as intra-doc links so I passed `--no-favored`.

* docs: convert https:// links to std/core/alloc to intra-doc links

Note that this adds some more broken intra doc links when building
without std support, but that was already a thing and I expect people
who build their own docs without std support can handle it.

This time I gave up on sed and used ruby.

    find -name '*.rs' -exec ruby -i -p blah.rb {} +

with

    $_.gsub!(%r{
        https://doc\.rust-lang\.org/
        (?: stable/)?
        ((?:core | std | alloc)(?:/\S+?)*)
        /(\w+)\.(\w+)\.html}x
    ) {
      path, kind, name = $~.captures
      suffix = case kind
        when 'method' then '()'
        when 'macro' then '!'
        else ''
      end
      r = [path.gsub('/', '::'), '::', name, suffix].join
      STDERR.puts [path, kind, name, suffix, r].inspect
      r
    }
    $_.gsub!(%r{
        https://doc\.rust-lang\.org/
        (?: stable/)?
        ((?: core | std | alloc)(?:/\S+?)*)
        /(?:
          index\.html
          | $
          | (?= \#)
         )}x
    ) {
      path, _ = $~.captures
      r = path.gsub('/', '::')
      STDERR.puts [path, r].inspect
      r
    }

* docs: more cross-crate intra-doc links

cargo intraconv doesn't seem to get them reliably and also plenty of
links to other crates aren't actually intra-doc because they're in
crates that don't depend (or only dev-depend, or only conditionally
depend) on those crates, so this wasn't very automated.

I tried to only convert docs.rs links to unconditional dependencies to
intra-crate links, but it's possible that some slipped through in either
direction.
2022-04-19 18:11:09 +00:00
Eliza Weisman
cb294a9958
core: prepare to release v0.1.26
# 0.1.26 (April 14, 2022)

This release adds a `Value` implementation for `Box<T: Value>` to allow
recording boxed values more conveniently. In particular, this should
improve the ergonomics of the implementations for `dyn std::error::Error`
trait objects, including those added in [v0.1.25]. 

### Added

- `Value` implementation for `Box<T> where T: Value` ([#2071])

### Fixed

- Broken documentation links ([#2068])

Thanks to new contributor @ben0x539 for contributing to this release!


[v0.1.25]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.25
[#2071]: https://github.com/tokio-rs/tracing/pull/2071
[#2068]: https://github.com/tokio-rs/tracing/pull/2068
2022-04-14 14:46:39 -07:00
Eliza Weisman
96347c7b78
core: add Value impl for Box<T> where T: Value (#2071)
This commit adds a `Value` implementation for `Box<T> where T: Value`.
This is *primarily* intended to make `Box<dyn Error + ...>` implement
`Value`, building on the `Value` impls for `dyn Error + ...` added in
#2066, but it may be useful for other boxed values as well.

Refs: #1308
2022-04-14 14:26:56 -07:00
Benjamin Herr
438b013c01
docs: use intra-doc links instead of relative file paths (#2068)
## Motivation

#940, I guess. I kept running into the odd broken link in the docs and
eventually realized it's because a lot of stuff is reexported in parent
modules and so the file path based relative links couldn't possibly work
in all contexts. Looks like master already underwent this treatment but
I suspect this is easier than backporting.

## Solution

Intra-doc links seem pretty good.

I started with

```
        find -name \*.rs -exec sed -i -e '
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\w\+\.\(\w\+\)\.html@\1super::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\(\w\+\)/\w\+\.\(\w\+\)\.html@\1super::\2::\3@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\.\./\w\+\.\(\w\+\)\.html@\1super::super::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\.\./\(\w\+\)/\w\+\.\(\w\+\)\.html@\1super::super::\2::\3@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\(\w\+\)/index\.html@\1super::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./index\.html@\1super@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\.\./\(\w\+\)/\?$@\1super::\2@;
    
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\./\w\+\.\(\w\+\)\.html@\1self::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\./\(\w\+\)/\w\+\.\(\w\+\)\.html@\1self::\2::\3@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\./\(\w\+\)/index\.html@\1self::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\./index\.html@\1self@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\./\(\w\+\)/\?$@\1self::\2@;
    
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\w\+\.\(\w\+\)\.html@\1self::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\(\w\+\)/\w\+\.\(\w\+\)\.html@\1self::\2::\3@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\(\w\+\)/index\.html@\1self::\2@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?index\.html@\1self@;
            s@\(//. \[[^]]*\]:\s\+\)[:"]\?\(\w\+\)/\?$@\1self::\2@;
    
            s@\(//. \[[^]]*\]:\s\+[A-Za-z_0-9:]\+\)#method\.\(\w\+\)@\1::\2@;
        ' {} +
```
and then removed redundant `self::`s when I realized you don't actually
need a `::` in the links, and fixed stuff up by hand as I ran into
errors from

```
x='--cfg docsrs --cfg tracing_unstable'; RUSTFLAGS=$x RUSTDOCFLAGS=$x cargo doc --all-features
```

I hope that's roughly how the docs are supposed to work.

I understand this is a relatively big unsolicited change in that it
touches a whole lot of files (definitely went further than I originally
intended), I'm happy to revise or split or reduce scope of this PR as
desired.
2022-04-14 12:12:43 -07:00
Eliza Weisman
9d10e2cfe0
core: prepare to release v0.1.25 (#2070)
# 0.1.25 (April 12, 2022)

This release adds additional `Value` implementations for
`std::error::Error` trait objects with auto trait bounds (`Send` and
`Sync`), as Rust will not auto-coerce trait objects. Additionally, it
fixes a bug when setting scoped dispatchers that was introduced in the
previous release ([v0.1.24]).

### Added

- `Value` implementations for `dyn Error + Send + 'static`, `dyn Error +
  Send + Sync + 'static`, `dyn Error + Sync + 'static` ([#2066])

### Fixed

- Failure to use the global default dispatcher if a thread has set a
  scoped default prior to setting the global default, and unset the
  scoped default after setting the global default ([#2065])

Thanks to @lilyball for contributing to this release!

[v0.1.24]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.24
[#2066]: https://github.com/tokio-rs/tracing/pull/2066
[#2065]: https://github.com/tokio-rs/tracing/pull/2065
2022-04-12 14:49:57 -07:00
Lily Ballard
50a726b647
core: impl Value for dyn Error + Send/Sync (#2066)
## Motivation

`Value` was already implemented for `dyn Error + 'static`, but rust
doesn't silently coerce trait objects. This means that passing an error
of type `dyn Error + Send + Sync + 'static` would not work. This is
related to #1308.

## Solution

Add impls for `dyn Error + …` variants for `Send`, `Sync`, and `Send +
Sync`. These extra impls just delegate to the existing `dyn Error +
'static` impl.

Also update one of the examples to use `dyn Error + Send + Sync` to
demonstrate that this works.

Refs: #1308
2022-04-12 12:24:16 -07:00
Eliza Weisman
fc694a5bcc
core: fix scoped dispatchers clobbering the global default (#2065)
## Motivation

PR https://github.com/tokio-rs/tracing/pull/2001 introduced --- or rather, _uncovered_ --- a bug which occurs
when a global default subscriber is set *after* a scoped default has
been set.

When the scoped default guard is dropped, it resets the
thread-local default cell to whatever subscriber was the default when
the scoped default was set. This allows nesting scoped default contexts.
However, when there was *no* default subscriber when the `DefaultGuard`
was created, it sets the "previous" subscriber as `NoSubscriber`. This
means dropping a `DefaultGuard` that was created before any other
subscriber was set as default will reset that thread's default to
`NoSubscriber`. Because https://github.com/tokio-rs/tracing/pull/2001 changed the dispatcher module to stop
using `NoSubscriber` as a placeholder for "use the global default if one
exists", this means that the global default is permanently clobbered on
the thread that set the scoped default prior to setting the global one.

## Solution

This PR changes the behavior when creating a `DefaultGuard` when no
default has been set. Instead of populating the "previous" dispatcher
with `NoSubscriber`, it instead leaves the `DefaultGuard` with a `None`.
When the `DefaultGuard` is dropped, if the subscriber is `None`, it will
just clear the thread-local cell, rather than setting it to
`NoSubscriber`. This way, the next time the cell is accessed, we will
check if a global default exists to populate the thread-local, and
everything works correctly. As a side benefit, this also makes the code
a bit simpler!

I've also added a test reproducing the bug.

This PR is against `v0.1.x` rather than `master`, because the issue does
not exist on `master` due to other implementation differences in v0.2.
We may want to forward-port the test to guard against future
regressions, though.

Fixes #2050
2022-04-12 09:06:55 -07:00
John-John Tedro
d91af65bde chore(ci): add a minimal-versions check (#2015)
This adds a minimal-versions check to the tracing project. Adapted from
`tokio-rs/tokio`. Adding this avoids breaking downstream dependencies
from accidentally under-constraining minimal versions of dependencies
when they depend on tracing.

I've currently just introduced the check. I will try to and do encourage
others to add patches to fix this where possible since it can be a fair
bit of work to chase down a version of all dependencies that passes
minimal-versions and is msrv. I've also seen some really odd
windows-specific issues (which are not being tested for here).

This is currently only testing `tracing`, `tracing-core`, and
`tracing-subscriber`. Packages such as `tracing-futures` are proving to
be a bit harder to deal with due to having features which enable very
old dependencies.

Steps to test the build minimal versions locally:

```sh
cargo install cargo-hack
rustup default nightly
cargo hack --remove-dev-deps --workspace
cargo update -Z minimal-versions
cargo hack check --all-features --ignore-private
```

CC: tokio-rs/tokio#4513
2022-04-09 10:43:52 -07:00
Eliza Weisman
8f240e6b6f
core: prepare to release 0.1.24 (#2042)
# 0.1.24 (April 1, 2022)

This release fixes a bug where setting `NoSubscriber` as the local
default would not locally disable the current global default subscriber.

### Fixed

- Setting `NoSubscriber` as the local default now correctly disables the
  global default subscriber ([#2001])
- Fixed compilation warnings with the "std" feature disabled ([#2022])

### Changed

- Removed unnecessary use of `write!` and `format_args!` macros
  ([#1988])

[#1988]: https://github.com/tokio-rs/tracing/pull/1988
[#2001]: https://github.com/tokio-rs/tracing/pull/2001
[#2022]: https://github.com/tokio-rs/tracing/pull/2022
2022-04-01 13:52:35 -07:00
Eliza Weisman
df9666bdeb
core: fix warnings when compiling without std (#2022)
## Motivation

Currently, compiling `tracing-core` with `default-features = false`
(i.e. for `no_std` targets) emits a few warnings. This is due to the
spinlock implementation's use of the deprecated `atomic::spin_loop_hint`
function (renamed to `hint::spin_loop`), and the use of deprecated
`compare_and_swap` instead of `compare_exchange` methods. Now that our
MSRV is 1.49 (the version in which `hint::spin_loop` was stabilized), we
can fix these warnings.

## Solution

This branch replaces the deprecated APIs. 

Also, I noticed that one of the tests emits unused-imports warnings with
`--no-default-features`. This is because the actual tests are feature
flagged to require `std`, but the module itself doesn't, so the imports
are just hanging out and not getting used for anything. I went ahead and
fixed that as well.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2022-03-25 00:27:20 +00:00
Eliza Weisman
b1123e4315 core: don't use NoSubscriber as local placeholder (#2001)
## Motivation

Currently, it is not actually possible to use `set_default(NoSubscriber)`
or similar to temporarily disable the global default subscriber (see
#1999).

This is because `NoSubscriber` is currently used as a placeholder value
when the thread-local cell that stores the current scoped default
subscriber is initialized. Therefore, we currently check if the current
scoped subscriber is `NoSubscriber`, and if it is, we fall back to
returning the global default instead.

This was fine, _when `NoSubscriber` was a private internal type only_.
However, PR #1549 makes `NoSubscriber` into a public API type. When users
can publicly construct `NoSubscriber` instances, it makes sense to want
to be able to use `NoSubscriber` to disable the current subscriber. This
is not possible when there is a global default set, because the local
default being `NoSubscriber` will cause the global default to be
returned.

## Solution

This branch changes the thread-local cell to store an `Option<Dispatch>`
instead, and use the `None` case to indicate no local default is set.
This way, when the local default is explicitly set to `NoSubscriber`, we
will return `NoSubscriber` rather than falling back.

This may also be a slight performance improvement, because we now check
if there's no global default by checking if the `Option` is `None`,
rather than downcasting it to a `NoSubscriber`.

I've also added a test reproducing #1999.

Fixes #1999

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2022-03-22 10:39:30 -07:00
hrxi
3524310317 core: avoid unnecessary format_args! and write! macros (#1988)
This branch removes some unnecessary uses of the `format_args!`
and `write!` macros in `tracing-core`. Using `fmt::Display::fmt` and
similar rather than the macros may be slightly more efficient.

Co-authored-by: David Barsky <me@davidbarsky.com>
2022-03-22 10:39:30 -07:00
Eliza Weisman
05d56ecfd7
core: fix wrong release numbers in changelog 2022-03-08 16:45:39 -08:00
Eliza Weisman
c6acb12286
core: prepare to release 0.1.23 (#1977)
# 0.1.23 (March 8, 2022)

### Changed

- Removed `#[inline]` attributes from some `Dispatch` methods whose
  callers are now inlined ([#1974])
- Bumped minimum supported Rust version (MSRV) to Rust 1.49.0 ([#1913])

[#1913]: https://github.com/tokio-rs/tracing/pull/1913
[#1974]: https://github.com/tokio-rs/tracing/pull/1974
2022-03-08 16:27:05 -08:00
Eliza Weisman
1f33756654 tracing: reduce disabled span Drop overhead (#1974)
## Motivation

Disabled spans introduce a non-trivial amount of overhead, even when no
`tracing` subscriber is in use. This is primarily due to the need to
create and then drop the empty `Span` struct even when the span is
disabled.

While thinking about #1970 a bit, I noticed that one source of overhead
is that dropping a disabled span always causes a function call, even
when the span is empty. This could be avoided.

## Solution

In this branch, I've changed the `Drop` impls for `Span`, `Entered`, and
`EnteredSpan` to be `#[inline(always)]`. In the always-inlined
functions, we perform a check for whether or not the span is empty, and
if it is not empty, we call into the dispatcher method to drop the span
or guard. The dispatcher methods are no longer inlined. Now, the
function call only occurs when the span _is_ enabled, rather than always
occurring in the `Drop` call. This significantly reduces the overhead
for holding a disabled span, or a disabled `Entered` guard, in a scope.

Also, the `log` integration when dropping a span would always check if
the span had metadata, even when `log` is disabled. This means we would
do an extra branch that wasn't necessary. I moved that into the macro
that guards for whether or not the `log` crate is enabled, which also
significantly reduces overhead.

This change reduces the overhead of a disabled span by 50-70%, per the
`no_subscriber.rs` benchmarks.  I also improved those benchmarks a
bit to test more cases, in order to find the precise difference in overhead
between just constructing `Span::none()` and the actual `span!` macros.

<details>

<summary><code>no_subscriber.rs</code> benchmark results</summary>

```
no_subscriber/span      time:   [696.37 ps 696.53 ps 696.73 ps]
                        change: [-50.599% -50.577% -50.544%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 8 outliers among 100 measurements (8.00%)
  4 (4.00%) high mild
  4 (4.00%) high severe
no_subscriber/span_enter
                        time:   [465.58 ps 466.35 ps 467.61 ps]
                        change: [-71.350% -71.244% -71.138%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  4 (4.00%) high mild
  2 (2.00%) high severe
no_subscriber/empty_span
                        time:   [226.15 ps 226.73 ps 227.36 ps]
                        change: [-84.404% -84.045% -83.663%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  5 (5.00%) high mild
  1 (1.00%) high severe
no_subscriber/empty_struct
                        time:   [693.32 ps 693.76 ps 694.30 ps]
                        change: [+1.7164% +1.9701% +2.2540%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 8 outliers among 100 measurements (8.00%)
  5 (5.00%) high mild
  3 (3.00%) high severe
no_subscriber/event     time:   [294.32 ps 301.68 ps 310.85 ps]
                        change: [+0.3073% +2.1111% +4.1919%] (p = 0.03 < 0.05)
                        Change within noise threshold.
Found 16 outliers among 100 measurements (16.00%)
  2 (2.00%) high mild
  14 (14.00%) high severe
no_subscriber/relaxed_load
                        time:   [463.24 ps 463.74 ps 464.33 ps]
                        change: [+1.4046% +1.6735% +1.9366%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 16 outliers among 100 measurements (16.00%)
  1 (1.00%) low severe
  6 (6.00%) high mild
  9 (9.00%) high severe
no_subscriber/acquire_load
                        time:   [465.28 ps 465.68 ps 466.08 ps]
                        change: [+0.6837% +1.1755% +1.6034%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 8 outliers among 100 measurements (8.00%)
  4 (4.00%) high mild
  4 (4.00%) high severe
no_subscriber/log       time:   [231.11 ps 231.27 ps 231.45 ps]
                        change: [-4.4700% -2.3810% -0.9164%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 17 outliers among 100 measurements (17.00%)
  3 (3.00%) low mild
  8 (8.00%) high mild
  6 (6.00%) high severe

no_subscriber_field/span
                        time:   [1.6334 ns 1.6343 ns 1.6354 ns]
                        change: [-12.401% -12.337% -12.279%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 1 outliers among 100 measurements (1.00%)
  1 (1.00%) high mild
no_subscriber_field/event
                        time:   [461.54 ps 461.84 ps 462.14 ps]
                        change: [-0.3654% +0.1235% +0.5557%] (p = 0.62 > 0.05)
                        No change in performance detected.
Found 6 outliers among 100 measurements (6.00%)
  3 (3.00%) high mild
  3 (3.00%) high severe
no_subscriber_field/log time:   [463.52 ps 463.98 ps 464.49 ps]
                        change: [+0.3011% +0.8645% +1.6355%] (p = 0.01 < 0.05)
                        Change within noise threshold.
Found 18 outliers among 100 measurements (18.00%)
  4 (4.00%) low mild
  10 (10.00%) high mild
  4 (4.00%) high severe
```

</details>

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2022-03-08 14:14:38 -08:00