## Motivation
Currently it is not possible to disable ANSI in `fmt::Subscriber`
without enabling the "ansi" crate feature. This makes it difficult for
users to implement interoperable settings that are controllable with
crate features without having to pull in the dependencies "ansi" does.
I hit this while writing an application with multiple logging options
set during compile-time and I wanted to cut down on dependencies if
possible.
## Solution
This changes `fmt::Subscriber::with_ansi()` to not require the "ansi"
feature flag. This way, `with_ansi(false)` can be called even when the
"ansi" feature is disabled. Calling `with_ansi(true)` when the "ansi"
feature is not enabled will panic in debug mode, or print a warning if
debug assertions are disabled.
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
This reverts commit 9744ec03f9. This
change breaks MSRV compatibility, and was accidentally auto-merged due
to what appears to be an issue with the CI configuration, which
(apparently) doesn't require the MSRV minimal-versions check runs to
complete before allowing a branch to merge.
We'll have to solve the original issue here through documentation for
now. See [this comment] for details.
[this comment]: https://github.com/tokio-rs/tracing/pull/2550#issuecomment-1507656030
## Motivation
syn 2.0 is out!
## Solution
Update to syn 2.0 🚀
Co-authored-by: David Barsky <me@davidbarsky.com>
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
## Motivation
Same reason as https://github.com/rust-lang/log/pull/536 :
`cfg_if` is only used in a single place and `tracing` is used by many
other crates, so even removing one dependency will be beneficial.
## Solution
Remove dependency `cfg-if` and replace `cfg_if::cfg_if!` with a `const
fn get_max_level_inner() -> LevelFilter` and uses `if cfg!(...)` inside.
Using if in const function is stablised in
[1.46](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1460-2020-08-27)
so this should work fine in msrv 1.56
Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
As part of upgrading syn to 2.0 (e.g.,
https://github.com/tokio-rs/tracing/pull/2516), we need to bump the MSRV
to 1.56. As part of this PR, I've:
- Updated the text descriptions of what would be an in-policy MSRV bump
to use more recent versions of rustc. The _niceness_ of said version
numbers are purely coincidental.
- I've removed some of the exceptions made in CI.yml in order to support
some crates with a higher MSRV.
This PR removes tracing-opentelemetry to a dedicated repo located at
https://github.com/tokio-rs/tracing-opentelemetry. (Note that at time of
writing this PR, the new repo has not be made public). We're moving
tracing-opentelemetry to a dedicated repository for the following
reasons:
1. opentelemetry's MSRV is higher than that of `tracing`'s.
2. more importantly, the main `tracing` repo is getting a bit unweildy
and it feels unreasonable to maintain backports for crates that
integrate with the larger tracing ecosystem.
(https://github.com/tokio-rs/tracing-opentelemetry does not have the
examples present in this repo; this will occur in a PR that will be
linked from _this_ PR.)
## Motivation
The current description for the default level of the `err` return value
event _strongly implies_ it's the same as the span. However, the
implementation actually defaults to `ERROR`.
## Solution
This PR documents that, so future generations don't have to chase down
the truth, like I did. 😉
## Motivation
The documentation under https://tracing.rs/tracing/ is missing CSS
styles. Fixes#2444
## Solution
Used the `--html-in-header` rustdoc flag instead of `--extend-css`.
Converted the css file into an html file.
There are new warnings as errors reported by clippy in Rust 1.67.0.
This are causing builds to fail, e.g.:
https://github.com/tokio-rs/tracing/actions/runs/4027112923/jobs/6922513360
In both cases they are reports of lifetimes that can be elided. This
change removes the unnecessary lifetime annotations to make clippy
happy.
## Motivation
There has been interest around publishing `tracing-mock` to crates.io
for some time. In order to make this possible, documentation and some
code clean up is needed.
The `subscriber` module needs documentation and examples.
## Solution
This change adds documentation to the `subscriber` module and all the public
APIs within it. This includes doctests on all the methods which serve as
examples.
The `MockSubscriberBuilder::record` method was removed as its
functionality is not implemented.
Previously, the `MockSubscriber` would verify the scope of an
`ExpectedEvent`, even if `in_scope` hadn't been called. In this case,
that would check that an event was not in a span if `in_scope` had not
been called. `tracing-subscriber` all adhere to this pattern. However it
is different to the behavior of all other expectation methods, where an
explicit call is needed to expect something, otherwise nothing is
checked. As such, the behavior has been modified to align with the rest
of the crate. The previous behavior can be achieved by calling
`in_scope(None)` to verify that an event has no scope. The documentation
for `in_scope` has been updated with an example for this case.
The tests in `tracing-subscriber` which previously verified *implicitly*
that an event had no scope (by not calling `in_scope` at all) have *not*
been modified. It is my opinion that this implicit behavior was never
required.
Refs: #539
## Motivation
There has been interest around publishing tracing-mock to crates.io
for some time. In order to make this possible, documentation and some
code clean up is needed.
The `event` module needs documentation and examples.
## Solution
This change adds documentation to the event module and all the public
APIs within it. This includes doctests on all the methods which serve as
examples.
The following pattern was applied to the description of most methods:
- Short description of expectation
- Additional clarification (where needed)
- Description of cases that cause the expectation to fail
- Examples
- Successful validation
- Unsuccesful validation
Two changes were also made in the text provided to the user when an
assertion fails for `with_explicit_parent` or `with_contextual_parent`.
One small API changes is also included:
The method `in_scope` has been placed behind the `tracing-subscriber`
feature flag as it currently only works with the `MockSubscriber`, not
with the `MockCollector`. If the feature flag is active and it is used
to set a non-empty scope, the `MockCollector` will panic with
`unimplemented` during validation.
Refs: #539
## Motivation
The `#[instrument]` macro cannot be used on `const fn`s, because the
generated code will perform runtime tracing behavior. However, when
adding the attribute to a `const fn`, the compiler errors generated
currently are somewhat unclear (see #2414). It would be better if we
generated a less verbose error that simply states that `#[instrument]`
is not supported on `const fn`s.
## Solution
This branch changes the `#[instrument]` macro to detect when the
annotated function is a `const fn`, and emit a simpler, more descritpive
error message. The new error simply states that the `#[instrument]`
attribute cannot be used on `const fn`s, and should be much less
confusing to the user.
Fixes#2414
The error message suggesting that you remove a semicolon to return a
value (instead of unit) was updated slightly in rust-lang/rust#102650,
which was included in Rust 1.66.0.
This causes one of the tests in tracing-attributes to fail. We fix it by
using the updated error message.
## Motivation
There has been interest around publishing `tracing-mock` to crates.io
for some time. In order to make this possible, documentation and some
code clean up is needed.
Specifically **I** want to have access to `tracing-mock` within parts of
`tokio` to write tests that ensure that the correct calling location is
picked up for all `spawn*` functions when the `tracing` feature is
enabled.
## Solution
This change starts that process by adding a README for `tracing-mock`.
The README follows the standard format for all `tracing` crates and
includes 2 examples. The README is included in the `lib.rs` docs using
`#[doc = include_str!(...)]`, so that the same documentation is included
in the crate, and the examples are tested when running doctests.
The README describes steps when using the `tracing` 1.0 from crates.io
and `tracing-mock` from the `v0.1.x` branch. The tests target the
current branch.
Co-authored-by: David Barsky <me@davidbarsky.com>
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
## Motivation
There is a small wording mistake in the tracing-subscriber docs
that can be fixed quickly and easily.
## Solution
Two duplicate words were removed.
* mock: change helper functions to `expect::<thing>`
The current format of test expectations in `tracing-mock` isn't ideal.
The format `span::expect` requires importing `tracing_mock::<thing>` which
may conflict with imports from other tracing crates, especially
`tracing-core`.
So we change the order and move the functions into a module called
`expect` so that:
* `event::expect` becomes `expect::event`
* `span::expect` becomes `expect::span`
* `field::expect` becomes `expect::field`
This format has two advantages.
1. It reads as natural English, e.g "expect span"
2. It is no longer common to import the modules directly.
Regarding point (2), the following format was previously common:
```rust
use tracing_mock::field;
field::expect();
```
This import of the `field` module may then conflict with importing the
same from `tracing_core`, making it necessary to rename one of the
imports.
The same code would now be written:
```rust
use tracing_mock::expect;
expect::field();
```
Which is less likely to conflict.
This change also fixes an unused warning on `MockHandle::new` when the
`tracing-subscriber` feature is not enabled.
Refs: #539
The `tracing-mock` crate provides a mock collector (and a subscriber for
use by the tests in the `tracing-subscriber` crate) which is able to
make assertions about what diagnostics are emitted.
These assertions are defined by structs that match on events, span, and
their fields and metadata. The structs that matched these objects have
been called, up until now, mocks, however this terminology may be
misleading, as the created objects don't mock anything.
There were two different names for similar functionality with `only()`
and `done()` on fields and collectors/subscribers respectively. Using a
single name for these may make it easier to onboard onto `tracing-mock`.
To reduce confusion, these structs have been split into two categories:
mocks and expectations.
Additionally, the `done()` function on the `Collector` and `Subscriber`
mocks has been replaced with `only()`. This matches the similar function
for `ExpectedField`, and may be more intuitive.
The mocks replace some component in the tracing ecosystem when a library
is under test. The expectations define the assertions we wish to make
about traces received by the mocks.
Mocks (per module):
* collector - `MockCollector`, no change
* subscriber - `MockSubscriber`, renamed from `ExpectSubscriber`
Expectations (per module):
* event - `ExpectedEvent`, renamed from `MockEvent`
* span - `ExpectedSpan`, renamed from `MockSpan`
* field - `ExpectedField` and `ExpectedFields`, renamed from `MockField`
and `Expected`. Also `ExpectedValue` renamed from `MockValue`.
* metadata - `ExpectedMetadata`, renamed from `Expected`
Refs: #539
The `tracing-subscriber` module `tests::support` included functionality
to mock a subscriber (via the `Subscribe` trait). This code depends on
some items from `tracing_mock::collector` which should otherwise not be
public.
This change moves the mocking functionality inside `tracing-mock` behind
a feature flag. Allowing the `Expect` enum and `MockHandle::new` from
`tracing_mock::collector` to be made `pub(crate)` instead of `pub`.
Since it's now used from two different modules, the `Expect` enum has
been moved to its own module.
This requires a lot of modifications to imports so that we're not doing
wildcard imports from another crate (i.e. in `tracing-subscriber`
importing wildcards from `tracing-mock`).
Closes: #2359
## Motivation
The worker thread name in non blocking mode is always "tracing-appender".
It can be convenient to quickly identify the appender threads for
audit reasons or affinity pinning.
## Solution
This patch adds a new setter to the builder and propagates the info to
the thread initialization.
Closes#2364
This `doc_cfg` attribute's `cfg` part has multiple predicates without an
`all`, which iis what's breaking the netlify build. I'm...kind of
surprised this ever succeeded, since the cfg is malformed...
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>
This branch adds the ability to override the level of the events
generated by the `ret` and `err` arguments to `#[instrument]`. An
overridden level can be specified with:
```rust
#[instrument(ret(level = "info"))]
```
```rust
#[instrument(err(level = Level::Debug))]
```
and so on.
This syntax is fully backwards compatible with existing uses of the
attribute.
In addition, some refactoring was done to how levels are parsed and how
the tokens for a specified level is generated.
Fixes#2330
## Motivation
There's currently a `fmt::Display` impl for `EnvFilter` that emits an
equiovalent filter string that can be parsed back into an `EnvFilter`,
but the `Targets` filter does not have a `fmt::Display` impl. We ought
to have one, especially to make using `Targets` with `clap` v4.0 easier.
## Solution
This branch adds a `fmt::Display` impl for `filter::Targets`. The
implementation is pretty straightforward.
I also added tests that a `Targets`' `fmt::Display` output can be parsed
back into a filter that's equivalent to the original.
Currently, the Netlify docs are failing because of a warning that one of
the lints we explicitly enable is no longer a warning on nightly but
becoming a hard error. This is because the docs are built on nightly
with `-D warnings`, which denies all warnings...which seems not ideal.
For now, let's not remove that lint from the `deny` list, as it's still
a valid lint on stable. Instead, this PR explicitly allows that lint on
the docs build.
## Motivation
When the `instrument` attribute is used on a function with inner
attributes, the proc macro generates code above the attributes within
the function block that causes compilation errors. These should be
parsed out separately and handled.
Fixes#2294
## Solution
I updated `MaybeItemFn` and `MaybeItemFnRef` to so they hold both the
outer and inner attributes for the instrumented function and updated the
codegen to inlcude them in the appropriate locations.
I couldn't preserve the existing implementation of
`From<&'_ ItemFn> for MaybeItemFnRef<'_, Box<Block>>`, because it is
now necessary to separate the inner and outer attributes of the
`ItemFn` into two separate `Vec`s. That implementation was replaced
with a `From<ItemFn> for MaybeItemFn`, which uses `Iterator::partition`
to separate out the inner and outer attributes.
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
## Motivation
This fixes a discrepancy in the `tracing-opentelemetry` docs for the new
MetricsLayer. The docs refer to `value.` as a way to collect discrete
data point, but this doesn't match any of the prefix constant mentioned
in the same file.
```rust
const METRIC_PREFIX_MONOTONIC_COUNTER: &str = "monotonic_counter.";
const METRIC_PREFIX_COUNTER: &str = "counter.";
const METRIC_PREFIX_HISTOGRAM: &str = "histogram.";
```
## Solution
This fixes the documentation and test by referring to `histogram.`
instead of `value.`.
## Motivation
Currently, when using the `Subscribe` impl for `Option<S:
Subscribe<...>>`, the `Subscribe::max_level_hint` returns
`Some(LevelFilter::OFF)`. This was intended to allow totally disabling
output in the case where a collector is composed entirely of `None`
subscribers. However, when other subscribers *do* exist but return
`None` from their `max_level_hint` implementations to indicate that they
don't care what the max level is, the presence of a single `None` layer
will globally disable everything, which is not the wanted behavior.
Fixes#2265
## Solution
This branch introduces a special downcast marker that can be used to
detect when a `Subscribe` in a `Layered` is `None`. This allows the
`pick_level_hint` method to short-circuit when a `Subscribe`
implementation which is `None` returns `Some(LevelFilter::OFF)` from its
`max_level_hint` if the other half of the `Layered` is not `None`. The
tests I added should be pretty thorough!
Additionally, the downcast marker is special-cased in the `reload`
subscriber. Normally, this subscriber doesn't support downcasting, but
it can in the case of the special marker value.
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
## Motivation
`tracing-appender` does not have `Rotation` based on size yet. Also, it
doesn't have the feature of keeping the most recent `N` log files
I believe the second feature is more easy to implement, and also will
partially solve the `Rotation` based on size problem. Because people may
choose `hourly` or `daily` rotation based on their needs, and put an
extra boundary of `keep the last 5 files` for example. Of course it
won't handle all the edge cases for `Rotation` based on size. But it
will cover most of the scenarios. And also, it is a good feature to have
on its own :)
## Solution
Introduce another field called `max_files: Option<usize>` to the `Inner`
of `RollingFileAppender` struct. I managed to did not touch any of the
existing functions, so it **WON'T BE A BREAKING CHANGE**. Yay :)
The solution is, whenever the rotation should happen, the
`refresh_writer()` is called. So I embed the following logic into that
function:
1- check the log folder and detect the log files 2- if there are more
log files than the `max_files` amount 3- store the filenames in a
vector, and sort them by their dates (dates are already present in the
filename) 4- keep deleting the oldest ones, till we have desired amount
of log files in the log folder
P.S. this PR was opened before, but got closed since it would be easier
for the maintainers to target `master` branch instead of `v0.1.x` Also,
@CBenoit contributed to this PR, it would be great to give credit to him
:)
Co-authored-by: Benoît Cortier <bcortier@proton.me>
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
Allows collectors and subscribers to stash their own `Dispatch` without
causing a memory leak.
## Motivation
Resolves a shortcoming of #2269: that it's impossible for collectors or
subscribers 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 collector. `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>
The `async_fn` test file in `tracing-attributes` contains several
functions that exist just to test whether they _compile_, rather than
make assertions about their behavior. Because these functions are never
called, they (naturally) emit dead code warnings.
This commit adds `#[allow(dead_code)]` to the compilation tests, plus a
comment explaining why we do this.
The error messages for these tests appear to have changed a bit with
Rust 1.64. This commit includes changes to the `.stderr` file after
running the tests with `TRYBUILD=overwrite`, in order to update the
expected output for the latest Rust.
## Motivation
`bare_trait_objects` lint will become a hard error in Rust 2021.
While tracing is still using Rust 2018, `bare_trait_objects` is a
warning in the MSRV and `dyn` keyword is recommended.
## Solution
Replace all `&Value` with `&dyn Value` in macro expansions.
When an error value is recorded, it should add the `exception.message`
and `exception.stacktrace` fields from the opentelemetry semantic
conventions to the span/event. Ideally the `exception.type` field would
be provided also, but there is currently not a mechanism to determine
the type name of a trait object.
Co-authored-by: Lily Mara <54288692+lilymara-onesignal@users.noreply.github.com>
Co-authored-by: Lily Mara <54288692+lilymara-onesignal@users.noreply.github.com>
## Motivation
Support the latest OpenTelemetry specification.
## Solution
Update `opentelemetry` to the latest `0.18.x` release. Breaking changes
in the metrics spec have removed value recorders and added histograms so
the metrics layer's `value.` prefix has been changed to `histogram.` and
behaves accordingly. Additionally the `PushController` configuration for
the metrics layer has been simplified to accept a `BasicController` that
can act in either push or pull modes. Finally trace sampling in the
sdk's `PreSampledTracer` impl has been updated to match the sampling
logic in https://github.com/open-telemetry/opentelemetry-rust/pull/839.
* Update MSRV to 1.56
* Update examples
* Fix async-trait dep
## Motivation
One can want to have an event added from outside context of a span,
especially in an async code (e.g. between polls of the future, or
between polling multiple futures instrumented with that span). Then it
is expected that the event will be attached indeed to the span specified
as the parent and not the contextual one.
Fixes: #2295
## Solution
See #2295
Fixes#2280
## Motivation
I've implemented an alternative to [`tracing-wasm`] to fix some issues
that I had when using it (most are open as longer time bug reports, no
need to recount them here). It should be more up to date with the
current tracing framework and, being layer based, is easier to compose
with other subscribers, e.g. supports formatting and timing on event
logs out of the box.
## Solution
Add the [`tracing-web`] crate to the list of related crates.
[`tracing-wasm`]: (https://github.com/storyai/tracing-wasm)
[`tracing-web`]: https://crates.io/crates/tracing-web/
Motivation:
When `Format_event::format_event(...)` returns an error, we are
currently silently dropping that
Event. https://github.com/tokio-rs/valuable/issues/88 explains one
such case in which this was encountered (due to a bug in
valuable-serde). We want to be made aware whenever an Event is dropped.
Solution:
Write to the Writer with an error message to let the user know that
we were unable to format a specific event. If writing to the Writer fails,
we fall back to writing to stderr. We are not emitting an actual tracing
Event, to avoid the risk of a cycle (the new Event could trigger the
same formatting error again).
Resolves#1965.
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
Co-authored-by: David Barsky <me@davidbarsky.com>
`SubscriberBuilder`s and `Layer`s configured with custom event/field
formatters do not provide any means of accessing or mutating those
formatters. Any configuration that needs to be done must be done before
setting them on the builder/layer. This is frustrating as it makes it
difficult to provide a pre-configured API akin to
`tracing_subscriber::fmt()` along with accessors like `.compact()` that
modify the formatter.
Add accessors `.map_event_format()` and `.map_fmt_fields()` to
`SubscriberBuilder` and `Layer` that map the existing formatter through
a closure. This allows the closure to modify it or to derive a new
formatter from it with a different type.
Also add a `.map_writer()` method that does the same thing for the
`MakeWriter`, to round out the accessors for the various type
parameters.
The filter type is currently restricted to just `LevelFilter` or
`EnvFilter` and so this does not add a corresponding `.map_filter()`.
That can be added later if we add the ability to attach arbitrary
filters.
Also fix some minor docs issues that were spotted as part of
implementing this.
Fixes#1756