Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/tracing/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/tracing/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"CHANGELOG.md":"8f2a5e3f70b90ef91e724b0089f511f6ce95cc6afaf1da30d3d486e30935c520","Cargo.toml":"e8262bfd368f8b9c2f902db368a71da88f446584167392a2611b8eb08e411175","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"baed1881843d68618241ccc57e2120993f6eb67c0e1987115b6855f7d328def3","benches/baseline.rs":"43a3e31b6c33dba2e6328052301b707b212487b83f0dcffc843061a9c48a2319","benches/dispatch_get_clone.rs":"866239abeb74a82440741c948a4e7e0a44e92e8cc87319ec57e3b057c9e8f5dd","benches/dispatch_get_ref.rs":"dd2803259a6784c256304e676bbce05de233e4c8451ac85863787213343e9be7","benches/empty_span.rs":"9f51cf376414ea751b2f50c357f2435a545d606118286f5b8b89f185e28aad8c","benches/enter_span.rs":"4410ec73d277e7b54e9f306c00ff3b79a150d1832966b7fc29984c8e3ad8d57c","benches/event.rs":"98de3c82ed18abe0a3cbe6eda9a4f9deec2b69bca42c3aac11dea4b608b85a67","benches/shared.rs":"2623311af7d153685064e664a5903d03e7dc3179754c324f3a76f29f060515e6","benches/span_fields.rs":"9166cd43ef2783e5419dd61ea57a02e48e8cc38aa1b357e9b79fa581929b60d8","benches/span_no_fields.rs":"79cc4befacf27d7ce728246087c4f06a6066f913e831d9043caeb7941f0193f6","benches/span_repeated.rs":"e4b3c99a7a9fc15d9042b8db399a56cf647b4eebd26f29d95325bb057b68330b","src/dispatcher.rs":"a8732392ffe56b1178f8fd3d6e6e02d40b51475c38bb4600abd9cd170df1bf6c","src/field.rs":"fe6c2eb36f92880254a707a465f873ca84510d93f06614b9b36ba20b48bf209d","src/instrument.rs":"034b1c7e46ab2fae331ea215a3d1b1a2211ef6b18d7e7113523e3ef5bf3ca9bb","src/level_filters.rs":"92aca5797a59b2f3c34adfb896260400c2602456eec0fe9c7d49204df37ff699","src/lib.rs":"54a1168ed65d746ce1cc6668a78931131af2afc7e0530391dcffcaa58a9f7971","src/macros.rs":"6ffcbea4b4b402b46e9e074f0808fb755b59ce2bb1c97aa4acdfdb31bb26bf4c","src/span.rs":"4efa37a8fc7604fcc3547eac488122c13bcb28e136f46381082480e0036217a0","src/stdlib.rs":"248514a9bae6106e436358aee44c92abf8e7f79022895c4a25136ddef211d198","src/subscriber.rs":"8933d8766439f929c0a98a0863d20aff37b221314b3825edd9058be511149968","tests/enabled.rs":"a80fd3c70be439b0d1d2509b46a2b9ca31748aab4341f67d0fa721f32c6a65a1","tests/event.rs":"d3c6d688fc1938516770a9fb486252bbe8e95f24b37097a2291e7119b6e78373","tests/filter_caching_is_lexically_scoped.rs":"5487a37db5fbdf3d57020ab1f01185d928c45d967d99d723ffc434540459d8dc","tests/filters_are_not_reevaluated_for_the_same_span.rs":"251abbc000dddd298448958a1f0e5be71da527ac6c1a368d57837c83a5467329","tests/filters_are_reevaluated_for_different_call_sites.rs":"e0fdd8e930c043674702831b4d96f331e63aba824576bbac50b3f53bb0241cc7","tests/filters_dont_leak.rs":"6c41d3209cf2a37a1656a8314399777022ceec556e44f5417f1f5a4cd24eb43a","tests/future_send.rs":"3e9c9193219d12e342c18bbedb2f6ec940334202feb3cffba91601d6001b8575","tests/instrument.rs":"e46cf30db3ff0174e4e0885720b97531c56cbe7d05bb4580e38790f272856b56","tests/macro_imports.rs":"d5de857162185d4a2384f3cb644bfcf76c7f5c1a3b5f72bfa0d2620ac6e3873c","tests/macros.rs":"acb6987a37be2035cde28c8a6b3cecbdbffffafebe6c007712cd145afbd1beb8","tests/macros_incompatible_concat.rs":"5f3bcbb65e4ae39db1cfc2def62fc913c20bab0fb769c8f731504e2615585ee5","tests/max_level_hint.rs":"39576a958df3ea215c49154ff72c3dd14c8b3be3fcdb849e7dd847c8c9fd09e2","tests/multiple_max_level_hints.rs":"28ead97a8424358a0632547dae987ddbddc5bb69cdcd996d20feb49a7f3ddc69","tests/no_subscriber.rs":"ca42d0d4a20eb3b4e0a342b5e0090c7ada8b5a157f3cddb7b5d051238cdc1202","tests/register_callsite_deadlock.rs":"c0b3142543e7a10065c7583a8ee0b6bc978ea4f3979599651101c5a28966e7c8","tests/scoped_clobbers_default.rs":"5fd48ff207df64b0e2ee443de75da0d8bd3b0817c6d9b003b0b00157ec244d7b","tests/span.rs":"2a5a8c666c8a2b51a1a1222e6046a1067690f039d15ef8b56d0e83bffa76f78d","tests/subscriber.rs":"ed3c02e8a75c6e4fc187a024fde6319e6d1ea95c993eda3fd9d559fd41fe7cce"},"package":"c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"}
|
||||
941
third-party/vendor/tracing/CHANGELOG.md
vendored
Normal file
941
third-party/vendor/tracing/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,941 @@
|
|||
# 0.1.40
|
||||
|
||||
This release fixes a potential stack use-after-free in the
|
||||
`Instrument::into_inner` method. Only uses of this method are affected by this
|
||||
bug.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Use `mem::ManuallyDrop` instead of `mem::forget` in `Instrument::into_inner`
|
||||
([#2765])
|
||||
|
||||
[#2765]: https://github.com/tokio-rs/tracing/pull/2765
|
||||
|
||||
Thanks to @cramertj and @manishearth for finding and fixing this issue!
|
||||
|
||||
# 0.1.39 (October 12, 2023)
|
||||
|
||||
This release adds several additional features to the `tracing` macros. In
|
||||
addition, it updates the `tracing-core` dependency to [v0.1.32][core-0.1.32] and
|
||||
the `tracing-attributes` dependency to [v0.1.27][attrs-0.1.27].
|
||||
|
||||
### Added
|
||||
|
||||
- Allow constant field names in macros ([#2617])
|
||||
- Allow setting event names in macros ([#2699])
|
||||
- **core**: Allow `ValueSet`s of any length ([#2508])
|
||||
|
||||
### Changed
|
||||
|
||||
- `tracing-attributes`: updated to [0.1.27][attrs-0.1.27]
|
||||
- `tracing-core`: updated to [0.1.32][core-0.1.32]
|
||||
- **attributes**: Bump minimum version of proc-macro2 to 1.0.60 ([#2732])
|
||||
- **attributes**: Generate less dead code for async block return type hint ([#2709])
|
||||
|
||||
### Fixed
|
||||
|
||||
- Use fully qualified names in macros for items exported from std prelude
|
||||
([#2621], [#2757])
|
||||
- **attributes**: Allow [`clippy::let_with_type_underscore`] in macro-generated
|
||||
code ([#2609])
|
||||
- **attributes**: Allow `unknown_lints` in macro-generated code ([#2626])
|
||||
- **attributes**: Fix a compilation error in `#[instrument]` when the `"log"`
|
||||
feature is enabled ([#2599])
|
||||
|
||||
### Documented
|
||||
|
||||
- Add `axum-insights` to relevant crates. ([#2713])
|
||||
- Fix link to RAI pattern crate documentation ([#2612])
|
||||
- Fix docs typos and warnings ([#2581])
|
||||
- Add `clippy-tracing` to related crates ([#2628])
|
||||
- Add `tracing-cloudwatch` to related crates ([#2667])
|
||||
- Fix deadlink to `tracing-etw` repo ([#2602])
|
||||
|
||||
[#2617]: https://github.com/tokio-rs/tracing/pull/2617
|
||||
[#2699]: https://github.com/tokio-rs/tracing/pull/2699
|
||||
[#2508]: https://github.com/tokio-rs/tracing/pull/2508
|
||||
[#2621]: https://github.com/tokio-rs/tracing/pull/2621
|
||||
[#2713]: https://github.com/tokio-rs/tracing/pull/2713
|
||||
[#2581]: https://github.com/tokio-rs/tracing/pull/2581
|
||||
[#2628]: https://github.com/tokio-rs/tracing/pull/2628
|
||||
[#2667]: https://github.com/tokio-rs/tracing/pull/2667
|
||||
[#2602]: https://github.com/tokio-rs/tracing/pull/2602
|
||||
[#2626]: https://github.com/tokio-rs/tracing/pull/2626
|
||||
[#2757]: https://github.com/tokio-rs/tracing/pull/2757
|
||||
[#2732]: https://github.com/tokio-rs/tracing/pull/2732
|
||||
[#2709]: https://github.com/tokio-rs/tracing/pull/2709
|
||||
[#2599]: https://github.com/tokio-rs/tracing/pull/2599
|
||||
[`let_with_type_underscore`]: http://rust-lang.github.io/rust-clippy/rust-1.70.0/index.html#let_with_type_underscore
|
||||
[attrs-0.1.27]:
|
||||
https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.27
|
||||
[core-0.1.32]:
|
||||
https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.32
|
||||
|
||||
# 0.1.38 (April 25th, 2023)
|
||||
|
||||
This `tracing` release changes the `Drop` implementation for `Instrumented`
|
||||
`Future`s so that the attached `Span` is entered when dropping the `Future`. This
|
||||
means that events emitted by the `Future`'s `Drop` implementation will now be
|
||||
recorded within its `Span`. It also adds `#[inline]` hints to methods called in
|
||||
the `event!` macro's expansion, for an improvement in both binary size and
|
||||
performance.
|
||||
|
||||
Additionally, this release updates the `tracing-attributes` dependency to
|
||||
[v0.1.24][attrs-0.1.24], which updates the [`syn`] dependency to v2.x.x.
|
||||
`tracing-attributes` v0.1.24 also includes improvements to the `#[instrument]`
|
||||
macro; see [the `tracing-attributes` 0.1.24 release notes][attrs-0.1.24] for
|
||||
details.
|
||||
|
||||
### Added
|
||||
|
||||
- `Instrumented` futures will now enter the attached `Span` in their `Drop`
|
||||
implementation, allowing events emitted when dropping the future to occur
|
||||
within the span ([#2562])
|
||||
- `#[inline]` attributes for methods called by the `event!` macros, making
|
||||
generated code smaller ([#2555])
|
||||
- **attributes**: `level` argument to `#[instrument(err)]` and
|
||||
`#[instrument(ret)]` to override the level of
|
||||
the generated return value event ([#2335])
|
||||
- **attributes**: Improved compiler error message when `#[instrument]` is added to a `const fn`
|
||||
([#2418])
|
||||
|
||||
### Changed
|
||||
|
||||
- `tracing-attributes`: updated to [0.1.24][attrs-0.1.24]
|
||||
- Removed unneeded `cfg-if` dependency ([#2553])
|
||||
- **attributes**: Updated [`syn`] dependency to 2.0 ([#2516])
|
||||
|
||||
### Fixed
|
||||
|
||||
- **attributes**: Fix `clippy::unreachable` warnings in `#[instrument]`-generated code ([#2356])
|
||||
- **attributes**: Removed unused "visit" feature flag from `syn` dependency ([#2530])
|
||||
|
||||
### Documented
|
||||
|
||||
- **attributes**: Documented default level for `#[instrument(err)]` ([#2433])
|
||||
- **attributes**: Improved documentation for levels in `#[instrument]` ([#2350])
|
||||
|
||||
Thanks to @nitnelave, @jsgf, @Abhicodes-crypto, @LukeMathWalker, @andrewpollack,
|
||||
@quad, @klensy, @davidpdrsn, @dbidwell94, @ldm0, @NobodyXu, @ilsv, and @daxpedda
|
||||
for contributing to this release!
|
||||
|
||||
[`syn`]: https://crates.io/crates/syn
|
||||
[attrs-0.1.24]:
|
||||
https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.24
|
||||
[#2565]: https://github.com/tokio-rs/tracing/pull/2565
|
||||
[#2555]: https://github.com/tokio-rs/tracing/pull/2555
|
||||
[#2553]: https://github.com/tokio-rs/tracing/pull/2553
|
||||
[#2335]: https://github.com/tokio-rs/tracing/pull/2335
|
||||
[#2418]: https://github.com/tokio-rs/tracing/pull/2418
|
||||
[#2516]: https://github.com/tokio-rs/tracing/pull/2516
|
||||
[#2356]: https://github.com/tokio-rs/tracing/pull/2356
|
||||
[#2530]: https://github.com/tokio-rs/tracing/pull/2530
|
||||
[#2433]: https://github.com/tokio-rs/tracing/pull/2433
|
||||
[#2350]: https://github.com/tokio-rs/tracing/pull/2350
|
||||
|
||||
# 0.1.37 (October 6, 2022)
|
||||
|
||||
This release of `tracing` incorporates changes from `tracing-core`
|
||||
[v0.1.30][core-0.1.30] and `tracing-attributes` [v0.1.23][attrs-0.1.23],
|
||||
including the new `Subscriber::on_register_dispatch` method for performing late
|
||||
initialization after a `Subscriber` is registered as a `Dispatch`, and bugfixes
|
||||
for the `#[instrument]` attribute. Additionally, it fixes instances of the
|
||||
`bare_trait_objects` lint, which is now a warning on `tracing`'s MSRV and will
|
||||
become an error in the next edition.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **attributes**: Incorrect handling of inner attributes in `#[instrument]`ed
|
||||
functions ([#2307])
|
||||
- **attributes**: Incorrect location of compiler diagnostic spans generated for
|
||||
type errors in `#[instrument]`ed `async fn`s ([#2270])
|
||||
- **attributes**: Updated `syn` dependency to fix compilation with `-Z
|
||||
minimal-versions` ([#2246])
|
||||
- `bare_trait_objects` warning in `valueset!` macro expansion ([#2308])
|
||||
|
||||
### Added
|
||||
|
||||
- **core**: `Subscriber::on_register_dispatch` method ([#2269])
|
||||
- **core**: `WeakDispatch` type and `Dispatch::downgrade()` function ([#2293])
|
||||
|
||||
### Changed
|
||||
|
||||
- `tracing-core`: updated to [0.1.30][core-0.1.30]
|
||||
- `tracing-attributes`: updated to [0.1.23][attrs-0.1.23]
|
||||
|
||||
### Documented
|
||||
|
||||
- Added [`tracing-web`] and [`reqwest-tracing`] to related crates ([#2283],
|
||||
[#2331])
|
||||
|
||||
Thanks to new contributors @compiler-errors, @e-nomem, @WorldSEnder, @Xiami2012,
|
||||
and @tl-rodrigo-gryzinski, as well as @jswrenn and @CAD97, for contributing to
|
||||
this release!
|
||||
|
||||
[core-0.1.30]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.30
|
||||
[attrs-0.1.23]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.23
|
||||
[`tracing-web`]: https://crates.io/crates/tracing-web/
|
||||
[`reqwest-tracing`]: https://crates.io/crates/reqwest-tracing/
|
||||
[#2246]: https://github.com/tokio-rs/tracing/pull/2246
|
||||
[#2269]: https://github.com/tokio-rs/tracing/pull/2269
|
||||
[#2283]: https://github.com/tokio-rs/tracing/pull/2283
|
||||
[#2270]: https://github.com/tokio-rs/tracing/pull/2270
|
||||
[#2293]: https://github.com/tokio-rs/tracing/pull/2293
|
||||
[#2307]: https://github.com/tokio-rs/tracing/pull/2307
|
||||
[#2308]: https://github.com/tokio-rs/tracing/pull/2308
|
||||
[#2331]: https://github.com/tokio-rs/tracing/pull/2331
|
||||
|
||||
# 0.1.36 (July 29, 2022)
|
||||
|
||||
This release adds support for owned values and fat pointers as arguments to the
|
||||
`Span::record` method, as well as updating the minimum `tracing-core` version
|
||||
and several documentation improvements.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Incorrect docs in `dispatcher::set_default` ([#2220])
|
||||
- Compilation with `-Z minimal-versions` ([#2246])
|
||||
|
||||
### Added
|
||||
|
||||
- Support for owned values and fat pointers in `Span::record` ([#2212])
|
||||
- Documentation improvements ([#2208], [#2163])
|
||||
|
||||
### Changed
|
||||
|
||||
- `tracing-core`: updated to [0.1.29][core-0.1.29]
|
||||
|
||||
Thanks to @fredr, @cgbur, @jyn514, @matklad, and @CAD97 for contributing to this
|
||||
release!
|
||||
|
||||
[core-0.1.29]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.29
|
||||
[#2220]: https://github.com/tokio-rs/tracing/pull/2220
|
||||
[#2246]: https://github.com/tokio-rs/tracing/pull/2246
|
||||
[#2212]: https://github.com/tokio-rs/tracing/pull/2212
|
||||
[#2208]: https://github.com/tokio-rs/tracing/pull/2208
|
||||
[#2163]: https://github.com/tokio-rs/tracing/pull/2163
|
||||
|
||||
# 0.1.35 (June 8, 2022)
|
||||
|
||||
This release reduces the overhead of callsite registration by using new
|
||||
`tracing-core` APIs.
|
||||
|
||||
### Added
|
||||
|
||||
- Use `DefaultCallsite` to reduce callsite registration overhead ([#2083])
|
||||
|
||||
### Changed
|
||||
|
||||
- `tracing-core`: updated to [0.1.27][core-0.1.27]
|
||||
|
||||
[core-0.1.27]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.27
|
||||
[#2088]: https://github.com/tokio-rs/tracing/pull/2083
|
||||
|
||||
# 0.1.34 (April 14, 2022)
|
||||
|
||||
This release includes bug fixes for the "log" support feature and for the use of
|
||||
both scoped and global default dispatchers in the same program.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Failure to use the global default dispatcher when a thread sets a local
|
||||
default dispatcher before the global default is set ([#2065])
|
||||
- **log**: Compilation errors due to `async` block/fn futures becoming `!Send`
|
||||
when the "log" feature flag is enabled ([#2073])
|
||||
- Broken links in documentation ([#2068])
|
||||
|
||||
Thanks to @ben0x539 for contributing to this release!
|
||||
|
||||
[#2065]: https://github.com/tokio-rs/tracing/pull/2065
|
||||
[#2073]: https://github.com/tokio-rs/tracing/pull/2073
|
||||
[#2068]: https://github.com/tokio-rs/tracing/pull/2068
|
||||
|
||||
# 0.1.33 (April 9, 2022)
|
||||
|
||||
This release adds new `span_enabled!` and `event_enabled!` variants of the
|
||||
`enabled!` macro, for testing whether a subscriber would specifically enable a
|
||||
span or an event.
|
||||
|
||||
### Added
|
||||
|
||||
- `span_enabled!` and `event_enabled!` macros ([#1900])
|
||||
- Several documentation improvements ([#2010], [#2012])
|
||||
|
||||
### Fixed
|
||||
|
||||
- Compilation warning when compiling for <=32-bit targets (including `wasm32`)
|
||||
([#2060])
|
||||
|
||||
Thanks to @guswynn, @arifd, @hrxi, @CAD97, and @name1e5s for contributing to
|
||||
this release!
|
||||
|
||||
[#1900]: https://github.com/tokio-rs/tracing/pull/1900
|
||||
[#2010]: https://github.com/tokio-rs/tracing/pull/2010
|
||||
[#2012]: https://github.com/tokio-rs/tracing/pull/2012
|
||||
[#2060]: https://github.com/tokio-rs/tracing/pull/2060
|
||||
|
||||
# 0.1.32 (March 8th, 2022)
|
||||
|
||||
This release reduces the overhead of creating and dropping disabled
|
||||
spans significantly, which should improve performance when no `tracing`
|
||||
subscriber is in use or when spans are disabled by a filter.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **attributes**: Compilation failure with `--minimal-versions` due to a
|
||||
too-permissive `syn` dependency ([#1960])
|
||||
|
||||
### Changed
|
||||
|
||||
- Reduced `Drop` overhead for disabled spans ([#1974])
|
||||
- `tracing-attributes`: updated to [0.1.20][attributes-0.1.20]
|
||||
|
||||
[#1974]: https://github.com/tokio-rs/tracing/pull/1974
|
||||
[#1960]: https://github.com/tokio-rs/tracing/pull/1960
|
||||
[attributes-0.1.20]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.20
|
||||
|
||||
# 0.1.31 (February 17th, 2022)
|
||||
|
||||
This release increases the minimum supported Rust version (MSRV) to 1.49.0. In
|
||||
addition, it fixes some relatively rare macro bugs.
|
||||
|
||||
### Added
|
||||
|
||||
- Added `tracing-forest` to the list of related crates ([#1935])
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated minimum supported Rust version (MSRV) to 1.49.0 ([#1913])
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed the `warn!` macro incorrectly generating an event with the `TRACE` level
|
||||
([#1930])
|
||||
- Fixed macro hygiene issues when used in a crate that defines its own `concat!`
|
||||
macro, for real this time ([#1918])
|
||||
|
||||
Thanks to @QnnOkabayashi, @nicolaasg, and @teohhanhui for contributing to this
|
||||
release!
|
||||
|
||||
[#1935]: https://github.com/tokio-rs/tracing/pull/1935
|
||||
[#1913]: https://github.com/tokio-rs/tracing/pull/1913
|
||||
[#1930]: https://github.com/tokio-rs/tracing/pull/1930
|
||||
[#1918]: https://github.com/tokio-rs/tracing/pull/1918
|
||||
|
||||
# 0.1.30 (February 3rd, 2022)
|
||||
|
||||
This release adds *experimental* support for recording structured field
|
||||
values using the [`valuable`] crate. See [this blog post][post] for
|
||||
details on `valuable`.
|
||||
|
||||
Note that `valuable` support currently requires `--cfg tracing_unstable`. See
|
||||
the documentation for details.
|
||||
|
||||
This release also adds a new `enabled!` macro for testing if a span or event
|
||||
would be enabled.
|
||||
|
||||
### Added
|
||||
|
||||
- **field**: Experimental support for recording field values using the
|
||||
[`valuable`] crate ([#1608], [#1888], [#1887])
|
||||
- `enabled!` macro for testing if a span or event is enabled ([#1882])
|
||||
|
||||
### Changed
|
||||
|
||||
- `tracing-core`: updated to [0.1.22][core-0.1.22]
|
||||
- `tracing-attributes`: updated to [0.1.19][attributes-0.1.19]
|
||||
|
||||
### Fixed
|
||||
|
||||
- **log**: Fixed "use of moved value" compiler error when the "log" feature is
|
||||
enabled ([#1823])
|
||||
- Fixed macro hygiene issues when used in a crate that defines its own `concat!`
|
||||
macro ([#1842])
|
||||
- A very large number of documentation fixes and improvements.
|
||||
|
||||
Thanks to @@Vlad-Scherbina, @Skepfyr, @Swatinem, @guswynn, @teohhanhui,
|
||||
@xd009642, @tobz, @d-e-s-o@0b01, and @nickelc for contributing to this release!
|
||||
|
||||
[`valuable`]: https://crates.io/crates/valuable
|
||||
[post]: https://tokio.rs/blog/2021-05-valuable
|
||||
[core-0.1.22]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.22
|
||||
[attributes-0.1.19]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.19
|
||||
[#1608]: https://github.com/tokio-rs/tracing/pull/1608
|
||||
[#1888]: https://github.com/tokio-rs/tracing/pull/1888
|
||||
[#1887]: https://github.com/tokio-rs/tracing/pull/1887
|
||||
[#1882]: https://github.com/tokio-rs/tracing/pull/1882
|
||||
[#1823]: https://github.com/tokio-rs/tracing/pull/1823
|
||||
[#1842]: https://github.com/tokio-rs/tracing/pull/1842
|
||||
|
||||
# 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.18
|
||||
|
||||
### 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
|
||||
|
||||
# 0.1.28 (September 17th, 2021)
|
||||
|
||||
This release fixes an issue where the RustDoc documentation was rendered
|
||||
incorrectly. It doesn't include any actual code changes, and is very boring and
|
||||
can be ignored.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **docs**: Incorrect documentation rendering due to unclosed `<div>` tag
|
||||
([#1572])
|
||||
|
||||
[#1572]: https://github.com/tokio-rs/tracing/pull/1572
|
||||
|
||||
# 0.1.27 (September 13, 2021)
|
||||
|
||||
This release adds a new [`Span::or_current`] method to aid in efficiently
|
||||
propagating span contexts to spawned threads or tasks. Additionally, it updates
|
||||
the [`tracing-core`] version to [0.1.20] and the [`tracing-attributes`] version to
|
||||
[0.1.16], ensuring that a number of new features in those crates are present.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **instrument**: Added missing `WithSubscriber` implementations for futures and
|
||||
other types ([#1424])
|
||||
|
||||
### Added
|
||||
|
||||
- `Span::or_current` method, to help with efficient span context propagation
|
||||
([#1538])
|
||||
- **attributes**: add `skip_all` option to `#[instrument]` ([#1548])
|
||||
- **attributes**: record primitive types as primitive values rather than as
|
||||
`fmt::Debug` ([#1378])
|
||||
- **core**: `NoSubscriber`, a no-op `Subscriber` implementation
|
||||
([#1549])
|
||||
- **core**: Added `Visit::record_f64` and support for recording floating-point
|
||||
values ([#1507], [#1522])
|
||||
- A large number of documentation improvements and fixes ([#1369], [#1398],
|
||||
[#1435], [#1442], [#1524], [#1556])
|
||||
|
||||
Thanks to new contributors @dzvon and @mbergkvist, as well as @teozkr,
|
||||
@maxburke, @LukeMathWalker, and @jsgf, for contributing to this
|
||||
release!
|
||||
|
||||
[`Span::or_current`]: https://docs.rs/tracing/0.1.27/tracing/struct.Span.html#method.or_current
|
||||
[`tracing-core`]: https://crates.io/crates/tracing-core
|
||||
[`tracing-attributes`]: https://crates.io/crates/tracing-attributes
|
||||
[`tracing-core`]: https://crates.io/crates/tracing-core
|
||||
[0.1.20]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.20
|
||||
[0.1.16]: https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.16
|
||||
[#1424]: https://github.com/tokio-rs/tracing/pull/1424
|
||||
[#1538]: https://github.com/tokio-rs/tracing/pull/1538
|
||||
[#1548]: https://github.com/tokio-rs/tracing/pull/1548
|
||||
[#1378]: https://github.com/tokio-rs/tracing/pull/1378
|
||||
[#1507]: https://github.com/tokio-rs/tracing/pull/1507
|
||||
[#1522]: https://github.com/tokio-rs/tracing/pull/1522
|
||||
[#1369]: https://github.com/tokio-rs/tracing/pull/1369
|
||||
[#1398]: https://github.com/tokio-rs/tracing/pull/1398
|
||||
[#1435]: https://github.com/tokio-rs/tracing/pull/1435
|
||||
[#1442]: https://github.com/tokio-rs/tracing/pull/1442
|
||||
[#1524]: https://github.com/tokio-rs/tracing/pull/1524
|
||||
[#1556]: https://github.com/tokio-rs/tracing/pull/1556
|
||||
|
||||
# 0.1.26 (April 30, 2021)
|
||||
|
||||
### Fixed
|
||||
|
||||
- **attributes**: Compatibility between `#[instrument]` and `async-trait`
|
||||
v0.1.43 and newer ([#1228])
|
||||
- Several documentation fixes ([#1305], [#1344])
|
||||
### Added
|
||||
|
||||
- `Subscriber` impl for `Box<dyn Subscriber + Send + Sync + 'static>` ([#1358])
|
||||
- `Subscriber` impl for `Arc<dyn Subscriber + Send + Sync + 'static>` ([#1374])
|
||||
- Symmetric `From` impls for existing `Into` impls on `span::Current`, `Span`,
|
||||
and `Option<Id>` ([#1335], [#1338])
|
||||
- `From<EnteredSpan>` implementation for `Option<Id>`, allowing `EnteredSpan` to
|
||||
be used in a `span!` macro's `parent:` field ([#1325])
|
||||
- `Attributes::fields` accessor that returns the set of fields defined on a
|
||||
span's `Attributes` ([#1331])
|
||||
|
||||
|
||||
Thanks to @Folyd, @nightmared, and new contributors @rmsc and @Fishrock123 for
|
||||
contributing to this release!
|
||||
|
||||
[#1227]: https://github.com/tokio-rs/tracing/pull/1228
|
||||
[#1305]: https://github.com/tokio-rs/tracing/pull/1305
|
||||
[#1325]: https://github.com/tokio-rs/tracing/pull/1325
|
||||
[#1338]: https://github.com/tokio-rs/tracing/pull/1338
|
||||
[#1344]: https://github.com/tokio-rs/tracing/pull/1344
|
||||
[#1358]: https://github.com/tokio-rs/tracing/pull/1358
|
||||
[#1374]: https://github.com/tokio-rs/tracing/pull/1374
|
||||
[#1335]: https://github.com/tokio-rs/tracing/pull/1335
|
||||
[#1331]: https://github.com/tokio-rs/tracing/pull/1331
|
||||
|
||||
# 0.1.25 (February 23, 2021)
|
||||
|
||||
### Added
|
||||
|
||||
- `Span::entered` method for entering a span and moving it into a guard by value
|
||||
rather than borrowing it ([#1252])
|
||||
|
||||
Thanks to @matklad for contributing to this release!
|
||||
|
||||
[#1252]: https://github.com/tokio-rs/tracing/pull/1252
|
||||
|
||||
# 0.1.24 (February 17, 2021)
|
||||
|
||||
### Fixed
|
||||
|
||||
- **attributes**: Compiler error when using `#[instrument(err)]` on functions
|
||||
which return `impl Trait` ([#1236])
|
||||
- Fixed broken match arms in event macros ([#1239])
|
||||
- Documentation improvements ([#1232])
|
||||
|
||||
Thanks to @bkchr and @lfranke for contributing to this release!
|
||||
|
||||
[#1236]: https://github.com/tokio-rs/tracing/pull/1236
|
||||
[#1239]: https://github.com/tokio-rs/tracing/pull/1239
|
||||
[#1232]: https://github.com/tokio-rs/tracing/pull/1232
|
||||
|
||||
# 0.1.23 (February 4, 2021)
|
||||
|
||||
### Fixed
|
||||
|
||||
- **attributes**: Compiler error when using `#[instrument(err)]` on functions
|
||||
with mutable parameters ([#1167])
|
||||
- **attributes**: Missing function visibility modifier when using
|
||||
`#[instrument]` with `async-trait` ([#977])
|
||||
- **attributes** Removed unused `syn` features ([#928])
|
||||
- **log**: Fixed an issue where the `tracing` macros would generate code for
|
||||
events whose levels are disabled statically by the `log` crate's
|
||||
`static_max_level_XXX` features ([#1175])
|
||||
- Fixed deprecations and clippy lints ([#1195])
|
||||
- Several documentation fixes and improvements ([#941], [#965], [#981], [#1146],
|
||||
[#1215])
|
||||
|
||||
### Changed
|
||||
|
||||
- **attributes**: `tracing-futures` dependency is no longer required when using
|
||||
`#[instrument]` on async functions ([#808])
|
||||
- **attributes**: Updated `tracing-attributes` minimum dependency to v0.1.12
|
||||
([#1222])
|
||||
|
||||
Thanks to @nagisa, @Txuritan, @TaKO8Ki, @okready, and @krojew for contributing
|
||||
to this release!
|
||||
|
||||
[#1167]: https://github.com/tokio-rs/tracing/pull/1167
|
||||
[#977]: https://github.com/tokio-rs/tracing/pull/977
|
||||
[#965]: https://github.com/tokio-rs/tracing/pull/965
|
||||
[#981]: https://github.com/tokio-rs/tracing/pull/981
|
||||
[#1215]: https://github.com/tokio-rs/tracing/pull/1215
|
||||
[#808]: https://github.com/tokio-rs/tracing/pull/808
|
||||
[#941]: https://github.com/tokio-rs/tracing/pull/941
|
||||
[#1146]: https://github.com/tokio-rs/tracing/pull/1146
|
||||
[#1175]: https://github.com/tokio-rs/tracing/pull/1175
|
||||
[#1195]: https://github.com/tokio-rs/tracing/pull/1195
|
||||
[#1222]: https://github.com/tokio-rs/tracing/pull/1222
|
||||
|
||||
# 0.1.22 (November 23, 2020)
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated `pin-project-lite` dependency to 0.2 ([#1108])
|
||||
|
||||
[#1108]: https://github.com/tokio-rs/tracing/pull/1108
|
||||
|
||||
# 0.1.21 (September 28, 2020)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Incorrect inlining of `Span::new`, `Span::new_root`, and `Span::new_child_of`,
|
||||
which could result in `dispatcher::get_default` being inlined at the callsite
|
||||
([#994])
|
||||
- Regression where using a struct field as a span or event field when other
|
||||
fields on that struct are borrowed mutably would fail to compile ([#987])
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated `tracing-core` to 0.1.17 ([#992])
|
||||
|
||||
### Added
|
||||
|
||||
- `Instrument` trait and `Instrumented` type for attaching a `Span` to a
|
||||
`Future` ([#808])
|
||||
- `Copy` implementations for `Level` and `LevelFilter` ([#992])
|
||||
- Multiple documentation fixes and improvements ([#964], [#980], [#981])
|
||||
|
||||
Thanks to @nagisa, and new contributors @SecurityInsanity, @froydnj, @jyn514 and
|
||||
@TaKO8Ki for contributing to this release!
|
||||
|
||||
[#994]: https://github.com/tokio-rs/tracing/pull/994
|
||||
[#992]: https://github.com/tokio-rs/tracing/pull/992
|
||||
[#987]: https://github.com/tokio-rs/tracing/pull/987
|
||||
[#980]: https://github.com/tokio-rs/tracing/pull/980
|
||||
[#981]: https://github.com/tokio-rs/tracing/pull/981
|
||||
[#964]: https://github.com/tokio-rs/tracing/pull/964
|
||||
[#808]: https://github.com/tokio-rs/tracing/pull/808
|
||||
|
||||
# 0.1.20 (August 24, 2020)
|
||||
|
||||
### Changed
|
||||
|
||||
- Significantly reduced assembly generated by macro invocations (#943)
|
||||
- Updated `tracing-core` to 0.1.15 (#943)
|
||||
|
||||
### Added
|
||||
|
||||
- Documented minimum supported Rust version policy (#941)
|
||||
|
||||
# 0.1.19 (August 10, 2020)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Updated `tracing-core` to fix incorrect calculation of the global max level
|
||||
filter (#908)
|
||||
|
||||
### Added
|
||||
|
||||
- **attributes**: Support for using `self` in field expressions when
|
||||
instrumenting `async-trait` functions (#875)
|
||||
- Several documentation improvements (#832, #881, #896, #897, #911, #913)
|
||||
|
||||
Thanks to @anton-dutov, @nightmared, @mystor, and @toshokan for contributing to
|
||||
this release!
|
||||
|
||||
# 0.1.18 (July 31, 2020)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a bug where `LevelFilter::OFF` (and thus also the `static_max_level_off`
|
||||
feature flag) would enable *all* traces, rather than *none* (#853)
|
||||
- **log**: Fixed `tracing` macros and `Span`s not checking `log::max_level`
|
||||
before emitting `log` records (#870)
|
||||
|
||||
### Changed
|
||||
|
||||
- **macros**: Macros now check the global max level (`LevelFilter::current`)
|
||||
before the per-callsite cache when determining if a span or event is enabled.
|
||||
This significantly improves performance in some use cases (#853)
|
||||
- **macros**: Simplified the code generated by macro expansion significantly,
|
||||
which may improve compile times and/or `rustc` optimizatation of surrounding
|
||||
code (#869, #869)
|
||||
- **macros**: Macros now check the static max level before checking any runtime
|
||||
filtering, improving performance when a span or event is disabled by a
|
||||
`static_max_level_XXX` feature flag (#868)
|
||||
- `LevelFilter` is now a re-export of the `tracing_core::LevelFilter` type, it
|
||||
can now be used interchangably with the versions in `tracing-core` and
|
||||
`tracing-subscriber` (#853)
|
||||
- Significant performance improvements when comparing `LevelFilter`s and
|
||||
`Level`s (#853)
|
||||
- Updated the minimum `tracing-core` dependency to 0.1.12 (#853)
|
||||
|
||||
### Added
|
||||
|
||||
- **macros**: Quoted string literals may now be used as field names, to allow
|
||||
fields whose names are not valid Rust identifiers (#790)
|
||||
- **docs**: Several documentation improvements (#850, #857, #841)
|
||||
- `LevelFilter::current()` function, which returns the highest level that any
|
||||
subscriber will enable (#853)
|
||||
- `Subscriber::max_level_hint` optional trait method, for setting the value
|
||||
returned by `LevelFilter::current()` (#853)
|
||||
|
||||
Thanks to new contributors @cuviper, @ethanboxx, @ben0x539, @dignati,
|
||||
@colelawrence, and @rbtcollins for helping out with this release!
|
||||
|
||||
# 0.1.17 (July 22, 2020)
|
||||
|
||||
### Changed
|
||||
|
||||
- **log**: Moved verbose span enter/exit log records to "tracing::span::active"
|
||||
target, allowing them to be filtered separately (#833)
|
||||
- **log**: All span lifecycle log records without fields now have the `Trace`
|
||||
log filter, to guard against `log` users enabling them by default with blanket
|
||||
level filtering (#833)
|
||||
|
||||
### Fixed
|
||||
|
||||
- **log**/**macros**: Fixed missing implicit imports of the
|
||||
`tracing::field::debug` and `tracing::field::display` functions inside the
|
||||
macros when the "log" feature is enabled (#835)
|
||||
|
||||
# 0.1.16 (July 8, 2020)
|
||||
|
||||
### Added
|
||||
|
||||
- **attributes**: Support for arbitrary expressions as fields in `#[instrument]` (#672)
|
||||
- **attributes**: `#[instrument]` now emits a compiler warning when ignoring unrecognized
|
||||
input (#672, #786)
|
||||
- Improved documentation on using `tracing` in async code (#769)
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated `tracing-core` dependency to 0.1.11
|
||||
|
||||
### Fixed
|
||||
|
||||
- **macros**: Excessive monomorphization in macros, which could lead to
|
||||
longer compilation times (#787)
|
||||
- **log**: Compiler warnings in macros when `log` or `log-always` features
|
||||
are enabled (#753)
|
||||
- Compiler error when `tracing-core/std` feature is enabled but `tracing/std` is
|
||||
not (#760)
|
||||
|
||||
Thanks to @nagisa for contributing to this release!
|
||||
|
||||
# 0.1.15 (June 2, 2020)
|
||||
|
||||
### Changed
|
||||
|
||||
- **macros**: Replaced use of legacy `local_inner_macros` with `$crate::` (#740)
|
||||
|
||||
### Added
|
||||
|
||||
- Docs fixes and improvements (#742, #731, #730)
|
||||
|
||||
Thanks to @bnjjj, @blaenk, and @LukeMathWalker for contributing to this release!
|
||||
|
||||
# 0.1.14 (May 14, 2020)
|
||||
|
||||
### Added
|
||||
|
||||
- **log**: When using the [`log`] compatibility feature alongside a `tracing`
|
||||
`Subscriber`, log records for spans now include span IDs (#613)
|
||||
- **attributes**: Support for using `#[instrument]` on methods that are part of
|
||||
[`async-trait`] trait implementations (#711)
|
||||
- **attributes**: Optional `#[instrument(err)]` argument to automatically emit
|
||||
an event if an instrumented function returns `Err` (#637)
|
||||
- Added `#[must_use]` attribute to the guard returned by
|
||||
`subscriber::set_default` (#685)
|
||||
|
||||
### Changed
|
||||
|
||||
- **log**: Made [`log`] records emitted by spans much less noisy when span IDs are
|
||||
not available (#613)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Several typos in the documentation (#656, #710, #715)
|
||||
|
||||
Thanks to @FintanH, @shepmaster, @inanna-malick, @zekisharif, @bkchr, @majecty,
|
||||
@ilana and @nightmared for contributing to this release!
|
||||
|
||||
[`async-trait`]: https://crates.io/crates/async-trait
|
||||
[`log`]: https://crates.io/crates/log
|
||||
|
||||
# 0.1.13 (February 26, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- **field**: `field::Empty` type for declaring empty fields whose values will be
|
||||
recorded later (#548)
|
||||
- **field**: `field::Value` implementations for `Wrapping` and `NonZero*`
|
||||
numbers (#538)
|
||||
- **attributes**: Support for adding arbitrary literal fields to spans generated
|
||||
by `#[instrument]` (#569)
|
||||
- **attributes**: `#[instrument]` now emits a helpful compiler error when
|
||||
attempting to skip a function parameter (#600)
|
||||
|
||||
### Changed
|
||||
|
||||
- **attributes**: The `#[instrument]` attribute was placed under an on-by-default
|
||||
feature flag "attributes" (#603)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Broken and unresolvable links in RustDoc (#595)
|
||||
|
||||
Thanks to @oli-cosmian and @Kobzol for contributing to this release!
|
||||
|
||||
# 0.1.12 (January 11, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- `Span::with_subscriber` method to access the subscriber that tracks a `Span`
|
||||
(#503)
|
||||
- API documentation now shows which features are required by feature-flagged
|
||||
items (#523)
|
||||
- Improved README examples (#496)
|
||||
- Documentation links to related crates (#507)
|
||||
|
||||
# 0.1.11 (December 20, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- `Span::is_none` method (#475)
|
||||
- `LevelFilter::into_level` method (#470)
|
||||
- `LevelFilter::from_level` function and `From<Level>` impl (#471)
|
||||
- Documented minimum supported Rust version (#482)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Incorrect parameter type to `Span::follows_from` that made it impossible to
|
||||
call (#467)
|
||||
- Missing whitespace in `log` records generated when enabling the `log` feature
|
||||
flag (#484)
|
||||
- Typos and missing links in documentation (#405, #423, #439)
|
||||
|
||||
# 0.1.10 (October 23, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- Support for destructuring in arguments to `#[instrument]`ed functions (#397)
|
||||
- Generated field for `self` parameters when `#[instrument]`ing methods (#397)
|
||||
- Optional `skip` argument to `#[instrument]` for excluding function parameters
|
||||
from generated spans (#359)
|
||||
- Added `dispatcher::set_default` and `subscriber::set_default` APIs, which
|
||||
return a drop guard (#388)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Some minor documentation errors (#356, #370)
|
||||
|
||||
# 0.1.9 (September 13, 2019)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `#[instrument]`ed async functions not compiling on `nightly-2019-09-11`
|
||||
or newer (#342)
|
||||
|
||||
### Changed
|
||||
|
||||
- Significantly reduced performance impact of skipped spans and events when a
|
||||
`Subscriber` is not in use (#326)
|
||||
- The `log` feature will now only cause `tracing` spans and events to emit log
|
||||
records when a `Subscriber` is not in use (#346)
|
||||
|
||||
### Added
|
||||
|
||||
- Added support for overriding the name of the span generated by `#[instrument]`
|
||||
(#330)
|
||||
- `log-always` feature flag to emit log records even when a `Subscriber` is set
|
||||
(#346)
|
||||
|
||||
# 0.1.8 (September 3, 2019)
|
||||
|
||||
### Changed
|
||||
|
||||
- Reorganized and improved API documentation (#317)
|
||||
|
||||
### Removed
|
||||
|
||||
- Dev-dependencies on `ansi_term` and `humantime` crates, which were used only
|
||||
for examples (#316)
|
||||
|
||||
# 0.1.7 (August 30, 2019)
|
||||
|
||||
### Changed
|
||||
|
||||
- New (curly-brace free) event message syntax to place the message in the first
|
||||
field rather than the last (#309)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a regression causing macro stack exhaustion when the `log` feature flag
|
||||
is enabled (#304)
|
||||
|
||||
# 0.1.6 (August 20, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- `std::error::Error` as a new primitive type (#277)
|
||||
- Support for mixing key-value fields and `format_args` messages without curly
|
||||
braces as delimiters (#288)
|
||||
|
||||
### Changed
|
||||
|
||||
- `tracing-core` dependency to 0.1.5 (#294)
|
||||
- `tracing-attributes` dependency to 0.1.2 (#297)
|
||||
|
||||
# 0.1.5 (August 9, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- Support for `no-std` + `liballoc` (#263)
|
||||
|
||||
### Changed
|
||||
|
||||
- Using the `#[instrument]` attribute on `async fn`s no longer requires a
|
||||
feature flag (#258)
|
||||
|
||||
### Fixed
|
||||
|
||||
- The `#[instrument]` macro now works on generic functions (#262)
|
||||
|
||||
# 0.1.4 (August 8, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- `#[instrument]` attribute for automatically adding spans to functions (#253)
|
||||
|
||||
# 0.1.3 (July 11, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- Log messages when a subscriber indicates that a span has closed, when the
|
||||
`log` feature flag is enabled (#180).
|
||||
|
||||
### Changed
|
||||
|
||||
- `tracing-core` minimum dependency version to 0.1.2 (#174).
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed an issue where event macro invocations with a single field, using local
|
||||
variable shorthand, would recur infinitely (#166).
|
||||
- Fixed uses of deprecated `tracing-core` APIs (#174).
|
||||
|
||||
# 0.1.2 (July 6, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- `Span::none()` constructor, which does not require metadata and
|
||||
returns a completely empty span (#147).
|
||||
- `Span::current()` function, returning the current span if it is
|
||||
known to the subscriber (#148).
|
||||
|
||||
### Fixed
|
||||
|
||||
- Broken macro imports when used prefixed with `tracing::` (#152).
|
||||
|
||||
# 0.1.1 (July 3, 2019)
|
||||
|
||||
### Changed
|
||||
|
||||
- `cfg_if` dependency to 0.1.9.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Compilation errors when the `log` feature is enabled (#131).
|
||||
- Unclear wording and typos in documentation (#124, #128, #142).
|
||||
|
||||
# 0.1.0 (June 27, 2019)
|
||||
|
||||
- Initial release
|
||||
143
third-party/vendor/tracing/Cargo.toml
vendored
Normal file
143
third-party/vendor/tracing/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
rust-version = "1.56.0"
|
||||
name = "tracing"
|
||||
version = "0.1.40"
|
||||
authors = [
|
||||
"Eliza Weisman <eliza@buoyant.io>",
|
||||
"Tokio Contributors <team@tokio.rs>",
|
||||
]
|
||||
description = """
|
||||
Application-level tracing for Rust.
|
||||
"""
|
||||
homepage = "https://tokio.rs"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"logging",
|
||||
"tracing",
|
||||
"metrics",
|
||||
"async",
|
||||
]
|
||||
categories = [
|
||||
"development-tools::debugging",
|
||||
"development-tools::profiling",
|
||||
"asynchronous",
|
||||
"no-std",
|
||||
]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/tokio-rs/tracing"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustc-args = [
|
||||
"--cfg",
|
||||
"tracing_unstable",
|
||||
]
|
||||
rustdoc-args = [
|
||||
"--cfg",
|
||||
"docsrs",
|
||||
"--cfg",
|
||||
"tracing_unstable",
|
||||
]
|
||||
|
||||
[[bench]]
|
||||
name = "baseline"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "dispatch_get_clone"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "dispatch_get_ref"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "empty_span"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "enter_span"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "event"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "span_fields"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "span_no_fields"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "span_repeated"
|
||||
harness = false
|
||||
|
||||
[dependencies.log]
|
||||
version = "0.4.17"
|
||||
optional = true
|
||||
|
||||
[dependencies.pin-project-lite]
|
||||
version = "0.2.9"
|
||||
|
||||
[dependencies.tracing-attributes]
|
||||
version = "0.1.27"
|
||||
optional = true
|
||||
|
||||
[dependencies.tracing-core]
|
||||
version = "0.1.32"
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.criterion]
|
||||
version = "0.3.6"
|
||||
default_features = false
|
||||
|
||||
[dev-dependencies.futures]
|
||||
version = "0.3.21"
|
||||
default_features = false
|
||||
|
||||
[dev-dependencies.log]
|
||||
version = "0.4.17"
|
||||
|
||||
[features]
|
||||
async-await = []
|
||||
attributes = ["tracing-attributes"]
|
||||
default = [
|
||||
"std",
|
||||
"attributes",
|
||||
]
|
||||
log-always = ["log"]
|
||||
max_level_debug = []
|
||||
max_level_error = []
|
||||
max_level_info = []
|
||||
max_level_off = []
|
||||
max_level_trace = []
|
||||
max_level_warn = []
|
||||
release_max_level_debug = []
|
||||
release_max_level_error = []
|
||||
release_max_level_info = []
|
||||
release_max_level_off = []
|
||||
release_max_level_trace = []
|
||||
release_max_level_warn = []
|
||||
std = ["tracing-core/std"]
|
||||
valuable = ["tracing-core/valuable"]
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dev-dependencies.wasm-bindgen-test]
|
||||
version = "^0.3"
|
||||
|
||||
[badges.maintenance]
|
||||
status = "actively-developed"
|
||||
25
third-party/vendor/tracing/LICENSE
vendored
Normal file
25
third-party/vendor/tracing/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) 2019 Tokio Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
467
third-party/vendor/tracing/README.md
vendored
Normal file
467
third-party/vendor/tracing/README.md
vendored
Normal file
|
|
@ -0,0 +1,467 @@
|
|||
![Tracing — Structured, application-level diagnostics][splash]
|
||||
|
||||
[splash]: https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/splash.svg
|
||||
|
||||
# tracing
|
||||
|
||||
Application-level tracing for Rust.
|
||||
|
||||
[![Crates.io][crates-badge]][crates-url]
|
||||
[![Documentation][docs-badge]][docs-url]
|
||||
[![Documentation (master)][docs-master-badge]][docs-master-url]
|
||||
[![MIT licensed][mit-badge]][mit-url]
|
||||
[![Build Status][actions-badge]][actions-url]
|
||||
[![Discord chat][discord-badge]][discord-url]
|
||||
|
||||
[Documentation][docs-url] | [Chat][discord-url]
|
||||
|
||||
[crates-badge]: https://img.shields.io/crates/v/tracing.svg
|
||||
[crates-url]: https://crates.io/crates/tracing
|
||||
[docs-badge]: https://docs.rs/tracing/badge.svg
|
||||
[docs-url]: https://docs.rs/tracing
|
||||
[docs-master-badge]: https://img.shields.io/badge/docs-master-blue
|
||||
[docs-master-url]: https://tracing-rs.netlify.com/tracing
|
||||
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
|
||||
[mit-url]: LICENSE
|
||||
[actions-badge]: https://github.com/tokio-rs/tracing/workflows/CI/badge.svg
|
||||
[actions-url]:https://github.com/tokio-rs/tracing/actions?query=workflow%3ACI
|
||||
[discord-badge]: https://img.shields.io/discord/500028886025895936?logo=discord&label=discord&logoColor=white
|
||||
[discord-url]: https://discord.gg/EeF3cQw
|
||||
|
||||
## Overview
|
||||
|
||||
`tracing` is a framework for instrumenting Rust programs to collect
|
||||
structured, event-based diagnostic information.
|
||||
|
||||
In asynchronous systems like Tokio, interpreting traditional log messages can
|
||||
often be quite challenging. Since individual tasks are multiplexed on the same
|
||||
thread, associated events and log lines are intermixed making it difficult to
|
||||
trace the logic flow. `tracing` expands upon logging-style diagnostics by
|
||||
allowing libraries and applications to record structured events with additional
|
||||
information about *temporality* and *causality* — unlike a log message, a span
|
||||
in `tracing` has a beginning and end time, may be entered and exited by the
|
||||
flow of execution, and may exist within a nested tree of similar spans. In
|
||||
addition, `tracing` spans are *structured*, with the ability to record typed
|
||||
data as well as textual messages.
|
||||
|
||||
The `tracing` crate provides the APIs necessary for instrumenting libraries
|
||||
and applications to emit trace data.
|
||||
|
||||
*Compiler support: [requires `rustc` 1.56+][msrv]*
|
||||
|
||||
[msrv]: #supported-rust-versions
|
||||
|
||||
## Usage
|
||||
|
||||
(The examples below are borrowed from the `log` crate's yak-shaving
|
||||
[example](https://docs.rs/log/0.4.10/log/index.html#examples), modified to
|
||||
idiomatic `tracing`.)
|
||||
|
||||
### In Applications
|
||||
|
||||
In order to record trace events, executables have to use a `Subscriber`
|
||||
implementation compatible with `tracing`. A `Subscriber` implements a way of
|
||||
collecting trace data, such as by logging it to standard output. [`tracing_subscriber`](https://docs.rs/tracing-subscriber/)'s
|
||||
[`fmt` module](https://docs.rs/tracing-subscriber/0.3/tracing_subscriber/fmt/index.html) provides reasonable defaults.
|
||||
Additionally, `tracing-subscriber` is able to consume messages emitted by `log`-instrumented libraries and modules.
|
||||
|
||||
The simplest way to use a subscriber is to call the `set_global_default` function.
|
||||
|
||||
```rust
|
||||
use tracing::{info, Level};
|
||||
use tracing_subscriber::FmtSubscriber;
|
||||
|
||||
fn main() {
|
||||
// a builder for `FmtSubscriber`.
|
||||
let subscriber = FmtSubscriber::builder()
|
||||
// all spans/events with a level higher than TRACE (e.g, debug, info, warn, etc.)
|
||||
// will be written to stdout.
|
||||
.with_max_level(Level::TRACE)
|
||||
// completes the builder.
|
||||
.finish();
|
||||
|
||||
tracing::subscriber::set_global_default(subscriber)
|
||||
.expect("setting default subscriber failed");
|
||||
|
||||
let number_of_yaks = 3;
|
||||
// this creates a new event, outside of any spans.
|
||||
info!(number_of_yaks, "preparing to shave yaks");
|
||||
|
||||
let number_shaved = yak_shave::shave_all(number_of_yaks);
|
||||
info!(
|
||||
all_yaks_shaved = number_shaved == number_of_yaks,
|
||||
"yak shaving completed."
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = "0.3.0"
|
||||
```
|
||||
|
||||
This subscriber will be used as the default in all threads for the remainder of the duration
|
||||
of the program, similar to how loggers work in the `log` crate.
|
||||
|
||||
In addition, you can locally override the default subscriber. For example:
|
||||
|
||||
```rust
|
||||
use tracing::{info, Level};
|
||||
use tracing_subscriber::FmtSubscriber;
|
||||
|
||||
fn main() {
|
||||
let subscriber = tracing_subscriber::FmtSubscriber::builder()
|
||||
// all spans/events with a level higher than TRACE (e.g, debug, info, warn, etc.)
|
||||
// will be written to stdout.
|
||||
.with_max_level(Level::TRACE)
|
||||
// builds the subscriber.
|
||||
.finish();
|
||||
|
||||
tracing::subscriber::with_default(subscriber, || {
|
||||
info!("This will be logged to stdout");
|
||||
});
|
||||
info!("This will _not_ be logged to stdout");
|
||||
}
|
||||
```
|
||||
|
||||
This approach allows trace data to be collected by multiple subscribers
|
||||
within different contexts in the program. Note that the override only applies to the
|
||||
currently executing thread; other threads will not see the change from with_default.
|
||||
|
||||
Any trace events generated outside the context of a subscriber will not be collected.
|
||||
|
||||
Once a subscriber has been set, instrumentation points may be added to the
|
||||
executable using the `tracing` crate's macros.
|
||||
|
||||
### In Libraries
|
||||
|
||||
Libraries should only rely on the `tracing` crate and use the provided macros
|
||||
and types to collect whatever information might be useful to downstream consumers.
|
||||
|
||||
```rust
|
||||
use std::{error::Error, io};
|
||||
use tracing::{debug, error, info, span, warn, Level};
|
||||
|
||||
// the `#[tracing::instrument]` attribute creates and enters a span
|
||||
// every time the instrumented function is called. The span is named after the
|
||||
// the function or method. Paramaters passed to the function are recorded as fields.
|
||||
#[tracing::instrument]
|
||||
pub fn shave(yak: usize) -> Result<(), Box<dyn Error + 'static>> {
|
||||
// this creates an event at the DEBUG level with two fields:
|
||||
// - `excitement`, with the key "excitement" and the value "yay!"
|
||||
// - `message`, with the key "message" and the value "hello! I'm gonna shave a yak."
|
||||
//
|
||||
// unlike other fields, `message`'s shorthand initialization is just the string itself.
|
||||
debug!(excitement = "yay!", "hello! I'm gonna shave a yak.");
|
||||
if yak == 3 {
|
||||
warn!("could not locate yak!");
|
||||
// note that this is intended to demonstrate `tracing`'s features, not idiomatic
|
||||
// error handling! in a library or application, you should consider returning
|
||||
// a dedicated `YakError`. libraries like snafu or thiserror make this easy.
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "shaving yak failed!").into());
|
||||
} else {
|
||||
debug!("yak shaved successfully");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn shave_all(yaks: usize) -> usize {
|
||||
// Constructs a new span named "shaving_yaks" at the TRACE level,
|
||||
// and a field whose key is "yaks". This is equivalent to writing:
|
||||
//
|
||||
// let span = span!(Level::TRACE, "shaving_yaks", yaks = yaks);
|
||||
//
|
||||
// local variables (`yaks`) can be used as field values
|
||||
// without an assignment, similar to struct initializers.
|
||||
let _span_ = span!(Level::TRACE, "shaving_yaks", yaks).entered();
|
||||
|
||||
info!("shaving yaks");
|
||||
|
||||
let mut yaks_shaved = 0;
|
||||
for yak in 1..=yaks {
|
||||
let res = shave(yak);
|
||||
debug!(yak, shaved = res.is_ok());
|
||||
|
||||
if let Err(ref error) = res {
|
||||
// Like spans, events can also use the field initialization shorthand.
|
||||
// In this instance, `yak` is the field being initalized.
|
||||
error!(yak, error = error.as_ref(), "failed to shave yak!");
|
||||
} else {
|
||||
yaks_shaved += 1;
|
||||
}
|
||||
debug!(yaks_shaved);
|
||||
}
|
||||
|
||||
yaks_shaved
|
||||
}
|
||||
```
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
tracing = "0.1"
|
||||
```
|
||||
|
||||
Note: Libraries should *NOT* call `set_global_default()`, as this will cause
|
||||
conflicts when executables try to set the default later.
|
||||
|
||||
### In Asynchronous Code
|
||||
|
||||
If you are instrumenting code that make use of
|
||||
[`std::future::Future`](https://doc.rust-lang.org/stable/std/future/trait.Future.html)
|
||||
or async/await, avoid using the `Span::enter` method. The following example
|
||||
_will not_ work:
|
||||
|
||||
```rust
|
||||
async {
|
||||
let _s = span.enter();
|
||||
// ...
|
||||
}
|
||||
```
|
||||
```rust
|
||||
async {
|
||||
let _s = tracing::span!(...).entered();
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
The span guard `_s` will not exit until the future generated by the `async` block is complete.
|
||||
Since futures and spans can be entered and exited _multiple_ times without them completing,
|
||||
the span remains entered for as long as the future exists, rather than being entered only when
|
||||
it is polled, leading to very confusing and incorrect output.
|
||||
For more details, see [the documentation on closing spans](https://tracing.rs/tracing/span/index.html#closing-spans).
|
||||
|
||||
There are two ways to instrument asynchronous code. The first is through the
|
||||
[`Future::instrument`](https://docs.rs/tracing/latest/tracing/trait.Instrument.html#method.instrument) combinator:
|
||||
|
||||
```rust
|
||||
use tracing::Instrument;
|
||||
|
||||
let my_future = async {
|
||||
// ...
|
||||
};
|
||||
|
||||
my_future
|
||||
.instrument(tracing::info_span!("my_future"))
|
||||
.await
|
||||
```
|
||||
|
||||
`Future::instrument` attaches a span to the future, ensuring that the span's lifetime
|
||||
is as long as the future's.
|
||||
|
||||
The second, and preferred, option is through the
|
||||
[`#[instrument]`](https://docs.rs/tracing/0.1.38/tracing/attr.instrument.html)
|
||||
attribute:
|
||||
|
||||
```rust
|
||||
use tracing::{info, instrument};
|
||||
use tokio::{io::AsyncWriteExt, net::TcpStream};
|
||||
use std::io;
|
||||
|
||||
#[instrument]
|
||||
async fn write(stream: &mut TcpStream) -> io::Result<usize> {
|
||||
let result = stream.write(b"hello world\n").await;
|
||||
info!("wrote to stream; success={:?}", result.is_ok());
|
||||
result
|
||||
}
|
||||
```
|
||||
|
||||
Under the hood, the `#[instrument]` macro performs the same explicit span
|
||||
attachment that `Future::instrument` does.
|
||||
|
||||
### Concepts
|
||||
|
||||
This crate provides macros for creating `Span`s and `Event`s, which represent
|
||||
periods of time and momentary events within the execution of a program,
|
||||
respectively.
|
||||
|
||||
As a rule of thumb, _spans_ should be used to represent discrete units of work
|
||||
(e.g., a given request's lifetime in a server) or periods of time spent in a
|
||||
given context (e.g., time spent interacting with an instance of an external
|
||||
system, such as a database). In contrast, _events_ should be used to represent
|
||||
points in time within a span — a request returned with a given status code,
|
||||
_n_ new items were taken from a queue, and so on.
|
||||
|
||||
`Span`s are constructed using the `span!` macro, and then _entered_
|
||||
to indicate that some code takes place within the context of that `Span`:
|
||||
|
||||
```rust
|
||||
use tracing::{span, Level};
|
||||
|
||||
// Construct a new span named "my span".
|
||||
let mut span = span!(Level::INFO, "my span");
|
||||
span.in_scope(|| {
|
||||
// Any trace events in this closure or code called by it will occur within
|
||||
// the span.
|
||||
});
|
||||
// Dropping the span will close it, indicating that it has ended.
|
||||
```
|
||||
|
||||
The [`#[instrument]`](https://docs.rs/tracing/0.1.38/tracing/attr.instrument.html) attribute macro
|
||||
can reduce some of this boilerplate:
|
||||
|
||||
```rust
|
||||
use tracing::{instrument};
|
||||
|
||||
#[instrument]
|
||||
pub fn my_function(my_arg: usize) {
|
||||
// This event will be recorded inside a span named `my_function` with the
|
||||
// field `my_arg`.
|
||||
tracing::info!("inside my_function!");
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
The `Event` type represent an event that occurs instantaneously, and is
|
||||
essentially a `Span` that cannot be entered. They are created using the `event!`
|
||||
macro:
|
||||
|
||||
```rust
|
||||
use tracing::{event, Level};
|
||||
|
||||
event!(Level::INFO, "something has happened!");
|
||||
```
|
||||
|
||||
Users of the [`log`] crate should note that `tracing` exposes a set of macros for
|
||||
creating `Event`s (`trace!`, `debug!`, `info!`, `warn!`, and `error!`) which may
|
||||
be invoked with the same syntax as the similarly-named macros from the `log`
|
||||
crate. Often, the process of converting a project to use `tracing` can begin
|
||||
with a simple drop-in replacement.
|
||||
|
||||
## Supported Rust Versions
|
||||
|
||||
Tracing is built against the latest stable release. The minimum supported
|
||||
version is 1.42. The current Tracing version is not guaranteed to build on Rust
|
||||
versions earlier than the minimum supported version.
|
||||
|
||||
Tracing follows the same compiler support policies as the rest of the Tokio
|
||||
project. The current stable Rust compiler and the three most recent minor
|
||||
versions before it will always be supported. For example, if the current stable
|
||||
compiler version is 1.45, the minimum supported version will not be increased
|
||||
past 1.42, three minor versions prior. Increasing the minimum supported compiler
|
||||
version is not considered a semver breaking change as long as doing so complies
|
||||
with this policy.
|
||||
|
||||
## Ecosystem
|
||||
|
||||
### Related Crates
|
||||
|
||||
In addition to `tracing` and `tracing-core`, the [`tokio-rs/tracing`] repository
|
||||
contains several additional crates designed to be used with the `tracing` ecosystem.
|
||||
This includes a collection of `Subscriber` implementations, as well as utility
|
||||
and adapter crates to assist in writing `Subscriber`s and instrumenting
|
||||
applications.
|
||||
|
||||
In particular, the following crates are likely to be of interest:
|
||||
|
||||
- [`tracing-futures`] provides a compatibility layer with the `futures`
|
||||
crate, allowing spans to be attached to `Future`s, `Stream`s, and `Executor`s.
|
||||
- [`tracing-subscriber`] provides `Subscriber` implementations and
|
||||
utilities for working with `Subscriber`s. This includes a [`FmtSubscriber`]
|
||||
`FmtSubscriber` for logging formatted trace data to stdout, with similar
|
||||
filtering and formatting to the [`env_logger`] crate.
|
||||
- [`tracing-log`] provides a compatibility layer with the [`log`] crate,
|
||||
allowing log messages to be recorded as `tracing` `Event`s within the
|
||||
trace tree. This is useful when a project using `tracing` have
|
||||
dependencies which use `log`. Note that if you're using
|
||||
`tracing-subscriber`'s `FmtSubscriber`, you don't need to depend on
|
||||
`tracing-log` directly.
|
||||
|
||||
Additionally, there are also several third-party crates which are not
|
||||
maintained by the `tokio` project. These include:
|
||||
|
||||
- [`tracing-timing`] implements inter-event timing metrics on top of `tracing`.
|
||||
It provides a subscriber that records the time elapsed between pairs of
|
||||
`tracing` events and generates histograms.
|
||||
- [`tracing-opentelemetry`] provides a subscriber for emitting traces to
|
||||
[OpenTelemetry]-compatible distributed tracing systems.
|
||||
- [`tracing-honeycomb`] Provides a layer that reports traces spanning multiple machines to [honeycomb.io]. Backed by [`tracing-distributed`].
|
||||
- [`tracing-distributed`] Provides a generic implementation of a layer that reports traces spanning multiple machines to some backend.
|
||||
- [`tracing-actix`] provides `tracing` integration for the `actix` actor
|
||||
framework.
|
||||
- [`axum-insights`] provides `tracing` integration and Application insights export for the `axum` web framework.
|
||||
- [`tracing-gelf`] implements a subscriber for exporting traces in Greylog
|
||||
GELF format.
|
||||
- [`tracing-coz`] provides integration with the [coz] causal profiler
|
||||
(Linux-only).
|
||||
- [`test-log`] takes care of initializing `tracing` for tests, based on
|
||||
environment variables with an `env_logger` compatible syntax.
|
||||
- [`tracing-unwrap`] provides convenience methods to report failed unwraps on `Result` or `Option` types to a `Subscriber`.
|
||||
- [`diesel-tracing`] provides integration with [`diesel`] database connections.
|
||||
- [`tracing-tracy`] provides a way to collect [Tracy] profiles in instrumented
|
||||
applications.
|
||||
- [`tracing-elastic-apm`] provides a layer for reporting traces to [Elastic APM].
|
||||
- [`tracing-etw`] provides a layer for emitting Windows [ETW] events.
|
||||
- [`tracing-fluent-assertions`] provides a fluent assertions-style testing
|
||||
framework for validating the behavior of `tracing` spans.
|
||||
- [`sentry-tracing`] provides a layer for reporting events and traces to [Sentry].
|
||||
- [`tracing-loki`] provides a layer for shipping logs to [Grafana Loki].
|
||||
- [`tracing-logfmt`] provides a layer that formats events and spans into the logfmt format.
|
||||
|
||||
If you're the maintainer of a `tracing` ecosystem crate not listed above,
|
||||
please let us know! We'd love to add your project to the list!
|
||||
|
||||
[`tracing-timing`]: https://crates.io/crates/tracing-timing
|
||||
[`tracing-opentelemetry`]: https://crates.io/crates/tracing-opentelemetry
|
||||
[OpenTelemetry]: https://opentelemetry.io/
|
||||
[`tracing-honeycomb`]: https://crates.io/crates/tracing-honeycomb
|
||||
[`tracing-distributed`]: https://crates.io/crates/tracing-distributed
|
||||
[honeycomb.io]: https://www.honeycomb.io/
|
||||
[`tracing-actix`]: https://crates.io/crates/tracing-actix
|
||||
[`axum-insights`]: https://crates.io/crates/axum-insights
|
||||
[`tracing-gelf`]: https://crates.io/crates/tracing-gelf
|
||||
[`tracing-coz`]: https://crates.io/crates/tracing-coz
|
||||
[coz]: https://github.com/plasma-umass/coz
|
||||
[`test-log`]: https://crates.io/crates/test-log
|
||||
[`tracing-unwrap`]: https://docs.rs/tracing-unwrap
|
||||
[`diesel`]: https://crates.io/crates/diesel
|
||||
[`diesel-tracing`]: https://crates.io/crates/diesel-tracing
|
||||
[`tracing-tracy`]: https://crates.io/crates/tracing-tracy
|
||||
[Tracy]: https://github.com/wolfpld/tracy
|
||||
[`tracing-elastic-apm`]: https://crates.io/crates/tracing-elastic-apm
|
||||
[Elastic APM]: https://www.elastic.co/apm
|
||||
[`tracing-etw`]: https://github.com/microsoft/tracing-etw
|
||||
[ETW]: https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing
|
||||
[`tracing-fluent-assertions`]: https://crates.io/crates/tracing-fluent-assertions
|
||||
[`sentry-tracing`]: https://crates.io/crates/sentry-tracing
|
||||
[Sentry]: https://sentry.io/welcome/
|
||||
[`tracing-loki`]: https://crates.io/crates/tracing-loki
|
||||
[Grafana Loki]: https://grafana.com/oss/loki/
|
||||
[`tracing-logfmt`]: https://crates.io/crates/tracing-logfmt
|
||||
|
||||
**Note:** that some of the ecosystem crates are currently unreleased and
|
||||
undergoing active development. They may be less stable than `tracing` and
|
||||
`tracing-core`.
|
||||
|
||||
[`log`]: https://docs.rs/log/0.4.6/log/
|
||||
[`tokio-rs/tracing`]: https://github.com/tokio-rs/tracing
|
||||
[`tracing-futures`]: https://github.com/tokio-rs/tracing/tree/master/tracing-futures
|
||||
[`tracing-subscriber`]: https://github.com/tokio-rs/tracing/tree/master/tracing-subscriber
|
||||
[`tracing-log`]: https://github.com/tokio-rs/tracing/tree/master/tracing-log
|
||||
[`env_logger`]: https://crates.io/crates/env_logger
|
||||
[`FmtSubscriber`]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/fmt/struct.Subscriber.html
|
||||
[`examples`]: https://github.com/tokio-rs/tracing/tree/master/examples
|
||||
|
||||
## Supported Rust Versions
|
||||
|
||||
Tracing is built against the latest stable release. The minimum supported
|
||||
version is 1.56. The current Tracing version is not guaranteed to build on Rust
|
||||
versions earlier than the minimum supported version.
|
||||
|
||||
Tracing follows the same compiler support policies as the rest of the Tokio
|
||||
project. The current stable Rust compiler and the three most recent minor
|
||||
versions before it will always be supported. For example, if the current stable
|
||||
compiler version is 1.69, the minimum supported version will not be increased
|
||||
past 1.66, three minor versions prior. Increasing the minimum supported compiler
|
||||
version is not considered a semver breaking change as long as doing so complies
|
||||
with this policy.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the [MIT license](LICENSE).
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in Tokio by you, shall be licensed as MIT, without any additional
|
||||
terms or conditions.
|
||||
24
third-party/vendor/tracing/benches/baseline.rs
vendored
Normal file
24
third-party/vendor/tracing/benches/baseline.rs
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
|
||||
fn bench(c: &mut Criterion) {
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
let mut group = c.benchmark_group("comparison");
|
||||
group.bench_function("relaxed_load", |b| {
|
||||
let foo = AtomicUsize::new(1);
|
||||
b.iter(|| black_box(foo.load(Ordering::Relaxed)));
|
||||
});
|
||||
group.bench_function("acquire_load", |b| {
|
||||
let foo = AtomicUsize::new(1);
|
||||
b.iter(|| black_box(foo.load(Ordering::Acquire)))
|
||||
});
|
||||
group.bench_function("log", |b| {
|
||||
b.iter(|| {
|
||||
log::log!(log::Level::Info, "log");
|
||||
})
|
||||
});
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench);
|
||||
criterion_main!(benches);
|
||||
15
third-party/vendor/tracing/benches/dispatch_get_clone.rs
vendored
Normal file
15
third-party/vendor/tracing/benches/dispatch_get_clone.rs
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
|
||||
mod shared;
|
||||
|
||||
fn bench(c: &mut Criterion) {
|
||||
shared::for_all_dispatches(&mut c.benchmark_group("Dispatch::get_clone"), |b| {
|
||||
b.iter(|| {
|
||||
let current = tracing::dispatcher::get_default(|current| current.clone());
|
||||
black_box(current);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench);
|
||||
criterion_main!(benches);
|
||||
16
third-party/vendor/tracing/benches/dispatch_get_ref.rs
vendored
Normal file
16
third-party/vendor/tracing/benches/dispatch_get_ref.rs
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
|
||||
mod shared;
|
||||
|
||||
fn bench(c: &mut Criterion) {
|
||||
shared::for_all_dispatches(&mut c.benchmark_group("Dispatch::get_ref"), |b| {
|
||||
b.iter(|| {
|
||||
tracing::dispatcher::get_default(|current| {
|
||||
black_box(¤t);
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench);
|
||||
criterion_main!(benches);
|
||||
43
third-party/vendor/tracing/benches/empty_span.rs
vendored
Normal file
43
third-party/vendor/tracing/benches/empty_span.rs
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
|
||||
mod shared;
|
||||
|
||||
fn bench(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("empty_span");
|
||||
shared::for_all_dispatches(&mut group, |b| {
|
||||
b.iter(|| {
|
||||
let span = tracing::span::Span::none();
|
||||
black_box(&span);
|
||||
})
|
||||
});
|
||||
group.bench_function("baseline_struct", |b| {
|
||||
b.iter(|| {
|
||||
let span = FakeEmptySpan::new();
|
||||
black_box(&span);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
struct FakeEmptySpan {
|
||||
inner: Option<(usize, std::sync::Arc<()>)>,
|
||||
meta: Option<&'static ()>,
|
||||
}
|
||||
|
||||
impl FakeEmptySpan {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
inner: None,
|
||||
meta: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for FakeEmptySpan {
|
||||
fn drop(&mut self) {
|
||||
black_box(&self.inner);
|
||||
black_box(&self.meta);
|
||||
}
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench);
|
||||
criterion_main!(benches);
|
||||
16
third-party/vendor/tracing/benches/enter_span.rs
vendored
Normal file
16
third-party/vendor/tracing/benches/enter_span.rs
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use tracing::{span, Level};
|
||||
|
||||
mod shared;
|
||||
|
||||
fn bench(c: &mut Criterion) {
|
||||
shared::for_all_dispatches(&mut c.benchmark_group("enter_span"), |b| {
|
||||
let span = span!(Level::TRACE, "span");
|
||||
b.iter(|| {
|
||||
let _span = span.enter();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench);
|
||||
criterion_main!(benches);
|
||||
12
third-party/vendor/tracing/benches/event.rs
vendored
Normal file
12
third-party/vendor/tracing/benches/event.rs
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
|
||||
mod shared;
|
||||
|
||||
fn bench(c: &mut Criterion) {
|
||||
shared::for_all_recording(&mut c.benchmark_group("event"), |b| {
|
||||
b.iter(|| tracing::info!("hello world!"))
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench);
|
||||
criterion_main!(benches);
|
||||
160
third-party/vendor/tracing/benches/shared.rs
vendored
Normal file
160
third-party/vendor/tracing/benches/shared.rs
vendored
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
#![allow(dead_code)]
|
||||
use criterion::{black_box, measurement::WallTime, Bencher};
|
||||
use tracing::{field, span, Event, Id, Metadata};
|
||||
|
||||
use std::{
|
||||
fmt::{self, Write},
|
||||
sync::{Mutex, MutexGuard},
|
||||
};
|
||||
|
||||
pub fn for_all_recording(
|
||||
group: &mut criterion::BenchmarkGroup<'_, WallTime>,
|
||||
mut iter: impl FnMut(&mut Bencher<'_, WallTime>),
|
||||
) {
|
||||
// first, run benchmarks with no subscriber
|
||||
group.bench_function("none", &mut iter);
|
||||
|
||||
// then, run benchmarks with a scoped default subscriber
|
||||
tracing::subscriber::with_default(EnabledSubscriber, || {
|
||||
group.bench_function("scoped", &mut iter)
|
||||
});
|
||||
|
||||
let subscriber = VisitingSubscriber(Mutex::new(String::from("")));
|
||||
tracing::subscriber::with_default(subscriber, || {
|
||||
group.bench_function("scoped_recording", &mut iter);
|
||||
});
|
||||
|
||||
// finally, set a global default subscriber, and run the benchmarks again.
|
||||
tracing::subscriber::set_global_default(EnabledSubscriber)
|
||||
.expect("global default should not have already been set!");
|
||||
let _ = log::set_logger(&NOP_LOGGER);
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
group.bench_function("global", &mut iter);
|
||||
}
|
||||
|
||||
pub fn for_all_dispatches(
|
||||
group: &mut criterion::BenchmarkGroup<'_, WallTime>,
|
||||
mut iter: impl FnMut(&mut Bencher<'_, WallTime>),
|
||||
) {
|
||||
// first, run benchmarks with no subscriber
|
||||
group.bench_function("none", &mut iter);
|
||||
|
||||
// then, run benchmarks with a scoped default subscriber
|
||||
tracing::subscriber::with_default(EnabledSubscriber, || {
|
||||
group.bench_function("scoped", &mut iter)
|
||||
});
|
||||
|
||||
// finally, set a global default subscriber, and run the benchmarks again.
|
||||
tracing::subscriber::set_global_default(EnabledSubscriber)
|
||||
.expect("global default should not have already been set!");
|
||||
let _ = log::set_logger(&NOP_LOGGER);
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
group.bench_function("global", &mut iter);
|
||||
}
|
||||
|
||||
const NOP_LOGGER: NopLogger = NopLogger;
|
||||
|
||||
struct NopLogger;
|
||||
|
||||
impl log::Log for NopLogger {
|
||||
fn enabled(&self, _metadata: &log::Metadata) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn log(&self, record: &log::Record) {
|
||||
if self.enabled(record.metadata()) {
|
||||
let mut this = self;
|
||||
let _ = write!(this, "{}", record.args());
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&self) {}
|
||||
}
|
||||
|
||||
impl Write for &NopLogger {
|
||||
fn write_str(&mut self, s: &str) -> std::fmt::Result {
|
||||
black_box(s);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Simulates a subscriber that records span data.
|
||||
struct VisitingSubscriber(Mutex<String>);
|
||||
|
||||
struct Visitor<'a>(MutexGuard<'a, String>);
|
||||
|
||||
impl<'a> field::Visit for Visitor<'a> {
|
||||
fn record_debug(&mut self, _field: &field::Field, value: &dyn fmt::Debug) {
|
||||
let _ = write!(&mut *self.0, "{:?}", value);
|
||||
}
|
||||
}
|
||||
|
||||
impl tracing::Subscriber for VisitingSubscriber {
|
||||
fn new_span(&self, span: &span::Attributes<'_>) -> Id {
|
||||
let mut visitor = Visitor(self.0.lock().unwrap());
|
||||
span.record(&mut visitor);
|
||||
Id::from_u64(0xDEAD_FACE)
|
||||
}
|
||||
|
||||
fn record(&self, _span: &Id, values: &span::Record<'_>) {
|
||||
let mut visitor = Visitor(self.0.lock().unwrap());
|
||||
values.record(&mut visitor);
|
||||
}
|
||||
|
||||
fn event(&self, event: &Event<'_>) {
|
||||
let mut visitor = Visitor(self.0.lock().unwrap());
|
||||
event.record(&mut visitor);
|
||||
}
|
||||
|
||||
fn record_follows_from(&self, span: &Id, follows: &Id) {
|
||||
let _ = (span, follows);
|
||||
}
|
||||
|
||||
fn enabled(&self, metadata: &Metadata<'_>) -> bool {
|
||||
let _ = metadata;
|
||||
true
|
||||
}
|
||||
|
||||
fn enter(&self, span: &Id) {
|
||||
let _ = span;
|
||||
}
|
||||
|
||||
fn exit(&self, span: &Id) {
|
||||
let _ = span;
|
||||
}
|
||||
}
|
||||
|
||||
/// A subscriber that is enabled but otherwise does nothing.
|
||||
struct EnabledSubscriber;
|
||||
|
||||
impl tracing::Subscriber for EnabledSubscriber {
|
||||
fn new_span(&self, span: &span::Attributes<'_>) -> Id {
|
||||
let _ = span;
|
||||
Id::from_u64(0xDEAD_FACE)
|
||||
}
|
||||
|
||||
fn event(&self, event: &Event<'_>) {
|
||||
let _ = event;
|
||||
}
|
||||
|
||||
fn record(&self, span: &Id, values: &span::Record<'_>) {
|
||||
let _ = (span, values);
|
||||
}
|
||||
|
||||
fn record_follows_from(&self, span: &Id, follows: &Id) {
|
||||
let _ = (span, follows);
|
||||
}
|
||||
|
||||
fn enabled(&self, metadata: &Metadata<'_>) -> bool {
|
||||
let _ = metadata;
|
||||
true
|
||||
}
|
||||
|
||||
fn enter(&self, span: &Id) {
|
||||
let _ = span;
|
||||
}
|
||||
|
||||
fn exit(&self, span: &Id) {
|
||||
let _ = span;
|
||||
}
|
||||
}
|
||||
23
third-party/vendor/tracing/benches/span_fields.rs
vendored
Normal file
23
third-party/vendor/tracing/benches/span_fields.rs
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use tracing::{span, Level};
|
||||
|
||||
mod shared;
|
||||
|
||||
fn bench(c: &mut Criterion) {
|
||||
shared::for_all_recording(&mut c.benchmark_group("span_fields"), |b| {
|
||||
b.iter(|| {
|
||||
let span = span!(
|
||||
Level::TRACE,
|
||||
"span",
|
||||
foo = "foo",
|
||||
bar = "bar",
|
||||
baz = 3,
|
||||
quuux = tracing::field::debug(0.99)
|
||||
);
|
||||
criterion::black_box(span)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench);
|
||||
criterion_main!(benches);
|
||||
13
third-party/vendor/tracing/benches/span_no_fields.rs
vendored
Normal file
13
third-party/vendor/tracing/benches/span_no_fields.rs
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use tracing::{span, Level};
|
||||
|
||||
mod shared;
|
||||
|
||||
fn bench(c: &mut Criterion) {
|
||||
shared::for_all_recording(&mut c.benchmark_group("span_no_fields"), |b| {
|
||||
b.iter(|| span!(Level::TRACE, "span"))
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench);
|
||||
criterion_main!(benches);
|
||||
20
third-party/vendor/tracing/benches/span_repeated.rs
vendored
Normal file
20
third-party/vendor/tracing/benches/span_repeated.rs
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use tracing::{span, Level};
|
||||
|
||||
mod shared;
|
||||
|
||||
fn bench(c: &mut Criterion) {
|
||||
shared::for_all_recording(&mut c.benchmark_group("span_repeated"), |b| {
|
||||
let n = black_box(N_SPANS);
|
||||
b.iter(|| (0..n).fold(mk_span(0), |_, i| mk_span(i as u64)))
|
||||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn mk_span(i: u64) -> tracing::Span {
|
||||
span!(Level::TRACE, "span", i = i)
|
||||
}
|
||||
|
||||
const N_SPANS: usize = 100;
|
||||
criterion_group!(benches, bench);
|
||||
criterion_main!(benches);
|
||||
145
third-party/vendor/tracing/src/dispatcher.rs
vendored
Normal file
145
third-party/vendor/tracing/src/dispatcher.rs
vendored
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
//! Dispatches trace events to [`Subscriber`]s.
|
||||
//!
|
||||
//! The _dispatcher_ is the component of the tracing system which is responsible
|
||||
//! for forwarding trace data from the instrumentation points that generate it
|
||||
//! to the subscriber that collects it.
|
||||
//!
|
||||
//! # Using the Trace Dispatcher
|
||||
//!
|
||||
//! Every thread in a program using `tracing` has a _default subscriber_. When
|
||||
//! events occur, or spans are created, they are dispatched to the thread's
|
||||
//! current subscriber.
|
||||
//!
|
||||
//! ## Setting the Default Subscriber
|
||||
//!
|
||||
//! By default, the current subscriber is an empty implementation that does
|
||||
//! nothing. To use a subscriber implementation, it must be set as the default.
|
||||
//! There are two methods for doing so: [`with_default`] and
|
||||
//! [`set_global_default`]. `with_default` sets the default subscriber for the
|
||||
//! duration of a scope, while `set_global_default` sets a default subscriber
|
||||
//! for the entire process.
|
||||
//!
|
||||
//! To use either of these functions, we must first wrap our subscriber in a
|
||||
//! [`Dispatch`], a cloneable, type-erased reference to a subscriber. For
|
||||
//! example:
|
||||
//! ```rust
|
||||
//! # pub struct FooSubscriber;
|
||||
//! # use tracing_core::{
|
||||
//! # dispatcher, Event, Metadata,
|
||||
//! # span::{Attributes, Id, Record}
|
||||
//! # };
|
||||
//! # impl tracing_core::Subscriber for FooSubscriber {
|
||||
//! # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
|
||||
//! # fn record(&self, _: &Id, _: &Record) {}
|
||||
//! # fn event(&self, _: &Event) {}
|
||||
//! # fn record_follows_from(&self, _: &Id, _: &Id) {}
|
||||
//! # fn enabled(&self, _: &Metadata) -> bool { false }
|
||||
//! # fn enter(&self, _: &Id) {}
|
||||
//! # fn exit(&self, _: &Id) {}
|
||||
//! # }
|
||||
//! # impl FooSubscriber { fn new() -> Self { FooSubscriber } }
|
||||
//! use dispatcher::Dispatch;
|
||||
//!
|
||||
//! let my_subscriber = FooSubscriber::new();
|
||||
//! let my_dispatch = Dispatch::new(my_subscriber);
|
||||
//! ```
|
||||
//! Then, we can use [`with_default`] to set our `Dispatch` as the default for
|
||||
//! the duration of a block:
|
||||
//! ```rust
|
||||
//! # pub struct FooSubscriber;
|
||||
//! # use tracing_core::{
|
||||
//! # dispatcher, Event, Metadata,
|
||||
//! # span::{Attributes, Id, Record}
|
||||
//! # };
|
||||
//! # impl tracing_core::Subscriber for FooSubscriber {
|
||||
//! # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
|
||||
//! # fn record(&self, _: &Id, _: &Record) {}
|
||||
//! # fn event(&self, _: &Event) {}
|
||||
//! # fn record_follows_from(&self, _: &Id, _: &Id) {}
|
||||
//! # fn enabled(&self, _: &Metadata) -> bool { false }
|
||||
//! # fn enter(&self, _: &Id) {}
|
||||
//! # fn exit(&self, _: &Id) {}
|
||||
//! # }
|
||||
//! # impl FooSubscriber { fn new() -> Self { FooSubscriber } }
|
||||
//! # let my_subscriber = FooSubscriber::new();
|
||||
//! # let my_dispatch = dispatcher::Dispatch::new(my_subscriber);
|
||||
//! // no default subscriber
|
||||
//!
|
||||
//! # #[cfg(feature = "std")]
|
||||
//! dispatcher::with_default(&my_dispatch, || {
|
||||
//! // my_subscriber is the default
|
||||
//! });
|
||||
//!
|
||||
//! // no default subscriber again
|
||||
//! ```
|
||||
//! It's important to note that `with_default` will not propagate the current
|
||||
//! thread's default subscriber to any threads spawned within the `with_default`
|
||||
//! block. To propagate the default subscriber to new threads, either use
|
||||
//! `with_default` from the new thread, or use `set_global_default`.
|
||||
//!
|
||||
//! As an alternative to `with_default`, we can use [`set_global_default`] to
|
||||
//! set a `Dispatch` as the default for all threads, for the lifetime of the
|
||||
//! program. For example:
|
||||
//! ```rust
|
||||
//! # pub struct FooSubscriber;
|
||||
//! # use tracing_core::{
|
||||
//! # dispatcher, Event, Metadata,
|
||||
//! # span::{Attributes, Id, Record}
|
||||
//! # };
|
||||
//! # impl tracing_core::Subscriber for FooSubscriber {
|
||||
//! # fn new_span(&self, _: &Attributes) -> Id { Id::from_u64(0) }
|
||||
//! # fn record(&self, _: &Id, _: &Record) {}
|
||||
//! # fn event(&self, _: &Event) {}
|
||||
//! # fn record_follows_from(&self, _: &Id, _: &Id) {}
|
||||
//! # fn enabled(&self, _: &Metadata) -> bool { false }
|
||||
//! # fn enter(&self, _: &Id) {}
|
||||
//! # fn exit(&self, _: &Id) {}
|
||||
//! # }
|
||||
//! # impl FooSubscriber { fn new() -> Self { FooSubscriber } }
|
||||
//! # let my_subscriber = FooSubscriber::new();
|
||||
//! # let my_dispatch = dispatcher::Dispatch::new(my_subscriber);
|
||||
//! // no default subscriber
|
||||
//!
|
||||
//! dispatcher::set_global_default(my_dispatch)
|
||||
//! // `set_global_default` will return an error if the global default
|
||||
//! // subscriber has already been set.
|
||||
//! .expect("global default was already set!");
|
||||
//!
|
||||
//! // `my_subscriber` is now the default
|
||||
//! ```
|
||||
//!
|
||||
//! <pre class="ignore" style="white-space:normal;font:inherit;">
|
||||
//! <strong>Note</strong>: The thread-local scoped dispatcher (<code>with_default</code>)
|
||||
//! requires the Rust standard library. <code>no_std</code> users should
|
||||
//! use <a href="fn.set_global_default.html"><code>set_global_default</code></a>
|
||||
//! instead.
|
||||
//! </pre>
|
||||
//!
|
||||
//! ## Accessing the Default Subscriber
|
||||
//!
|
||||
//! A thread's current default subscriber can be accessed using the
|
||||
//! [`get_default`] function, which executes a closure with a reference to the
|
||||
//! currently default `Dispatch`. This is used primarily by `tracing`
|
||||
//! instrumentation.
|
||||
//!
|
||||
//! [`Subscriber`]: crate::Subscriber
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
pub use tracing_core::dispatcher::set_default;
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
pub use tracing_core::dispatcher::with_default;
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
pub use tracing_core::dispatcher::DefaultGuard;
|
||||
pub use tracing_core::dispatcher::{
|
||||
get_default, set_global_default, Dispatch, SetGlobalDefaultError, WeakDispatch,
|
||||
};
|
||||
|
||||
/// Private API for internal use by tracing's macros.
|
||||
///
|
||||
/// This function is *not* considered part of `tracing`'s public API, and has no
|
||||
/// stability guarantees. If you use it, and it breaks or disappears entirely,
|
||||
/// don't say we didn;'t warn you.
|
||||
#[doc(hidden)]
|
||||
pub use tracing_core::dispatcher::has_been_set;
|
||||
170
third-party/vendor/tracing/src/field.rs
vendored
Normal file
170
third-party/vendor/tracing/src/field.rs
vendored
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
//! `Span` and `Event` key-value data.
|
||||
//!
|
||||
//! Spans and events may be annotated with key-value data, referred to as _fields_.
|
||||
//! These fields consist of a mapping from a key (corresponding to
|
||||
//! a `&str` but represented internally as an array index) to a [`Value`].
|
||||
//!
|
||||
//! # `Value`s and `Subscriber`s
|
||||
//!
|
||||
//! `Subscriber`s consume `Value`s as fields attached to [span]s or [`Event`]s.
|
||||
//! The set of field keys on a given span or event is defined on its [`Metadata`].
|
||||
//! When a span is created, it provides [`Attributes`] to the `Subscriber`'s
|
||||
//! [`new_span`] method, containing any fields whose values were provided when
|
||||
//! the span was created; and may call the `Subscriber`'s [`record`] method
|
||||
//! with additional [`Record`]s if values are added for more of its fields.
|
||||
//! Similarly, the [`Event`] type passed to the subscriber's [`event`] method
|
||||
//! will contain any fields attached to each event.
|
||||
//!
|
||||
//! `tracing` represents values as either one of a set of Rust primitives
|
||||
//! (`i64`, `u64`, `f64`, `bool`, and `&str`) or using a `fmt::Display` or
|
||||
//! `fmt::Debug` implementation. `Subscriber`s are provided these primitive
|
||||
//! value types as `dyn Value` trait objects.
|
||||
//!
|
||||
//! These trait objects can be formatted using `fmt::Debug`, but may also be
|
||||
//! recorded as typed data by calling the [`Value::record`] method on these
|
||||
//! trait objects with a _visitor_ implementing the [`Visit`] trait. This trait
|
||||
//! represents the behavior used to record values of various types. For example,
|
||||
//! an implementation of `Visit` might record integers by incrementing counters
|
||||
//! for their field names rather than printing them.
|
||||
//!
|
||||
//!
|
||||
//! # Using `valuable`
|
||||
//!
|
||||
//! `tracing`'s [`Value`] trait is intentionally minimalist: it supports only a small
|
||||
//! number of Rust primitives as typed values, and only permits recording
|
||||
//! user-defined types with their [`fmt::Debug`] or [`fmt::Display`]
|
||||
//! implementations. However, there are some cases where it may be useful to record
|
||||
//! nested values (such as arrays, `Vec`s, or `HashMap`s containing values), or
|
||||
//! user-defined `struct` and `enum` types without having to format them as
|
||||
//! unstructured text.
|
||||
//!
|
||||
//! To address `Value`'s limitations, `tracing` offers experimental support for
|
||||
//! the [`valuable`] crate, which provides object-safe inspection of structured
|
||||
//! values. User-defined types can implement the [`valuable::Valuable`] trait,
|
||||
//! and be recorded as a `tracing` field by calling their [`as_value`] method.
|
||||
//! If the [`Subscriber`] also supports the `valuable` crate, it can
|
||||
//! then visit those types fields as structured values using `valuable`.
|
||||
//!
|
||||
//! <pre class="ignore" style="white-space:normal;font:inherit;">
|
||||
//! <strong>Note</strong>: <code>valuable</code> support is an
|
||||
//! <a href = "../index.html#unstable-features">unstable feature</a>. See
|
||||
//! the documentation on unstable features for details on how to enable it.
|
||||
//! </pre>
|
||||
//!
|
||||
//! For example:
|
||||
//! ```ignore
|
||||
//! // Derive `Valuable` for our types:
|
||||
//! use valuable::Valuable;
|
||||
//!
|
||||
//! #[derive(Clone, Debug, Valuable)]
|
||||
//! struct User {
|
||||
//! name: String,
|
||||
//! age: u32,
|
||||
//! address: Address,
|
||||
//! }
|
||||
//!
|
||||
//! #[derive(Clone, Debug, Valuable)]
|
||||
//! struct Address {
|
||||
//! country: String,
|
||||
//! city: String,
|
||||
//! street: String,
|
||||
//! }
|
||||
//!
|
||||
//! let user = User {
|
||||
//! name: "Arwen Undomiel".to_string(),
|
||||
//! age: 3000,
|
||||
//! address: Address {
|
||||
//! country: "Middle Earth".to_string(),
|
||||
//! city: "Rivendell".to_string(),
|
||||
//! street: "leafy lane".to_string(),
|
||||
//! },
|
||||
//! };
|
||||
//!
|
||||
//! // Recording `user` as a `valuable::Value` will allow the `tracing` subscriber
|
||||
//! // to traverse its fields as a nested, typed structure:
|
||||
//! tracing::info!(current_user = user.as_value());
|
||||
//! ```
|
||||
//!
|
||||
//! Alternatively, the [`valuable()`] function may be used to convert a type
|
||||
//! implementing [`Valuable`] into a `tracing` field value.
|
||||
//!
|
||||
//! When the `valuable` feature is enabled, the [`Visit`] trait will include an
|
||||
//! optional [`record_value`] method. `Visit` implementations that wish to
|
||||
//! record `valuable` values can implement this method with custom behavior.
|
||||
//! If a visitor does not implement `record_value`, the [`valuable::Value`] will
|
||||
//! be forwarded to the visitor's [`record_debug`] method.
|
||||
//!
|
||||
//! [`fmt::Debug`]: std::fmt::Debug
|
||||
//! [`fmt::Display`]: std::fmt::Debug
|
||||
//! [`valuable`]: https://crates.io/crates/valuable
|
||||
//! [`valuable::Valuable`]: https://docs.rs/valuable/latest/valuable/trait.Valuable.html
|
||||
//! [`as_value`]: https://docs.rs/valuable/latest/valuable/trait.Valuable.html#tymethod.as_value
|
||||
//! [`valuable::Value`]: https://docs.rs/valuable/latest/valuable/enum.Value.html
|
||||
//! [`Subscriber`]: crate::Subscriber
|
||||
//! [`record_value`]: Visit::record_value
|
||||
//! [`record_debug`]: Visit::record_debug
|
||||
//! [span]: mod@crate::span
|
||||
//! [`Event`]: crate::event::Event
|
||||
//! [`Metadata`]: crate::Metadata
|
||||
//! [`Attributes`]: crate::span::Attributes
|
||||
//! [`Record`]: crate::span::Record
|
||||
//! [`new_span`]: crate::Subscriber::new_span
|
||||
//! [`record`]: crate::Subscriber::record
|
||||
//! [`event`]: crate::Subscriber::event
|
||||
pub use tracing_core::field::*;
|
||||
|
||||
use crate::Metadata;
|
||||
|
||||
/// Trait implemented to allow a type to be used as a field key.
|
||||
///
|
||||
/// <pre class="ignore" style="white-space:normal;font:inherit;">
|
||||
/// <strong>Note</strong>: Although this is implemented for both the
|
||||
/// <a href="./struct.Field.html"><code>Field</code></a> type <em>and</em> any
|
||||
/// type that can be borrowed as an <code>&str</code>, only <code>Field</code>
|
||||
/// allows <em>O</em>(1) access.
|
||||
/// Indexing a field with a string results in an iterative search that performs
|
||||
/// string comparisons. Thus, if possible, once the key for a field is known, it
|
||||
/// should be used whenever possible.
|
||||
/// </pre>
|
||||
pub trait AsField: crate::sealed::Sealed {
|
||||
/// Attempts to convert `&self` into a `Field` with the specified `metadata`.
|
||||
///
|
||||
/// If `metadata` defines this field, then the field is returned. Otherwise,
|
||||
/// this returns `None`.
|
||||
fn as_field(&self, metadata: &Metadata<'_>) -> Option<Field>;
|
||||
}
|
||||
|
||||
// ===== impl AsField =====
|
||||
|
||||
impl AsField for Field {
|
||||
#[inline]
|
||||
fn as_field(&self, metadata: &Metadata<'_>) -> Option<Field> {
|
||||
if self.callsite() == metadata.callsite() {
|
||||
Some(self.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AsField for &'a Field {
|
||||
#[inline]
|
||||
fn as_field(&self, metadata: &Metadata<'_>) -> Option<Field> {
|
||||
if self.callsite() == metadata.callsite() {
|
||||
Some((*self).clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsField for str {
|
||||
#[inline]
|
||||
fn as_field(&self, metadata: &Metadata<'_>) -> Option<Field> {
|
||||
metadata.fields().field(&self)
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::sealed::Sealed for Field {}
|
||||
impl<'a> crate::sealed::Sealed for &'a Field {}
|
||||
impl crate::sealed::Sealed for str {}
|
||||
429
third-party/vendor/tracing/src/instrument.rs
vendored
Normal file
429
third-party/vendor/tracing/src/instrument.rs
vendored
Normal file
|
|
@ -0,0 +1,429 @@
|
|||
use crate::{
|
||||
dispatcher::{self, Dispatch},
|
||||
span::Span,
|
||||
};
|
||||
use core::{
|
||||
future::Future,
|
||||
marker::Sized,
|
||||
mem::ManuallyDrop,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use pin_project_lite::pin_project;
|
||||
|
||||
/// Attaches spans to a [`std::future::Future`].
|
||||
///
|
||||
/// Extension trait allowing futures to be
|
||||
/// instrumented with a `tracing` [span].
|
||||
///
|
||||
/// [span]: super::Span
|
||||
pub trait Instrument: Sized {
|
||||
/// Instruments this type with the provided [`Span`], returning an
|
||||
/// `Instrumented` wrapper.
|
||||
///
|
||||
/// The attached [`Span`] will be [entered] every time the instrumented
|
||||
/// [`Future`] is polled or [`Drop`]ped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Instrumenting a future:
|
||||
///
|
||||
/// ```rust
|
||||
/// use tracing::Instrument;
|
||||
///
|
||||
/// # async fn doc() {
|
||||
/// let my_future = async {
|
||||
/// // ...
|
||||
/// };
|
||||
///
|
||||
/// my_future
|
||||
/// .instrument(tracing::info_span!("my_future"))
|
||||
/// .await
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// The [`Span::or_current`] combinator can be used in combination with
|
||||
/// `instrument` to ensure that the [current span] is attached to the
|
||||
/// future if the span passed to `instrument` is [disabled]:
|
||||
///
|
||||
/// ```
|
||||
/// use tracing::Instrument;
|
||||
/// # mod tokio {
|
||||
/// # pub(super) fn spawn(_: impl std::future::Future) {}
|
||||
/// # }
|
||||
///
|
||||
/// let my_future = async {
|
||||
/// // ...
|
||||
/// };
|
||||
///
|
||||
/// let outer_span = tracing::info_span!("outer").entered();
|
||||
///
|
||||
/// // If the "my_future" span is enabled, then the spawned task will
|
||||
/// // be within both "my_future" *and* "outer", since "outer" is
|
||||
/// // "my_future"'s parent. However, if "my_future" is disabled,
|
||||
/// // the spawned task will *not* be in any span.
|
||||
/// tokio::spawn(
|
||||
/// my_future
|
||||
/// .instrument(tracing::debug_span!("my_future"))
|
||||
/// );
|
||||
///
|
||||
/// // Using `Span::or_current` ensures the spawned task is instrumented
|
||||
/// // with the current span, if the new span passed to `instrument` is
|
||||
/// // not enabled. This means that if the "my_future" span is disabled,
|
||||
/// // the spawned task will still be instrumented with the "outer" span:
|
||||
/// # let my_future = async {};
|
||||
/// tokio::spawn(
|
||||
/// my_future
|
||||
/// .instrument(tracing::debug_span!("my_future").or_current())
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// [entered]: super::Span::enter()
|
||||
/// [`Span::or_current`]: super::Span::or_current()
|
||||
/// [current span]: super::Span::current()
|
||||
/// [disabled]: super::Span::is_disabled()
|
||||
/// [`Future`]: std::future::Future
|
||||
fn instrument(self, span: Span) -> Instrumented<Self> {
|
||||
Instrumented {
|
||||
inner: ManuallyDrop::new(self),
|
||||
span,
|
||||
}
|
||||
}
|
||||
|
||||
/// Instruments this type with the [current] [`Span`], returning an
|
||||
/// `Instrumented` wrapper.
|
||||
///
|
||||
/// The attached [`Span`] will be [entered] every time the instrumented
|
||||
/// [`Future`] is polled or [`Drop`]ped.
|
||||
///
|
||||
/// This can be used to propagate the current span when spawning a new future.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use tracing::Instrument;
|
||||
///
|
||||
/// # mod tokio {
|
||||
/// # pub(super) fn spawn(_: impl std::future::Future) {}
|
||||
/// # }
|
||||
/// # async fn doc() {
|
||||
/// let span = tracing::info_span!("my_span");
|
||||
/// let _enter = span.enter();
|
||||
///
|
||||
/// // ...
|
||||
///
|
||||
/// let future = async {
|
||||
/// tracing::debug!("this event will occur inside `my_span`");
|
||||
/// // ...
|
||||
/// };
|
||||
/// tokio::spawn(future.in_current_span());
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [current]: super::Span::current()
|
||||
/// [entered]: super::Span::enter()
|
||||
/// [`Span`]: crate::Span
|
||||
/// [`Future`]: std::future::Future
|
||||
#[inline]
|
||||
fn in_current_span(self) -> Instrumented<Self> {
|
||||
self.instrument(Span::current())
|
||||
}
|
||||
}
|
||||
|
||||
/// Extension trait allowing futures to be instrumented with
|
||||
/// a `tracing` [`Subscriber`](crate::Subscriber).
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
pub trait WithSubscriber: Sized {
|
||||
/// Attaches the provided [`Subscriber`] to this type, returning a
|
||||
/// [`WithDispatch`] wrapper.
|
||||
///
|
||||
/// The attached [`Subscriber`] will be set as the [default] when the returned
|
||||
/// [`Future`] is polled.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use tracing::subscriber::NoSubscriber as MySubscriber;
|
||||
/// # use tracing::subscriber::NoSubscriber as MyOtherSubscriber;
|
||||
/// # async fn docs() {
|
||||
/// use tracing::instrument::WithSubscriber;
|
||||
///
|
||||
/// // Set the default `Subscriber`
|
||||
/// let _default = tracing::subscriber::set_default(MySubscriber::default());
|
||||
///
|
||||
/// tracing::info!("this event will be recorded by the default `Subscriber`");
|
||||
///
|
||||
/// // Create a different `Subscriber` and attach it to a future.
|
||||
/// let other_subscriber = MyOtherSubscriber::default();
|
||||
/// let future = async {
|
||||
/// tracing::info!("this event will be recorded by the other `Subscriber`");
|
||||
/// // ...
|
||||
/// };
|
||||
///
|
||||
/// future
|
||||
/// // Attach the other `Subscriber` to the future before awaiting it
|
||||
/// .with_subscriber(other_subscriber)
|
||||
/// .await;
|
||||
///
|
||||
/// // Once the future has completed, we return to the default `Subscriber`.
|
||||
/// tracing::info!("this event will be recorded by the default `Subscriber`");
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`Subscriber`]: super::Subscriber
|
||||
/// [default]: crate::dispatcher#setting-the-default-subscriber
|
||||
/// [`Future`]: std::future::Future
|
||||
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
|
||||
where
|
||||
S: Into<Dispatch>,
|
||||
{
|
||||
WithDispatch {
|
||||
inner: self,
|
||||
dispatcher: subscriber.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Attaches the current [default] [`Subscriber`] to this type, returning a
|
||||
/// [`WithDispatch`] wrapper.
|
||||
///
|
||||
/// The attached `Subscriber` will be set as the [default] when the returned
|
||||
/// [`Future`] is polled.
|
||||
///
|
||||
/// This can be used to propagate the current dispatcher context when
|
||||
/// spawning a new future that may run on a different thread.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # mod tokio {
|
||||
/// # pub(super) fn spawn(_: impl std::future::Future) {}
|
||||
/// # }
|
||||
/// # use tracing::subscriber::NoSubscriber as MySubscriber;
|
||||
/// # async fn docs() {
|
||||
/// use tracing::instrument::WithSubscriber;
|
||||
///
|
||||
/// // Using `set_default` (rather than `set_global_default`) sets the
|
||||
/// // default `Subscriber` for *this* thread only.
|
||||
/// let _default = tracing::subscriber::set_default(MySubscriber::default());
|
||||
///
|
||||
/// let future = async {
|
||||
/// // ...
|
||||
/// };
|
||||
///
|
||||
/// // If a multi-threaded async runtime is in use, this spawned task may
|
||||
/// // run on a different thread, in a different default `Subscriber`'s context.
|
||||
/// tokio::spawn(future);
|
||||
///
|
||||
/// // However, calling `with_current_subscriber` on the future before
|
||||
/// // spawning it, ensures that the current thread's default `Subscriber` is
|
||||
/// // propagated to the spawned task, regardless of where it executes:
|
||||
/// # let future = async { };
|
||||
/// tokio::spawn(future.with_current_subscriber());
|
||||
/// # }
|
||||
/// ```
|
||||
/// [`Subscriber`]: super::Subscriber
|
||||
/// [default]: crate::dispatcher#setting-the-default-subscriber
|
||||
/// [`Future`]: std::future::Future
|
||||
#[inline]
|
||||
fn with_current_subscriber(self) -> WithDispatch<Self> {
|
||||
WithDispatch {
|
||||
inner: self,
|
||||
dispatcher: crate::dispatcher::get_default(|default| default.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin_project! {
|
||||
/// A [`Future`] that has been instrumented with a `tracing` [`Subscriber`].
|
||||
///
|
||||
/// This type is returned by the [`WithSubscriber`] extension trait. See that
|
||||
/// trait's documentation for details.
|
||||
///
|
||||
/// [`Future`]: std::future::Future
|
||||
/// [`Subscriber`]: crate::Subscriber
|
||||
#[derive(Clone, Debug)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
pub struct WithDispatch<T> {
|
||||
#[pin]
|
||||
inner: T,
|
||||
dispatcher: Dispatch,
|
||||
}
|
||||
}
|
||||
|
||||
pin_project! {
|
||||
/// A [`Future`] that has been instrumented with a `tracing` [`Span`].
|
||||
///
|
||||
/// This type is returned by the [`Instrument`] extension trait. See that
|
||||
/// trait's documentation for details.
|
||||
///
|
||||
/// [`Future`]: std::future::Future
|
||||
/// [`Span`]: crate::Span
|
||||
#[project = InstrumentedProj]
|
||||
#[project_ref = InstrumentedProjRef]
|
||||
#[derive(Debug, Clone)]
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub struct Instrumented<T> {
|
||||
// `ManuallyDrop` is used here to to enter instrument `Drop` by entering
|
||||
// `Span` and executing `ManuallyDrop::drop`.
|
||||
#[pin]
|
||||
inner: ManuallyDrop<T>,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl<T> PinnedDrop for Instrumented<T> {
|
||||
fn drop(this: Pin<&mut Self>) {
|
||||
let this = this.project();
|
||||
let _enter = this.span.enter();
|
||||
// SAFETY: 1. `Pin::get_unchecked_mut()` is safe, because this isn't
|
||||
// different from wrapping `T` in `Option` and calling
|
||||
// `Pin::set(&mut this.inner, None)`, except avoiding
|
||||
// additional memory overhead.
|
||||
// 2. `ManuallyDrop::drop()` is safe, because
|
||||
// `PinnedDrop::drop()` is guaranteed to be called only
|
||||
// once.
|
||||
unsafe { ManuallyDrop::drop(this.inner.get_unchecked_mut()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> InstrumentedProj<'a, T> {
|
||||
/// Get a mutable reference to the [`Span`] a pinned mutable reference to
|
||||
/// the wrapped type.
|
||||
fn span_and_inner_pin_mut(self) -> (&'a mut Span, Pin<&'a mut T>) {
|
||||
// SAFETY: As long as `ManuallyDrop<T>` does not move, `T` won't move
|
||||
// and `inner` is valid, because `ManuallyDrop::drop` is called
|
||||
// only inside `Drop` of the `Instrumented`.
|
||||
let inner = unsafe { self.inner.map_unchecked_mut(|v| &mut **v) };
|
||||
(self.span, inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> InstrumentedProjRef<'a, T> {
|
||||
/// Get a reference to the [`Span`] a pinned reference to the wrapped type.
|
||||
fn span_and_inner_pin_ref(self) -> (&'a Span, Pin<&'a T>) {
|
||||
// SAFETY: As long as `ManuallyDrop<T>` does not move, `T` won't move
|
||||
// and `inner` is valid, because `ManuallyDrop::drop` is called
|
||||
// only inside `Drop` of the `Instrumented`.
|
||||
let inner = unsafe { self.inner.map_unchecked(|v| &**v) };
|
||||
(self.span, inner)
|
||||
}
|
||||
}
|
||||
|
||||
// === impl Instrumented ===
|
||||
|
||||
impl<T: Future> Future for Instrumented<T> {
|
||||
type Output = T::Output;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let (span, inner) = self.project().span_and_inner_pin_mut();
|
||||
let _enter = span.enter();
|
||||
inner.poll(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Sized> Instrument for T {}
|
||||
|
||||
impl<T> Instrumented<T> {
|
||||
/// Borrows the `Span` that this type is instrumented by.
|
||||
pub fn span(&self) -> &Span {
|
||||
&self.span
|
||||
}
|
||||
|
||||
/// Mutably borrows the `Span` that this type is instrumented by.
|
||||
pub fn span_mut(&mut self) -> &mut Span {
|
||||
&mut self.span
|
||||
}
|
||||
|
||||
/// Borrows the wrapped type.
|
||||
pub fn inner(&self) -> &T {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
/// Mutably borrows the wrapped type.
|
||||
pub fn inner_mut(&mut self) -> &mut T {
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
/// Get a pinned reference to the wrapped type.
|
||||
pub fn inner_pin_ref(self: Pin<&Self>) -> Pin<&T> {
|
||||
self.project_ref().span_and_inner_pin_ref().1
|
||||
}
|
||||
|
||||
/// Get a pinned mutable reference to the wrapped type.
|
||||
pub fn inner_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
|
||||
self.project().span_and_inner_pin_mut().1
|
||||
}
|
||||
|
||||
/// Consumes the `Instrumented`, returning the wrapped type.
|
||||
///
|
||||
/// Note that this drops the span.
|
||||
pub fn into_inner(self) -> T {
|
||||
// To manually destructure `Instrumented` without `Drop`, we
|
||||
// move it into a ManuallyDrop and use pointers to its fields
|
||||
let this = ManuallyDrop::new(self);
|
||||
let span: *const Span = &this.span;
|
||||
let inner: *const ManuallyDrop<T> = &this.inner;
|
||||
// SAFETY: Those pointers are valid for reads, because `Drop` didn't
|
||||
// run, and properly aligned, because `Instrumented` isn't
|
||||
// `#[repr(packed)]`.
|
||||
let _span = unsafe { span.read() };
|
||||
let inner = unsafe { inner.read() };
|
||||
ManuallyDrop::into_inner(inner)
|
||||
}
|
||||
}
|
||||
|
||||
// === impl WithDispatch ===
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
impl<T: Future> Future for WithDispatch<T> {
|
||||
type Output = T::Output;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let this = self.project();
|
||||
let dispatcher = this.dispatcher;
|
||||
let future = this.inner;
|
||||
let _default = dispatcher::set_default(dispatcher);
|
||||
future.poll(cx)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
impl<T: Sized> WithSubscriber for T {}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
impl<T> WithDispatch<T> {
|
||||
/// Borrows the [`Dispatch`] that is entered when this type is polled.
|
||||
pub fn dispatcher(&self) -> &Dispatch {
|
||||
&self.dispatcher
|
||||
}
|
||||
|
||||
/// Borrows the wrapped type.
|
||||
pub fn inner(&self) -> &T {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
/// Mutably borrows the wrapped type.
|
||||
pub fn inner_mut(&mut self) -> &mut T {
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
/// Get a pinned reference to the wrapped type.
|
||||
pub fn inner_pin_ref(self: Pin<&Self>) -> Pin<&T> {
|
||||
self.project_ref().inner
|
||||
}
|
||||
|
||||
/// Get a pinned mutable reference to the wrapped type.
|
||||
pub fn inner_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
|
||||
self.project().inner
|
||||
}
|
||||
|
||||
/// Consumes the `Instrumented`, returning the wrapped type.
|
||||
///
|
||||
/// Note that this drops the span.
|
||||
pub fn into_inner(self) -> T {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
98
third-party/vendor/tracing/src/level_filters.rs
vendored
Normal file
98
third-party/vendor/tracing/src/level_filters.rs
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
//! Trace verbosity level filtering.
|
||||
//!
|
||||
//! # Compile time filters
|
||||
//!
|
||||
//! Trace verbosity levels can be statically disabled at compile time via Cargo
|
||||
//! features, similar to the [`log` crate]. Trace instrumentation at disabled
|
||||
//! levels will be skipped and will not even be present in the resulting binary
|
||||
//! unless the verbosity level is specified dynamically. This level is
|
||||
//! configured separately for release and debug builds. The features are:
|
||||
//!
|
||||
//! * `max_level_off`
|
||||
//! * `max_level_error`
|
||||
//! * `max_level_warn`
|
||||
//! * `max_level_info`
|
||||
//! * `max_level_debug`
|
||||
//! * `max_level_trace`
|
||||
//! * `release_max_level_off`
|
||||
//! * `release_max_level_error`
|
||||
//! * `release_max_level_warn`
|
||||
//! * `release_max_level_info`
|
||||
//! * `release_max_level_debug`
|
||||
//! * `release_max_level_trace`
|
||||
//!
|
||||
//! These features control the value of the `STATIC_MAX_LEVEL` constant. The
|
||||
//! instrumentation macros macros check this value before recording an event or
|
||||
//! constructing a span. By default, no levels are disabled.
|
||||
//!
|
||||
//! For example, a crate can disable trace level instrumentation in debug builds
|
||||
//! and trace, debug, and info level instrumentation in release builds with the
|
||||
//! following configuration:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! tracing = { version = "0.1", features = ["max_level_debug", "release_max_level_warn"] }
|
||||
//! ```
|
||||
//! ## Notes
|
||||
//!
|
||||
//! Please note that `tracing`'s static max level features do *not* control the
|
||||
//! [`log`] records that may be emitted when [`tracing`'s "log" feature flag][f] is
|
||||
//! enabled. This is to allow `tracing` to be disabled entirely at compile time
|
||||
//! while still emitting `log` records --- such as when a library using
|
||||
//! `tracing` is used by an application using `log` that doesn't want to
|
||||
//! generate any `tracing`-related code, but does want to collect `log` records.
|
||||
//!
|
||||
//! This means that if the "log" feature is in use, some code may be generated
|
||||
//! for `log` records emitted by disabled `tracing` events. If this is not
|
||||
//! desirable, `log` records may be disabled separately using [`log`'s static
|
||||
//! max level features][`log` crate].
|
||||
//!
|
||||
//! [`log`]: https://docs.rs/log/
|
||||
//! [`log` crate]: https://docs.rs/log/latest/log/#compile-time-filters
|
||||
//! [f]: https://docs.rs/tracing/latest/tracing/#emitting-log-records
|
||||
pub use tracing_core::{metadata::ParseLevelFilterError, LevelFilter};
|
||||
|
||||
/// The statically configured maximum trace level.
|
||||
///
|
||||
/// See the [module-level documentation] for information on how to configure
|
||||
/// this.
|
||||
///
|
||||
/// This value is checked by the `event!` and `span!` macros. Code that
|
||||
/// manually constructs events or spans via the `Event::record` function or
|
||||
/// `Span` constructors should compare the level against this value to
|
||||
/// determine if those spans or events are enabled.
|
||||
///
|
||||
/// [module-level documentation]: self#compile-time-filters
|
||||
pub const STATIC_MAX_LEVEL: LevelFilter = get_max_level_inner();
|
||||
|
||||
const fn get_max_level_inner() -> LevelFilter {
|
||||
if cfg!(not(debug_assertions)) {
|
||||
if cfg!(feature = "release_max_level_off") {
|
||||
LevelFilter::OFF
|
||||
} else if cfg!(feature = "release_max_level_error") {
|
||||
LevelFilter::ERROR
|
||||
} else if cfg!(feature = "release_max_level_warn") {
|
||||
LevelFilter::WARN
|
||||
} else if cfg!(feature = "release_max_level_info") {
|
||||
LevelFilter::INFO
|
||||
} else if cfg!(feature = "release_max_level_debug") {
|
||||
LevelFilter::DEBUG
|
||||
} else {
|
||||
// Same as branch cfg!(feature = "release_max_level_trace")
|
||||
LevelFilter::TRACE
|
||||
}
|
||||
} else if cfg!(feature = "max_level_off") {
|
||||
LevelFilter::OFF
|
||||
} else if cfg!(feature = "max_level_error") {
|
||||
LevelFilter::ERROR
|
||||
} else if cfg!(feature = "max_level_warn") {
|
||||
LevelFilter::WARN
|
||||
} else if cfg!(feature = "max_level_info") {
|
||||
LevelFilter::INFO
|
||||
} else if cfg!(feature = "max_level_debug") {
|
||||
LevelFilter::DEBUG
|
||||
} else {
|
||||
// Same as branch cfg!(feature = "max_level_trace")
|
||||
LevelFilter::TRACE
|
||||
}
|
||||
}
|
||||
1125
third-party/vendor/tracing/src/lib.rs
vendored
Normal file
1125
third-party/vendor/tracing/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
3165
third-party/vendor/tracing/src/macros.rs
vendored
Normal file
3165
third-party/vendor/tracing/src/macros.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
1623
third-party/vendor/tracing/src/span.rs
vendored
Normal file
1623
third-party/vendor/tracing/src/span.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
55
third-party/vendor/tracing/src/stdlib.rs
vendored
Normal file
55
third-party/vendor/tracing/src/stdlib.rs
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
//! Re-exports either the Rust `std` library or `core` and `alloc` when `std` is
|
||||
//! disabled.
|
||||
//!
|
||||
//! `crate::stdlib::...` should be used rather than `std::` when adding code that
|
||||
//! will be available with the standard library disabled.
|
||||
//!
|
||||
//! Note that this module is called `stdlib` rather than `std`, as Rust 1.34.0
|
||||
//! does not permit redefining the name `stdlib` (although this works on the
|
||||
//! latest stable Rust).
|
||||
#[cfg(feature = "std")]
|
||||
pub(crate) use std::*;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub(crate) use self::no_std::*;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
mod no_std {
|
||||
// We pre-emptively export everything from libcore/liballoc, (even modules
|
||||
// we aren't using currently) to make adding new code easier. Therefore,
|
||||
// some of these imports will be unused.
|
||||
#![allow(unused_imports)]
|
||||
|
||||
pub(crate) use core::{
|
||||
any, array, ascii, cell, char, clone, cmp, convert, default, f32, f64, ffi, future, hash,
|
||||
hint, i128, i16, i8, isize, iter, marker, mem, num, ops, option, pin, ptr, result, task,
|
||||
time, u128, u16, u32, u8, usize,
|
||||
};
|
||||
|
||||
pub(crate) use alloc::{boxed, collections, rc, string, vec};
|
||||
|
||||
pub(crate) mod borrow {
|
||||
pub(crate) use alloc::borrow::*;
|
||||
pub(crate) use core::borrow::*;
|
||||
}
|
||||
|
||||
pub(crate) mod fmt {
|
||||
pub(crate) use alloc::fmt::*;
|
||||
pub(crate) use core::fmt::*;
|
||||
}
|
||||
|
||||
pub(crate) mod slice {
|
||||
pub(crate) use alloc::slice::*;
|
||||
pub(crate) use core::slice::*;
|
||||
}
|
||||
|
||||
pub(crate) mod str {
|
||||
pub(crate) use alloc::str::*;
|
||||
pub(crate) use core::str::*;
|
||||
}
|
||||
|
||||
pub(crate) mod sync {
|
||||
pub(crate) use alloc::sync::*;
|
||||
pub(crate) use core::sync::*;
|
||||
}
|
||||
}
|
||||
65
third-party/vendor/tracing/src/subscriber.rs
vendored
Normal file
65
third-party/vendor/tracing/src/subscriber.rs
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
//! Collects and records trace data.
|
||||
pub use tracing_core::subscriber::*;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
pub use tracing_core::dispatcher::DefaultGuard;
|
||||
|
||||
/// Sets this [`Subscriber`] as the default for the current thread for the
|
||||
/// duration of a closure.
|
||||
///
|
||||
/// The default subscriber is used when creating a new [`Span`] or
|
||||
/// [`Event`].
|
||||
///
|
||||
///
|
||||
/// [`Span`]: super::span::Span
|
||||
/// [`Subscriber`]: super::subscriber::Subscriber
|
||||
/// [`Event`]: super::event::Event
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
pub fn with_default<T, S>(subscriber: S, f: impl FnOnce() -> T) -> T
|
||||
where
|
||||
S: Subscriber + Send + Sync + 'static,
|
||||
{
|
||||
crate::dispatcher::with_default(&crate::Dispatch::new(subscriber), f)
|
||||
}
|
||||
|
||||
/// Sets this subscriber as the global default for the duration of the entire program.
|
||||
/// Will be used as a fallback if no thread-local subscriber has been set in a thread (using `with_default`.)
|
||||
///
|
||||
/// Can only be set once; subsequent attempts to set the global default will fail.
|
||||
/// Returns whether the initialization was successful.
|
||||
///
|
||||
/// Note: Libraries should *NOT* call `set_global_default()`! That will cause conflicts when
|
||||
/// executables try to set them later.
|
||||
///
|
||||
/// [span]: super::span
|
||||
/// [`Subscriber`]: super::subscriber::Subscriber
|
||||
/// [`Event`]: super::event::Event
|
||||
pub fn set_global_default<S>(subscriber: S) -> Result<(), SetGlobalDefaultError>
|
||||
where
|
||||
S: Subscriber + Send + Sync + 'static,
|
||||
{
|
||||
crate::dispatcher::set_global_default(crate::Dispatch::new(subscriber))
|
||||
}
|
||||
|
||||
/// Sets the [`Subscriber`] as the default for the current thread for the
|
||||
/// duration of the lifetime of the returned [`DefaultGuard`].
|
||||
///
|
||||
/// The default subscriber is used when creating a new [`Span`] or [`Event`].
|
||||
///
|
||||
/// [`Span`]: super::span::Span
|
||||
/// [`Subscriber`]: super::subscriber::Subscriber
|
||||
/// [`Event`]: super::event::Event
|
||||
/// [`DefaultGuard`]: super::dispatcher::DefaultGuard
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
#[must_use = "Dropping the guard unregisters the subscriber."]
|
||||
pub fn set_default<S>(subscriber: S) -> DefaultGuard
|
||||
where
|
||||
S: Subscriber + Send + Sync + 'static,
|
||||
{
|
||||
crate::dispatcher::set_default(&crate::Dispatch::new(subscriber))
|
||||
}
|
||||
|
||||
pub use tracing_core::dispatcher::SetGlobalDefaultError;
|
||||
54
third-party/vendor/tracing/tests/enabled.rs
vendored
Normal file
54
third-party/vendor/tracing/tests/enabled.rs
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#![cfg(feature = "std")]
|
||||
use tracing::Level;
|
||||
use tracing_mock::*;
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn level_and_target() {
|
||||
let subscriber = subscriber::mock()
|
||||
.with_filter(|meta| {
|
||||
if meta.target() == "debug_module" {
|
||||
meta.level() <= &Level::DEBUG
|
||||
} else {
|
||||
meta.level() <= &Level::INFO
|
||||
}
|
||||
})
|
||||
.only()
|
||||
.run();
|
||||
|
||||
let _guard = tracing::subscriber::set_default(subscriber);
|
||||
|
||||
assert!(tracing::enabled!(target: "debug_module", Level::DEBUG));
|
||||
assert!(tracing::enabled!(Level::ERROR));
|
||||
assert!(!tracing::enabled!(Level::DEBUG));
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn span_and_event() {
|
||||
let subscriber = subscriber::mock()
|
||||
.with_filter(|meta| {
|
||||
if meta.target() == "debug_module" {
|
||||
meta.level() <= &Level::DEBUG
|
||||
} else if meta.is_span() {
|
||||
meta.level() <= &Level::TRACE
|
||||
} else if meta.is_event() {
|
||||
meta.level() <= &Level::DEBUG
|
||||
} else {
|
||||
meta.level() <= &Level::INFO
|
||||
}
|
||||
})
|
||||
.only()
|
||||
.run();
|
||||
|
||||
let _guard = tracing::subscriber::set_default(subscriber);
|
||||
|
||||
// Ensure that the `_event` and `_span` alternatives work corretly
|
||||
assert!(!tracing::event_enabled!(Level::TRACE));
|
||||
assert!(tracing::event_enabled!(Level::DEBUG));
|
||||
assert!(tracing::span_enabled!(Level::TRACE));
|
||||
|
||||
// target variants
|
||||
assert!(tracing::span_enabled!(target: "debug_module", Level::DEBUG));
|
||||
assert!(tracing::event_enabled!(target: "debug_module", Level::DEBUG));
|
||||
}
|
||||
554
third-party/vendor/tracing/tests/event.rs
vendored
Normal file
554
third-party/vendor/tracing/tests/event.rs
vendored
Normal file
|
|
@ -0,0 +1,554 @@
|
|||
// These tests require the thread-local scoped dispatcher, which only works when
|
||||
// we have a standard library. The behaviour being tested should be the same
|
||||
// with the standard lib disabled.
|
||||
//
|
||||
// The alternative would be for each of these tests to be defined in a separate
|
||||
// file, which is :(
|
||||
#![cfg(feature = "std")]
|
||||
|
||||
use tracing::{
|
||||
debug, error,
|
||||
field::{debug, display},
|
||||
info,
|
||||
subscriber::with_default,
|
||||
trace, warn, Level,
|
||||
};
|
||||
use tracing_mock::*;
|
||||
|
||||
macro_rules! event_without_message {
|
||||
($name:ident: $e:expr) => {
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn $name() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("answer")
|
||||
.with_value(&42)
|
||||
.and(
|
||||
expect::field("to_question")
|
||||
.with_value(&"life, the universe, and everything"),
|
||||
)
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
info!(
|
||||
answer = $e,
|
||||
to_question = "life, the universe, and everything"
|
||||
);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
event_without_message! {event_without_message: 42}
|
||||
event_without_message! {wrapping_event_without_message: std::num::Wrapping(42)}
|
||||
event_without_message! {nonzeroi32_event_without_message: std::num::NonZeroI32::new(42).unwrap()}
|
||||
// needs API breakage
|
||||
//event_without_message!{nonzerou128_event_without_message: std::num::NonZeroU128::new(42).unwrap()}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn event_with_message() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(expect::field("message").with_value(
|
||||
&tracing::field::debug(format_args!(
|
||||
"hello from my tracing::event! yak shaved = {:?}",
|
||||
true
|
||||
)),
|
||||
)),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
debug!("hello from my tracing::event! yak shaved = {:?}", true);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn message_without_delims() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("answer")
|
||||
.with_value(&42)
|
||||
.and(
|
||||
expect::field("question").with_value(&"life, the universe, and everything"),
|
||||
)
|
||||
.and(field::msg(format_args!(
|
||||
"hello from my event! tricky? {:?}!",
|
||||
true
|
||||
)))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let question = "life, the universe, and everything";
|
||||
debug!(answer = 42, question, "hello from {where}! tricky? {:?}!", true, where = "my event");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn string_message_without_delims() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("answer")
|
||||
.with_value(&42)
|
||||
.and(
|
||||
expect::field("question").with_value(&"life, the universe, and everything"),
|
||||
)
|
||||
.and(field::msg(format_args!("hello from my event")))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let question = "life, the universe, and everything";
|
||||
debug!(answer = 42, question, "hello from my event");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn one_with_everything() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event()
|
||||
.with_fields(
|
||||
expect::field("message")
|
||||
.with_value(&tracing::field::debug(format_args!(
|
||||
"{:#x} make me one with{what:.>20}",
|
||||
4_277_009_102u64,
|
||||
what = "everything"
|
||||
)))
|
||||
.and(expect::field("foo").with_value(&666))
|
||||
.and(expect::field("bar").with_value(&false))
|
||||
.and(expect::field("like_a_butterfly").with_value(&42.0))
|
||||
.only(),
|
||||
)
|
||||
.at_level(Level::ERROR)
|
||||
.with_target("whatever"),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
tracing::event!(
|
||||
target: "whatever",
|
||||
Level::ERROR,
|
||||
{ foo = 666, bar = false, like_a_butterfly = 42.0 },
|
||||
"{:#x} make me one with{what:.>20}", 4_277_009_102u64, what = "everything"
|
||||
);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn moved_field() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("foo")
|
||||
.with_value(&display("hello from my event"))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
let from = "my event";
|
||||
tracing::event!(Level::INFO, foo = display(format!("hello from {}", from)))
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn dotted_field_name() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("foo.bar")
|
||||
.with_value(&true)
|
||||
.and(expect::field("foo.baz").with_value(&false))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
tracing::event!(Level::INFO, foo.bar = true, foo.baz = false);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn borrowed_field() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("foo")
|
||||
.with_value(&display("hello from my event"))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
let from = "my event";
|
||||
let mut message = format!("hello from {}", from);
|
||||
tracing::event!(Level::INFO, foo = display(&message));
|
||||
message.push_str(", which happened!");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
// If emitting log instrumentation, this gets moved anyway, breaking the test.
|
||||
#[cfg(not(feature = "log"))]
|
||||
fn move_field_out_of_struct() {
|
||||
use tracing::field::debug;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Position {
|
||||
x: f32,
|
||||
y: f32,
|
||||
}
|
||||
|
||||
let pos = Position {
|
||||
x: 3.234,
|
||||
y: -1.223,
|
||||
};
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("x")
|
||||
.with_value(&debug(3.234))
|
||||
.and(expect::field("y").with_value(&debug(-1.223)))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.event(expect::event().with_fields(expect::field("position").with_value(&debug(&pos))))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let pos = Position {
|
||||
x: 3.234,
|
||||
y: -1.223,
|
||||
};
|
||||
debug!(x = debug(pos.x), y = debug(pos.y));
|
||||
debug!(target: "app_events", { position = debug(pos) }, "New position");
|
||||
});
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn display_shorthand() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("my_field")
|
||||
.with_value(&display("hello world"))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
tracing::event!(Level::TRACE, my_field = %"hello world");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn debug_shorthand() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("my_field")
|
||||
.with_value(&debug("hello world"))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
tracing::event!(Level::TRACE, my_field = ?"hello world");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn both_shorthands() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("display_field")
|
||||
.with_value(&display("hello world"))
|
||||
.and(expect::field("debug_field").with_value(&debug("hello world")))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
tracing::event!(Level::TRACE, display_field = %"hello world", debug_field = ?"hello world");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn explicit_child() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(expect::span().named("foo"))
|
||||
.event(expect::event().with_explicit_parent(Some("foo")))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let foo = tracing::span!(Level::TRACE, "foo");
|
||||
tracing::event!(parent: foo.id(), Level::TRACE, "bar");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn explicit_child_at_levels() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(expect::span().named("foo"))
|
||||
.event(expect::event().with_explicit_parent(Some("foo")))
|
||||
.event(expect::event().with_explicit_parent(Some("foo")))
|
||||
.event(expect::event().with_explicit_parent(Some("foo")))
|
||||
.event(expect::event().with_explicit_parent(Some("foo")))
|
||||
.event(expect::event().with_explicit_parent(Some("foo")))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let foo = tracing::span!(Level::TRACE, "foo");
|
||||
trace!(parent: foo.id(), "a");
|
||||
debug!(parent: foo.id(), "b");
|
||||
info!(parent: foo.id(), "c");
|
||||
warn!(parent: foo.id(), "d");
|
||||
error!(parent: foo.id(), "e");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn option_values() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("some_str")
|
||||
.with_value(&"yes")
|
||||
.and(expect::field("some_bool").with_value(&true))
|
||||
.and(expect::field("some_u64").with_value(&42_u64))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let some_str = Some("yes");
|
||||
let none_str: Option<&'static str> = None;
|
||||
let some_bool = Some(true);
|
||||
let none_bool: Option<bool> = None;
|
||||
let some_u64 = Some(42_u64);
|
||||
let none_u64: Option<u64> = None;
|
||||
trace!(
|
||||
some_str = some_str,
|
||||
none_str = none_str,
|
||||
some_bool = some_bool,
|
||||
none_bool = none_bool,
|
||||
some_u64 = some_u64,
|
||||
none_u64 = none_u64
|
||||
);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn option_ref_values() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("some_str")
|
||||
.with_value(&"yes")
|
||||
.and(expect::field("some_bool").with_value(&true))
|
||||
.and(expect::field("some_u64").with_value(&42_u64))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let some_str = &Some("yes");
|
||||
let none_str: &Option<&'static str> = &None;
|
||||
let some_bool = &Some(true);
|
||||
let none_bool: &Option<bool> = &None;
|
||||
let some_u64 = &Some(42_u64);
|
||||
let none_u64: &Option<u64> = &None;
|
||||
trace!(
|
||||
some_str = some_str,
|
||||
none_str = none_str,
|
||||
some_bool = some_bool,
|
||||
none_bool = none_bool,
|
||||
some_u64 = some_u64,
|
||||
none_u64 = none_u64
|
||||
);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn option_ref_mut_values() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("some_str")
|
||||
.with_value(&"yes")
|
||||
.and(expect::field("some_bool").with_value(&true))
|
||||
.and(expect::field("some_u64").with_value(&42_u64))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let some_str = &mut Some("yes");
|
||||
let none_str: &mut Option<&'static str> = &mut None;
|
||||
let some_bool = &mut Some(true);
|
||||
let none_bool: &mut Option<bool> = &mut None;
|
||||
let some_u64 = &mut Some(42_u64);
|
||||
let none_u64: &mut Option<u64> = &mut None;
|
||||
trace!(
|
||||
some_str = some_str,
|
||||
none_str = none_str,
|
||||
some_bool = some_bool,
|
||||
none_bool = none_bool,
|
||||
some_u64 = some_u64,
|
||||
none_u64 = none_u64
|
||||
);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn string_field() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(expect::event().with_fields(expect::field("my_string").with_value(&"hello").only()))
|
||||
.event(
|
||||
expect::event().with_fields(
|
||||
expect::field("my_string")
|
||||
.with_value(&"hello world!")
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
let mut my_string = String::from("hello");
|
||||
|
||||
tracing::event!(Level::INFO, my_string);
|
||||
|
||||
// the string is not moved by using it as a field!
|
||||
my_string.push_str(" world!");
|
||||
|
||||
tracing::event!(Level::INFO, my_string);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn constant_field_name() {
|
||||
let expect_event = || {
|
||||
expect::event().with_fields(
|
||||
expect::field("foo")
|
||||
.with_value(&"bar")
|
||||
.and(expect::field("constant string").with_value(&"also works"))
|
||||
.and(expect::field("foo.bar").with_value(&"baz"))
|
||||
.and(expect::field("message").with_value(&debug(format_args!("quux"))))
|
||||
.only(),
|
||||
)
|
||||
};
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(expect_event())
|
||||
.event(expect_event())
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
const FOO: &str = "foo";
|
||||
tracing::event!(
|
||||
Level::INFO,
|
||||
{ std::convert::identity(FOO) } = "bar",
|
||||
{ "constant string" } = "also works",
|
||||
foo.bar = "baz",
|
||||
"quux"
|
||||
);
|
||||
tracing::event!(
|
||||
Level::INFO,
|
||||
{
|
||||
{ std::convert::identity(FOO) } = "bar",
|
||||
{ "constant string" } = "also works",
|
||||
foo.bar = "baz",
|
||||
},
|
||||
"quux"
|
||||
);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
65
third-party/vendor/tracing/tests/filter_caching_is_lexically_scoped.rs
vendored
Normal file
65
third-party/vendor/tracing/tests/filter_caching_is_lexically_scoped.rs
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
// Tests that depend on a count of the number of times their filter is evaluated
|
||||
// can't exist in the same file with other tests that add subscribers to the
|
||||
// registry. The registry was changed so that each time a new dispatcher is
|
||||
// added all filters are re-evaluated. The tests being run only in separate
|
||||
// threads with shared global state lets them interfere with each other
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
extern crate std;
|
||||
|
||||
use tracing::{span, Level};
|
||||
use tracing_mock::*;
|
||||
|
||||
use std::sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
Arc,
|
||||
};
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn filter_caching_is_lexically_scoped() {
|
||||
pub fn my_great_function() -> bool {
|
||||
span!(Level::TRACE, "emily").in_scope(|| true)
|
||||
}
|
||||
|
||||
pub fn my_other_function() -> bool {
|
||||
span!(Level::TRACE, "frank").in_scope(|| true)
|
||||
}
|
||||
|
||||
let count = Arc::new(AtomicUsize::new(0));
|
||||
let count2 = count.clone();
|
||||
|
||||
let subscriber = subscriber::mock()
|
||||
.with_filter(move |meta| match meta.name() {
|
||||
"emily" | "frank" => {
|
||||
count2.fetch_add(1, Ordering::Relaxed);
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
})
|
||||
.run();
|
||||
|
||||
// Since this test is in its own file anyway, we can do this. Thus, this
|
||||
// test will work even with no-std.
|
||||
tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||
|
||||
// Call the function once. The filter should be re-evaluated.
|
||||
assert!(my_great_function());
|
||||
assert_eq!(count.load(Ordering::Relaxed), 1);
|
||||
|
||||
// Call the function again. The cached result should be used.
|
||||
assert!(my_great_function());
|
||||
assert_eq!(count.load(Ordering::Relaxed), 1);
|
||||
|
||||
assert!(my_other_function());
|
||||
assert_eq!(count.load(Ordering::Relaxed), 2);
|
||||
|
||||
assert!(my_great_function());
|
||||
assert_eq!(count.load(Ordering::Relaxed), 2);
|
||||
|
||||
assert!(my_other_function());
|
||||
assert_eq!(count.load(Ordering::Relaxed), 2);
|
||||
|
||||
assert!(my_great_function());
|
||||
assert_eq!(count.load(Ordering::Relaxed), 2);
|
||||
}
|
||||
70
third-party/vendor/tracing/tests/filters_are_not_reevaluated_for_the_same_span.rs
vendored
Normal file
70
third-party/vendor/tracing/tests/filters_are_not_reevaluated_for_the_same_span.rs
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
// Tests that depend on a count of the number of times their filter is evaluated
|
||||
// cant exist in the same file with other tests that add subscribers to the
|
||||
// registry. The registry was changed so that each time a new dispatcher is
|
||||
// added all filters are re-evaluated. The tests being run only in separate
|
||||
// threads with shared global state lets them interfere with each other
|
||||
#[cfg(not(feature = "std"))]
|
||||
extern crate std;
|
||||
|
||||
use tracing::{span, Level};
|
||||
use tracing_mock::*;
|
||||
|
||||
use std::sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
Arc,
|
||||
};
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn filters_are_not_reevaluated_for_the_same_span() {
|
||||
// Asserts that the `span!` macro caches the result of calling
|
||||
// `Subscriber::enabled` for each span.
|
||||
let alice_count = Arc::new(AtomicUsize::new(0));
|
||||
let bob_count = Arc::new(AtomicUsize::new(0));
|
||||
let alice_count2 = alice_count.clone();
|
||||
let bob_count2 = bob_count.clone();
|
||||
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.with_filter(move |meta| match meta.name() {
|
||||
"alice" => {
|
||||
alice_count2.fetch_add(1, Ordering::Relaxed);
|
||||
false
|
||||
}
|
||||
"bob" => {
|
||||
bob_count2.fetch_add(1, Ordering::Relaxed);
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
})
|
||||
.run_with_handle();
|
||||
|
||||
// Since this test is in its own file anyway, we can do this. Thus, this
|
||||
// test will work even with no-std.
|
||||
tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||
|
||||
// Enter "alice" and then "bob". The dispatcher expects to see "bob" but
|
||||
// not "alice."
|
||||
let alice = span!(Level::TRACE, "alice");
|
||||
let bob = alice.in_scope(|| {
|
||||
let bob = span!(Level::TRACE, "bob");
|
||||
bob.in_scope(|| ());
|
||||
bob
|
||||
});
|
||||
|
||||
// The filter should have seen each span a single time.
|
||||
assert_eq!(alice_count.load(Ordering::Relaxed), 1);
|
||||
assert_eq!(bob_count.load(Ordering::Relaxed), 1);
|
||||
|
||||
alice.in_scope(|| bob.in_scope(|| {}));
|
||||
|
||||
// The subscriber should see "bob" again, but the filter should not have
|
||||
// been called.
|
||||
assert_eq!(alice_count.load(Ordering::Relaxed), 1);
|
||||
assert_eq!(bob_count.load(Ordering::Relaxed), 1);
|
||||
|
||||
bob.in_scope(|| {});
|
||||
assert_eq!(alice_count.load(Ordering::Relaxed), 1);
|
||||
assert_eq!(bob_count.load(Ordering::Relaxed), 1);
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
80
third-party/vendor/tracing/tests/filters_are_reevaluated_for_different_call_sites.rs
vendored
Normal file
80
third-party/vendor/tracing/tests/filters_are_reevaluated_for_different_call_sites.rs
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
// Tests that depend on a count of the number of times their filter is evaluated
|
||||
// cant exist in the same file with other tests that add subscribers to the
|
||||
// registry. The registry was changed so that each time a new dispatcher is
|
||||
// added all filters are re-evaluated. The tests being run only in separate
|
||||
// threads with shared global state lets them interfere with each other
|
||||
#[cfg(not(feature = "std"))]
|
||||
extern crate std;
|
||||
|
||||
use tracing::{span, Level};
|
||||
use tracing_mock::*;
|
||||
|
||||
use std::sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
Arc,
|
||||
};
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn filters_are_reevaluated_for_different_call_sites() {
|
||||
// Asserts that the `span!` macro caches the result of calling
|
||||
// `Subscriber::enabled` for each span.
|
||||
let charlie_count = Arc::new(AtomicUsize::new(0));
|
||||
let dave_count = Arc::new(AtomicUsize::new(0));
|
||||
let charlie_count2 = charlie_count.clone();
|
||||
let dave_count2 = dave_count.clone();
|
||||
|
||||
let subscriber = subscriber::mock()
|
||||
.with_filter(move |meta| {
|
||||
println!("Filter: {:?}", meta.name());
|
||||
match meta.name() {
|
||||
"charlie" => {
|
||||
charlie_count2.fetch_add(1, Ordering::Relaxed);
|
||||
false
|
||||
}
|
||||
"dave" => {
|
||||
dave_count2.fetch_add(1, Ordering::Relaxed);
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
.run();
|
||||
|
||||
// Since this test is in its own file anyway, we can do this. Thus, this
|
||||
// test will work even with no-std.
|
||||
tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||
|
||||
// Enter "charlie" and then "dave". The dispatcher expects to see "dave" but
|
||||
// not "charlie."
|
||||
let charlie = span!(Level::TRACE, "charlie");
|
||||
let dave = charlie.in_scope(|| {
|
||||
let dave = span!(Level::TRACE, "dave");
|
||||
dave.in_scope(|| {});
|
||||
dave
|
||||
});
|
||||
|
||||
// The filter should have seen each span a single time.
|
||||
assert_eq!(charlie_count.load(Ordering::Relaxed), 1);
|
||||
assert_eq!(dave_count.load(Ordering::Relaxed), 1);
|
||||
|
||||
charlie.in_scope(|| dave.in_scope(|| {}));
|
||||
|
||||
// The subscriber should see "dave" again, but the filter should not have
|
||||
// been called.
|
||||
assert_eq!(charlie_count.load(Ordering::Relaxed), 1);
|
||||
assert_eq!(dave_count.load(Ordering::Relaxed), 1);
|
||||
|
||||
// A different span with the same name has a different call site, so it
|
||||
// should cause the filter to be reapplied.
|
||||
let charlie2 = span!(Level::TRACE, "charlie");
|
||||
charlie.in_scope(|| {});
|
||||
assert_eq!(charlie_count.load(Ordering::Relaxed), 2);
|
||||
assert_eq!(dave_count.load(Ordering::Relaxed), 1);
|
||||
|
||||
// But, the filter should not be re-evaluated for the new "charlie" span
|
||||
// when it is re-entered.
|
||||
charlie2.in_scope(|| span!(Level::TRACE, "dave").in_scope(|| {}));
|
||||
assert_eq!(charlie_count.load(Ordering::Relaxed), 2);
|
||||
assert_eq!(dave_count.load(Ordering::Relaxed), 2);
|
||||
}
|
||||
81
third-party/vendor/tracing/tests/filters_dont_leak.rs
vendored
Normal file
81
third-party/vendor/tracing/tests/filters_dont_leak.rs
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#![cfg(feature = "std")]
|
||||
|
||||
use tracing_mock::*;
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn spans_dont_leak() {
|
||||
fn do_span() {
|
||||
let span = tracing::debug_span!("alice");
|
||||
let _e = span.enter();
|
||||
}
|
||||
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.named("spans/subscriber1")
|
||||
.with_filter(|_| false)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
let _guard = tracing::subscriber::set_default(subscriber);
|
||||
|
||||
do_span();
|
||||
|
||||
let alice = expect::span().named("alice");
|
||||
let (subscriber2, handle2) = subscriber::mock()
|
||||
.named("spans/subscriber2")
|
||||
.with_filter(|_| true)
|
||||
.new_span(alice.clone())
|
||||
.enter(alice.clone())
|
||||
.exit(alice.clone())
|
||||
.drop_span(alice)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
tracing::subscriber::with_default(subscriber2, || {
|
||||
println!("--- subscriber 2 is default ---");
|
||||
do_span()
|
||||
});
|
||||
|
||||
println!("--- subscriber 1 is default ---");
|
||||
do_span();
|
||||
|
||||
handle.assert_finished();
|
||||
handle2.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn events_dont_leak() {
|
||||
fn do_event() {
|
||||
tracing::debug!("alice");
|
||||
}
|
||||
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.named("events/subscriber1")
|
||||
.with_filter(|_| false)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
let _guard = tracing::subscriber::set_default(subscriber);
|
||||
|
||||
do_event();
|
||||
|
||||
let (subscriber2, handle2) = subscriber::mock()
|
||||
.named("events/subscriber2")
|
||||
.with_filter(|_| true)
|
||||
.event(expect::event())
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
tracing::subscriber::with_default(subscriber2, || {
|
||||
println!("--- subscriber 2 is default ---");
|
||||
do_event()
|
||||
});
|
||||
|
||||
println!("--- subscriber 1 is default ---");
|
||||
|
||||
do_event();
|
||||
|
||||
handle.assert_finished();
|
||||
handle2.assert_finished();
|
||||
}
|
||||
22
third-party/vendor/tracing/tests/future_send.rs
vendored
Normal file
22
third-party/vendor/tracing/tests/future_send.rs
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// These tests reproduce the following issues:
|
||||
// - https://github.com/tokio-rs/tracing/issues/1487
|
||||
// - https://github.com/tokio-rs/tracing/issues/1793
|
||||
|
||||
use core::future::{self, Future};
|
||||
#[test]
|
||||
fn async_fn_is_send() {
|
||||
async fn some_async_fn() {
|
||||
tracing::info!("{}", future::ready("test").await);
|
||||
}
|
||||
|
||||
assert_send(some_async_fn())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn async_block_is_send() {
|
||||
assert_send(async {
|
||||
tracing::info!("{}", future::ready("test").await);
|
||||
})
|
||||
}
|
||||
|
||||
fn assert_send<F: Future + Send>(_f: F) {}
|
||||
59
third-party/vendor/tracing/tests/instrument.rs
vendored
Normal file
59
third-party/vendor/tracing/tests/instrument.rs
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// These tests require the thread-local scoped dispatcher, which only works when
|
||||
// we have a standard library. The behaviour being tested should be the same
|
||||
// with the standard lib disabled.
|
||||
#![cfg(feature = "std")]
|
||||
|
||||
use std::{future::Future, pin::Pin, task};
|
||||
|
||||
use futures::FutureExt as _;
|
||||
use tracing::{subscriber::with_default, Instrument as _, Level};
|
||||
use tracing_mock::*;
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn span_on_drop() {
|
||||
#[derive(Clone, Debug)]
|
||||
struct AssertSpanOnDrop;
|
||||
|
||||
impl Drop for AssertSpanOnDrop {
|
||||
fn drop(&mut self) {
|
||||
tracing::info!("Drop");
|
||||
}
|
||||
}
|
||||
|
||||
struct Fut(Option<AssertSpanOnDrop>);
|
||||
|
||||
impl Future for Fut {
|
||||
type Output = ();
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut task::Context<'_>) -> task::Poll<Self::Output> {
|
||||
self.set(Fut(None));
|
||||
task::Poll::Ready(())
|
||||
}
|
||||
}
|
||||
|
||||
let subscriber = subscriber::mock()
|
||||
.enter(expect::span().named("foo"))
|
||||
.event(expect::event().at_level(Level::INFO))
|
||||
.exit(expect::span().named("foo"))
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.enter(expect::span().named("bar"))
|
||||
.event(expect::event().at_level(Level::INFO))
|
||||
.exit(expect::span().named("bar"))
|
||||
.drop_span(expect::span().named("bar"))
|
||||
.only()
|
||||
.run();
|
||||
|
||||
with_default(subscriber, || {
|
||||
// polled once
|
||||
Fut(Some(AssertSpanOnDrop))
|
||||
.instrument(tracing::span!(Level::TRACE, "foo"))
|
||||
.now_or_never()
|
||||
.unwrap();
|
||||
|
||||
// never polled
|
||||
drop(Fut(Some(AssertSpanOnDrop)).instrument(tracing::span!(Level::TRACE, "bar")));
|
||||
});
|
||||
}
|
||||
23
third-party/vendor/tracing/tests/macro_imports.rs
vendored
Normal file
23
third-party/vendor/tracing/tests/macro_imports.rs
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
use tracing::Level;
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn prefixed_span_macros() {
|
||||
tracing::span!(Level::DEBUG, "foo");
|
||||
tracing::trace_span!("foo");
|
||||
tracing::debug_span!("foo");
|
||||
tracing::info_span!("foo");
|
||||
tracing::warn_span!("foo");
|
||||
tracing::error_span!("foo");
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn prefixed_event_macros() {
|
||||
tracing::event!(Level::DEBUG, "foo");
|
||||
tracing::trace!("foo");
|
||||
tracing::debug!("foo");
|
||||
tracing::info!("foo");
|
||||
tracing::warn!("foo");
|
||||
tracing::error!("foo");
|
||||
}
|
||||
1271
third-party/vendor/tracing/tests/macros.rs
vendored
Normal file
1271
third-party/vendor/tracing/tests/macros.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
24
third-party/vendor/tracing/tests/macros_incompatible_concat.rs
vendored
Normal file
24
third-party/vendor/tracing/tests/macros_incompatible_concat.rs
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
use tracing::{enabled, event, span, Level};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! concat {
|
||||
() => {};
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn span() {
|
||||
span!(Level::DEBUG, "foo");
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn event() {
|
||||
event!(Level::DEBUG, "foo");
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn enabled() {
|
||||
enabled!(Level::DEBUG);
|
||||
}
|
||||
37
third-party/vendor/tracing/tests/max_level_hint.rs
vendored
Normal file
37
third-party/vendor/tracing/tests/max_level_hint.rs
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use tracing::Level;
|
||||
use tracing_mock::*;
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn max_level_hints() {
|
||||
// This test asserts that when a subscriber provides us with the global
|
||||
// maximum level that it will enable (by implementing the
|
||||
// `Subscriber::max_level_hint` method), we will never call
|
||||
// `Subscriber::enabled` for events above that maximum level.
|
||||
//
|
||||
// In this case, we test that by making the `enabled` method assert that no
|
||||
// `Metadata` for spans or events at the `TRACE` or `DEBUG` levels.
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.with_max_level_hint(Level::INFO)
|
||||
.with_filter(|meta| {
|
||||
assert!(
|
||||
dbg!(meta).level() <= &Level::INFO,
|
||||
"a TRACE or DEBUG event was dynamically filtered: "
|
||||
);
|
||||
true
|
||||
})
|
||||
.event(expect::event().at_level(Level::INFO))
|
||||
.event(expect::event().at_level(Level::WARN))
|
||||
.event(expect::event().at_level(Level::ERROR))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||
|
||||
tracing::info!("doing a thing that you might care about");
|
||||
tracing::debug!("charging turboencabulator with interocitor");
|
||||
tracing::warn!("extremely serious warning, pay attention");
|
||||
tracing::trace!("interocitor charge level is 10%");
|
||||
tracing::error!("everything is on fire");
|
||||
handle.assert_finished();
|
||||
}
|
||||
69
third-party/vendor/tracing/tests/multiple_max_level_hints.rs
vendored
Normal file
69
third-party/vendor/tracing/tests/multiple_max_level_hints.rs
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#![cfg(feature = "std")]
|
||||
|
||||
use tracing::Level;
|
||||
use tracing_mock::*;
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn multiple_max_level_hints() {
|
||||
// This test ensures that when multiple subscribers are active, their max
|
||||
// level hints are handled correctly. The global max level should be the
|
||||
// maximum of the level filters returned by the two `Subscriber`'s
|
||||
// `max_level_hint` method.
|
||||
//
|
||||
// In this test, we create a subscriber whose max level is `INFO`, and
|
||||
// another whose max level is `DEBUG`. We then add an assertion to both of
|
||||
// those subscribers' `enabled` method that no metadata for `TRACE` spans or
|
||||
// events are filtered, since they are disabled by the global max filter.
|
||||
|
||||
fn do_events() {
|
||||
tracing::info!("doing a thing that you might care about");
|
||||
tracing::debug!("charging turboencabulator with interocitor");
|
||||
tracing::warn!("extremely serious warning, pay attention");
|
||||
tracing::trace!("interocitor charge level is 10%");
|
||||
tracing::error!("everything is on fire");
|
||||
}
|
||||
|
||||
let (subscriber1, handle1) = subscriber::mock()
|
||||
.named("subscriber1")
|
||||
.with_max_level_hint(Level::INFO)
|
||||
.with_filter(|meta| {
|
||||
let level = dbg!(meta.level());
|
||||
assert!(
|
||||
level <= &Level::DEBUG,
|
||||
"a TRACE event was dynamically filtered by subscriber1"
|
||||
);
|
||||
level <= &Level::INFO
|
||||
})
|
||||
.event(expect::event().at_level(Level::INFO))
|
||||
.event(expect::event().at_level(Level::WARN))
|
||||
.event(expect::event().at_level(Level::ERROR))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
let (subscriber2, handle2) = subscriber::mock()
|
||||
.named("subscriber2")
|
||||
.with_max_level_hint(Level::DEBUG)
|
||||
.with_filter(|meta| {
|
||||
let level = dbg!(meta.level());
|
||||
assert!(
|
||||
level <= &Level::DEBUG,
|
||||
"a TRACE event was dynamically filtered by subscriber2"
|
||||
);
|
||||
level <= &Level::DEBUG
|
||||
})
|
||||
.event(expect::event().at_level(Level::INFO))
|
||||
.event(expect::event().at_level(Level::DEBUG))
|
||||
.event(expect::event().at_level(Level::WARN))
|
||||
.event(expect::event().at_level(Level::ERROR))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
let dispatch1 = tracing::Dispatch::new(subscriber1);
|
||||
|
||||
tracing::dispatcher::with_default(&dispatch1, do_events);
|
||||
handle1.assert_finished();
|
||||
|
||||
let dispatch2 = tracing::Dispatch::new(subscriber2);
|
||||
tracing::dispatcher::with_default(&dispatch2, do_events);
|
||||
handle2.assert_finished();
|
||||
}
|
||||
16
third-party/vendor/tracing/tests/no_subscriber.rs
vendored
Normal file
16
third-party/vendor/tracing/tests/no_subscriber.rs
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#![cfg(feature = "std")]
|
||||
|
||||
use tracing_mock::subscriber;
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn no_subscriber_disables_global() {
|
||||
// Reproduces https://github.com/tokio-rs/tracing/issues/1999
|
||||
let (subscriber, handle) = subscriber::mock().only().run_with_handle();
|
||||
tracing::subscriber::set_global_default(subscriber)
|
||||
.expect("setting global default must succeed");
|
||||
tracing::subscriber::with_default(tracing::subscriber::NoSubscriber::default(), || {
|
||||
tracing::info!("this should not be recorded");
|
||||
});
|
||||
handle.assert_finished();
|
||||
}
|
||||
47
third-party/vendor/tracing/tests/register_callsite_deadlock.rs
vendored
Normal file
47
third-party/vendor/tracing/tests/register_callsite_deadlock.rs
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
use std::{sync::mpsc, thread, time::Duration};
|
||||
use tracing::{
|
||||
metadata::Metadata,
|
||||
span,
|
||||
subscriber::{self, Interest, Subscriber},
|
||||
Event,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn register_callsite_doesnt_deadlock() {
|
||||
pub struct EvilSubscriber;
|
||||
|
||||
impl Subscriber for EvilSubscriber {
|
||||
fn register_callsite(&self, meta: &'static Metadata<'static>) -> Interest {
|
||||
tracing::info!(?meta, "registered a callsite");
|
||||
Interest::always()
|
||||
}
|
||||
|
||||
fn enabled(&self, _: &Metadata<'_>) -> bool {
|
||||
true
|
||||
}
|
||||
fn new_span(&self, _: &span::Attributes<'_>) -> span::Id {
|
||||
span::Id::from_u64(1)
|
||||
}
|
||||
fn record(&self, _: &span::Id, _: &span::Record<'_>) {}
|
||||
fn record_follows_from(&self, _: &span::Id, _: &span::Id) {}
|
||||
fn event(&self, _: &Event<'_>) {}
|
||||
fn enter(&self, _: &span::Id) {}
|
||||
fn exit(&self, _: &span::Id) {}
|
||||
}
|
||||
|
||||
subscriber::set_global_default(EvilSubscriber).unwrap();
|
||||
|
||||
// spawn a thread, and assert it doesn't hang...
|
||||
let (tx, didnt_hang) = mpsc::channel();
|
||||
let th = thread::spawn(move || {
|
||||
tracing::info!("hello world!");
|
||||
tx.send(()).unwrap();
|
||||
});
|
||||
|
||||
didnt_hang
|
||||
// Note: 60 seconds is *way* more than enough, but let's be generous in
|
||||
// case of e.g. slow CI machines.
|
||||
.recv_timeout(Duration::from_secs(60))
|
||||
.expect("the thread must not have hung!");
|
||||
th.join().expect("thread should join successfully");
|
||||
}
|
||||
35
third-party/vendor/tracing/tests/scoped_clobbers_default.rs
vendored
Normal file
35
third-party/vendor/tracing/tests/scoped_clobbers_default.rs
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#![cfg(feature = "std")]
|
||||
use tracing_mock::*;
|
||||
|
||||
#[test]
|
||||
fn scoped_clobbers_global() {
|
||||
// Reproduces https://github.com/tokio-rs/tracing/issues/2050
|
||||
|
||||
let (scoped, scoped_handle) = subscriber::mock()
|
||||
.event(event::msg("before global"))
|
||||
.event(event::msg("before drop"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
let (global, global_handle) = subscriber::mock()
|
||||
.event(event::msg("after drop"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
// Set a scoped default subscriber, returning a guard.
|
||||
let guard = tracing::subscriber::set_default(scoped);
|
||||
tracing::info!("before global");
|
||||
|
||||
// Now, set the global default.
|
||||
tracing::subscriber::set_global_default(global)
|
||||
.expect("global default should not already be set");
|
||||
// This event should still be collected by the scoped default.
|
||||
tracing::info!("before drop");
|
||||
|
||||
// Drop the guard. Now, the global default subscriber should be used.
|
||||
drop(guard);
|
||||
tracing::info!("after drop");
|
||||
|
||||
scoped_handle.assert_finished();
|
||||
global_handle.assert_finished();
|
||||
}
|
||||
868
third-party/vendor/tracing/tests/span.rs
vendored
Normal file
868
third-party/vendor/tracing/tests/span.rs
vendored
Normal file
|
|
@ -0,0 +1,868 @@
|
|||
// These tests require the thread-local scoped dispatcher, which only works when
|
||||
// we have a standard library. The behaviour being tested should be the same
|
||||
// with the standard lib disabled.
|
||||
#![cfg(feature = "std")]
|
||||
|
||||
use std::thread;
|
||||
|
||||
use tracing::{
|
||||
field::{debug, display},
|
||||
subscriber::with_default,
|
||||
Level, Span,
|
||||
};
|
||||
use tracing_mock::*;
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn handles_to_the_same_span_are_equal() {
|
||||
// Create a mock subscriber that will return `true` on calls to
|
||||
// `Subscriber::enabled`, so that the spans will be constructed. We
|
||||
// won't enter any spans in this test, so the subscriber won't actually
|
||||
// expect to see any spans.
|
||||
with_default(subscriber::mock().run(), || {
|
||||
let foo1 = tracing::span!(Level::TRACE, "foo");
|
||||
|
||||
// The purpose of this test is to assert that two clones of the same
|
||||
// span are equal, so the clone here is kind of the whole point :)
|
||||
#[allow(clippy::redundant_clone)]
|
||||
let foo2 = foo1.clone();
|
||||
|
||||
// Two handles that point to the same span are equal.
|
||||
assert_eq!(foo1, foo2);
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn handles_to_different_spans_are_not_equal() {
|
||||
with_default(subscriber::mock().run(), || {
|
||||
// Even though these spans have the same name and fields, they will have
|
||||
// differing metadata, since they were created on different lines.
|
||||
let foo1 = tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false);
|
||||
let foo2 = tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false);
|
||||
|
||||
assert_ne!(foo1, foo2);
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn handles_to_different_spans_with_the_same_metadata_are_not_equal() {
|
||||
// Every time time this function is called, it will return a _new
|
||||
// instance_ of a span with the same metadata, name, and fields.
|
||||
fn make_span() -> Span {
|
||||
tracing::span!(Level::TRACE, "foo", bar = 1u64, baz = false)
|
||||
}
|
||||
|
||||
with_default(subscriber::mock().run(), || {
|
||||
let foo1 = make_span();
|
||||
let foo2 = make_span();
|
||||
|
||||
assert_ne!(foo1, foo2);
|
||||
// assert_ne!(foo1.data(), foo2.data());
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn spans_always_go_to_the_subscriber_that_tagged_them() {
|
||||
let subscriber1 = subscriber::mock()
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run();
|
||||
let subscriber2 = subscriber::mock().run();
|
||||
|
||||
let foo = with_default(subscriber1, || {
|
||||
let foo = tracing::span!(Level::TRACE, "foo");
|
||||
foo.in_scope(|| {});
|
||||
foo
|
||||
});
|
||||
// Even though we enter subscriber 2's context, the subscriber that
|
||||
// tagged the span should see the enter/exit.
|
||||
with_default(subscriber2, move || foo.in_scope(|| {}));
|
||||
}
|
||||
|
||||
// This gets exempt from testing in wasm because of: `thread::spawn` which is
|
||||
// not yet possible to do in WASM. There is work going on see:
|
||||
// <https://rustwasm.github.io/2018/10/24/multithreading-rust-and-wasm.html>
|
||||
//
|
||||
// But for now since it's not possible we don't need to test for it :)
|
||||
#[test]
|
||||
fn spans_always_go_to_the_subscriber_that_tagged_them_even_across_threads() {
|
||||
let subscriber1 = subscriber::mock()
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run();
|
||||
let foo = with_default(subscriber1, || {
|
||||
let foo = tracing::span!(Level::TRACE, "foo");
|
||||
foo.in_scope(|| {});
|
||||
foo
|
||||
});
|
||||
|
||||
// Even though we enter subscriber 2's context, the subscriber that
|
||||
// tagged the span should see the enter/exit.
|
||||
thread::spawn(move || {
|
||||
with_default(subscriber::mock().run(), || {
|
||||
foo.in_scope(|| {});
|
||||
})
|
||||
})
|
||||
.join()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn dropping_a_span_calls_drop_span() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
let span = tracing::span!(Level::TRACE, "foo");
|
||||
span.in_scope(|| {});
|
||||
drop(span);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn span_closes_after_event() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.enter(expect::span().named("foo"))
|
||||
.event(expect::event())
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
tracing::span!(Level::TRACE, "foo").in_scope(|| {
|
||||
tracing::event!(Level::DEBUG, {}, "my tracing::event!");
|
||||
});
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn new_span_after_event() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.enter(expect::span().named("foo"))
|
||||
.event(expect::event())
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.enter(expect::span().named("bar"))
|
||||
.exit(expect::span().named("bar"))
|
||||
.drop_span(expect::span().named("bar"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
tracing::span!(Level::TRACE, "foo").in_scope(|| {
|
||||
tracing::event!(Level::DEBUG, {}, "my tracing::event!");
|
||||
});
|
||||
tracing::span!(Level::TRACE, "bar").in_scope(|| {});
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn event_outside_of_span() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.event(expect::event())
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
tracing::debug!("my tracing::event!");
|
||||
tracing::span!(Level::TRACE, "foo").in_scope(|| {});
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn cloning_a_span_calls_clone_span() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.clone_span(expect::span().named("foo"))
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
let span = tracing::span!(Level::TRACE, "foo");
|
||||
// Allow the "redundant" `.clone` since it is used to call into the `.clone_span` hook.
|
||||
#[allow(clippy::redundant_clone)]
|
||||
let _span2 = span.clone();
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn drop_span_when_exiting_dispatchers_context() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.clone_span(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
let span = tracing::span!(Level::TRACE, "foo");
|
||||
let _span2 = span.clone();
|
||||
drop(span);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn clone_and_drop_span_always_go_to_the_subscriber_that_tagged_the_span() {
|
||||
let (subscriber1, handle1) = subscriber::mock()
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.clone_span(expect::span().named("foo"))
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.run_with_handle();
|
||||
let subscriber2 = subscriber::mock().only().run();
|
||||
|
||||
let foo = with_default(subscriber1, || {
|
||||
let foo = tracing::span!(Level::TRACE, "foo");
|
||||
foo.in_scope(|| {});
|
||||
foo
|
||||
});
|
||||
// Even though we enter subscriber 2's context, the subscriber that
|
||||
// tagged the span should see the enter/exit.
|
||||
with_default(subscriber2, move || {
|
||||
let foo2 = foo.clone();
|
||||
foo.in_scope(|| {});
|
||||
drop(foo);
|
||||
drop(foo2);
|
||||
});
|
||||
|
||||
handle1.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn span_closes_when_exited() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
let foo = tracing::span!(Level::TRACE, "foo");
|
||||
|
||||
foo.in_scope(|| {});
|
||||
|
||||
drop(foo);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn enter() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.enter(expect::span().named("foo"))
|
||||
.event(expect::event())
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
let foo = tracing::span!(Level::TRACE, "foo");
|
||||
let _enter = foo.enter();
|
||||
tracing::debug!("dropping guard...");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn entered() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.enter(expect::span().named("foo"))
|
||||
.event(expect::event())
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
let _span = tracing::span!(Level::TRACE, "foo").entered();
|
||||
tracing::debug!("dropping guard...");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn entered_api() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.enter(expect::span().named("foo"))
|
||||
.event(expect::event())
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
let span = tracing::span!(Level::TRACE, "foo").entered();
|
||||
let _derefs_to_span = span.id();
|
||||
tracing::debug!("exiting span...");
|
||||
let _: Span = span.exit();
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn moved_field() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("foo").with_field(
|
||||
expect::field("bar")
|
||||
.with_value(&display("hello from my span"))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
let from = "my span";
|
||||
let span = tracing::span!(
|
||||
Level::TRACE,
|
||||
"foo",
|
||||
bar = display(format!("hello from {}", from))
|
||||
);
|
||||
span.in_scope(|| {});
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn dotted_field_name() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span()
|
||||
.named("foo")
|
||||
.with_field(expect::field("fields.bar").with_value(&true).only()),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
tracing::span!(Level::TRACE, "foo", fields.bar = true);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn borrowed_field() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("foo").with_field(
|
||||
expect::field("bar")
|
||||
.with_value(&display("hello from my span"))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let from = "my span";
|
||||
let mut message = format!("hello from {}", from);
|
||||
let span = tracing::span!(Level::TRACE, "foo", bar = display(&message));
|
||||
span.in_scope(|| {
|
||||
message.insert_str(10, " inside");
|
||||
});
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
// If emitting log instrumentation, this gets moved anyway, breaking the test.
|
||||
#[cfg(not(feature = "log"))]
|
||||
fn move_field_out_of_struct() {
|
||||
use tracing::field::debug;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Position {
|
||||
x: f32,
|
||||
y: f32,
|
||||
}
|
||||
|
||||
let pos = Position {
|
||||
x: 3.234,
|
||||
y: -1.223,
|
||||
};
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("foo").with_field(
|
||||
expect::field("x")
|
||||
.with_value(&debug(3.234))
|
||||
.and(expect::field("y").with_value(&debug(-1.223)))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.new_span(
|
||||
expect::span()
|
||||
.named("bar")
|
||||
.with_field(expect::field("position").with_value(&debug(&pos)).only()),
|
||||
)
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let pos = Position {
|
||||
x: 3.234,
|
||||
y: -1.223,
|
||||
};
|
||||
let foo = tracing::span!(Level::TRACE, "foo", x = debug(pos.x), y = debug(pos.y));
|
||||
let bar = tracing::span!(Level::TRACE, "bar", position = debug(pos));
|
||||
foo.in_scope(|| {});
|
||||
bar.in_scope(|| {});
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn float_values() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("foo").with_field(
|
||||
expect::field("x")
|
||||
.with_value(&3.234)
|
||||
.and(expect::field("y").with_value(&-1.223))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let foo = tracing::span!(Level::TRACE, "foo", x = 3.234, y = -1.223);
|
||||
foo.in_scope(|| {});
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
// TODO(#1138): determine a new syntax for uninitialized span fields, and
|
||||
// re-enable these.
|
||||
/*
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn add_field_after_new_span() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span()
|
||||
.named("foo")
|
||||
.with_field(expect::field("bar").with_value(&5)
|
||||
.and(expect::field("baz").with_value).only()),
|
||||
)
|
||||
.record(
|
||||
expect::span().named("foo"),
|
||||
field::expect("baz").with_value(&true).only(),
|
||||
)
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let span = tracing::span!(Level::TRACE, "foo", bar = 5, baz = false);
|
||||
span.record("baz", &true);
|
||||
span.in_scope(|| {})
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn add_fields_only_after_new_span() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(expect::span().named("foo"))
|
||||
.record(
|
||||
expect::span().named("foo"),
|
||||
field::expect("bar").with_value(&5).only(),
|
||||
)
|
||||
.record(
|
||||
expect::span().named("foo"),
|
||||
field::expect("baz").with_value(&true).only(),
|
||||
)
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let span = tracing::span!(Level::TRACE, "foo", bar = _, baz = _);
|
||||
span.record("bar", &5);
|
||||
span.record("baz", &true);
|
||||
span.in_scope(|| {})
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
*/
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn record_new_value_for_field() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("foo").with_field(
|
||||
expect::field("bar")
|
||||
.with_value(&5)
|
||||
.and(expect::field("baz").with_value(&false))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.record(
|
||||
expect::span().named("foo"),
|
||||
expect::field("baz").with_value(&true).only(),
|
||||
)
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let span = tracing::span!(Level::TRACE, "foo", bar = 5, baz = false);
|
||||
span.record("baz", true);
|
||||
span.in_scope(|| {})
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn record_new_values_for_fields() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("foo").with_field(
|
||||
expect::field("bar")
|
||||
.with_value(&4)
|
||||
.and(expect::field("baz").with_value(&false))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.record(
|
||||
expect::span().named("foo"),
|
||||
expect::field("bar").with_value(&5).only(),
|
||||
)
|
||||
.record(
|
||||
expect::span().named("foo"),
|
||||
expect::field("baz").with_value(&true).only(),
|
||||
)
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let span = tracing::span!(Level::TRACE, "foo", bar = 4, baz = false);
|
||||
span.record("bar", 5);
|
||||
span.record("baz", true);
|
||||
span.in_scope(|| {})
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn new_span_with_target_and_log_level() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span()
|
||||
.named("foo")
|
||||
.with_target("app_span")
|
||||
.at_level(Level::DEBUG),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
tracing::span!(target: "app_span", Level::DEBUG, "foo");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn explicit_root_span_is_root() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(expect::span().named("foo").with_explicit_parent(None))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
tracing::span!(parent: None, Level::TRACE, "foo");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn explicit_root_span_is_root_regardless_of_ctx() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(expect::span().named("foo"))
|
||||
.enter(expect::span().named("foo"))
|
||||
.new_span(expect::span().named("bar").with_explicit_parent(None))
|
||||
.exit(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
tracing::span!(Level::TRACE, "foo").in_scope(|| {
|
||||
tracing::span!(parent: None, Level::TRACE, "bar");
|
||||
})
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn explicit_child() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(expect::span().named("foo"))
|
||||
.new_span(
|
||||
expect::span()
|
||||
.named("bar")
|
||||
.with_explicit_parent(Some("foo")),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let foo = tracing::span!(Level::TRACE, "foo");
|
||||
tracing::span!(parent: foo.id(), Level::TRACE, "bar");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn explicit_child_at_levels() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(expect::span().named("foo"))
|
||||
.new_span(expect::span().named("a").with_explicit_parent(Some("foo")))
|
||||
.new_span(expect::span().named("b").with_explicit_parent(Some("foo")))
|
||||
.new_span(expect::span().named("c").with_explicit_parent(Some("foo")))
|
||||
.new_span(expect::span().named("d").with_explicit_parent(Some("foo")))
|
||||
.new_span(expect::span().named("e").with_explicit_parent(Some("foo")))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let foo = tracing::span!(Level::TRACE, "foo");
|
||||
tracing::trace_span!(parent: foo.id(), "a");
|
||||
tracing::debug_span!(parent: foo.id(), "b");
|
||||
tracing::info_span!(parent: foo.id(), "c");
|
||||
tracing::warn_span!(parent: foo.id(), "d");
|
||||
tracing::error_span!(parent: foo.id(), "e");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn explicit_child_regardless_of_ctx() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(expect::span().named("foo"))
|
||||
.new_span(expect::span().named("bar"))
|
||||
.enter(expect::span().named("bar"))
|
||||
.new_span(
|
||||
expect::span()
|
||||
.named("baz")
|
||||
.with_explicit_parent(Some("foo")),
|
||||
)
|
||||
.exit(expect::span().named("bar"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
let foo = tracing::span!(Level::TRACE, "foo");
|
||||
tracing::span!(Level::TRACE, "bar")
|
||||
.in_scope(|| tracing::span!(parent: foo.id(), Level::TRACE, "baz"))
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn contextual_root() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(expect::span().named("foo").with_contextual_parent(None))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
tracing::span!(Level::TRACE, "foo");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn contextual_child() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(expect::span().named("foo"))
|
||||
.enter(expect::span().named("foo"))
|
||||
.new_span(
|
||||
expect::span()
|
||||
.named("bar")
|
||||
.with_contextual_parent(Some("foo")),
|
||||
)
|
||||
.exit(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
tracing::span!(Level::TRACE, "foo").in_scope(|| {
|
||||
tracing::span!(Level::TRACE, "bar");
|
||||
})
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn display_shorthand() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("my_span").with_field(
|
||||
expect::field("my_field")
|
||||
.with_value(&display("hello world"))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
tracing::span!(Level::TRACE, "my_span", my_field = %"hello world");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn debug_shorthand() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("my_span").with_field(
|
||||
expect::field("my_field")
|
||||
.with_value(&debug("hello world"))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
tracing::span!(Level::TRACE, "my_span", my_field = ?"hello world");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn both_shorthands() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("my_span").with_field(
|
||||
expect::field("display_field")
|
||||
.with_value(&display("hello world"))
|
||||
.and(expect::field("debug_field").with_value(&debug("hello world")))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
with_default(subscriber, || {
|
||||
tracing::span!(Level::TRACE, "my_span", display_field = %"hello world", debug_field = ?"hello world");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn constant_field_name() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("my_span").with_field(
|
||||
expect::field("foo")
|
||||
.with_value(&"bar")
|
||||
.and(expect::field("constant string").with_value(&"also works"))
|
||||
.and(expect::field("foo.bar").with_value(&"baz"))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
|
||||
with_default(subscriber, || {
|
||||
const FOO: &str = "foo";
|
||||
tracing::span!(
|
||||
Level::TRACE,
|
||||
"my_span",
|
||||
{ std::convert::identity(FOO) } = "bar",
|
||||
{ "constant string" } = "also works",
|
||||
foo.bar = "baz",
|
||||
);
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
129
third-party/vendor/tracing/tests/subscriber.rs
vendored
Normal file
129
third-party/vendor/tracing/tests/subscriber.rs
vendored
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
// These tests require the thread-local scoped dispatcher, which only works when
|
||||
// we have a standard library. The behaviour being tested should be the same
|
||||
// with the standard lib disabled.
|
||||
//
|
||||
// The alternative would be for each of these tests to be defined in a separate
|
||||
// file, which is :(
|
||||
#![cfg(feature = "std")]
|
||||
use tracing::{
|
||||
field::display,
|
||||
span::{Attributes, Id, Record},
|
||||
subscriber::{with_default, Interest, Subscriber},
|
||||
Event, Level, Metadata,
|
||||
};
|
||||
use tracing_mock::{expect, subscriber};
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn event_macros_dont_infinite_loop() {
|
||||
// This test ensures that an event macro within a subscriber
|
||||
// won't cause an infinite loop of events.
|
||||
struct TestSubscriber;
|
||||
impl Subscriber for TestSubscriber {
|
||||
fn register_callsite(&self, _: &Metadata<'_>) -> Interest {
|
||||
// Always return sometimes so that `enabled` will be called
|
||||
// (which can loop).
|
||||
Interest::sometimes()
|
||||
}
|
||||
|
||||
fn enabled(&self, meta: &Metadata<'_>) -> bool {
|
||||
assert!(meta.fields().iter().any(|f| f.name() == "foo"));
|
||||
tracing::event!(Level::TRACE, bar = false);
|
||||
true
|
||||
}
|
||||
|
||||
fn new_span(&self, _: &Attributes<'_>) -> Id {
|
||||
Id::from_u64(0xAAAA)
|
||||
}
|
||||
|
||||
fn record(&self, _: &Id, _: &Record<'_>) {}
|
||||
|
||||
fn record_follows_from(&self, _: &Id, _: &Id) {}
|
||||
|
||||
fn event(&self, event: &Event<'_>) {
|
||||
assert!(event.metadata().fields().iter().any(|f| f.name() == "foo"));
|
||||
tracing::event!(Level::TRACE, baz = false);
|
||||
}
|
||||
|
||||
fn enter(&self, _: &Id) {}
|
||||
|
||||
fn exit(&self, _: &Id) {}
|
||||
}
|
||||
|
||||
with_default(TestSubscriber, || {
|
||||
tracing::event!(Level::TRACE, foo = false);
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn boxed_subscriber() {
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("foo").with_field(
|
||||
expect::field("bar")
|
||||
.with_value(&display("hello from my span"))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.only()
|
||||
.run_with_handle();
|
||||
let subscriber: Box<dyn Subscriber + Send + Sync + 'static> = Box::new(subscriber);
|
||||
|
||||
with_default(subscriber, || {
|
||||
let from = "my span";
|
||||
let span = tracing::span!(
|
||||
Level::TRACE,
|
||||
"foo",
|
||||
bar = format_args!("hello from {}", from)
|
||||
);
|
||||
span.in_scope(|| {});
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
#[test]
|
||||
fn arced_subscriber() {
|
||||
use std::sync::Arc;
|
||||
|
||||
let (subscriber, handle) = subscriber::mock()
|
||||
.new_span(
|
||||
expect::span().named("foo").with_field(
|
||||
expect::field("bar")
|
||||
.with_value(&display("hello from my span"))
|
||||
.only(),
|
||||
),
|
||||
)
|
||||
.enter(expect::span().named("foo"))
|
||||
.exit(expect::span().named("foo"))
|
||||
.drop_span(expect::span().named("foo"))
|
||||
.event(
|
||||
expect::event()
|
||||
.with_fields(expect::field("message").with_value(&display("hello from my event"))),
|
||||
)
|
||||
.only()
|
||||
.run_with_handle();
|
||||
let subscriber: Arc<dyn Subscriber + Send + Sync + 'static> = Arc::new(subscriber);
|
||||
|
||||
// Test using a clone of the `Arc`ed subscriber
|
||||
with_default(subscriber.clone(), || {
|
||||
let from = "my span";
|
||||
let span = tracing::span!(
|
||||
Level::TRACE,
|
||||
"foo",
|
||||
bar = format_args!("hello from {}", from)
|
||||
);
|
||||
span.in_scope(|| {});
|
||||
});
|
||||
|
||||
with_default(subscriber, || {
|
||||
tracing::info!("hello from my event");
|
||||
});
|
||||
|
||||
handle.assert_finished();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue