Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

1
vendor/tracing/.cargo-checksum.json vendored Normal file
View File

@@ -0,0 +1 @@
{"files":{"CHANGELOG.md":"e41336be068976091df56bff671d38042286b776bbeb087f4bf6f4e85631cb81","Cargo.toml":"6c23bca19dcda69692ad102f2c395d5f098635cdcd27091c467837251827522f","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"0293821b9246c4b1a74211b74f2ce9655951931b8411eb365dced29a4ef46af5","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":"7a934a9dcec4f847c2b1534f49417dba2068050af017a857e12b660ac06f9a6f","src/macros.rs":"ba1df10032f8832536dfdd43e567dc0e260d8679fea30ccf68061bc58f9e1cce","src/span.rs":"8c5cce0ab990960c5e7bc0dd99dd9eefde6d8d2477e98c39f17dffa9170c4185","src/stdlib.rs":"248514a9bae6106e436358aee44c92abf8e7f79022895c4a25136ddef211d198","src/subscriber.rs":"8933d8766439f929c0a98a0863d20aff37b221314b3825edd9058be511149968","tests/enabled.rs":"e19d039cf0e984918838aaab9d8b3ca5a1eea9d01a54a264a70184b440a9e880","tests/event.rs":"f51b286c1224346f96f38bee6bed9c4eac5e6405f269e90b770ebfb370820fa1","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":"a3ee726247d897ad2af8123e6d44abce1a43a72ccbc3fd479257f810d8cbbbb2","tests/macro_imports.rs":"d5de857162185d4a2384f3cb644bfcf76c7f5c1a3b5f72bfa0d2620ac6e3873c","tests/macros.rs":"71474339414ff573471de125f2d369da8caffbfe47fa2e9a18f2e87de20d2a79","tests/macros_incompatible_concat.rs":"5f3bcbb65e4ae39db1cfc2def62fc913c20bab0fb769c8f731504e2615585ee5","tests/max_level_hint.rs":"39576a958df3ea215c49154ff72c3dd14c8b3be3fcdb849e7dd847c8c9fd09e2","tests/missed_register_callsite.rs":"3211f0f030c9baf6333abf709d6520ced25619ee82cdf88a4e6ba8e1aff12296","tests/multiple_max_level_hints.rs":"28ead97a8424358a0632547dae987ddbddc5bb69cdcd996d20feb49a7f3ddc69","tests/no_subscriber.rs":"ca42d0d4a20eb3b4e0a342b5e0090c7ada8b5a157f3cddb7b5d051238cdc1202","tests/register_callsite_deadlock.rs":"c0b3142543e7a10065c7583a8ee0b6bc978ea4f3979599651101c5a28966e7c8","tests/scoped_clobbers_default.rs":"a7615615d176fb2a4b877c48d2aa7a75fca436d997d9672b56cc2c30177f889b","tests/span.rs":"91995aa0f59b09a6230ec146abcafce5710e6657159e4b6f47a56fb6ec76be8c","tests/subscriber.rs":"2da999bedb978bab019a70ccc9fdd43b062ec2e383af1e7c5b780df23adc219b"},"package":"784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"}

994
vendor/tracing/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,994 @@
# 0.1.41 (November 27, 2024)
[ [crates.io][crate-0.1.41] ] | [ [docs.rs][docs-0.1.41] ]
This release updates the `tracing-core` dependency to [v0.1.33][core-0.1.33] and
the `tracing-attributes` dependency to [v0.1.28][attrs-0.1.28].
### Added
- **core**: Add index API for `Field` ([#2820])
- **core**: Allow `&[u8]` to be recorded as event/span field ([#2954])
### Changed
- Bump MSRV to 1.63 ([#2793])
- **core**: Use const `thread_local`s when possible ([#2838])
### Fixed
- Removed core imports in macros ([#2762])
- **attributes**: Added missing RecordTypes for instrument ([#2781])
- **attributes**: Change order of async and unsafe modifier ([#2864])
- Fix missing field prefixes ([#2878])
- **attributes**: Extract match scrutinee ([#2880])
- Fix non-simple macro usage without message ([#2879])
- Fix event macros with constant field names in the first position ([#2883])
- Allow field path segments to be keywords ([#2925])
- **core**: Fix missed `register_callsite` error ([#2938])
- **attributes**: Support const values for `target` and `name` ([#2941])
- Prefix macro calls with ::core to avoid clashing with local macros ([#3024])
[#2762]: https://github.com/tokio-rs/tracing/pull/2762
[#2781]: https://github.com/tokio-rs/tracing/pull/2781
[#2793]: https://github.com/tokio-rs/tracing/pull/2793
[#2820]: https://github.com/tokio-rs/tracing/pull/2820
[#2838]: https://github.com/tokio-rs/tracing/pull/2838
[#2864]: https://github.com/tokio-rs/tracing/pull/2864
[#2878]: https://github.com/tokio-rs/tracing/pull/2878
[#2879]: https://github.com/tokio-rs/tracing/pull/2879
[#2880]: https://github.com/tokio-rs/tracing/pull/2880
[#2883]: https://github.com/tokio-rs/tracing/pull/2883
[#2925]: https://github.com/tokio-rs/tracing/pull/2925
[#2938]: https://github.com/tokio-rs/tracing/pull/2938
[#2941]: https://github.com/tokio-rs/tracing/pull/2941
[#2954]: https://github.com/tokio-rs/tracing/pull/2954
[#3024]: https://github.com/tokio-rs/tracing/pull/3024
[attrs-0.1.28]:
https://github.com/tokio-rs/tracing/releases/tag/tracing-attributes-0.1.28
[core-0.1.33]:
https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.33
[docs-0.1.41]: https://docs.rs/tracing/0.1.41/tracing/
[crate-0.1.41]: https://crates.io/crates/tracing/0.1.41
# 0.1.40 (October 19, 2023)
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 interchangeably 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

250
vendor/tracing/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,250 @@
# 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.63.0"
name = "tracing"
version = "0.1.41"
authors = [
"Eliza Weisman <eliza@buoyant.io>",
"Tokio Contributors <team@tokio.rs>",
]
build = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
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"
resolver = "2"
[package.metadata.docs.rs]
all-features = true
rustc-args = [
"--cfg",
"tracing_unstable",
]
rustdoc-args = [
"--cfg",
"docsrs",
"--cfg",
"tracing_unstable",
]
[lib]
name = "tracing"
path = "src/lib.rs"
[[test]]
name = "enabled"
path = "tests/enabled.rs"
[[test]]
name = "event"
path = "tests/event.rs"
[[test]]
name = "filter_caching_is_lexically_scoped"
path = "tests/filter_caching_is_lexically_scoped.rs"
[[test]]
name = "filters_are_not_reevaluated_for_the_same_span"
path = "tests/filters_are_not_reevaluated_for_the_same_span.rs"
[[test]]
name = "filters_are_reevaluated_for_different_call_sites"
path = "tests/filters_are_reevaluated_for_different_call_sites.rs"
[[test]]
name = "filters_dont_leak"
path = "tests/filters_dont_leak.rs"
[[test]]
name = "future_send"
path = "tests/future_send.rs"
[[test]]
name = "instrument"
path = "tests/instrument.rs"
[[test]]
name = "macro_imports"
path = "tests/macro_imports.rs"
[[test]]
name = "macros"
path = "tests/macros.rs"
[[test]]
name = "macros_incompatible_concat"
path = "tests/macros_incompatible_concat.rs"
[[test]]
name = "max_level_hint"
path = "tests/max_level_hint.rs"
[[test]]
name = "missed_register_callsite"
path = "tests/missed_register_callsite.rs"
[[test]]
name = "multiple_max_level_hints"
path = "tests/multiple_max_level_hints.rs"
[[test]]
name = "no_subscriber"
path = "tests/no_subscriber.rs"
[[test]]
name = "register_callsite_deadlock"
path = "tests/register_callsite_deadlock.rs"
[[test]]
name = "scoped_clobbers_default"
path = "tests/scoped_clobbers_default.rs"
[[test]]
name = "span"
path = "tests/span.rs"
[[test]]
name = "subscriber"
path = "tests/subscriber.rs"
[[bench]]
name = "baseline"
path = "benches/baseline.rs"
harness = false
[[bench]]
name = "dispatch_get_clone"
path = "benches/dispatch_get_clone.rs"
harness = false
[[bench]]
name = "dispatch_get_ref"
path = "benches/dispatch_get_ref.rs"
harness = false
[[bench]]
name = "empty_span"
path = "benches/empty_span.rs"
harness = false
[[bench]]
name = "enter_span"
path = "benches/enter_span.rs"
harness = false
[[bench]]
name = "event"
path = "benches/event.rs"
harness = false
[[bench]]
name = "shared"
path = "benches/shared.rs"
[[bench]]
name = "span_fields"
path = "benches/span_fields.rs"
harness = false
[[bench]]
name = "span_no_fields"
path = "benches/span_no_fields.rs"
harness = false
[[bench]]
name = "span_repeated"
path = "benches/span_repeated.rs"
harness = false
[dependencies.log]
version = "0.4.17"
optional = true
[dependencies.pin-project-lite]
version = "0.2.9"
[dependencies.tracing-attributes]
version = "0.1.28"
optional = true
[dependencies.tracing-core]
version = "0.1.33"
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.38"
[badges.maintenance]
status = "actively-developed"
[lints.rust.unexpected_cfgs]
level = "warn"
priority = 0
check-cfg = [
"cfg(flaky_tests)",
"cfg(tracing_unstable)",
]

25
vendor/tracing/LICENSE vendored Normal file
View 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.

469
vendor/tracing/README.md vendored Normal file
View File

@@ -0,0 +1,469 @@
![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.63+][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. Parameters 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 initialized.
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.41/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.41/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.
- [`json-subscriber`] provides a layer for emitting JSON logs. The output can be customized much more than with [`FmtSubscriber`]'s JSON output.
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
[`json-subscriber`]: https://crates.io/crates/json-subscriber
**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.63. 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
vendor/tracing/benches/baseline.rs vendored Normal file
View 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);

View 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);

View 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(&current);
})
})
});
}
criterion_group!(benches, bench);
criterion_main!(benches);

43
vendor/tracing/benches/empty_span.rs vendored Normal file
View 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
vendor/tracing/benches/enter_span.rs vendored Normal file
View 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
vendor/tracing/benches/event.rs vendored Normal file
View 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
vendor/tracing/benches/shared.rs vendored Normal file
View 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
vendor/tracing/benches/span_fields.rs vendored Normal file
View 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);

View 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
vendor/tracing/benches/span_repeated.rs vendored Normal file
View 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
vendor/tracing/src/dispatcher.rs vendored Normal file
View 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
vendor/tracing/src/field.rs vendored Normal file
View 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
vendor/tracing/src/instrument.rs vendored Normal file
View 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
vendor/tracing/src/level_filters.rs vendored Normal file
View 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
}
}

1131
vendor/tracing/src/lib.rs vendored Normal file

File diff suppressed because it is too large Load Diff

3160
vendor/tracing/src/macros.rs vendored Normal file

File diff suppressed because it is too large Load Diff

1609
vendor/tracing/src/span.rs vendored Normal file

File diff suppressed because it is too large Load Diff

55
vendor/tracing/src/stdlib.rs vendored Normal file
View 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
vendor/tracing/src/subscriber.rs vendored Normal file
View 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
vendor/tracing/tests/enabled.rs vendored Normal file
View 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 correctly
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));
}

620
vendor/tracing/tests/event.rs vendored Normal file
View File

@@ -0,0 +1,620 @@
// 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(expect::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(expect::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_ancestry(expect::has_explicit_parent("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_ancestry(expect::has_explicit_parent("foo")))
.event(expect::event().with_ancestry(expect::has_explicit_parent("foo")))
.event(expect::event().with_ancestry(expect::has_explicit_parent("foo")))
.event(expect::event().with_ancestry(expect::has_explicit_parent("foo")))
.event(expect::event().with_ancestry(expect::has_explicit_parent("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())
.event(expect_event())
.event(expect_event())
.event(expect_event())
.event(expect_event())
.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"
);
tracing::info!(
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
"quux"
);
tracing::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"
);
tracing::event!(
Level::INFO,
{
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
},
"{}",
"quux"
);
tracing::info!(
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
"{}",
"quux"
);
tracing::info!(
{
{ std::convert::identity(FOO) } = "bar",
{ "constant string" } = "also works",
foo.bar = "baz",
},
"{}",
"quux"
);
});
handle.assert_finished();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn keyword_ident_in_field_name() {
let (subscriber, handle) = subscriber::mock()
.event(expect::event().with_fields(expect::field("crate").with_value(&"tracing")))
.only()
.run_with_handle();
with_default(subscriber, || error!(crate = "tracing", "message"));
handle.assert_finished();
}

View 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);
}

View 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();
}

View 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);
}

View 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
vendor/tracing/tests/future_send.rs vendored Normal file
View 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) {}

68
vendor/tracing/tests/instrument.rs vendored Normal file
View File

@@ -0,0 +1,68 @@
// 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");
}
}
#[allow(dead_code)] // Field not used, but logs on `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()
.with_ancestry(expect::has_contextual_parent("foo"))
.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()
.with_ancestry(expect::has_contextual_parent("bar"))
.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
vendor/tracing/tests/macro_imports.rs vendored Normal file
View 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");
}

1387
vendor/tracing/tests/macros.rs vendored Normal file

File diff suppressed because it is too large Load Diff

View 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
vendor/tracing/tests/max_level_hint.rs vendored Normal file
View 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();
}

View File

@@ -0,0 +1,109 @@
use std::{
ptr,
sync::atomic::{AtomicPtr, Ordering},
thread::{self, JoinHandle},
time::Duration,
};
use tracing::Subscriber;
use tracing_core::{span, Metadata};
struct TestSubscriber {
creator_thread: String,
sleep: Duration,
callsite: AtomicPtr<Metadata<'static>>,
}
impl TestSubscriber {
fn new(sleep_micros: u64) -> Self {
let creator_thread = thread::current()
.name()
.unwrap_or("<unknown thread>")
.to_owned();
Self {
creator_thread,
sleep: Duration::from_micros(sleep_micros),
callsite: AtomicPtr::new(ptr::null_mut()),
}
}
}
impl Subscriber for TestSubscriber {
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> tracing_core::Interest {
if !self.sleep.is_zero() {
thread::sleep(self.sleep);
}
self.callsite
.store(metadata as *const _ as *mut _, Ordering::SeqCst);
println!(
"{creator} from {thread:?}: register_callsite: {callsite:#?}",
creator = self.creator_thread,
callsite = metadata as *const _,
thread = thread::current().name(),
);
tracing_core::Interest::always()
}
fn event(&self, event: &tracing_core::Event<'_>) {
let stored_callsite = self.callsite.load(Ordering::SeqCst);
let event_callsite: *mut Metadata<'static> = event.metadata() as *const _ as *mut _;
println!(
"{creator} from {thread:?}: event (with callsite): {event_callsite:#?} (stored callsite: {stored_callsite:#?})",
creator = self.creator_thread,
thread = thread::current().name(),
);
// This assert is the actual test.
assert_eq!(
stored_callsite, event_callsite,
"stored callsite: {stored_callsite:#?} does not match event \
callsite: {event_callsite:#?}. Was `event` called before \
`register_callsite`?"
);
}
fn enabled(&self, _metadata: &Metadata<'_>) -> bool {
true
}
fn new_span(&self, _span: &span::Attributes<'_>) -> span::Id {
span::Id::from_u64(0)
}
fn record(&self, _span: &span::Id, _values: &span::Record<'_>) {}
fn record_follows_from(&self, _span: &span::Id, _follows: &span::Id) {}
fn enter(&self, _span: &tracing_core::span::Id) {}
fn exit(&self, _span: &tracing_core::span::Id) {}
}
fn subscriber_thread(idx: usize, register_sleep_micros: u64) -> JoinHandle<()> {
thread::Builder::new()
.name(format!("subscriber-{idx}"))
.spawn(move || {
// We use a sleep to ensure the starting order of the 2 threads.
let subscriber = TestSubscriber::new(register_sleep_micros);
let _subscriber_guard = tracing::subscriber::set_default(subscriber);
tracing::info!("event-from-{idx}", idx = idx);
// Wait a bit for everything to end (we don't want to remove the subscriber
// immediately because that will mix up the test).
thread::sleep(Duration::from_millis(100));
})
.expect("failed to spawn thread")
}
#[test]
fn event_before_register() {
let subscriber_1_register_sleep_micros = 100;
let subscriber_2_register_sleep_micros = 0;
let jh1 = subscriber_thread(1, subscriber_1_register_sleep_micros);
// This delay ensures that the event!() in the first thread is executed first.
thread::sleep(Duration::from_micros(50));
let jh2 = subscriber_thread(2, subscriber_2_register_sleep_micros);
jh1.join().expect("failed to join thread");
jh2.join().expect("failed to join thread");
}

View 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
vendor/tracing/tests/no_subscriber.rs vendored Normal file
View 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();
}

View 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");
}

View File

@@ -0,0 +1,35 @@
#![cfg(feature = "std")]
use tracing_mock::{expect, subscriber};
#[test]
fn scoped_clobbers_global() {
// Reproduces https://github.com/tokio-rs/tracing/issues/2050
let (scoped, scoped_handle) = subscriber::mock()
.event(expect::event().with_fields(expect::msg("before global")))
.event(expect::event().with_fields(expect::msg("before drop")))
.only()
.run_with_handle();
let (global, global_handle) = subscriber::mock()
.event(expect::event().with_fields(expect::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();
}

918
vendor/tracing/tests/span.rs vendored Normal file
View File

@@ -0,0 +1,918 @@
// 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::{
error_span,
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_fields(
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_fields(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_fields(
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_fields(
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_fields(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_fields(
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_fields(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_fields(
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_fields(
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_ancestry(expect::is_explicit_root()),
)
.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_ancestry(expect::is_explicit_root()),
)
.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_ancestry(expect::has_explicit_parent("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_ancestry(expect::has_explicit_parent("foo")),
)
.new_span(
expect::span()
.named("b")
.with_ancestry(expect::has_explicit_parent("foo")),
)
.new_span(
expect::span()
.named("c")
.with_ancestry(expect::has_explicit_parent("foo")),
)
.new_span(
expect::span()
.named("d")
.with_ancestry(expect::has_explicit_parent("foo")),
)
.new_span(
expect::span()
.named("e")
.with_ancestry(expect::has_explicit_parent("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_ancestry(expect::has_explicit_parent("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_ancestry(expect::is_contextual_root()),
)
.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_ancestry(expect::has_contextual_parent("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_fields(
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_fields(
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_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::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_fields(
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();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn keyword_ident_in_field_name_span_macro() {
#[derive(Debug)]
struct Foo;
let (subscriber, handle) = subscriber::mock()
.new_span(expect::span().with_fields(expect::field("self").with_value(&debug(Foo)).only()))
.only()
.run_with_handle();
with_default(subscriber, || {
error_span!("span", self = ?Foo);
});
handle.assert_finished();
}

129
vendor/tracing/tests/subscriber.rs vendored Normal file
View 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_fields(
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_fields(
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();
}