1071 Commits

Author SHA1 Message Date
Eliza Weisman
4e56741c65
subscriber: prepare to release v0.3.0 (#1677)
# 0.3.0 (Oct 22, 2021)

This is a breaking release of `tracing-subscriber`. The primary breaking
change in this release is the removal of the dependency on the [`chrono`
crate], due to [RUSTSEC-2020-0159]. To replace `chrono`, support is
added for formatting timestamps using the [`time` crate] instead.

In addition, this release includes a number of other breaking API
changes, such as adding (limited) support for `#![no_std]` targets,
removing previously deprecated APIs, and more.

### Breaking Changes

- Removed APIs deprecated in the v0.2.x release series.
- Renamed `Layer::new_span` to `Layer::on_new_span` ([#1674])
- Removed `Layer` impl for `Arc<L: Layer<S>>` and `Arc<dyn Layer<S> +
  ...>` ([#1649])
- Replaced the [`chrono` crate] with the [`time` crate] for timestamp
  formatting, to resolve [RUSTSEC-2020-0159] ([#1646])
- Removed `json` and `env-filter` from default features. They must now
  be enabled explictly ([#1647])
- Changed `FormatEvent::format_event` and `FormatFields::format_fields`
  trait methods to take a `Writer` type, rather than a `&mut dyn
  fmt::Write` trait object ([#1661])
- Changed the signature of the `MakeWriter` trait by adding a lifetime
  parameter ([#781])
  ### Changed

- **layer**: Renamed `Layer::new_span` to `Layer::on_new_span` ([#1674])
- **fmt**: Changed `FormatEvent::format_event` and
  `FormatFields::format_fields` trait methods to take a `Writer` type,
  rather than a `&mut dyn fmt::Write` trait object ([#1661])
- **json**, **env-filter**: `json` and `env-filter` feature flags are no
  longer enabled by default ([#1647])
  ### Removed

- Removed deprecated `CurrentSpan` type ([#1320])
- **registry**: Removed deprecated `SpanRef::parents` iterator, replaced
  by `SpanRef::scope` in [#1431] ([#1648)])
- **layer**: Removed deprecated `Context::scope` iterator, replaced by
  `Context::span_scope` and `Context::event_scope` in [#1431] and
  [#1434] ([#1648)])
- **layer**: Removed `Layer` impl for `Arc<L: Layer<S>>` and `Arc<dyn
  Layer<S> + ...>`. These interfere with per-layer filtering. ([#1649])
- **fmt**: Removed deprecated `LayerBuilder` type ([#1673])
- **fmt**: Removed `fmt::Layer::on_event` (renamed to
  `fmt::Layer::fmt_event`) ([#1673])
- **fmt**, **chrono**: Removed the `chrono` feature flag and APIs for
  using the [`chrono` crate] for timestamp formatting ([#1646])
  ### Added

- **fmt**, **time**: `LocalTime` and `UtcTime` types for formatting
  timestamps using the [`time` crate] ([#1646])
- **fmt**: Added a lifetime parameter to the `MakeWriter` trait,
  allowing it to return a borrowed writer. This enables implementations
  of `MakeWriter` for types such as `Mutex<T: io::Write>` and
  `std::fs::File`. ([#781])
- **env-filter**: Documentation improvements ([#1637])
- Support for some APIs on `#![no_std]` targets, by disabling the `std`
  feature flag ([#1660])

Thanks to @Folyd and @nmathewson for contributing to this release!

[#1320]: https://github.com/tokio-rs/tracing/pull/1320
[#1673]: https://github.com/tokio-rs/tracing/pull/1673
[#1674]: https://github.com/tokio-rs/tracing/pull/1674
[#1646]: https://github.com/tokio-rs/tracing/pull/1646
[#1647]: https://github.com/tokio-rs/tracing/pull/1647
[#1648]: https://github.com/tokio-rs/tracing/pull/1648
[#1649]: https://github.com/tokio-rs/tracing/pull/1649
[#1660]: https://github.com/tokio-rs/tracing/pull/1660
[#1661]: https://github.com/tokio-rs/tracing/pull/1661
[#1431]: https://github.com/tokio-rs/tracing/pull/1431
[#1434]: https://github.com/tokio-rs/tracing/pull/1434
[#781]: https://github.com/tokio-rs/tracing/pull/781

[`chrono` crate]: https://crates.io/crates/chrono
[`time` crate]: https://crates.io/crates/time
[RUSTSEC-2020-0159]: https://rustsec.org/advisories/RUSTSEC-2020-0159.html

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
tracing-subscriber-0.3.0
2021-10-22 16:01:35 -07:00
Eliza Weisman
f461c5bbd0 appender: fix compilation 32-bit platforms like PowerPC (#1675)
This branch is @dzvon's PR #1508, with the following changes:

* Add a newtype wrapping the error counter to hide that it's internally
  an `Arc<AtomicUsize>`. This would allow us to make additional changes
  to the implementation without potentially causing breaking changes.

* Use saturating arithmetic when incrementing the counter to avoid
  wrapping to 0 on overflows. This is more likely to be an issue on
  32-bit platforms.

This is a breaking change that will be released as part of 
`tracing-appender` 0.2.

Closes #1508

Description from @dzvon's original PR:

## Motivation

Currently, tracing-appender crate cannot be compiled on PowerPC
platform. Because

> PowerPC and MIPS platforms with 32-bit pointers do not have
> `AtomicU64` or `AtomicI64` types.

quote from std library docs.
(https://doc.rust-lang.org/std/sync/atomic/index.html#portability)

## Solution

Change `AtomicU64` to `AtomicUsize`.

Co-authored-by: Dezhi Wu <wu543065657@163.com>
2021-10-22 13:26:09 -07:00
Eliza Weisman
8777d2c925 subscriber: rename Layer::new_span to on_new_span (#1674)
While we're breaking things, we may as well do this as well.

Closes #630
Closes #662
2021-10-22 13:26:09 -07:00
David Barsky
c62dac9f73 appender: replace chrono with time (#1652)
## Motivation

This PR continues the work started in
https://github.com/tokio-rs/tracing/pull/1646 to replace `chrono` with
`time`. I'll refer to @hawkw's motivation:

> Currently, `tracing-subscriber` supports the `chrono` crate for
> timestamp formatting, via a default-on feature flag. When this code
> was initially added to `tracing-subscriber`, the `time` crate did not
> have support for the timestamp formatting options we needed.
>
> Unfortunately, the `chrono` crate's maintenance status is now in
> question (see #1598). Furthermore, `chrono` depends on version 0.1 of
> the `time` crate, which contains a security vulnerability
> (https://rustsec.org/advisories/RUSTSEC-2020-0071.html). This
> vulnerability is fixed in more recent releases of `time`, but `chrono`
> still uses v0.1.

## Solution

I've replaced chrono with time 0.3. Unfortunately, some of chrono's
builders for DateTimes are not present in `time`, which required the
usage of `macro_rules!` macros to construct some of the hard-coded
times. I also took the opportunity to tidy some of the tests and change
the internal representation of `Rotation::NEVER` from year 9,999 to an
`Option::None`.

This branch changes `tracing-appender`'s MSRV from Rust 1.42 to Rust
1.51, the MSRV for the `time` crate when certain required feature flags
are enabled. This does *not* effect the MSRV for other crates in this
repository.
2021-10-22 13:26:09 -07:00
Eliza Weisman
60a2644fcb chore: add CI env variable configurations (#1672)
This branch adds some environment variables to configure *all* CI jobs.
In particular, we:

- disable incremental compilation
- increase the number of retries for network requests in `cargo` and
  `rustup`
- emit shortened backtraces from panics

This config was blatantly stolen from linkerd/linkerd2-proxy#7137. :)

Incremental compilation is useful as part of an edit-build-test-edit
cycle, as it lets the compiler avoid recompiling code that hasn't
changed. However, on CI, we're not making small edits; we're almost
always building the entire project from scratch. Thus, incremental
compilation on CI actually introduces *additional* overhead to support
making future builds faster...but no future builds will ever occur in
any given CI environment.

See https://matklad.github.io/2021/09/04/fast-rust-builds.html#ci-workflow
for details.

Increasing retries for network requests should help reduce flakiness a
bit.
2021-10-22 13:26:09 -07:00
Bryan Burgers
ffdce75bef docs: add blog posts as external resources (#1667)
As requested at https://twitter.com/mycoliza/status/1451288675547967514
2021-10-22 13:26:09 -07:00
Markus Bergkvist
d019e43540 core: update parent() documentation (#1665)
`Event::parent()` and `Span::parent()` returns an `Option`, not boolean.
2021-10-22 13:26:09 -07:00
Eliza Weisman
f5aac47f68 attributes: refactor into separate modules (#1643)
## Motivation

Currently, `tracing-attributes` consists of one very large `lib.rs`
module that's 1358 lines long. In my opinion, this makes the code
somewhat hard to navigate.

## Solution

This branch refactors `tracing-attributes` so that most of the code is
split into two separate modules: `attrs.rs`, which contains the types
representing the attribute arguments and the code for parsing them, and
`expand.rs`, which contains the code for actually expanding an
`#[instrument]` macro to generate the instrumented code. For the most
part, this was a pretty clean split.

I also did a small change to the way `async-trait` support is
implemented; moving the two steps for generating instrumented code for
`async-trait` to two methods on the `AsyncTraitInfo` struct; one for
determining if the instrumented function is also an `async-trait` method
and finding the necessary information to instrument it, and one for
generating the instrumented code. This feels a bit neater than doing all
of that in the `gen_function` function.

There shouldn't be any functional changes or significant
implementatation changes (besides the `async-trait` change) in this
branch; just moving code around.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-22 13:26:09 -07:00
cynecx
8540abcb82 attributes: speculative expand when parsing fails (#1634)
## Motivation

Recent `rust-analyzer` versions enabled automatic expansion of proc
macro attributes by default. This is a problem with `#[instrument]`,
because it currently produces a `compile_error!` when parsing the code
inside the `#[instrument]`ed function fails, and *discards* those
tokens. This means that if the `#[instrument]` attribute is placed on a
function whose implementation fails to parse, recent versions of
`rust-analyzer` will no longer be able to display diagnostics for those
errors. In some cases, this can also break autocompletion.

## Solution

This branch changes `#[instrument]` to always expand to the tokens
contained in the `#[instrument]`ed function body, regardless of whether
or not they could be parsed successfully. Now, an error is only emitted
when the `#[instrument]` attribute *itself* could not be parsed. Since
the instrumented function is always expanded, any errors within that
function can be displayed properly by `rust-analyzer`.

Fixes #1633.
2021-10-22 13:26:09 -07:00
Ceyhun Can Ulker
f515e9d35c attributes: add err(Debug) meta to use Debug impl (#1631)
## Motivation

This PR attempts to solve #1630 by introducing `err(Debug)` meta to
`intrument` attribute macro. As `err` meta causes the error (`e`)
returned by instrumented function to be passed to `tracing::error!(error
= %e)` i.e. makes it use the `Display` implementation of `e`, the newly
added `err(Debug)` makes expands to `tracing::error!(error = ?e)` which
makes the `error!` macro to use `Debug` implementation for `e`. `err`
and `err(Debug)` are mutually exclusive, adding both will create a
compilation error.

`err(Display)` is also supported to specify `Display` explicitly.

As tried to describe, for some types implementing `Error` it might be
more suitable to use `Debug` implementation as in the case of
`eyre::Result`. This frees us to manually go over the error chain and
print them all, so that `instrument` attribute macro would do it for us.

## Solution

- Added a custom keyword `err(Debug)` similar to `err`,
- Add `err(Debug)` field to `InstrumentArgs`,
- Add parsing for `err(Debug)` arg and check for conflicts with `err`,
- Generate `tracing::error!(error = ?e)` when `err(Debug)` is `true` and
  `tracing::error!(error = %e)` when `err(Display)` or `err` is `true`,
- Interpolate generated `err_block` into `Err` branches in both async
  and sync return positions, if `err` or `err(Debug)` is `true`.
2021-10-22 13:26:09 -07:00
Ricky Han
00aebfac9e docs: add tracing-etw to Related Crates (#1635)
This PR adds tracing-etw which is a new crate.

* Update README.md

* Update lib.rs
2021-10-22 13:26:09 -07:00
Eliza Weisman
a927607fdf
subscriber: remove deprecated APIs (#1673)
## Motivation

`tracing-subscriber` currently contains some APIs that were deprecated
in the v0.2.x series:
- `fmt::LayerBuilder`, which is now a type alias for `fmt::Layer` (as
  the `Layer` type can expose all the same methods as the builder)
- `registry::SpanRef::parent_id`, which doesn't play nice with per-layer
  filtering,
- `fmt::Layer::inherit_fields`, which no longer does anything as it's
  now the default behavior
- `fmt::Layer::on_event`, which was renamed to `fmt_event`
- the `SpanRef::parents` and `layer::Context::scope` iterators, which
  were replaced by the APIs added in #1431 and #1434

Prior to releasing v0.3, the deprecated APIs should be removed.

## Solution

This branch deletes the deprecated APIs, with the exception of
`SpanRef::parents` and `Context::scope` (which were already removed in
240d11a7ef70c1197f8071d98db74a02bd58fad9).

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-22 10:28:18 -07:00
Eliza Weisman
7d3bff82d6 subscriber: fix imports with std only
Turns out that if `std` is enabled but `smallvec` is not, we have some
missing imports. This fixes the build when a crate passes
`default-features = "false` but then enables `std`.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-21 12:39:23 -07:00
Eliza Weisman
abe2b6a9f4 chore(CI): change cargo audit to run on a schedule (#1658)
## Motivation

Currently, `cargo audit` checks are run on every push that modifies
`Cargo.toml` or lockfiles. The intention behind this was to fail changes
that introduce dependencies that have security advisories. However, it
turns out that this is not actually the primary use-case for `cargo audit`
runs. Typically, when a dependency of a `tracing` crate has a
security advisory, this isn't newly introduced by a PR, but a new
*advisory* that was just announced for a library we *already* depended
on. In this case, this isn't a failure that should block any particular
branch from merging; instead, it's a *new issue* that should block
effected crates from being *released*.

## Solution

This branch changes the audit workflow from running on pushes to running
on a schedule (nightly). When using `actions-rs/audit-check` in a
scheduled mode, it will automatically open new issues if any
dependencies have security advisories (see
https://github.com/actions-rs/audit-check#scheduled-audit for details).
This means those advisories can be fixed separately while still allowing
unrelated branches to pass CI. This is, IMO, a better workflow for
handling security advisories.

If we introduce release automation in the future, we should ensure that
the release automation process checks that the crate being released has
no open security advisory issues, and fails the *release* if any such
issues are still open.
2021-10-21 12:39:23 -07:00
Eliza Weisman
e82596842c subscriber: minor feature flagging fixup
This fixes unused code warnings with the default featureset.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-21 12:39:23 -07:00
Eliza Weisman
2d34bdb8c7 subscriber: replace dyn Write with a Writer type (#1661)
## Motivation

Currently, the `FormatEvent` and `FormatFields` traits in
`tracing-subscriber` are passed a `&mut dyn fmt::Write` trait object to
write formatted representations of events and fields to. This is fine,
but it doesn't give us the ability to easily provide additional
configuration to the formatter, such as whether ANSI color codes are
supported.

Issue #1651 describes some approaches for adding a way to expose the
ANSI color code configuration to custom formatters. In particular, the
proposed solution involves wrapping the `fmt::Write` trait object in an
opaque struct, which can then implement additional methods for exposing
information like "are ANSI colors enabled" to the formatter. Since this
changes the signature of the `FormatEvent::format_event` and
`FormatFields::format_fields` methods, it's a breaking change.
Therefore, we need to make this change _now_ if we want to get the API
change in for `tracing-subscriber` 0.3.

## Solution

This branch adds a `Writer` struct that wraps the `&mut dyn fmt::Write`
trait object, and changes the various method signatures as appropriate.
It does **not** actually implement the change related to ANSI color
formatting. Once we change these methods' signatures to accept a
`Writer` struct, we can add as many methods to that struct as we like
without making additional breaking API changes. Therefore, this branch
_just_ makes the breaking change that's necessary to get in before v0.3
is released.

Propagating the ANSI color configuration can be implemented in a future
branch.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-21 12:39:23 -07:00
Eliza Weisman
3baf4542ca subscriber: feature flags that require std enable it (#1660)
## Motivation

Currently, some `tracing-subscriber` dependencies in other crates use
`default-features = false`, to ensure that unneeded default features of
`tracing-subscriber` are not inadvertently enabled. However, some of the
features those crates enable also require the `std` feature flag. The
`default-features = false` config _disables_ the `std` feature, so the
required features are not available.

## Solution

This branch changes `tracing-subscriber`'s `fmt`, `registry`, and
`env-filter` feature flags to also enable the `std` feature flag
automatically.

## Alternatives

As an alternative solution, we could change crates that depend on
`tracing-subscriber` with `default-features = false` to also explicitly
ensure that the `std` feature is enabled (which might be worth doing
regardless). This is what PR #1659 does. However, I think the approach
in this branch is more correct; the feature flags that require standard
library support should automatically enable it. This provides a better
experience for most users, who are simply adding `default-features = false`
in order to avoid enabling un-needed features, not to support
`no_std`, and would like enabling a feature flag to *actually* enable
that feature.

`no_std` users will know not to enable `registry`, `fmt`, and
`env-filter` because the documentation notes that those features require
the standard library.
2021-10-21 12:39:23 -07:00
Eliza Weisman
240d11a7ef subscriber: add minimal #![no_std] support (#1648)
Backports #1648 from `master`.

Depends on #1649

## Motivation

Presently, the `tracing-subscriber` crate requires the Rust standard
library and doesn't build with `#![no_std]` targets. For the most part,
this is fine, as much of `tracing-subscriber` inherently depends on
`std` APIs.

However, `tracing-subscriber` also contains some key abstractions that
are necessary for interoperability: the `Layer` and `LookupSpan`
traits. Since these traits are in `tracing-subscriber`, `no-std` users
cannot currently access them.

Some of the other utilities in this crate, such as the field visitor
combinators, may also be useful for `#![no_std]` projects.

## Solution

This branch adds "std" and "alloc" feature flags to
`tracing-subscriber`, for conditionally enabling `libstd` and
`liballoc`, respectively. The `registry`, `fmt`, `EnvFilter`, and
`reload` APIs all require libstd, and cannot be implemented without it,
but the core `Layer` and `LookupSpan` traits are now available with
`#![no_std]`.

Fixes #999

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-21 12:39:23 -07:00
Eliza Weisman
b420ae7f4c subscriber: remove Layer impls for Arcs (#1649)
Implementing `Layer` for `Arc`s, which are immutable, breaks the
ability to implement `Layer::on_layer` with a mutable reference.
This is necessary for per-layer filtering. See
https://github.com/tokio-rs/tracing/pull/1576#discussion_r711609810 for
details. Therefore, the `Layer` impls for `Arc`s should not be used.

In 0.3, we have the opportunity to remove these APIs. Therefore, this PR
removes them.
2021-10-21 12:39:23 -07:00
Eliza Weisman
c8b91caa05 subscriber: reduce default features (#1647)
This changes `tracing-subscriber` so that the `env-filter`, `json`,
 and `chrono` features are not enabled by default, and instead require
users to opt in. This should significantly reduce the default
dependency footprint.

Of course, this is a breaking change, and therefore will be part of
`tracing-subscriber` v0.3.

Fixes #1258

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-21 12:39:23 -07:00
Eliza Weisman
3634c9120f subscriber: replace chrono with time for timestamp formatting (#1646)
## Motivation

Currently, `tracing-subscriber` supports the `chrono` crate for
timestamp formatting, via a default-on feature flag. When this code was
initially added to `tracing-subscriber`, the `time` crate did not have
support for the timestamp formatting options we needed.

Unfortunately, the `chrono` crate's maintainance status is now in
question (see #1598). Furthermore, `chrono` depends on version 0.1 of
the `time` crate, which contains a security vulnerability
(https://rustsec.org/advisories/RUSTSEC-2020-0071.html). This
vulnerability is fixed in more recent releases of `time`, but `chrono`
still uses v0.1.

## Solution

Fortunately, the `time` crate now has its own timestamp formatting
support.

This branch replaces the `ChronoLocal` and `ChronoUtc` timestamp
formatters with new `LocalTime` and `UtcTime` formatters. These
formatters use the `time` crate's formatting APIs rather than
`chrono`'s. This removes the vulnerable dependency on `time` 0.1

Additionally, the new `time` APIs are feature flagged as an _opt-in_
feature, rather than as an _opt-out_ feature. This should make it easier
to avoid accidentally depending on the `time` crate when more
sophisticated timestamp formatting is _not_ required.

In a follow-up branch, we could also add support for `humantime` as an
option for timestamp formatting.

Naturally, since this removes existing APIs, this is a breaking change,
and will thus require publishing `tracing-subscriber` 0.3. We'll want to
do some other breaking changes as well.

Fixes #1598.
2021-10-21 12:39:23 -07:00
Nick Mathewson
470661a439 subscriber: document that directives are comma-separated (#1637)
Previously, the documentation explained that an `EnvFilter` consisted
of multiple directives, but didn't describe how to actually put
these directives together.  (My first guess was "with spaces", but
that was wrong.)

This patch changes the documentation to say that directives are
comma-separated, and gives an example of a comma-separated filter.
2021-10-21 12:39:23 -07:00
Folyd
8c998447f6 subscriber: remove legacy CurrentSpan (#1320)
I'm quite confident that no elsewhere using the
`tracing_subscriber::CurrentSpan`  in the present codebases. Do we need
to keep it for the future version? Otherwise, I think we can remove it
and the related `thread.rs`.

Feel free to point me out if I'm wrong. :)

Co-authored-by: Eliza Weisman <eliza@buoyant.io>
2021-10-21 12:39:23 -07:00
Eliza Weisman
6cc6c47354
subscriber: add lifetime parameter to MakeWriter (#781) (#1654)
This backports PR #781 from `master`.

## Motivation

Currently, the `tracing-subscriber` crate has the `MakeWriter` trait for
customizing the io writer used by `fmt`. This trait is necessary (rather
than simply using a `Write` instance) because the default implementation
performs the IO on the thread where an event was recorded, meaning that
a separate writer needs to be acquired by each thread (either by calling
a function like `io::stdout`, by locking a shared `Write` instance,
etc).

Right now there is a blanket impl for `Fn() -> T where T: Write`. This
works fine with functions like `io::stdout`. However, the _other_ common
case for this trait is locking a shared writer.

Therefore, it makes sense to see an implementation like this:

``` rust
impl<'a, W: io::Write> MakeWriter for Mutex<W>
where
    W: io::Write,
{
    type Writer = MutexWriter<'a, W>;
    fn make_writer(&self) -> Self::Writer {
        MutexWriter(self.lock().unwrap())
    }
}

pub struct MutexWriter<'a, W>(MutexGuard<'a, W>);

impl<W: io::Write> io::Write for MutexWriter<'_, W> {
    // write to the shared writer in the `MutexGuard`...
}
```

Unfortunately, it's impossible to write this. Since `MakeWriter` always
takes an `&self` parameter and returns `Self::Writer`, the generic
parameter is unbounded:
```
    Checking tracing-subscriber v0.2.4 (/home/eliza/code/tracing/tracing-subscriber)
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
  --> tracing-subscriber/src/fmt/writer.rs:61:6
   |
61 | impl<'a, W: io::Write> MakeWriter for Mutex<W>
   |      ^^ unconstrained lifetime parameter

error: aborting due to previous error
```

This essentially precludes any `MakeWriter` impl where the writer is
borrowed from the type implementing `MakeWriter`. This is a significant
blow to the usefulness of the trait. For example, it prevented the use
of `MakeWriter` in `tracing-flame` as suggested in
https://github.com/tokio-rs/tracing/pull/631#discussion_r391138233.

## Proposal

This PR changes `MakeWriter` to be generic over a lifetime `'a`:

```rust
pub trait MakeWriter<'a> {
    type Writer: io::Write;

    fn make_writer(&'a self) -> Self::Writer;
}
```
The `self` parameter is now borrowed for the `&'a` lifetime, so it is
okay to return a writer borrowed from `self`, such as in the `Mutex`
case.

I've also added an impl of `MakeWriter` for `Mutex<T> where T: Writer`.

Unfortunately, this is a breaking change and will need to wait until we
release `tracing-subscriber` 0.3.

Fixes #675.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-19 16:45:14 -07:00
Koute
4e5f0f06ab
log: add an interest cache for logs emitted through the log crate (#1636)
## Motivation

We use `tracing` as our logger in
[`substrate`](https://github.com/paritytech/substrate). We've noticed
that as soon as *any* `trace` log is enabled (even one which doesn't
exists) the whole logging machinery starts to take a lot of time, even
if nothing at all is actually printed!

In one of our quick-and-dirty reproduction benchmarks (JIT-ing a WASM
program) we saw the total real runtime rise from around ~1.3s to ~7s
just by adding a `trace` log filter which doesn't match anything.
(Depending on the hardware and on how many threads are simultaneously
logging this figure varies pretty widely, but it's always a very
significant drop.)

After looking into this problem I've found that the culprit of the
slowdown were `trace!` and `debug!` logs sprinkled quite liberally in
some of the more hot codepaths. When there are no `trace`-level filters
defined on the logger it can basically reject those inert `trace!` and
`debug!` logs purely based on the current maximum logging level (which
is cheap!), but as soon as you define *any* trace filter the current
maximum logging changes, and then every `trace!` and `debug!` log has to
go through the whole filtering machinery before it can be rejected.
While this is cheap if you only do it once, it starts to become very
expensive when you do it a lot, especially when you're running multiple
threads and enable log reloading. (This is related to
https://github.com/tokio-rs/tracing/issues/1632.)

## Solution

I've added an opt-in per-thread LRU cache which tries to cache whenever
the logger is actually interested in a given `target` + `level` pair for
every log emitted through the `log` crate.

I've also added a benchmark very roughly replicating the situation from
our code; here's the performance *without* the cache: (`cargo bench`)

```
[838.67 ns 846.51 ns 854.04 ns]
```

And here's the performance *with* the cache: (`cargo bench --features
interest-cache`)

```
[25.322 ns 25.556 ns 25.820 ns]
```

As you can see the per-call cost was cut down to less than ~3%.
2021-10-18 09:23:35 -07:00
nickelc
a10ddf8aa3
docs: fix a typo in tracing's changelog (#1624)
tracing-attributes v0.1.18 was released yesterday not v0.1.19
2021-10-06 10:47:59 -07:00
Eliza Weisman
d0ef14d3f5
tracing: prepare to release v0.1.29 (#1623)
# 0.1.29 (October 5th, 2021

This release adds support for recording `Option<T> where T: Value` as
typed `tracing` field values. It also includes significant performance
improvements for functions annotated with the `#[instrument]` attribute
when the generated span is disabled.

### Changed

- `tracing-core`: updated to v0.1.21
- `tracing-attributes`: updated to v0.1.19

### Added

- **field**: `Value` impl for `Option<T> where T: Value` ([#1585])
- **attributes**: - improved performance when skipping
  `#[instrument]`-generated spans below the max level ([#1600], [#1605],
  [#1614], [#1616], [#1617])

### Fixed

- **instrument**: added missing `Future` implementation for
  `WithSubscriber`, making the `WithDispatch` extension trait actually
  useable ([#1602])
- Documentation fixes and improvements ([#1595], [#1601], [#1597])

Thanks to @brianburgers, @mattiast, @DCjanus, @oli-obk, and @matklad for
contributing to this release!

[#1585]: https://github.com/tokio-rs/tracing/pull/1585
[#1595]: https://github.com/tokio-rs/tracing/pull/1596
[#1597]: https://github.com/tokio-rs/tracing/pull/1597
[#1600]: https://github.com/tokio-rs/tracing/pull/1600
[#1601]: https://github.com/tokio-rs/tracing/pull/1601
[#1602]: https://github.com/tokio-rs/tracing/pull/1602
[#1605]: https://github.com/tokio-rs/tracing/pull/1605
[#1614]: https://github.com/tokio-rs/tracing/pull/1614
[#1616]: https://github.com/tokio-rs/tracing/pull/1616
[#1617]: https://github.com/tokio-rs/tracing/pull/1617
tracing-0.1.29
2021-10-05 18:39:55 -07:00
Eliza Weisman
6692aaf738
subscriber: prepare to release 0.2.25 (#1622)
# 0.2.25 (October 5, 2021)

This release fixes an issue where a `Layer` implementation's custom
`downcast_raw` implementation was lost when wrapping that layer with a
per-layer filter.

### Fixed

- **registry**: Forward `Filtered::downcast_raw` to wrapped `Layer`
  ([#1619])

### Added

- Documentation improvements ([#1596], [#1601])

Thanks to @bryanburgers for contributing to this release!

[#1619]: https://github.com/tokio-rs/tracing/pull/1619
[#1601]: https://github.com/tokio-rs/tracing/pull/1601
[#1596]: https://github.com/tokio-rs/tracing/pull/1596
tracing-subscriber-0.2.25
2021-10-05 15:39:32 -07:00
Bryan Burgers
29ffdbc2b2
subscriber: forward Filtered::downcast_raw to wrapped Layer (#1619)
## Motivation

I'm trying to implement a `Layer` that has something very similar to
tracing-error's
[`WithContext`](66cd79f72a/tracing-error/src/layer.rs (L32))
to support erasing types and getting access to the current span's state.

To do that, I implement `Layer::downcast_raw` in [the same way that
tracing-error
does](66cd79f72a/tracing-error/src/layer.rs (L55-L63)).

This works great when the layer is not filtered. However, once I filter
the layer

```rust
let filter = tracing_subscriber::filter::Targets::new().with_default(tracing::Level::INFO);
let layer = MyLayer::new();
tracing_subscriber::registry().with(layer.with_filter(filter)).init();
```

I'm not able to get a `WithContext` instance anymore, because `Filtered`
[handles `downcast_raw`, and doesn't forward
it](66cd79f72a/tracing-subscriber/src/filter/layer_filters.rs (L379-L391))
to `MyLayer::downcast_raw`.

## Solution

If `Filtered::downcast_raw` does not know how to handle the given type,
forward it to the wrapped layer's `Layer::downcast_raw` implementation.


Fixes #1618
2021-10-05 14:12:02 -07:00
Eliza Weisman
645f282eee
attributes: prepare to release 0.1.18 (#1621)
# 0.1.18 (October 5, 2021)

This release fixes issues introduced in v0.1.17.

### Fixed

- fixed mismatched types compiler error that may occur when using
  `#[instrument]` on an `async fn` that returns an `impl Trait` value
  that includes a closure ([#1616])
- fixed false positives for `clippy::suspicious_else_formatting`
  warnings due to rust-lang/rust-clippy#7760 and
  rust-lang/rust-clippy#6249 ([#1617])
- fixed `clippy::let_unit_value` lints when using `#[instrument]`
  ([#1614])

[#1617]: https://github.com/tokio-rs/tracing/pull/1617
[#1616]: https://github.com/tokio-rs/tracing/pull/1616
[#1614]: https://github.com/tokio-rs/tracing/pull/1614
tracing-attributes-0.1.18
2021-10-05 14:10:42 -07:00
Eliza Weisman
7dda7f5e90 attributes: remove unnecessary quote_spanned! (#1617)
## Motivation

Apparently, using `quote_spanned!` can trigger a Clippy bug where the
text `else`, even inside a comment, _may_ cause the
`suspicious_else_formatting` lint to be triggered incorrectly (see
rust-lang/rust-clippy#7760 and rust-lang/rust-clippy#6249). This causes
the lint to fire in some cases when the `#[instrument]` attribute is
used on `async fn`s. See issue #1613 for details.

## Solution

It turns out that some of the uses of `quote_spanned!` in the
`tracing-attributes` code generation are not needed. We really only need
`quote_spanned!` when actually interpolating the user provided code into
a block, not in the `tracing-attributes` code that inserts the generated
code for producing the span etc. Replacing some of these
`quote_spanned!` uses with the normal `quote!` macro still generates
correct location diagnostics for errors in the user code, but fixes the
incorrect clippy lint.

I've added a few test cases that should reproduce the bug.

Fixes #1613

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-05 13:27:27 -07:00
Eliza Weisman
243a3e2d2f attributes: fix compile error with instrumented async functions (#1616)
## Motivation

The changes in #1607 introduced a potential compilation error when using
the `#[instrument]` attribute on `async fn`s that return a type that
includes a closure or is otherwise unnameable. This is because the
future's body code was quoted in two separate places in order to have a
separate branch when the span is statically disabled. This means that
when a closure is returned, it will technically have two distinct types
based on whether or not the span is enabled, since it originates from
two separate source code locations (although `quote_spanned!` obscures
this, so the compiler diagnostic will appear to have two closures
originating from the same location).

## Solution

This branch fixes this issue by changing the code generated for
`#[instrument]`ed async functions. Unfortunately, for async functions,
we can't have the optimization of not creating the span at all when the
level is disabled, because we need to create the span _before_ creating
the future, as it may borrow arguments.

I've also added tests reproducing issue #1615

Fixes #1615
2021-10-05 13:27:27 -07:00
Eliza Weisman
ac74ba0ca5 attributes: suppress clippy::suspicious_else without nop let (#1614)
Currently, `tracing-attributes` generates a `let _ = ();` in between the
`if tracing::level_enabled!(...) {}` and the function body. This is
intended to suppress the `clippy::suspicious_else_formatting` lint,
which is generated when an `if` is followed immediately by a block with
no whitespace in between. Since we can't add whitespace in the generated
code (as `quote` produces a stream of _rust tokens_, not text), we
can't suppress the lint without adding a no-op statement.

However, unfortunately, the no-op let triggers a _different_ lint
(`clippy::let_unit_value`), when `clippy::pedantic` is enabled. This is
kind of annoying for some users.

This branch changes the code to suppress the
`suspicious_else_formatting` lint using `#[allow(...)]` attributes,
instead. The warning is turned back on inside of user code, since users
probably want the warning.
2021-10-05 13:27:27 -07:00
Eliza Weisman
66cd79f72a
attributes: prepare to release v0.1.17 (#1611)
# 0.1.17 (October 1, 2021)

This release significantly improves performance when
`#[instrument]`-generated spans are below the maximum enabled level.

### Added

- improve performance when skipping `#[instrument]`-generated spans
  below the max level ([#1600], [#1605])

Thanks to @oli-obk for contributing to this release!

[#1600]: https://github.com/tokio-rs/tracing/pull/1600
[#1605]: https://github.com/tokio-rs/tracing/pull/1605
tracing-attributes-0.1.17
2021-10-01 16:58:39 -07:00
Eliza Weisman
3ee87f3cb9
core: prepare to release 0.1.21 (#1610)
# 0.1.21 (October 1, 2021)

This release adds support for recording `Option<T> where T: Value` as
typed `tracing` field values.

### Added

- **field**: `Value` impl for `Option<T> where T: Value` ([#1585])

### Fixed

- Fixed deprecation warnings when building with `default-features`
  disabled ([#1603], [#1606])
- Documentation fixes and improvements ([#1595], [#1601])

Thanks to @brianburgers, @DCjanus, and @matklad for contributing to this
release!

[#1585]: https://github.com/tokio-rs/tracing/pull/1585
[#1595]: https://github.com/tokio-rs/tracing/pull/1595
[#1601]: https://github.com/tokio-rs/tracing/pull/1601
[#1603]: https://github.com/tokio-rs/tracing/pull/1603
[#1606]: https://github.com/tokio-rs/tracing/pull/1606
tracing-core-0.1.21
2021-10-01 16:56:22 -07:00
Eliza Weisman
84c1c264ad chore: fix CI tracing-core nostd testing tracing
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-01 14:34:01 -07:00
Eliza Weisman
c9db496a95 attributes: skip async spans if level disabled (#1607)
## Motivation

In #1600, the `instrument` code generation was changed to avoid ever
constructing a `Span` struct if the level is explicitly disabled.
However, for `async` functions, `#[instrument]` will currently still
create the span, but simply skips constructing an `Instrument` future if
the level is disabled.

## Solution

This branch changes the `#[instrument]` code generation for async blocks
to totally skip constructing the span if the level is disabled. I also
simplfied the code generation a bit by combining the shared code between
the `err` and non-`err` cases, reducing code duplication a bit.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-01 14:34:01 -07:00
Eliza Weisman
ca3a51c6ef tracing: add missing Future impl for WithDispatch (#1602)
The version of `WithSubscriber` in `tracing::instrument` (rather than in
`tracing-futures`) is currently...useless, since there is no `Future`
impl for the `WithDispatch` type. This means that calling
`with_collector` on a `Future` returns a value that _isn't_ a `Future`.
Additionally, the `WithSubscriber` trait isn't actually implemented for
anything (although this was fixed on v0.1.x).

This branch adds the missing implementations. I also improved the docs a
bit.

Note that the `Future` impl requires the "std" feature flag, but the
`WithSubscriber` trait and `WithDispatch` type do not. This is because
requiring the feature flag for these definitions would *technically* be
a breaking change, since they were previously published without the
feature flag and could e.g. be imported...even though they were totally
useless. Sigh.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
; Conflicts:
;	tracing/src/instrument.rs
2021-10-01 14:34:01 -07:00
Zach Kemp
024d6abcf2 appender: explicitly flush previous BufWriter before dropping (#1604)
## Motivation

When a `RollingFileAppender` is refreshed, the previous `BufWriter` may
encounter and suppress errors in `drop`.

From https://doc.rust-lang.org/std/io/struct.BufWriter.html:

> It is critical to call flush before BufWriter<W> is dropped. Though
> dropping will attempt to flush the contents of the buffer, any errors
> that happen in the process of dropping will be ignored.

## Solution

Explicitly flush the previous buffer before dropping, printing any error
to stderr.
2021-10-01 14:34:01 -07:00
Eliza Weisman
f350c08a26 core: additional deprecation fixes (#1606)
This should *actually* fix the build on no-std.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-01 14:34:01 -07:00
Eliza Weisman
ee2f67c667 core: fix spin_loop_hint deprecation (#1603)
Allow the deprecated API for now, until the next MSRV bump.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2021-10-01 14:34:01 -07:00
Matti Åstrand
700fd15055 docs: add a parenthesis (#1597)
## Motivation
Looks like doc is missing a parenthesis


## Solution
Add a parenthesis
2021-10-01 14:34:01 -07:00
Aleksey Kladov
30d90bac2e core: fix missing dyn in Visit docs example (#1595)
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
2021-10-01 14:34:01 -07:00
Eliza Weisman
4f9987dcd1 examples: add tokio_panic_hook example (#1593)
It turns out panic hooks also work nicely even when panics are captured.
I figured we may as well have an example demoing this!
2021-10-01 14:34:01 -07:00
Oli Scherer
3b038ed3ad
attributes: help LLVM understand that some spans are never going to do anything (#1600) (#1605)
## Motivation

Adding `#[instrument(level = "debug")]` attributes to functions in rustc
caused a performance regression (in release, where `debug!` is fully
optimized out) across all crates:
https://github.com/rust-lang/rust/pull/89048#issuecomment-929566530

While trying to debug this, I noticed that spans don't have the same
advantage that events have wrt to how LLVM sees them. Spans (or more
precisely, the enter-guard), will get dropped at the end of the scope,
which throws a spanner into the LLVM optimization pipeline. I am not
entirely sure where the problem is, but I am moderately certain that the
issue is that even entering a dummy span is too much code for LLVM to
reliably (or at all) optimize out.

## Solution

My hope is that in trusting the Rust compiler to generate cool code when using
drop flags, we can essentially generate a drop flag that depends on something we
know (due to events working as expected) to be optimizable.

So instead of doing

```rust
let _x = span!();
let _y = _x.enter();
// lotsa code
drop(_y)
```

we do

```rust
let _x;
let _y;
let must_drop = false;
if level_enabled!(DEBUG) {
    must_drop = true;
    _x = span!();
    _y = _x.enter();
}
// lotsa code
if must_drop {
    drop(_y)
}
```

I believe this will allow LLVM to properly optimize this again. Testing that
right now, but I wanted to open this PR immediately for review.
2021-10-01 09:51:02 -07:00
David Barsky
6720becc5d
chore: fix several typos in tracing-core and tracing-subscriber (#1601) 2021-09-29 14:53:09 -07:00
David Barsky
66fd693387
subscriber: add example of Option<Layer> (#1596)
This PR contains two changes:
1. An example as how to use `Option<Layer>` to toggle layers at runtime, and...
2. A fix to an example writing to disk when doc tests are run.

Co-authored-by: Eliza Weisman <eliza@buoyant.io>
2021-09-29 09:58:07 -07:00
Bryan Burgers
f250f6fd7c
core: impl field::Value for Option<T> (#1585)
## Motivation

Building a span with some field might be `None` is bother now.

Before:
```rust
let span = info!("example", data = Empty );
if let Some(data) = foo() {
    span.record("data", &data);
}
```

After:
```rust
let span = info!("example", data = foo() );
```

Co-authored-by: DCjanus <DCjanus@dcjanus.com>
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
2021-09-24 12:32:25 -07:00
Eliza Weisman
e4553672fc
tower: drop http from default features (#1594)
## Motivation

Currently, our MSRV CI build is broken because of the `tracing-tower`
crate, which depends on `http`. The latest `http` release broke support
for Rust 1.42.0.

Since the `tracing-tower` crate is unreleased and is probably never
going to be published in its current form (see #238), this isn't
actually an issue, but the CI breakage is quite sad. I'm working on an
upstream PR to `tower` to add tracing support there, so we can
eventually deprecate the `tracing-tower` crate and direct users to
upstream. However, that's not quite ready.

Also, we should probably just drop the `http` support from
`tracing-tower` entirely, since tracing HTTP requests with `Tower`
services is probably better served by the `tower-http` crate's [`trace`
middleware][1]. This middleware is significantly more featureful.

[1]: https://docs.rs/tower-http/0.1.1/tower_http/trace/index.html

## Solution

For now, this branch just makes the `http` feature flag on
`tracing-tower` off by default, instead of on by default. This may break
git deps, but this crate was never officially stable. Doing this should
fix CI.

## Alternatives

We could also just modify the `check-msrv` CI job to test every crate
_except_ for `tracing-tower`. This would be a bit of a pain but wouldn't
break any git deps that use tracing-tower's http feature...
2021-09-24 11:22:01 -07:00
Eliza Weisman
9ac27fbc92
subscriber: prepare to release 0.2.24 (#1582)
# 0.2.24 (September 19, 2021)

This release contains a number of bug fixes, including a fix for
`tracing-subscriber` failing to compile on the minimum supported Rust
version of 1.42.0. It also adds `IntoIterator` implementations for the
`Targets` type.

### Fixed

- Fixed compilation on Rust 1.42.0 ([#1580], [#1581])
- **registry**: Ensure per-layer filter `enabled` state is cleared when
  a global filter short-circuits filter evaluation ([#1575])
- **layer**: Fixed `Layer::on_layer` not being called for `Box`ed
  `Layer`s, which broke  per-layer filtering ([#1576])

### Added

- **filter**: Added `Targets::iter`, returning an iterator over the set
  of target-level pairs enabled by a `Targets` filter ([#1574])
- **filter**:  Added `IntoIterator` implementations for `Targets` and
  `&Targets` ([#1574])

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

[#1580]: https://github.com/tokio-rs/tracing/pull/1580
[#1581]: https://github.com/tokio-rs/tracing/pull/1581
[#1575]: https://github.com/tokio-rs/tracing/pull/1575
[#1576]: https://github.com/tokio-rs/tracing/pull/1576
[#1574]: https://github.com/tokio-rs/tracing/pull/1574
tracing-subscriber-0.2.24
2021-09-19 17:32:01 -07:00