Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/tracing-core/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/tracing-core/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"CHANGELOG.md":"5c72ced3c4b609b6121b0ca5f980f8292f8b542d3f11c7b97581f23fd6ab7e1b","Cargo.toml":"7ae6601ad9768415a61eba2be6c82e30c71c6d3c76561f230ce6eafa2e66255f","LICENSE":"898b1ae9821e98daf8964c8d6c7f61641f5f5aa78ad500020771c0939ee0dea1","README.md":"0ace2b660151cc4aa04d954daef0b60151c2f797d695dfb0b78d931f497c82ac","src/callsite.rs":"83789dd16601faa675e2c75e1bbfe1512c2d4b405b880bf99db2a6f6bbb15363","src/dispatcher.rs":"2a751f9256e8418105d1f7134fd80500f39b920c8a17b02eaf3dcd701d1737ad","src/event.rs":"f2673bf5d266972e567e521c9cd92fb33f28b0c7e010937e3bc2bf9eb483087f","src/field.rs":"0f7ec541d932beae7ee67d0fcb09cfeabacdcb4ee6310a7b20f9fb07a75e091f","src/lazy.rs":"318e3558e4446abf26294287167c0788e343044a28072f9217bd985929809087","src/lib.rs":"d0f56d6d890f721e1d769376f500dc3e80b7ac969330c98049c344fda47a107a","src/metadata.rs":"319e8a80804c7e927595e73d2139c027b2c4d58887af4a95ab2bb3411e7ab3d1","src/parent.rs":"5d5ad733343280a64a1feb6a008e186c39305ec554f14279012b8d7915821471","src/span.rs":"dcf2135e4ca158c1be45007f0be25426c375a4081f8f3c5a4d7f7382d8a950a4","src/spin/LICENSE":"58545fed1565e42d687aecec6897d35c6d37ccb71479a137c0deb2203e125c79","src/spin/mod.rs":"c458ce5e875acb7fbfb279f23254f4924d7c6d6fee419b740800d2e8087d1524","src/spin/mutex.rs":"4d30ff2b59b18fd7909f016e1abdf9aa0c04aa11d047a46e98cffe1319e32dad","src/spin/once.rs":"3781fd4eae0db04d80c03a039906c99b1e01d1583b29ac0144e6fbbd5a0fef0b","src/stdlib.rs":"698693062b8109cace3ffea02e9c2372b7d5b5d43c0b11cb4800b0e7b1a69971","src/subscriber.rs":"c7b6d52633e479bcad50fc30e1bf596339e575533761d269498cfc79e99020ef","tests/common/mod.rs":"0bbb217baa17df0f96cc1ff57dfa74ccc5a959e7f66b15bb7d25d5f43358a278","tests/dispatch.rs":"d3f000fab43734a854c82a7783142910c5e79f806cbd3f8ec5eded598c59ddb1","tests/global_dispatch.rs":"cdc05d77e448ee8b50bfb930abafa3f19b4c6f922b7bebc7797fa1dbdaa1d398","tests/local_dispatch_before_init.rs":"338846cd519e9a3a6895f958b11bd3f97e4350d08adb50f95b8552113a593b0d","tests/macros.rs":"b1603d888b349c8d103794deceec3b1ae4538b8d3eba805f3f561899e8ad0dd2"},"package":"c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"}
|
||||
541
third-party/vendor/tracing-core/CHANGELOG.md
vendored
Normal file
541
third-party/vendor/tracing-core/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,541 @@
|
|||
# 0.1.32 (October 13, 2023)
|
||||
|
||||
### Documented
|
||||
|
||||
- Fix typo in `field` docs ([#2611])
|
||||
- Remove duplicate wording ([#2674])
|
||||
|
||||
### Changed
|
||||
|
||||
- Allow `ValueSet`s of any length ([#2508])
|
||||
|
||||
[#2611]: https://github.com/tokio-rs/tracing/pull/2611
|
||||
[#2674]: https://github.com/tokio-rs/tracing/pull/2674
|
||||
[#2508]: https://github.com/tokio-rs/tracing/pull/2508
|
||||
|
||||
# 0.1.31 (May 11, 2023)
|
||||
|
||||
This release of `tracing-core` fixes a bug that caused threads which call
|
||||
`dispatcher::get_default` _before_ a global default subscriber is set to never
|
||||
see the global default once it is set. In addition, it includes improvements for
|
||||
instrumentation performance in some cases, especially when using a global
|
||||
default dispatcher.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed incorrect thread-local caching of `Dispatch::none` if
|
||||
`dispatcher::get_default` is called before `dispatcher::set_global_default`
|
||||
([#2593])
|
||||
|
||||
### Changed
|
||||
|
||||
- Cloning a `Dispatch` that points at a global default subscriber no longer
|
||||
requires an `Arc` reference count increment, improving performance
|
||||
substantially ([#2593])
|
||||
- `dispatcher::get_default` no longer attempts to access a thread local if the
|
||||
scoped dispatcher is not in use, improving performance when the default
|
||||
dispatcher is global ([#2593])
|
||||
- Added `#[inline]` annotations called by the `event!` and `span!` macros to
|
||||
reduce the size of macro-generated code and improve recording performance
|
||||
([#2555])
|
||||
|
||||
Thanks to new contributor @ldm0 for contributing to this release!
|
||||
|
||||
[#2593]: https://github.com/tokio-rs/tracing/pull/2593
|
||||
[#2555]: https://github.com/tokio-rs/tracing/pull/2555
|
||||
|
||||
# 0.1.30 (October 6, 2022)
|
||||
|
||||
This release of `tracing-core` adds a new `on_register_dispatch` method to the
|
||||
`Subscriber` trait to allow the `Subscriber` to perform initialization after
|
||||
being registered as a `Dispatch`, and a `WeakDispatch` type to allow a
|
||||
`Subscriber` to store its own `Dispatch` without creating reference count
|
||||
cycles.
|
||||
|
||||
### Added
|
||||
|
||||
- `Subscriber::on_register_dispatch` method ([#2269])
|
||||
- `WeakDispatch` type and `Dispatch::downgrade()` function ([#2293])
|
||||
|
||||
Thanks to @jswrenn for contributing to this release!
|
||||
|
||||
[#2269]: https://github.com/tokio-rs/tracing/pull/2269
|
||||
[#2293]: https://github.com/tokio-rs/tracing/pull/2293
|
||||
|
||||
# 0.1.29 (July 29, 2022)
|
||||
|
||||
This release of `tracing-core` adds `PartialEq` and `Eq` implementations for
|
||||
metadata types, and improves error messages when setting the global default
|
||||
subscriber fails.
|
||||
|
||||
### Added
|
||||
|
||||
- `PartialEq` and `Eq` implementations for `Metadata` ([#2229])
|
||||
- `PartialEq` and `Eq` implementations for `FieldSet` ([#2229])
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed unhelpful `fmt::Debug` output for `dispatcher::SetGlobalDefaultError`
|
||||
([#2250])
|
||||
- Fixed compilation with `-Z minimal-versions` ([#2246])
|
||||
|
||||
Thanks to @jswrenn and @CAD97 for contributing to this release!
|
||||
|
||||
[#2229]: https://github.com/tokio-rs/tracing/pull/2229
|
||||
[#2246]: https://github.com/tokio-rs/tracing/pull/2246
|
||||
[#2250]: https://github.com/tokio-rs/tracing/pull/2250
|
||||
|
||||
# 0.1.28 (June 23, 2022)
|
||||
|
||||
This release of `tracing-core` adds new `Value` implementations, including one
|
||||
for `String`, to allow recording `&String` as a value without having to call
|
||||
`as_str()` or similar, and for 128-bit integers (`i128` and `u128`). In
|
||||
addition, it adds new methods and trait implementations for `Subscriber`s.
|
||||
|
||||
### Added
|
||||
|
||||
- `Value` implementation for `String` ([#2164])
|
||||
- `Value` implementation for `u128` and `i28` ([#2166])
|
||||
- `downcast_ref` and `is` methods for `dyn Subscriber + Sync`,
|
||||
`dyn Subscriber + Send`, and `dyn Subscriber + Send + Sync` ([#2160])
|
||||
- `Subscriber::event_enabled` method to enable filtering based on `Event` field
|
||||
values ([#2008])
|
||||
- `Subscriber` implementation for `Box<S: Subscriber + ?Sized>` and
|
||||
`Arc<S: Subscriber + ?Sized>` ([#2161])
|
||||
|
||||
Thanks to @jswrenn and @CAD97 for contributing to this release!
|
||||
|
||||
[#2164]: https://github.com/tokio-rs/tracing/pull/2164
|
||||
[#2166]: https://github.com/tokio-rs/tracing/pull/2166
|
||||
[#2160]: https://github.com/tokio-rs/tracing/pull/2160
|
||||
[#2008]: https://github.com/tokio-rs/tracing/pull/2008
|
||||
[#2161]: https://github.com/tokio-rs/tracing/pull/2161
|
||||
|
||||
# 0.1.27 (June 7, 2022)
|
||||
|
||||
This release of `tracing-core` introduces a new `DefaultCallsite` type, which
|
||||
can be used by instrumentation crates rather than implementing their own
|
||||
callsite types. Using `DefaultCallsite` may offer reduced overhead from callsite
|
||||
registration.
|
||||
|
||||
### Added
|
||||
|
||||
- `DefaultCallsite`, a pre-written `Callsite` implementation for use in
|
||||
instrumentation crates ([#2083])
|
||||
- `ValueSet::len` and `Record::len` methods returning the number of fields in a
|
||||
`ValueSet` or `Record` ([#2152])
|
||||
|
||||
### Changed
|
||||
|
||||
- Replaced `lazy_static` dependency with `once_cell` ([#2147])
|
||||
|
||||
### Documented
|
||||
|
||||
- Added documentation to the `callsite` module ([#2088], [#2149])
|
||||
|
||||
Thanks to new contributors @jamesmunns and @james7132 for contributing to this
|
||||
release!
|
||||
|
||||
[#2083]: https://github.com/tokio-rs/tracing/pull/2083
|
||||
[#2152]: https://github.com/tokio-rs/tracing/pull/2152
|
||||
[#2147]: https://github.com/tokio-rs/tracing/pull/2147
|
||||
[#2088]: https://github.com/tokio-rs/tracing/pull/2088
|
||||
[#2149]: https://github.com/tokio-rs/tracing/pull/2149
|
||||
|
||||
# 0.1.26 (April 14, 2022)
|
||||
|
||||
This release adds a `Value` implementation for `Box<T: Value>` to allow
|
||||
recording boxed values more conveniently. In particular, this should improve
|
||||
the ergonomics of the implementations for `dyn std::error::Error` trait objects,
|
||||
including those added in [v0.1.25].
|
||||
|
||||
### Added
|
||||
|
||||
- `Value` implementation for `Box<T> where T: Value` ([#2071])
|
||||
|
||||
### Fixed
|
||||
|
||||
- Broken documentation links ([#2068])
|
||||
|
||||
Thanks to new contributor @ben0x539 for contributing to this release!
|
||||
|
||||
|
||||
[v0.1.25]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.25
|
||||
[#2071]: https://github.com/tokio-rs/tracing/pull/2071
|
||||
[#2068]: https://github.com/tokio-rs/tracing/pull/2068
|
||||
|
||||
# 0.1.25 (April 12, 2022)
|
||||
|
||||
This release adds additional `Value` implementations for `std::error::Error`
|
||||
trait objects with auto trait bounds (`Send` and `Sync`), as Rust will not
|
||||
auto-coerce trait objects. Additionally, it fixes a bug when setting scoped
|
||||
dispatchers that was introduced in the previous release ([v0.1.24]).
|
||||
|
||||
### Added
|
||||
|
||||
- `Value` implementations for `dyn Error + Send + 'static`, `dyn Error + Send +
|
||||
Sync + 'static`, `dyn Error + Sync + 'static` ([#2066])
|
||||
|
||||
### Fixed
|
||||
|
||||
- Failure to use the global default dispatcher if a thread has set a scoped
|
||||
default prior to setting the global default, and unset the scoped default
|
||||
after setting the global default ([#2065])
|
||||
|
||||
Thanks to @lilyball for contributing to this release!
|
||||
|
||||
[v0.1.24]: https://github.com/tokio-rs/tracing/releases/tag/tracing-core-0.1.24
|
||||
[#2066]: https://github.com/tokio-rs/tracing/pull/2066
|
||||
[#2065]: https://github.com/tokio-rs/tracing/pull/2065
|
||||
|
||||
# 0.1.24 (April 1, 2022)
|
||||
|
||||
This release fixes a bug where setting `NoSubscriber` as the local default would
|
||||
not disable the global default subscriber locally.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Setting `NoSubscriber` as the local default now correctly disables the global
|
||||
default subscriber ([#2001])
|
||||
- Fixed compilation warnings with the "std" feature disabled ([#2022])
|
||||
|
||||
### Changed
|
||||
|
||||
- Removed unnecessary use of `write!` and `format_args!` macros ([#1988])
|
||||
|
||||
[#1988]: https://github.com/tokio-rs/tracing/pull/1988
|
||||
[#2001]: https://github.com/tokio-rs/tracing/pull/2001
|
||||
[#2022]: https://github.com/tokio-rs/tracing/pull/2022
|
||||
|
||||
# 0.1.23 (March 8, 2022)
|
||||
|
||||
### Changed
|
||||
|
||||
- Removed `#[inline]` attributes from some `Dispatch` methods whose
|
||||
callers are now inlined ([#1974])
|
||||
- Bumped minimum supported Rust version (MSRV) to Rust 1.49.0 ([#1913])
|
||||
|
||||
[#1913]: https://github.com/tokio-rs/tracing/pull/1913
|
||||
[#1974]: https://github.com/tokio-rs/tracing/pull/1974
|
||||
|
||||
# 0.1.22 (February 3, 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.
|
||||
|
||||
### Added
|
||||
|
||||
- **field**: Experimental support for recording field values using the
|
||||
[`valuable`] crate ([#1608], [#1888], [#1887])
|
||||
- **field**: Added `ValueSet::record` method ([#1823])
|
||||
- **subscriber**: `Default` impl for `NoSubscriber` ([#1785])
|
||||
- **metadata**: New `Kind::HINT` to support the `enabled!` macro in `tracing`
|
||||
([#1883], [#1891])
|
||||
### Fixed
|
||||
|
||||
- Fixed a number of documentation issues ([#1665], [#1692], [#1737])
|
||||
|
||||
Thanks to @xd009642, @Skepfyr, @guswynn, @Folyd, and @mbergkvist for
|
||||
contributing to this release!
|
||||
|
||||
[`valuable`]: https://crates.io/crates/valuable
|
||||
[post]: https://tokio.rs/blog/2021-05-valuable
|
||||
[#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
|
||||
[#1823]: https://github.com/tokio-rs/tracing/pull/1823
|
||||
[#1785]: https://github.com/tokio-rs/tracing/pull/1785
|
||||
[#1883]: https://github.com/tokio-rs/tracing/pull/1883
|
||||
[#1891]: https://github.com/tokio-rs/tracing/pull/1891
|
||||
[#1665]: https://github.com/tokio-rs/tracing/pull/1665
|
||||
[#1692]: https://github.com/tokio-rs/tracing/pull/1692
|
||||
[#1737]: https://github.com/tokio-rs/tracing/pull/1737
|
||||
|
||||
# 0.1.21 (October 1, 2021)
|
||||
|
||||
This release adds support for recording `Option<T> where T: Value` as typed
|
||||
`tracing` field values.
|
||||
|
||||
### Added
|
||||
|
||||
- **field**: `Value` impl for `Option<T> where T: Value` ([#1585])
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed deprecation warnings when building with `default-features` disabled
|
||||
([#1603], [#1606])
|
||||
- Documentation fixes and improvements ([#1595], [#1601])
|
||||
|
||||
Thanks to @brianburgers, @DCjanus, and @matklad for contributing to this
|
||||
release!
|
||||
|
||||
[#1585]: https://github.com/tokio-rs/tracing/pull/1585
|
||||
[#1595]: https://github.com/tokio-rs/tracing/pull/1595
|
||||
[#1601]: https://github.com/tokio-rs/tracing/pull/1601
|
||||
[#1603]: https://github.com/tokio-rs/tracing/pull/1603
|
||||
[#1606]: https://github.com/tokio-rs/tracing/pull/1606
|
||||
|
||||
# 0.1.20 (September 12, 2021)
|
||||
|
||||
This release adds support for `f64` as one of the `tracing-core`
|
||||
primitive field values, allowing floating-point values to be recorded as
|
||||
typed values rather than with `fmt::Debug`. Additionally, it adds
|
||||
`NoSubscriber`, a `Subscriber` implementation that does nothing.
|
||||
|
||||
### Added
|
||||
|
||||
- **subscriber**: `NoSubscriber`, a no-op `Subscriber` implementation
|
||||
([#1549])
|
||||
- **field**: Added `Visit::record_f64` and support for recording
|
||||
floating-point values ([#1507])
|
||||
|
||||
Thanks to new contributors @jsgf and @maxburke for contributing to this
|
||||
release!
|
||||
|
||||
[#1549]: https://github.com/tokio-rs/tracing/pull/1549
|
||||
[#1507]: https://github.com/tokio-rs/tracing/pull/1507
|
||||
|
||||
# 0.1.19 (August 17, 2021)
|
||||
### Added
|
||||
|
||||
- `Level::as_str` ([#1413])
|
||||
- `Hash` implementation for `Level` and `LevelFilter` ([#1456])
|
||||
- `Value` implementation for `&mut T where T: Value` ([#1385])
|
||||
- Multiple documentation fixes and improvements ([#1435], [#1446])
|
||||
|
||||
Thanks to @Folyd, @teozkr, and @dvdplm for contributing to this release!
|
||||
|
||||
[#1413]: https://github.com/tokio-rs/tracing/pull/1413
|
||||
[#1456]: https://github.com/tokio-rs/tracing/pull/1456
|
||||
[#1385]: https://github.com/tokio-rs/tracing/pull/1385
|
||||
[#1435]: https://github.com/tokio-rs/tracing/pull/1435
|
||||
[#1446]: https://github.com/tokio-rs/tracing/pull/1446
|
||||
|
||||
# 0.1.18 (April 30, 2021)
|
||||
|
||||
### 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 `Current` and `Option<Id>`
|
||||
([#1335])
|
||||
- `Attributes::fields` accessor that returns the set of fields defined on a
|
||||
span's `Attributes` ([#1331])
|
||||
|
||||
|
||||
Thanks to @Folyd for contributing to this release!
|
||||
|
||||
[#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.17 (September 28, 2020)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Incorrect inlining of `Event::dispatch` and `Event::child_of`, which could
|
||||
result in `dispatcher::get_default` being inlined at the callsite ([#994])
|
||||
|
||||
### Added
|
||||
|
||||
- `Copy` implementations for `Level` and `LevelFilter` ([#992])
|
||||
|
||||
Thanks to new contributors @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
|
||||
|
||||
# 0.1.16 (September 8, 2020)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Added a conversion from `Option<Level>` to `LevelFilter`. This resolves a
|
||||
previously unreported regression where `Option<Level>` was no longer
|
||||
a valid LevelFilter. ([#966](https://github.com/tokio-rs/tracing/pull/966))
|
||||
|
||||
# 0.1.15 (August 22, 2020)
|
||||
|
||||
### Fixed
|
||||
|
||||
- When combining `Interest` from multiple subscribers, if the interests differ,
|
||||
the current subscriber is now always asked if a callsite should be enabled
|
||||
(#927)
|
||||
|
||||
## Added
|
||||
|
||||
- Internal API changes to support optimizations in the `tracing` crate (#943)
|
||||
- **docs**: Multiple fixes and improvements (#913, #941)
|
||||
|
||||
# 0.1.14 (August 10, 2020)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Incorrect calculation of global max level filter which could result in fast
|
||||
filtering paths not being taken (#908)
|
||||
|
||||
# 0.1.13 (August 4, 2020)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Missing `fmt::Display` impl for `field::DisplayValue` causing a compilation
|
||||
failure when the "log" feature is enabled (#887)
|
||||
|
||||
Thanks to @d-e-s-o for contributing to this release!
|
||||
|
||||
# 0.1.12 (July 31, 2020)
|
||||
|
||||
### Added
|
||||
|
||||
- `LevelFilter` type and `LevelFilter::current()` for returning 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)
|
||||
|
||||
### Fixed
|
||||
|
||||
- **docs**: Removed outdated reference to a Tokio API that no longer exists
|
||||
(#857)
|
||||
|
||||
Thanks to new contributor @dignati for contributing to this release!
|
||||
|
||||
# 0.1.11 (June 8, 2020)
|
||||
|
||||
### Changed
|
||||
|
||||
- Replaced use of `inner_local_macros` with `$crate::` (#729)
|
||||
|
||||
### Added
|
||||
|
||||
- `must_use` warning to guards returned by `dispatcher::set_default` (#686)
|
||||
- `fmt::Debug` impl to `dyn Value`s (#696)
|
||||
- Functions to convert between `span::Id` and `NonZeroU64` (#770)
|
||||
- More obvious warnings in documentation (#769)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Compiler error when `tracing-core/std` feature is enabled but `tracing/std` is
|
||||
not (#760)
|
||||
- Clippy warning on vtable address comparison in `callsite::Identifier` (#749)
|
||||
- Documentation formatting issues (#715, #771)
|
||||
|
||||
Thanks to @bkchr, @majecty, @taiki-e, @nagisa, and @nvzqz for contributing to
|
||||
this release!
|
||||
|
||||
# 0.1.10 (January 24, 2020)
|
||||
|
||||
### Added
|
||||
|
||||
- `field::Empty` type for declaring empty fields whose values will be recorded
|
||||
later (#548)
|
||||
- `field::Value` implementations for `Wrapping` and `NonZero*` numbers (#538)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Broken and unresolvable links in RustDoc (#595)
|
||||
|
||||
Thanks to @oli-cosmian for contributing to this release!
|
||||
|
||||
# 0.1.9 (January 10, 2020)
|
||||
|
||||
### Added
|
||||
|
||||
- API docs now show what feature flags are required to enable each item (#523)
|
||||
|
||||
### Fixed
|
||||
|
||||
- A panic when the current default subscriber subscriber calls
|
||||
`dispatcher::with_default` as it is being dropped (#522)
|
||||
- Incorrect documentation for `Subscriber::drop_span` (#524)
|
||||
|
||||
# 0.1.8 (December 20, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- `Default` impl for `Dispatch` (#411)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Removed duplicate `lazy_static` dependencies (#424)
|
||||
- Fixed no-std dependencies being enabled even when `std` feature flag is set
|
||||
(#424)
|
||||
- Broken link to `Metadata` in `Event` docs (#461)
|
||||
|
||||
# 0.1.7 (October 18, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- Added `dispatcher::set_default` API which returns a drop guard (#388)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Added missing `Value` impl for `u8` (#392)
|
||||
- Broken links in docs.
|
||||
|
||||
# 0.1.6 (September 12, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- Internal APIs to support performance optimizations (#326)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Clarified wording in `field::display` documentation (#340)
|
||||
|
||||
# 0.1.5 (August 16, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- `std::error::Error` as a new primitive `Value` type (#277)
|
||||
- `Event::new` and `Event::new_child_of` to manually construct `Event`s (#281)
|
||||
|
||||
# 0.1.4 (August 9, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- Support for `no-std` + `liballoc` (#256)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Broken links in RustDoc (#259)
|
||||
|
||||
# 0.1.3 (August 8, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- `std::fmt::Display` implementation for `Level` (#194)
|
||||
- `std::str::FromStr` implementation for `Level` (#195)
|
||||
|
||||
# 0.1.2 (July 10, 2019)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- `Subscriber::drop_span` in favor of new `Subscriber::try_close` (#168)
|
||||
|
||||
### Added
|
||||
|
||||
- `Into<Option<&Id>>`, `Into<Option<Id>>`, and
|
||||
`Into<Option<&'static Metadata<'static>>>` impls for `span::Current` (#170)
|
||||
- `Subscriber::try_close` method (#153)
|
||||
- Improved documentation for `dispatcher` (#171)
|
||||
|
||||
# 0.1.1 (July 6, 2019)
|
||||
|
||||
### Added
|
||||
|
||||
- `Subscriber::current_span` API to return the current span (#148).
|
||||
- `span::Current` type, representing the `Subscriber`'s view of the current
|
||||
span (#148).
|
||||
|
||||
### Fixed
|
||||
|
||||
- Typos and broken links in documentation (#123, #124, #128, #154)
|
||||
|
||||
# 0.1.0 (June 27, 2019)
|
||||
|
||||
- Initial release
|
||||
66
third-party/vendor/tracing-core/Cargo.toml
vendored
Normal file
66
third-party/vendor/tracing-core/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
rust-version = "1.56.0"
|
||||
name = "tracing-core"
|
||||
version = "0.1.32"
|
||||
authors = ["Tokio Contributors <team@tokio.rs>"]
|
||||
description = """
|
||||
Core primitives for application-level tracing.
|
||||
"""
|
||||
homepage = "https://tokio.rs"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"logging",
|
||||
"tracing",
|
||||
"profiling",
|
||||
]
|
||||
categories = [
|
||||
"development-tools::debugging",
|
||||
"development-tools::profiling",
|
||||
"asynchronous",
|
||||
]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/tokio-rs/tracing"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustc-args = [
|
||||
"--cfg",
|
||||
"tracing_unstable",
|
||||
]
|
||||
rustdoc-args = [
|
||||
"--cfg",
|
||||
"docsrs",
|
||||
"--cfg",
|
||||
"tracing_unstable",
|
||||
]
|
||||
|
||||
[dependencies.once_cell]
|
||||
version = "1.13.0"
|
||||
optional = true
|
||||
|
||||
[features]
|
||||
default = [
|
||||
"std",
|
||||
"valuable/std",
|
||||
]
|
||||
std = ["once_cell"]
|
||||
|
||||
[target."cfg(tracing_unstable)".dependencies.valuable]
|
||||
version = "0.1.0"
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[badges.maintenance]
|
||||
status = "actively-developed"
|
||||
25
third-party/vendor/tracing-core/LICENSE
vendored
Normal file
25
third-party/vendor/tracing-core/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) 2019 Tokio Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
121
third-party/vendor/tracing-core/README.md
vendored
Normal file
121
third-party/vendor/tracing-core/README.md
vendored
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
![Tracing — Structured, application-level diagnostics][splash]
|
||||
|
||||
[splash]: https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/splash.svg
|
||||
|
||||
# tracing-core
|
||||
|
||||
Core primitives for application-level tracing.
|
||||
|
||||
[![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-core.svg
|
||||
[crates-url]: https://crates.io/crates/tracing-core/0.1.31
|
||||
[docs-badge]: https://docs.rs/tracing-core/badge.svg
|
||||
[docs-url]: https://docs.rs/tracing-core/0.1.31
|
||||
[docs-master-badge]: https://img.shields.io/badge/docs-master-blue
|
||||
[docs-master-url]: https://tracing-rs.netlify.com/tracing_core
|
||||
[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. This crate defines the core
|
||||
primitives of `tracing`.
|
||||
|
||||
The crate provides:
|
||||
|
||||
* [`span::Id`] identifies a span within the execution of a program.
|
||||
|
||||
* [`Event`] represents a single event within a trace.
|
||||
|
||||
* [`Subscriber`], the trait implemented to collect trace data.
|
||||
|
||||
* [`Metadata`] and [`Callsite`] provide information describing spans and
|
||||
events.
|
||||
|
||||
* [`Field`], [`FieldSet`], [`Value`], and [`ValueSet`] represent the
|
||||
structured data attached to spans and events.
|
||||
|
||||
* [`Dispatch`] allows spans and events to be dispatched to `Subscriber`s.
|
||||
|
||||
In addition, it defines the global callsite registry and per-thread current
|
||||
dispatcher which other components of the tracing system rely on.
|
||||
|
||||
*Compiler support: [requires `rustc` 1.56+][msrv]*
|
||||
|
||||
[msrv]: #supported-rust-versions
|
||||
|
||||
## Usage
|
||||
|
||||
Application authors will typically not use this crate directly. Instead, they
|
||||
will use the [`tracing`] crate, which provides a much more fully-featured
|
||||
API. However, this crate's API will change very infrequently, so it may be used
|
||||
when dependencies must be very stable.
|
||||
|
||||
`Subscriber` implementations may depend on `tracing-core` rather than `tracing`,
|
||||
as the additional APIs provided by `tracing` are primarily useful for
|
||||
instrumenting libraries and applications, and are generally not necessary for
|
||||
`Subscriber` implementations.
|
||||
|
||||
### Crate Feature Flags
|
||||
|
||||
The following crate feature flags are available:
|
||||
|
||||
* `std`: Depend on the Rust standard library (enabled by default).
|
||||
|
||||
`no_std` users may disable this feature with `default-features = false`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
tracing-core = { version = "0.1.31", default-features = false }
|
||||
```
|
||||
|
||||
**Note**:`tracing-core`'s `no_std` support requires `liballoc`.
|
||||
|
||||
[`tracing`]: ../tracing
|
||||
[`span::Id`]: https://docs.rs/tracing-core/0.1.31/tracing_core/span/struct.Id.html
|
||||
[`Event`]: https://docs.rs/tracing-core/0.1.31/tracing_core/event/struct.Event.html
|
||||
[`Subscriber`]: https://docs.rs/tracing-core/0.1.31/tracing_core/subscriber/trait.Subscriber.html
|
||||
[`Metadata`]: https://docs.rs/tracing-core/0.1.31/tracing_core/metadata/struct.Metadata.html
|
||||
[`Callsite`]: https://docs.rs/tracing-core/0.1.31/tracing_core/callsite/trait.Callsite.html
|
||||
[`Field`]: https://docs.rs/tracing-core/0.1.31/tracing_core/field/struct.Field.html
|
||||
[`FieldSet`]: https://docs.rs/tracing-core/0.1.31/tracing_core/field/struct.FieldSet.html
|
||||
[`Value`]: https://docs.rs/tracing-core/0.1.31/tracing_core/field/trait.Value.html
|
||||
[`ValueSet`]: https://docs.rs/tracing-core/0.1.31/tracing_core/field/struct.ValueSet.html
|
||||
[`Dispatch`]: https://docs.rs/tracing-core/0.1.31/tracing_core/dispatcher/struct.Dispatch.html
|
||||
|
||||
## Supported Rust Versions
|
||||
|
||||
Tracing is built against the latest stable release. The minimum supported
|
||||
version is 1.56. The current Tracing version is not guaranteed to build on Rust
|
||||
versions earlier than the minimum supported version.
|
||||
|
||||
Tracing follows the same compiler support policies as the rest of the Tokio
|
||||
project. The current stable Rust compiler and the three most recent minor
|
||||
versions before it will always be supported. For example, if the current stable
|
||||
compiler version is 1.69, the minimum supported version will not be increased
|
||||
past 1.69, 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.
|
||||
619
third-party/vendor/tracing-core/src/callsite.rs
vendored
Normal file
619
third-party/vendor/tracing-core/src/callsite.rs
vendored
Normal file
|
|
@ -0,0 +1,619 @@
|
|||
//! Callsites represent the source locations from which spans or events
|
||||
//! originate.
|
||||
//!
|
||||
//! # What Are Callsites?
|
||||
//!
|
||||
//! Every span or event in `tracing` is associated with a [`Callsite`]. A
|
||||
//! callsite is a small `static` value that is responsible for the following:
|
||||
//!
|
||||
//! * Storing the span or event's [`Metadata`],
|
||||
//! * Uniquely [identifying](Identifier) the span or event definition,
|
||||
//! * Caching the subscriber's [`Interest`][^1] in that span or event, to avoid
|
||||
//! re-evaluating filters.
|
||||
//!
|
||||
//! # Registering Callsites
|
||||
//!
|
||||
//! When a span or event is recorded for the first time, its callsite
|
||||
//! [`register`]s itself with the global callsite registry. Registering a
|
||||
//! callsite calls the [`Subscriber::register_callsite`][`register_callsite`]
|
||||
//! method with that callsite's [`Metadata`] on every currently active
|
||||
//! subscriber. This serves two primary purposes: informing subscribers of the
|
||||
//! callsite's existence, and performing static filtering.
|
||||
//!
|
||||
//! ## Callsite Existence
|
||||
//!
|
||||
//! If a [`Subscriber`] implementation wishes to allocate storage for each
|
||||
//! unique span/event location in the program, or pre-compute some value
|
||||
//! that will be used to record that span or event in the future, it can
|
||||
//! do so in its [`register_callsite`] method.
|
||||
//!
|
||||
//! ## Performing Static Filtering
|
||||
//!
|
||||
//! The [`register_callsite`] method returns an [`Interest`] value,
|
||||
//! which indicates that the subscriber either [always] wishes to record
|
||||
//! that span or event, [sometimes] wishes to record it based on a
|
||||
//! dynamic filter evaluation, or [never] wishes to record it.
|
||||
//!
|
||||
//! When registering a new callsite, the [`Interest`]s returned by every
|
||||
//! currently active subscriber are combined, and the result is stored at
|
||||
//! each callsite. This way, when the span or event occurs in the
|
||||
//! future, the cached [`Interest`] value can be checked efficiently
|
||||
//! to determine if the span or event should be recorded, without
|
||||
//! needing to perform expensive filtering (i.e. calling the
|
||||
//! [`Subscriber::enabled`] method every time a span or event occurs).
|
||||
//!
|
||||
//! ### Rebuilding Cached Interest
|
||||
//!
|
||||
//! When a new [`Dispatch`] is created (i.e. a new subscriber becomes
|
||||
//! active), any previously cached [`Interest`] values are re-evaluated
|
||||
//! for all callsites in the program. This way, if the new subscriber
|
||||
//! will enable a callsite that was not previously enabled, the
|
||||
//! [`Interest`] in that callsite is updated. Similarly, when a
|
||||
//! subscriber is dropped, the interest cache is also re-evaluated, so
|
||||
//! that any callsites enabled only by that subscriber are disabled.
|
||||
//!
|
||||
//! In addition, the [`rebuild_interest_cache`] function in this module can be
|
||||
//! used to manually invalidate all cached interest and re-register those
|
||||
//! callsites. This function is useful in situations where a subscriber's
|
||||
//! interest can change, but it does so relatively infrequently. The subscriber
|
||||
//! may wish for its interest to be cached most of the time, and return
|
||||
//! [`Interest::always`][always] or [`Interest::never`][never] in its
|
||||
//! [`register_callsite`] method, so that its [`Subscriber::enabled`] method
|
||||
//! doesn't need to be evaluated every time a span or event is recorded.
|
||||
//! However, when the configuration changes, the subscriber can call
|
||||
//! [`rebuild_interest_cache`] to re-evaluate the entire interest cache with its
|
||||
//! new configuration. This is a relatively costly operation, but if the
|
||||
//! configuration changes infrequently, it may be more efficient than calling
|
||||
//! [`Subscriber::enabled`] frequently.
|
||||
//!
|
||||
//! # Implementing Callsites
|
||||
//!
|
||||
//! In most cases, instrumenting code using `tracing` should *not* require
|
||||
//! implementing the [`Callsite`] trait directly. When using the [`tracing`
|
||||
//! crate's macros][macros] or the [`#[instrument]` attribute][instrument], a
|
||||
//! `Callsite` is automatically generated.
|
||||
//!
|
||||
//! However, code which provides alternative forms of `tracing` instrumentation
|
||||
//! may need to interact with the callsite system directly. If
|
||||
//! instrumentation-side code needs to produce a `Callsite` to emit spans or
|
||||
//! events, the [`DefaultCallsite`] struct provided in this module is a
|
||||
//! ready-made `Callsite` implementation that is suitable for most uses. When
|
||||
//! possible, the use of `DefaultCallsite` should be preferred over implementing
|
||||
//! [`Callsite`] for user types, as `DefaultCallsite` may benefit from
|
||||
//! additional performance optimizations.
|
||||
//!
|
||||
//! [^1]: Returned by the [`Subscriber::register_callsite`][`register_callsite`]
|
||||
//! method.
|
||||
//!
|
||||
//! [`Metadata`]: crate::metadata::Metadata
|
||||
//! [`Interest`]: crate::subscriber::Interest
|
||||
//! [`Subscriber`]: crate::subscriber::Subscriber
|
||||
//! [`register_callsite`]: crate::subscriber::Subscriber::register_callsite
|
||||
//! [`Subscriber::enabled`]: crate::subscriber::Subscriber::enabled
|
||||
//! [always]: crate::subscriber::Interest::always
|
||||
//! [sometimes]: crate::subscriber::Interest::sometimes
|
||||
//! [never]: crate::subscriber::Interest::never
|
||||
//! [`Dispatch`]: crate::dispatch::Dispatch
|
||||
//! [macros]: https://docs.rs/tracing/latest/tracing/#macros
|
||||
//! [instrument]: https://docs.rs/tracing/latest/tracing/attr.instrument.html
|
||||
use crate::stdlib::{
|
||||
any::TypeId,
|
||||
fmt,
|
||||
hash::{Hash, Hasher},
|
||||
ptr,
|
||||
sync::{
|
||||
atomic::{AtomicBool, AtomicPtr, AtomicU8, Ordering},
|
||||
Mutex,
|
||||
},
|
||||
vec::Vec,
|
||||
};
|
||||
use crate::{
|
||||
dispatcher::Dispatch,
|
||||
lazy::Lazy,
|
||||
metadata::{LevelFilter, Metadata},
|
||||
subscriber::Interest,
|
||||
};
|
||||
|
||||
use self::dispatchers::Dispatchers;
|
||||
|
||||
/// Trait implemented by callsites.
|
||||
///
|
||||
/// These functions are only intended to be called by the callsite registry, which
|
||||
/// correctly handles determining the common interest between all subscribers.
|
||||
///
|
||||
/// See the [module-level documentation](crate::callsite) for details on
|
||||
/// callsites.
|
||||
pub trait Callsite: Sync {
|
||||
/// Sets the [`Interest`] for this callsite.
|
||||
///
|
||||
/// See the [documentation on callsite interest caching][cache-docs] for
|
||||
/// details.
|
||||
///
|
||||
/// [`Interest`]: super::subscriber::Interest
|
||||
/// [cache-docs]: crate::callsite#performing-static-filtering
|
||||
fn set_interest(&self, interest: Interest);
|
||||
|
||||
/// Returns the [metadata] associated with the callsite.
|
||||
///
|
||||
/// <div class="example-wrap" style="display:inline-block">
|
||||
/// <pre class="ignore" style="white-space:normal;font:inherit;">
|
||||
///
|
||||
/// **Note:** Implementations of this method should not produce [`Metadata`]
|
||||
/// that share the same callsite [`Identifier`] but otherwise differ in any
|
||||
/// way (e.g., have different `name`s).
|
||||
///
|
||||
/// </pre></div>
|
||||
///
|
||||
/// [metadata]: super::metadata::Metadata
|
||||
fn metadata(&self) -> &Metadata<'_>;
|
||||
|
||||
/// This method is an *internal implementation detail* of `tracing-core`. It
|
||||
/// is *not* intended to be called or overridden from downstream code.
|
||||
///
|
||||
/// The `Private` type can only be constructed from within `tracing-core`.
|
||||
/// Because this method takes a `Private` as an argument, it cannot be
|
||||
/// called from (safe) code external to `tracing-core`. Because it must
|
||||
/// *return* a `Private`, the only valid implementation possible outside of
|
||||
/// `tracing-core` would have to always unconditionally panic.
|
||||
///
|
||||
/// THIS IS BY DESIGN. There is currently no valid reason for code outside
|
||||
/// of `tracing-core` to override this method.
|
||||
// TODO(eliza): this could be used to implement a public downcasting API
|
||||
// for `&dyn Callsite`s in the future.
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
fn private_type_id(&self, _: private::Private<()>) -> private::Private<TypeId>
|
||||
where
|
||||
Self: 'static,
|
||||
{
|
||||
private::Private(TypeId::of::<Self>())
|
||||
}
|
||||
}
|
||||
|
||||
/// Uniquely identifies a [`Callsite`]
|
||||
///
|
||||
/// Two `Identifier`s are equal if they both refer to the same callsite.
|
||||
///
|
||||
/// [`Callsite`]: super::callsite::Callsite
|
||||
#[derive(Clone)]
|
||||
pub struct Identifier(
|
||||
/// **Warning**: The fields on this type are currently `pub` because it must
|
||||
/// be able to be constructed statically by macros. However, when `const
|
||||
/// fn`s are available on stable Rust, this will no longer be necessary.
|
||||
/// Thus, these fields are *not* considered stable public API, and they may
|
||||
/// change warning. Do not rely on any fields on `Identifier`. When
|
||||
/// constructing new `Identifier`s, use the `identify_callsite!` macro
|
||||
/// instead.
|
||||
#[doc(hidden)]
|
||||
pub &'static dyn Callsite,
|
||||
);
|
||||
|
||||
/// A default [`Callsite`] implementation.
|
||||
#[derive(Debug)]
|
||||
pub struct DefaultCallsite {
|
||||
interest: AtomicU8,
|
||||
registration: AtomicU8,
|
||||
meta: &'static Metadata<'static>,
|
||||
next: AtomicPtr<Self>,
|
||||
}
|
||||
|
||||
/// Clear and reregister interest on every [`Callsite`]
|
||||
///
|
||||
/// This function is intended for runtime reconfiguration of filters on traces
|
||||
/// when the filter recalculation is much less frequent than trace events are.
|
||||
/// The alternative is to have the [`Subscriber`] that supports runtime
|
||||
/// reconfiguration of filters always return [`Interest::sometimes()`] so that
|
||||
/// [`enabled`] is evaluated for every event.
|
||||
///
|
||||
/// This function will also re-compute the global maximum level as determined by
|
||||
/// the [`max_level_hint`] method. If a [`Subscriber`]
|
||||
/// implementation changes the value returned by its `max_level_hint`
|
||||
/// implementation at runtime, then it **must** call this function after that
|
||||
/// value changes, in order for the change to be reflected.
|
||||
///
|
||||
/// See the [documentation on callsite interest caching][cache-docs] for
|
||||
/// additional information on this function's usage.
|
||||
///
|
||||
/// [`max_level_hint`]: super::subscriber::Subscriber::max_level_hint
|
||||
/// [`Callsite`]: super::callsite::Callsite
|
||||
/// [`enabled`]: super::subscriber::Subscriber#tymethod.enabled
|
||||
/// [`Interest::sometimes()`]: super::subscriber::Interest::sometimes
|
||||
/// [`Subscriber`]: super::subscriber::Subscriber
|
||||
/// [cache-docs]: crate::callsite#rebuilding-cached-interest
|
||||
pub fn rebuild_interest_cache() {
|
||||
CALLSITES.rebuild_interest(DISPATCHERS.rebuilder());
|
||||
}
|
||||
|
||||
/// Register a new [`Callsite`] with the global registry.
|
||||
///
|
||||
/// This should be called once per callsite after the callsite has been
|
||||
/// constructed.
|
||||
///
|
||||
/// See the [documentation on callsite registration][reg-docs] for details
|
||||
/// on the global callsite registry.
|
||||
///
|
||||
/// [`Callsite`]: crate::callsite::Callsite
|
||||
/// [reg-docs]: crate::callsite#registering-callsites
|
||||
pub fn register(callsite: &'static dyn Callsite) {
|
||||
rebuild_callsite_interest(callsite, &DISPATCHERS.rebuilder());
|
||||
|
||||
// Is this a `DefaultCallsite`? If so, use the fancy linked list!
|
||||
if callsite.private_type_id(private::Private(())).0 == TypeId::of::<DefaultCallsite>() {
|
||||
let callsite = unsafe {
|
||||
// Safety: the pointer cast is safe because the type id of the
|
||||
// provided callsite matches that of the target type for the cast
|
||||
// (`DefaultCallsite`). Because user implementations of `Callsite`
|
||||
// cannot override `private_type_id`, we can trust that the callsite
|
||||
// is not lying about its type ID.
|
||||
&*(callsite as *const dyn Callsite as *const DefaultCallsite)
|
||||
};
|
||||
CALLSITES.push_default(callsite);
|
||||
return;
|
||||
}
|
||||
|
||||
CALLSITES.push_dyn(callsite);
|
||||
}
|
||||
|
||||
static CALLSITES: Callsites = Callsites {
|
||||
list_head: AtomicPtr::new(ptr::null_mut()),
|
||||
has_locked_callsites: AtomicBool::new(false),
|
||||
};
|
||||
|
||||
static DISPATCHERS: Dispatchers = Dispatchers::new();
|
||||
|
||||
static LOCKED_CALLSITES: Lazy<Mutex<Vec<&'static dyn Callsite>>> = Lazy::new(Default::default);
|
||||
|
||||
struct Callsites {
|
||||
list_head: AtomicPtr<DefaultCallsite>,
|
||||
has_locked_callsites: AtomicBool,
|
||||
}
|
||||
|
||||
// === impl DefaultCallsite ===
|
||||
|
||||
impl DefaultCallsite {
|
||||
const UNREGISTERED: u8 = 0;
|
||||
const REGISTERING: u8 = 1;
|
||||
const REGISTERED: u8 = 2;
|
||||
|
||||
const INTEREST_NEVER: u8 = 0;
|
||||
const INTEREST_SOMETIMES: u8 = 1;
|
||||
const INTEREST_ALWAYS: u8 = 2;
|
||||
|
||||
/// Returns a new `DefaultCallsite` with the specified `Metadata`.
|
||||
pub const fn new(meta: &'static Metadata<'static>) -> Self {
|
||||
Self {
|
||||
interest: AtomicU8::new(0xFF),
|
||||
meta,
|
||||
next: AtomicPtr::new(ptr::null_mut()),
|
||||
registration: AtomicU8::new(Self::UNREGISTERED),
|
||||
}
|
||||
}
|
||||
|
||||
/// Registers this callsite with the global callsite registry.
|
||||
///
|
||||
/// If the callsite is already registered, this does nothing. When using
|
||||
/// [`DefaultCallsite`], this method should be preferred over
|
||||
/// [`tracing_core::callsite::register`], as it ensures that the callsite is
|
||||
/// only registered a single time.
|
||||
///
|
||||
/// Other callsite implementations will generally ensure that
|
||||
/// callsites are not re-registered through another mechanism.
|
||||
///
|
||||
/// See the [documentation on callsite registration][reg-docs] for details
|
||||
/// on the global callsite registry.
|
||||
///
|
||||
/// [`Callsite`]: crate::callsite::Callsite
|
||||
/// [reg-docs]: crate::callsite#registering-callsites
|
||||
#[inline(never)]
|
||||
// This only happens once (or if the cached interest value was corrupted).
|
||||
#[cold]
|
||||
pub fn register(&'static self) -> Interest {
|
||||
// Attempt to advance the registration state to `REGISTERING`...
|
||||
match self.registration.compare_exchange(
|
||||
Self::UNREGISTERED,
|
||||
Self::REGISTERING,
|
||||
Ordering::AcqRel,
|
||||
Ordering::Acquire,
|
||||
) {
|
||||
Ok(_) => {
|
||||
// Okay, we advanced the state, try to register the callsite.
|
||||
rebuild_callsite_interest(self, &DISPATCHERS.rebuilder());
|
||||
CALLSITES.push_default(self);
|
||||
self.registration.store(Self::REGISTERED, Ordering::Release);
|
||||
}
|
||||
// Great, the callsite is already registered! Just load its
|
||||
// previous cached interest.
|
||||
Err(Self::REGISTERED) => {}
|
||||
// Someone else is registering...
|
||||
Err(_state) => {
|
||||
debug_assert_eq!(
|
||||
_state,
|
||||
Self::REGISTERING,
|
||||
"weird callsite registration state"
|
||||
);
|
||||
// Just hit `enabled` this time.
|
||||
return Interest::sometimes();
|
||||
}
|
||||
}
|
||||
|
||||
match self.interest.load(Ordering::Relaxed) {
|
||||
Self::INTEREST_NEVER => Interest::never(),
|
||||
Self::INTEREST_ALWAYS => Interest::always(),
|
||||
_ => Interest::sometimes(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the callsite's cached `Interest`, or registers it for the
|
||||
/// first time if it has not yet been registered.
|
||||
#[inline]
|
||||
pub fn interest(&'static self) -> Interest {
|
||||
match self.interest.load(Ordering::Relaxed) {
|
||||
Self::INTEREST_NEVER => Interest::never(),
|
||||
Self::INTEREST_SOMETIMES => Interest::sometimes(),
|
||||
Self::INTEREST_ALWAYS => Interest::always(),
|
||||
_ => self.register(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Callsite for DefaultCallsite {
|
||||
fn set_interest(&self, interest: Interest) {
|
||||
let interest = match () {
|
||||
_ if interest.is_never() => Self::INTEREST_NEVER,
|
||||
_ if interest.is_always() => Self::INTEREST_ALWAYS,
|
||||
_ => Self::INTEREST_SOMETIMES,
|
||||
};
|
||||
self.interest.store(interest, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn metadata(&self) -> &Metadata<'static> {
|
||||
self.meta
|
||||
}
|
||||
}
|
||||
|
||||
// ===== impl Identifier =====
|
||||
|
||||
impl PartialEq for Identifier {
|
||||
fn eq(&self, other: &Identifier) -> bool {
|
||||
core::ptr::eq(
|
||||
self.0 as *const _ as *const (),
|
||||
other.0 as *const _ as *const (),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Identifier {}
|
||||
|
||||
impl fmt::Debug for Identifier {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Identifier({:p})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for Identifier {
|
||||
fn hash<H>(&self, state: &mut H)
|
||||
where
|
||||
H: Hasher,
|
||||
{
|
||||
(self.0 as *const dyn Callsite).hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
// === impl Callsites ===
|
||||
|
||||
impl Callsites {
|
||||
/// Rebuild `Interest`s for all callsites in the registry.
|
||||
///
|
||||
/// This also re-computes the max level hint.
|
||||
fn rebuild_interest(&self, dispatchers: dispatchers::Rebuilder<'_>) {
|
||||
let mut max_level = LevelFilter::OFF;
|
||||
dispatchers.for_each(|dispatch| {
|
||||
// If the subscriber did not provide a max level hint, assume
|
||||
// that it may enable every level.
|
||||
let level_hint = dispatch.max_level_hint().unwrap_or(LevelFilter::TRACE);
|
||||
if level_hint > max_level {
|
||||
max_level = level_hint;
|
||||
}
|
||||
});
|
||||
|
||||
self.for_each(|callsite| {
|
||||
rebuild_callsite_interest(callsite, &dispatchers);
|
||||
});
|
||||
LevelFilter::set_max(max_level);
|
||||
}
|
||||
|
||||
/// Push a `dyn Callsite` trait object to the callsite registry.
|
||||
///
|
||||
/// This will attempt to lock the callsites vector.
|
||||
fn push_dyn(&self, callsite: &'static dyn Callsite) {
|
||||
let mut lock = LOCKED_CALLSITES.lock().unwrap();
|
||||
self.has_locked_callsites.store(true, Ordering::Release);
|
||||
lock.push(callsite);
|
||||
}
|
||||
|
||||
/// Push a `DefaultCallsite` to the callsite registry.
|
||||
///
|
||||
/// If we know the callsite being pushed is a `DefaultCallsite`, we can push
|
||||
/// it to the linked list without having to acquire a lock.
|
||||
fn push_default(&self, callsite: &'static DefaultCallsite) {
|
||||
let mut head = self.list_head.load(Ordering::Acquire);
|
||||
|
||||
loop {
|
||||
callsite.next.store(head, Ordering::Release);
|
||||
|
||||
assert_ne!(
|
||||
callsite as *const _, head,
|
||||
"Attempted to register a `DefaultCallsite` that already exists! \
|
||||
This will cause an infinite loop when attempting to read from the \
|
||||
callsite cache. This is likely a bug! You should only need to call \
|
||||
`DefaultCallsite::register` once per `DefaultCallsite`."
|
||||
);
|
||||
|
||||
match self.list_head.compare_exchange(
|
||||
head,
|
||||
callsite as *const _ as *mut _,
|
||||
Ordering::AcqRel,
|
||||
Ordering::Acquire,
|
||||
) {
|
||||
Ok(_) => {
|
||||
break;
|
||||
}
|
||||
Err(current) => head = current,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Invokes the provided closure `f` with each callsite in the registry.
|
||||
fn for_each(&self, mut f: impl FnMut(&'static dyn Callsite)) {
|
||||
let mut head = self.list_head.load(Ordering::Acquire);
|
||||
|
||||
while let Some(cs) = unsafe { head.as_ref() } {
|
||||
f(cs);
|
||||
|
||||
head = cs.next.load(Ordering::Acquire);
|
||||
}
|
||||
|
||||
if self.has_locked_callsites.load(Ordering::Acquire) {
|
||||
let locked = LOCKED_CALLSITES.lock().unwrap();
|
||||
for &cs in locked.iter() {
|
||||
f(cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn register_dispatch(dispatch: &Dispatch) {
|
||||
let dispatchers = DISPATCHERS.register_dispatch(dispatch);
|
||||
dispatch.subscriber().on_register_dispatch(dispatch);
|
||||
CALLSITES.rebuild_interest(dispatchers);
|
||||
}
|
||||
|
||||
fn rebuild_callsite_interest(
|
||||
callsite: &'static dyn Callsite,
|
||||
dispatchers: &dispatchers::Rebuilder<'_>,
|
||||
) {
|
||||
let meta = callsite.metadata();
|
||||
|
||||
let mut interest = None;
|
||||
dispatchers.for_each(|dispatch| {
|
||||
let this_interest = dispatch.register_callsite(meta);
|
||||
interest = match interest.take() {
|
||||
None => Some(this_interest),
|
||||
Some(that_interest) => Some(that_interest.and(this_interest)),
|
||||
}
|
||||
});
|
||||
|
||||
let interest = interest.unwrap_or_else(Interest::never);
|
||||
callsite.set_interest(interest)
|
||||
}
|
||||
|
||||
mod private {
|
||||
/// Don't call this function, it's private.
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Private<T>(pub(crate) T);
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
mod dispatchers {
|
||||
use crate::{dispatcher, lazy::Lazy};
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
RwLock, RwLockReadGuard, RwLockWriteGuard,
|
||||
};
|
||||
|
||||
pub(super) struct Dispatchers {
|
||||
has_just_one: AtomicBool,
|
||||
}
|
||||
|
||||
static LOCKED_DISPATCHERS: Lazy<RwLock<Vec<dispatcher::Registrar>>> =
|
||||
Lazy::new(Default::default);
|
||||
|
||||
pub(super) enum Rebuilder<'a> {
|
||||
JustOne,
|
||||
Read(RwLockReadGuard<'a, Vec<dispatcher::Registrar>>),
|
||||
Write(RwLockWriteGuard<'a, Vec<dispatcher::Registrar>>),
|
||||
}
|
||||
|
||||
impl Dispatchers {
|
||||
pub(super) const fn new() -> Self {
|
||||
Self {
|
||||
has_just_one: AtomicBool::new(true),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn rebuilder(&self) -> Rebuilder<'_> {
|
||||
if self.has_just_one.load(Ordering::SeqCst) {
|
||||
return Rebuilder::JustOne;
|
||||
}
|
||||
Rebuilder::Read(LOCKED_DISPATCHERS.read().unwrap())
|
||||
}
|
||||
|
||||
pub(super) fn register_dispatch(&self, dispatch: &dispatcher::Dispatch) -> Rebuilder<'_> {
|
||||
let mut dispatchers = LOCKED_DISPATCHERS.write().unwrap();
|
||||
dispatchers.retain(|d| d.upgrade().is_some());
|
||||
dispatchers.push(dispatch.registrar());
|
||||
self.has_just_one
|
||||
.store(dispatchers.len() <= 1, Ordering::SeqCst);
|
||||
Rebuilder::Write(dispatchers)
|
||||
}
|
||||
}
|
||||
|
||||
impl Rebuilder<'_> {
|
||||
pub(super) fn for_each(&self, mut f: impl FnMut(&dispatcher::Dispatch)) {
|
||||
let iter = match self {
|
||||
Rebuilder::JustOne => {
|
||||
dispatcher::get_default(f);
|
||||
return;
|
||||
}
|
||||
Rebuilder::Read(vec) => vec.iter(),
|
||||
Rebuilder::Write(vec) => vec.iter(),
|
||||
};
|
||||
iter.filter_map(dispatcher::Registrar::upgrade)
|
||||
.for_each(|dispatch| f(&dispatch))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
mod dispatchers {
|
||||
use crate::dispatcher;
|
||||
|
||||
pub(super) struct Dispatchers(());
|
||||
pub(super) struct Rebuilder<'a>(Option<&'a dispatcher::Dispatch>);
|
||||
|
||||
impl Dispatchers {
|
||||
pub(super) const fn new() -> Self {
|
||||
Self(())
|
||||
}
|
||||
|
||||
pub(super) fn rebuilder(&self) -> Rebuilder<'_> {
|
||||
Rebuilder(None)
|
||||
}
|
||||
|
||||
pub(super) fn register_dispatch<'dispatch>(
|
||||
&self,
|
||||
dispatch: &'dispatch dispatcher::Dispatch,
|
||||
) -> Rebuilder<'dispatch> {
|
||||
// nop; on no_std, there can only ever be one dispatcher
|
||||
Rebuilder(Some(dispatch))
|
||||
}
|
||||
}
|
||||
|
||||
impl Rebuilder<'_> {
|
||||
#[inline]
|
||||
pub(super) fn for_each(&self, mut f: impl FnMut(&dispatcher::Dispatch)) {
|
||||
if let Some(dispatch) = self.0 {
|
||||
// we are rebuilding the interest cache because a new dispatcher
|
||||
// is about to be set. on `no_std`, this should only happen
|
||||
// once, because the new dispatcher will be the global default.
|
||||
f(dispatch)
|
||||
} else {
|
||||
// otherwise, we are rebuilding the cache because the subscriber
|
||||
// configuration changed, so use the global default.
|
||||
// on no_std, there can only ever be one dispatcher
|
||||
dispatcher::get_default(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1071
third-party/vendor/tracing-core/src/dispatcher.rs
vendored
Normal file
1071
third-party/vendor/tracing-core/src/dispatcher.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
128
third-party/vendor/tracing-core/src/event.rs
vendored
Normal file
128
third-party/vendor/tracing-core/src/event.rs
vendored
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
//! Events represent single points in time during the execution of a program.
|
||||
use crate::parent::Parent;
|
||||
use crate::span::Id;
|
||||
use crate::{field, Metadata};
|
||||
|
||||
/// `Event`s represent single points in time where something occurred during the
|
||||
/// execution of a program.
|
||||
///
|
||||
/// An `Event` can be compared to a log record in unstructured logging, but with
|
||||
/// two key differences:
|
||||
/// - `Event`s exist _within the context of a [span]_. Unlike log lines, they
|
||||
/// may be located within the trace tree, allowing visibility into the
|
||||
/// _temporal_ context in which the event occurred, as well as the source
|
||||
/// code location.
|
||||
/// - Like spans, `Event`s have structured key-value data known as _[fields]_,
|
||||
/// which may include textual message. In general, a majority of the data
|
||||
/// associated with an event should be in the event's fields rather than in
|
||||
/// the textual message, as the fields are more structured.
|
||||
///
|
||||
/// [span]: super::span
|
||||
/// [fields]: super::field
|
||||
#[derive(Debug)]
|
||||
pub struct Event<'a> {
|
||||
fields: &'a field::ValueSet<'a>,
|
||||
metadata: &'static Metadata<'static>,
|
||||
parent: Parent,
|
||||
}
|
||||
|
||||
impl<'a> Event<'a> {
|
||||
/// Constructs a new `Event` with the specified metadata and set of values,
|
||||
/// and observes it with the current subscriber.
|
||||
pub fn dispatch(metadata: &'static Metadata<'static>, fields: &'a field::ValueSet<'_>) {
|
||||
let event = Event::new(metadata, fields);
|
||||
crate::dispatcher::get_default(|current| {
|
||||
current.event(&event);
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns a new `Event` in the current span, with the specified metadata
|
||||
/// and set of values.
|
||||
#[inline]
|
||||
pub fn new(metadata: &'static Metadata<'static>, fields: &'a field::ValueSet<'a>) -> Self {
|
||||
Event {
|
||||
fields,
|
||||
metadata,
|
||||
parent: Parent::Current,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a new `Event` as a child of the specified span, with the
|
||||
/// provided metadata and set of values.
|
||||
#[inline]
|
||||
pub fn new_child_of(
|
||||
parent: impl Into<Option<Id>>,
|
||||
metadata: &'static Metadata<'static>,
|
||||
fields: &'a field::ValueSet<'a>,
|
||||
) -> Self {
|
||||
let parent = match parent.into() {
|
||||
Some(p) => Parent::Explicit(p),
|
||||
None => Parent::Root,
|
||||
};
|
||||
Event {
|
||||
fields,
|
||||
metadata,
|
||||
parent,
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a new `Event` with the specified metadata and set of values,
|
||||
/// and observes it with the current subscriber and an explicit parent.
|
||||
pub fn child_of(
|
||||
parent: impl Into<Option<Id>>,
|
||||
metadata: &'static Metadata<'static>,
|
||||
fields: &'a field::ValueSet<'_>,
|
||||
) {
|
||||
let event = Self::new_child_of(parent, metadata, fields);
|
||||
crate::dispatcher::get_default(|current| {
|
||||
current.event(&event);
|
||||
});
|
||||
}
|
||||
|
||||
/// Visits all the fields on this `Event` with the specified [visitor].
|
||||
///
|
||||
/// [visitor]: super::field::Visit
|
||||
#[inline]
|
||||
pub fn record(&self, visitor: &mut dyn field::Visit) {
|
||||
self.fields.record(visitor);
|
||||
}
|
||||
|
||||
/// Returns an iterator over the set of values on this `Event`.
|
||||
pub fn fields(&self) -> field::Iter {
|
||||
self.fields.field_set().iter()
|
||||
}
|
||||
|
||||
/// Returns [metadata] describing this `Event`.
|
||||
///
|
||||
/// [metadata]: super::Metadata
|
||||
pub fn metadata(&self) -> &'static Metadata<'static> {
|
||||
self.metadata
|
||||
}
|
||||
|
||||
/// Returns true if the new event should be a root.
|
||||
pub fn is_root(&self) -> bool {
|
||||
matches!(self.parent, Parent::Root)
|
||||
}
|
||||
|
||||
/// Returns true if the new event's parent should be determined based on the
|
||||
/// current context.
|
||||
///
|
||||
/// If this is true and the current thread is currently inside a span, then
|
||||
/// that span should be the new event's parent. Otherwise, if the current
|
||||
/// thread is _not_ inside a span, then the new event will be the root of its
|
||||
/// own trace tree.
|
||||
pub fn is_contextual(&self) -> bool {
|
||||
matches!(self.parent, Parent::Current)
|
||||
}
|
||||
|
||||
/// Returns the new event's explicitly-specified parent, if there is one.
|
||||
///
|
||||
/// Otherwise (if the new event is a root or is a child of the current span),
|
||||
/// returns `None`.
|
||||
pub fn parent(&self) -> Option<&Id> {
|
||||
match self.parent {
|
||||
Parent::Explicit(ref p) => Some(p),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
1255
third-party/vendor/tracing-core/src/field.rs
vendored
Normal file
1255
third-party/vendor/tracing-core/src/field.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
76
third-party/vendor/tracing-core/src/lazy.rs
vendored
Normal file
76
third-party/vendor/tracing-core/src/lazy.rs
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#[cfg(feature = "std")]
|
||||
pub(crate) use once_cell::sync::Lazy;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub(crate) use self::spin::Lazy;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
mod spin {
|
||||
//! This is the `once_cell::sync::Lazy` type, but modified to use our
|
||||
//! `spin::Once` type rather than `OnceCell`. This is used to replace
|
||||
//! `once_cell::sync::Lazy` on `no-std` builds.
|
||||
use crate::spin::Once;
|
||||
use core::{cell::Cell, fmt, ops::Deref};
|
||||
|
||||
/// Re-implementation of `once_cell::sync::Lazy` on top of `spin::Once`
|
||||
/// rather than `OnceCell`.
|
||||
///
|
||||
/// This is used when the standard library is disabled.
|
||||
pub(crate) struct Lazy<T, F = fn() -> T> {
|
||||
cell: Once<T>,
|
||||
init: Cell<Option<F>>,
|
||||
}
|
||||
|
||||
impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Lazy")
|
||||
.field("cell", &self.cell)
|
||||
.field("init", &"..")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
// We never create a `&F` from a `&Lazy<T, F>` so it is fine to not impl
|
||||
// `Sync` for `F`. We do create a `&mut Option<F>` in `force`, but this is
|
||||
// properly synchronized, so it only happens once so it also does not
|
||||
// contribute to this impl.
|
||||
unsafe impl<T, F: Send> Sync for Lazy<T, F> where Once<T>: Sync {}
|
||||
// auto-derived `Send` impl is OK.
|
||||
|
||||
impl<T, F> Lazy<T, F> {
|
||||
/// Creates a new lazy value with the given initializing function.
|
||||
pub(crate) const fn new(init: F) -> Lazy<T, F> {
|
||||
Lazy {
|
||||
cell: Once::new(),
|
||||
init: Cell::new(Some(init)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, F: FnOnce() -> T> Lazy<T, F> {
|
||||
/// Forces the evaluation of this lazy value and returns a reference to
|
||||
/// the result.
|
||||
///
|
||||
/// This is equivalent to the `Deref` impl, but is explicit.
|
||||
pub(crate) fn force(this: &Lazy<T, F>) -> &T {
|
||||
this.cell.call_once(|| match this.init.take() {
|
||||
Some(f) => f(),
|
||||
None => panic!("Lazy instance has previously been poisoned"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T {
|
||||
Lazy::force(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Default for Lazy<T> {
|
||||
/// Creates a new lazy value using `Default` as the initializing function.
|
||||
fn default() -> Lazy<T> {
|
||||
Lazy::new(T::default)
|
||||
}
|
||||
}
|
||||
}
|
||||
293
third-party/vendor/tracing-core/src/lib.rs
vendored
Normal file
293
third-party/vendor/tracing-core/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
//! Core primitives for `tracing`.
|
||||
//!
|
||||
//! [`tracing`] is a framework for instrumenting Rust programs to collect
|
||||
//! structured, event-based diagnostic information. This crate defines the core
|
||||
//! primitives of `tracing`.
|
||||
//!
|
||||
//! This crate provides:
|
||||
//!
|
||||
//! * [`span::Id`] identifies a span within the execution of a program.
|
||||
//!
|
||||
//! * [`Event`] represents a single event within a trace.
|
||||
//!
|
||||
//! * [`Subscriber`], the trait implemented to collect trace data.
|
||||
//!
|
||||
//! * [`Metadata`] and [`Callsite`] provide information describing spans and
|
||||
//! `Event`s.
|
||||
//!
|
||||
//! * [`Field`], [`FieldSet`], [`Value`], and [`ValueSet`] represent the
|
||||
//! structured data attached to a span.
|
||||
//!
|
||||
//! * [`Dispatch`] allows spans and events to be dispatched to `Subscriber`s.
|
||||
//!
|
||||
//! In addition, it defines the global callsite registry and per-thread current
|
||||
//! dispatcher which other components of the tracing system rely on.
|
||||
//!
|
||||
//! *Compiler support: [requires `rustc` 1.56+][msrv]*
|
||||
//!
|
||||
//! [msrv]: #supported-rust-versions
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! Application authors will typically not use this crate directly. Instead,
|
||||
//! they will use the [`tracing`] crate, which provides a much more
|
||||
//! fully-featured API. However, this crate's API will change very infrequently,
|
||||
//! so it may be used when dependencies must be very stable.
|
||||
//!
|
||||
//! `Subscriber` implementations may depend on `tracing-core` rather than
|
||||
//! `tracing`, as the additional APIs provided by `tracing` are primarily useful
|
||||
//! for instrumenting libraries and applications, and are generally not
|
||||
//! necessary for `Subscriber` implementations.
|
||||
//!
|
||||
//! The [`tokio-rs/tracing`] repository contains less stable crates designed to
|
||||
//! be used with the `tracing` ecosystem. It includes a collection of
|
||||
//! `Subscriber` implementations, as well as utility and adapter crates.
|
||||
//!
|
||||
//! ## Crate Feature Flags
|
||||
//!
|
||||
//! The following crate [feature flags] are available:
|
||||
//!
|
||||
//! * `std`: Depend on the Rust standard library (enabled by default).
|
||||
//!
|
||||
//! `no_std` users may disable this feature with `default-features = false`:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! tracing-core = { version = "0.1.22", default-features = false }
|
||||
//! ```
|
||||
//!
|
||||
//! **Note**:`tracing-core`'s `no_std` support requires `liballoc`.
|
||||
//!
|
||||
//! ### Unstable Features
|
||||
//!
|
||||
//! These feature flags enable **unstable** features. The public API may break in 0.1.x
|
||||
//! releases. To enable these features, the `--cfg tracing_unstable` must be passed to
|
||||
//! `rustc` when compiling.
|
||||
//!
|
||||
//! The following unstable feature flags are currently available:
|
||||
//!
|
||||
//! * `valuable`: Enables support for recording [field values] using the
|
||||
//! [`valuable`] crate.
|
||||
//!
|
||||
//! #### Enabling Unstable Features
|
||||
//!
|
||||
//! The easiest way to set the `tracing_unstable` cfg is to use the `RUSTFLAGS`
|
||||
//! env variable when running `cargo` commands:
|
||||
//!
|
||||
//! ```shell
|
||||
//! RUSTFLAGS="--cfg tracing_unstable" cargo build
|
||||
//! ```
|
||||
//! Alternatively, the following can be added to the `.cargo/config` file in a
|
||||
//! project to automatically enable the cfg flag for that project:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [build]
|
||||
//! rustflags = ["--cfg", "tracing_unstable"]
|
||||
//! ```
|
||||
//!
|
||||
//! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
|
||||
//! [field values]: crate::field
|
||||
//! [`valuable`]: https://crates.io/crates/valuable
|
||||
//!
|
||||
//! ## Supported Rust Versions
|
||||
//!
|
||||
//! Tracing is built against the latest stable release. The minimum supported
|
||||
//! version is 1.56. The current Tracing version is not guaranteed to build on
|
||||
//! Rust versions earlier than the minimum supported version.
|
||||
//!
|
||||
//! Tracing follows the same compiler support policies as the rest of the Tokio
|
||||
//! project. The current stable Rust compiler and the three most recent minor
|
||||
//! versions before it will always be supported. For example, if the current
|
||||
//! stable compiler version is 1.69, the minimum supported version will not be
|
||||
//! increased past 1.66, three minor versions prior. Increasing the minimum
|
||||
//! supported compiler version is not considered a semver breaking change as
|
||||
//! long as doing so complies with this policy.
|
||||
//!
|
||||
//!
|
||||
//! [`span::Id`]: span::Id
|
||||
//! [`Event`]: event::Event
|
||||
//! [`Subscriber`]: subscriber::Subscriber
|
||||
//! [`Metadata`]: metadata::Metadata
|
||||
//! [`Callsite`]: callsite::Callsite
|
||||
//! [`Field`]: field::Field
|
||||
//! [`FieldSet`]: field::FieldSet
|
||||
//! [`Value`]: field::Value
|
||||
//! [`ValueSet`]: field::ValueSet
|
||||
//! [`Dispatch`]: dispatcher::Dispatch
|
||||
//! [`tokio-rs/tracing`]: https://github.com/tokio-rs/tracing
|
||||
//! [`tracing`]: https://crates.io/crates/tracing
|
||||
#![doc(
|
||||
html_logo_url = "https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/logo-type.png",
|
||||
issue_tracker_base_url = "https://github.com/tokio-rs/tracing/issues/"
|
||||
)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg), deny(rustdoc::broken_intra_doc_links))]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub,
|
||||
bad_style,
|
||||
dead_code,
|
||||
improper_ctypes,
|
||||
non_shorthand_field_patterns,
|
||||
no_mangle_generic_items,
|
||||
overflowing_literals,
|
||||
path_statements,
|
||||
patterns_in_fns_without_body,
|
||||
private_in_public,
|
||||
unconditional_recursion,
|
||||
unused,
|
||||
unused_allocation,
|
||||
unused_comparisons,
|
||||
unused_parens,
|
||||
while_true
|
||||
)]
|
||||
#[cfg(not(feature = "std"))]
|
||||
extern crate alloc;
|
||||
|
||||
/// Statically constructs an [`Identifier`] for the provided [`Callsite`].
|
||||
///
|
||||
/// This may be used in contexts such as static initializers.
|
||||
///
|
||||
/// For example:
|
||||
/// ```rust
|
||||
/// use tracing_core::{callsite, identify_callsite};
|
||||
/// # use tracing_core::{Metadata, subscriber::Interest};
|
||||
/// # fn main() {
|
||||
/// pub struct MyCallsite {
|
||||
/// // ...
|
||||
/// }
|
||||
/// impl callsite::Callsite for MyCallsite {
|
||||
/// # fn set_interest(&self, _: Interest) { unimplemented!() }
|
||||
/// # fn metadata(&self) -> &Metadata { unimplemented!() }
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// static CALLSITE: MyCallsite = MyCallsite {
|
||||
/// // ...
|
||||
/// };
|
||||
///
|
||||
/// static CALLSITE_ID: callsite::Identifier = identify_callsite!(&CALLSITE);
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`Identifier`]: callsite::Identifier
|
||||
/// [`Callsite`]: callsite::Callsite
|
||||
#[macro_export]
|
||||
macro_rules! identify_callsite {
|
||||
($callsite:expr) => {
|
||||
$crate::callsite::Identifier($callsite)
|
||||
};
|
||||
}
|
||||
|
||||
/// Statically constructs new span [metadata].
|
||||
///
|
||||
/// /// For example:
|
||||
/// ```rust
|
||||
/// # use tracing_core::{callsite::Callsite, subscriber::Interest};
|
||||
/// use tracing_core::metadata;
|
||||
/// use tracing_core::metadata::{Kind, Level, Metadata};
|
||||
/// # fn main() {
|
||||
/// # pub struct MyCallsite { }
|
||||
/// # impl Callsite for MyCallsite {
|
||||
/// # fn set_interest(&self, _: Interest) { unimplemented!() }
|
||||
/// # fn metadata(&self) -> &Metadata { unimplemented!() }
|
||||
/// # }
|
||||
/// #
|
||||
/// static FOO_CALLSITE: MyCallsite = MyCallsite {
|
||||
/// // ...
|
||||
/// };
|
||||
///
|
||||
/// static FOO_METADATA: Metadata = metadata!{
|
||||
/// name: "foo",
|
||||
/// target: module_path!(),
|
||||
/// level: Level::DEBUG,
|
||||
/// fields: &["bar", "baz"],
|
||||
/// callsite: &FOO_CALLSITE,
|
||||
/// kind: Kind::SPAN,
|
||||
/// };
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [metadata]: metadata::Metadata
|
||||
/// [`Metadata::new`]: metadata::Metadata::new
|
||||
#[macro_export]
|
||||
macro_rules! metadata {
|
||||
(
|
||||
name: $name:expr,
|
||||
target: $target:expr,
|
||||
level: $level:expr,
|
||||
fields: $fields:expr,
|
||||
callsite: $callsite:expr,
|
||||
kind: $kind:expr
|
||||
) => {
|
||||
$crate::metadata! {
|
||||
name: $name,
|
||||
target: $target,
|
||||
level: $level,
|
||||
fields: $fields,
|
||||
callsite: $callsite,
|
||||
kind: $kind,
|
||||
}
|
||||
};
|
||||
(
|
||||
name: $name:expr,
|
||||
target: $target:expr,
|
||||
level: $level:expr,
|
||||
fields: $fields:expr,
|
||||
callsite: $callsite:expr,
|
||||
kind: $kind:expr,
|
||||
) => {
|
||||
$crate::metadata::Metadata::new(
|
||||
$name,
|
||||
$target,
|
||||
$level,
|
||||
::core::option::Option::Some(file!()),
|
||||
::core::option::Option::Some(line!()),
|
||||
::core::option::Option::Some(module_path!()),
|
||||
$crate::field::FieldSet::new($fields, $crate::identify_callsite!($callsite)),
|
||||
$kind,
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) mod lazy;
|
||||
|
||||
// Trimmed-down vendored version of spin 0.5.2 (0387621)
|
||||
// Dependency of no_std lazy_static, not required in a std build
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub(crate) mod spin;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[doc(hidden)]
|
||||
pub type Once = self::spin::Once<()>;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use stdlib::sync::Once;
|
||||
|
||||
pub mod callsite;
|
||||
pub mod dispatcher;
|
||||
pub mod event;
|
||||
pub mod field;
|
||||
pub mod metadata;
|
||||
mod parent;
|
||||
pub mod span;
|
||||
pub(crate) mod stdlib;
|
||||
pub mod subscriber;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use self::{
|
||||
callsite::Callsite,
|
||||
dispatcher::Dispatch,
|
||||
event::Event,
|
||||
field::Field,
|
||||
metadata::{Level, LevelFilter, Metadata},
|
||||
subscriber::Subscriber,
|
||||
};
|
||||
|
||||
pub use self::{metadata::Kind, subscriber::Interest};
|
||||
|
||||
mod sealed {
|
||||
pub trait Sealed {}
|
||||
}
|
||||
1115
third-party/vendor/tracing-core/src/metadata.rs
vendored
Normal file
1115
third-party/vendor/tracing-core/src/metadata.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
11
third-party/vendor/tracing-core/src/parent.rs
vendored
Normal file
11
third-party/vendor/tracing-core/src/parent.rs
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
use crate::span::Id;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum Parent {
|
||||
/// The new span will be a root span.
|
||||
Root,
|
||||
/// The new span will be rooted in the current span.
|
||||
Current,
|
||||
/// The new span has an explicitly-specified parent.
|
||||
Explicit(Id),
|
||||
}
|
||||
341
third-party/vendor/tracing-core/src/span.rs
vendored
Normal file
341
third-party/vendor/tracing-core/src/span.rs
vendored
Normal file
|
|
@ -0,0 +1,341 @@
|
|||
//! Spans represent periods of time in the execution of a program.
|
||||
use crate::field::FieldSet;
|
||||
use crate::parent::Parent;
|
||||
use crate::stdlib::num::NonZeroU64;
|
||||
use crate::{field, Metadata};
|
||||
|
||||
/// Identifies a span within the context of a subscriber.
|
||||
///
|
||||
/// They are generated by [`Subscriber`]s for each span as it is created, by
|
||||
/// the [`new_span`] trait method. See the documentation for that method for
|
||||
/// more information on span ID generation.
|
||||
///
|
||||
/// [`Subscriber`]: super::subscriber::Subscriber
|
||||
/// [`new_span`]: super::subscriber::Subscriber::new_span
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Id(NonZeroU64);
|
||||
|
||||
/// Attributes provided to a `Subscriber` describing a new span when it is
|
||||
/// created.
|
||||
#[derive(Debug)]
|
||||
pub struct Attributes<'a> {
|
||||
metadata: &'static Metadata<'static>,
|
||||
values: &'a field::ValueSet<'a>,
|
||||
parent: Parent,
|
||||
}
|
||||
|
||||
/// A set of fields recorded by a span.
|
||||
#[derive(Debug)]
|
||||
pub struct Record<'a> {
|
||||
values: &'a field::ValueSet<'a>,
|
||||
}
|
||||
|
||||
/// Indicates what [the `Subscriber` considers] the "current" span.
|
||||
///
|
||||
/// As subscribers may not track a notion of a current span, this has three
|
||||
/// possible states:
|
||||
/// - "unknown", indicating that the subscriber does not track a current span,
|
||||
/// - "none", indicating that the current context is known to not be in a span,
|
||||
/// - "some", with the current span's [`Id`] and [`Metadata`].
|
||||
///
|
||||
/// [the `Subscriber` considers]: super::subscriber::Subscriber::current_span
|
||||
/// [`Metadata`]: super::metadata::Metadata
|
||||
#[derive(Debug)]
|
||||
pub struct Current {
|
||||
inner: CurrentInner,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum CurrentInner {
|
||||
Current {
|
||||
id: Id,
|
||||
metadata: &'static Metadata<'static>,
|
||||
},
|
||||
None,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
// ===== impl Span =====
|
||||
|
||||
impl Id {
|
||||
/// Constructs a new span ID from the given `u64`.
|
||||
///
|
||||
/// <pre class="ignore" style="white-space:normal;font:inherit;">
|
||||
/// <strong>Note</strong>: Span IDs must be greater than zero.
|
||||
/// </pre>
|
||||
///
|
||||
/// # Panics
|
||||
/// - If the provided `u64` is 0.
|
||||
pub fn from_u64(u: u64) -> Self {
|
||||
Id(NonZeroU64::new(u).expect("span IDs must be > 0"))
|
||||
}
|
||||
|
||||
/// Constructs a new span ID from the given `NonZeroU64`.
|
||||
///
|
||||
/// Unlike [`Id::from_u64`](Id::from_u64()), this will never panic.
|
||||
#[inline]
|
||||
pub const fn from_non_zero_u64(id: NonZeroU64) -> Self {
|
||||
Id(id)
|
||||
}
|
||||
|
||||
// Allow `into` by-ref since we don't want to impl Copy for Id
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
/// Returns the span's ID as a `u64`.
|
||||
pub fn into_u64(&self) -> u64 {
|
||||
self.0.get()
|
||||
}
|
||||
|
||||
// Allow `into` by-ref since we don't want to impl Copy for Id
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
/// Returns the span's ID as a `NonZeroU64`.
|
||||
#[inline]
|
||||
pub const fn into_non_zero_u64(&self) -> NonZeroU64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Id> for Option<Id> {
|
||||
fn from(id: &'a Id) -> Self {
|
||||
Some(id.clone())
|
||||
}
|
||||
}
|
||||
|
||||
// ===== impl Attributes =====
|
||||
|
||||
impl<'a> Attributes<'a> {
|
||||
/// Returns `Attributes` describing a new child span of the current span,
|
||||
/// with the provided metadata and values.
|
||||
pub fn new(metadata: &'static Metadata<'static>, values: &'a field::ValueSet<'a>) -> Self {
|
||||
Attributes {
|
||||
metadata,
|
||||
values,
|
||||
parent: Parent::Current,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `Attributes` describing a new span at the root of its own trace
|
||||
/// tree, with the provided metadata and values.
|
||||
pub fn new_root(metadata: &'static Metadata<'static>, values: &'a field::ValueSet<'a>) -> Self {
|
||||
Attributes {
|
||||
metadata,
|
||||
values,
|
||||
parent: Parent::Root,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `Attributes` describing a new child span of the specified
|
||||
/// parent span, with the provided metadata and values.
|
||||
pub fn child_of(
|
||||
parent: Id,
|
||||
metadata: &'static Metadata<'static>,
|
||||
values: &'a field::ValueSet<'a>,
|
||||
) -> Self {
|
||||
Attributes {
|
||||
metadata,
|
||||
values,
|
||||
parent: Parent::Explicit(parent),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a reference to the new span's metadata.
|
||||
pub fn metadata(&self) -> &'static Metadata<'static> {
|
||||
self.metadata
|
||||
}
|
||||
|
||||
/// Returns a reference to a `ValueSet` containing any values the new span
|
||||
/// was created with.
|
||||
pub fn values(&self) -> &field::ValueSet<'a> {
|
||||
self.values
|
||||
}
|
||||
|
||||
/// Returns true if the new span should be a root.
|
||||
pub fn is_root(&self) -> bool {
|
||||
matches!(self.parent, Parent::Root)
|
||||
}
|
||||
|
||||
/// Returns true if the new span's parent should be determined based on the
|
||||
/// current context.
|
||||
///
|
||||
/// If this is true and the current thread is currently inside a span, then
|
||||
/// that span should be the new span's parent. Otherwise, if the current
|
||||
/// thread is _not_ inside a span, then the new span will be the root of its
|
||||
/// own trace tree.
|
||||
pub fn is_contextual(&self) -> bool {
|
||||
matches!(self.parent, Parent::Current)
|
||||
}
|
||||
|
||||
/// Returns the new span's explicitly-specified parent, if there is one.
|
||||
///
|
||||
/// Otherwise (if the new span is a root or is a child of the current span),
|
||||
/// returns `None`.
|
||||
pub fn parent(&self) -> Option<&Id> {
|
||||
match self.parent {
|
||||
Parent::Explicit(ref p) => Some(p),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Records all the fields in this set of `Attributes` with the provided
|
||||
/// [Visitor].
|
||||
///
|
||||
/// [visitor]: super::field::Visit
|
||||
pub fn record(&self, visitor: &mut dyn field::Visit) {
|
||||
self.values.record(visitor)
|
||||
}
|
||||
|
||||
/// Returns `true` if this set of `Attributes` contains a value for the
|
||||
/// given `Field`.
|
||||
pub fn contains(&self, field: &field::Field) -> bool {
|
||||
self.values.contains(field)
|
||||
}
|
||||
|
||||
/// Returns true if this set of `Attributes` contains _no_ values.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.values.is_empty()
|
||||
}
|
||||
|
||||
/// Returns the set of all [fields] defined by this span's [`Metadata`].
|
||||
///
|
||||
/// Note that the [`FieldSet`] returned by this method includes *all* the
|
||||
/// fields declared by this span, not just those with values that are recorded
|
||||
/// as part of this set of `Attributes`. Other fields with values not present in
|
||||
/// this `Attributes`' value set may [record] values later.
|
||||
///
|
||||
/// [fields]: crate::field
|
||||
/// [record]: Attributes::record()
|
||||
/// [`Metadata`]: crate::metadata::Metadata
|
||||
/// [`FieldSet`]: crate::field::FieldSet
|
||||
pub fn fields(&self) -> &FieldSet {
|
||||
self.values.field_set()
|
||||
}
|
||||
}
|
||||
|
||||
// ===== impl Record =====
|
||||
|
||||
impl<'a> Record<'a> {
|
||||
/// Constructs a new `Record` from a `ValueSet`.
|
||||
pub fn new(values: &'a field::ValueSet<'a>) -> Self {
|
||||
Self { values }
|
||||
}
|
||||
|
||||
/// Records all the fields in this `Record` with the provided [Visitor].
|
||||
///
|
||||
/// [visitor]: super::field::Visit
|
||||
pub fn record(&self, visitor: &mut dyn field::Visit) {
|
||||
self.values.record(visitor)
|
||||
}
|
||||
|
||||
/// Returns the number of fields that would be visited from this `Record`
|
||||
/// when [`Record::record()`] is called
|
||||
///
|
||||
/// [`Record::record()`]: Record::record()
|
||||
pub fn len(&self) -> usize {
|
||||
self.values.len()
|
||||
}
|
||||
|
||||
/// Returns `true` if this `Record` contains a value for the given `Field`.
|
||||
pub fn contains(&self, field: &field::Field) -> bool {
|
||||
self.values.contains(field)
|
||||
}
|
||||
|
||||
/// Returns true if this `Record` contains _no_ values.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.values.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
// ===== impl Current =====
|
||||
|
||||
impl Current {
|
||||
/// Constructs a new `Current` that indicates the current context is a span
|
||||
/// with the given `metadata` and `metadata`.
|
||||
pub fn new(id: Id, metadata: &'static Metadata<'static>) -> Self {
|
||||
Self {
|
||||
inner: CurrentInner::Current { id, metadata },
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a new `Current` that indicates the current context is *not*
|
||||
/// in a span.
|
||||
pub fn none() -> Self {
|
||||
Self {
|
||||
inner: CurrentInner::None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a new `Current` that indicates the `Subscriber` does not
|
||||
/// track a current span.
|
||||
pub(crate) fn unknown() -> Self {
|
||||
Self {
|
||||
inner: CurrentInner::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the `Subscriber` that constructed this `Current` tracks a
|
||||
/// current span.
|
||||
///
|
||||
/// If this returns `true` and [`id`], [`metadata`], or [`into_inner`]
|
||||
/// return `None`, that indicates that we are currently known to *not* be
|
||||
/// inside a span. If this returns `false`, those methods will also return
|
||||
/// `None`, but in this case, that is because the subscriber does not keep
|
||||
/// track of the currently-entered span.
|
||||
///
|
||||
/// [`id`]: Current::id()
|
||||
/// [`metadata`]: Current::metadata()
|
||||
/// [`into_inner`]: Current::into_inner()
|
||||
pub fn is_known(&self) -> bool {
|
||||
!matches!(self.inner, CurrentInner::Unknown)
|
||||
}
|
||||
|
||||
/// Consumes `self` and returns the span `Id` and `Metadata` of the current
|
||||
/// span, if one exists and is known.
|
||||
pub fn into_inner(self) -> Option<(Id, &'static Metadata<'static>)> {
|
||||
match self.inner {
|
||||
CurrentInner::Current { id, metadata } => Some((id, metadata)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Borrows the `Id` of the current span, if one exists and is known.
|
||||
pub fn id(&self) -> Option<&Id> {
|
||||
match self.inner {
|
||||
CurrentInner::Current { ref id, .. } => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Borrows the `Metadata` of the current span, if one exists and is known.
|
||||
pub fn metadata(&self) -> Option<&'static Metadata<'static>> {
|
||||
match self.inner {
|
||||
CurrentInner::Current { metadata, .. } => Some(metadata),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Current> for Option<&'a Id> {
|
||||
fn from(cur: &'a Current) -> Self {
|
||||
cur.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Current> for Option<Id> {
|
||||
fn from(cur: &'a Current) -> Self {
|
||||
cur.id().cloned()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Current> for Option<Id> {
|
||||
fn from(cur: Current) -> Self {
|
||||
match cur.inner {
|
||||
CurrentInner::Current { id, .. } => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Current> for Option<&'static Metadata<'static>> {
|
||||
fn from(cur: &'a Current) -> Self {
|
||||
cur.metadata()
|
||||
}
|
||||
}
|
||||
21
third-party/vendor/tracing-core/src/spin/LICENSE
vendored
Normal file
21
third-party/vendor/tracing-core/src/spin/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Mathijs van de Nes
|
||||
|
||||
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.
|
||||
7
third-party/vendor/tracing-core/src/spin/mod.rs
vendored
Normal file
7
third-party/vendor/tracing-core/src/spin/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
//! Synchronization primitives based on spinning
|
||||
|
||||
pub(crate) use mutex::*;
|
||||
pub(crate) use once::Once;
|
||||
|
||||
mod mutex;
|
||||
mod once;
|
||||
118
third-party/vendor/tracing-core/src/spin/mutex.rs
vendored
Normal file
118
third-party/vendor/tracing-core/src/spin/mutex.rs
vendored
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
use core::cell::UnsafeCell;
|
||||
use core::default::Default;
|
||||
use core::fmt;
|
||||
use core::hint;
|
||||
use core::marker::Sync;
|
||||
use core::ops::{Deref, DerefMut, Drop};
|
||||
use core::option::Option::{self, None, Some};
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
/// This type provides MUTual EXclusion based on spinning.
|
||||
pub(crate) struct Mutex<T: ?Sized> {
|
||||
lock: AtomicBool,
|
||||
data: UnsafeCell<T>,
|
||||
}
|
||||
|
||||
/// A guard to which the protected data can be accessed
|
||||
///
|
||||
/// When the guard falls out of scope it will release the lock.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct MutexGuard<'a, T: ?Sized> {
|
||||
lock: &'a AtomicBool,
|
||||
data: &'a mut T,
|
||||
}
|
||||
|
||||
// Same unsafe impls as `std::sync::Mutex`
|
||||
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
|
||||
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
|
||||
|
||||
impl<T> Mutex<T> {
|
||||
/// Creates a new spinlock wrapping the supplied data.
|
||||
pub(crate) const fn new(user_data: T) -> Mutex<T> {
|
||||
Mutex {
|
||||
lock: AtomicBool::new(false),
|
||||
data: UnsafeCell::new(user_data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Mutex<T> {
|
||||
fn obtain_lock(&self) {
|
||||
while self
|
||||
.lock
|
||||
.compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed)
|
||||
.is_err()
|
||||
{
|
||||
// Wait until the lock looks unlocked before retrying
|
||||
while self.lock.load(Ordering::Relaxed) {
|
||||
hint::spin_loop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Locks the spinlock and returns a guard.
|
||||
///
|
||||
/// The returned value may be dereferenced for data access
|
||||
/// and the lock will be dropped when the guard falls out of scope.
|
||||
pub(crate) fn lock(&self) -> MutexGuard<'_, T> {
|
||||
self.obtain_lock();
|
||||
MutexGuard {
|
||||
lock: &self.lock,
|
||||
data: unsafe { &mut *self.data.get() },
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to lock the mutex. If it is already locked, it will return None. Otherwise it returns
|
||||
/// a guard within Some.
|
||||
pub(crate) fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
|
||||
if self
|
||||
.lock
|
||||
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
|
||||
.is_ok()
|
||||
{
|
||||
Some(MutexGuard {
|
||||
lock: &self.lock,
|
||||
data: unsafe { &mut *self.data.get() },
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.try_lock() {
|
||||
Some(guard) => write!(f, "Mutex {{ data: ")
|
||||
.and_then(|()| (&*guard).fmt(f))
|
||||
.and_then(|()| write!(f, "}}")),
|
||||
None => write!(f, "Mutex {{ <locked> }}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + Default> Default for Mutex<T> {
|
||||
fn default() -> Mutex<T> {
|
||||
Mutex::new(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> {
|
||||
type Target = T;
|
||||
fn deref<'b>(&'b self) -> &'b T {
|
||||
&*self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
|
||||
fn deref_mut<'b>(&'b mut self) -> &'b mut T {
|
||||
&mut *self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
|
||||
/// The dropping of the MutexGuard will release the lock it was created from.
|
||||
fn drop(&mut self) {
|
||||
self.lock.store(false, Ordering::Release);
|
||||
}
|
||||
}
|
||||
158
third-party/vendor/tracing-core/src/spin/once.rs
vendored
Normal file
158
third-party/vendor/tracing-core/src/spin/once.rs
vendored
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
use core::cell::UnsafeCell;
|
||||
use core::fmt;
|
||||
use core::hint::spin_loop;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
/// A synchronization primitive which can be used to run a one-time global
|
||||
/// initialization. Unlike its std equivalent, this is generalized so that the
|
||||
/// closure returns a value and it is stored. Once therefore acts something like
|
||||
/// a future, too.
|
||||
pub struct Once<T> {
|
||||
state: AtomicUsize,
|
||||
data: UnsafeCell<Option<T>>, // TODO remove option and use mem::uninitialized
|
||||
}
|
||||
|
||||
impl<T: fmt::Debug> fmt::Debug for Once<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.r#try() {
|
||||
Some(s) => write!(f, "Once {{ data: ")
|
||||
.and_then(|()| s.fmt(f))
|
||||
.and_then(|()| write!(f, "}}")),
|
||||
None => write!(f, "Once {{ <uninitialized> }}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Same unsafe impls as `std::sync::RwLock`, because this also allows for
|
||||
// concurrent reads.
|
||||
unsafe impl<T: Send + Sync> Sync for Once<T> {}
|
||||
unsafe impl<T: Send> Send for Once<T> {}
|
||||
|
||||
// Four states that a Once can be in, encoded into the lower bits of `state` in
|
||||
// the Once structure.
|
||||
const INCOMPLETE: usize = 0x0;
|
||||
const RUNNING: usize = 0x1;
|
||||
const COMPLETE: usize = 0x2;
|
||||
const PANICKED: usize = 0x3;
|
||||
|
||||
use core::hint::unreachable_unchecked as unreachable;
|
||||
|
||||
impl<T> Once<T> {
|
||||
/// Initialization constant of `Once`.
|
||||
pub const INIT: Self = Once {
|
||||
state: AtomicUsize::new(INCOMPLETE),
|
||||
data: UnsafeCell::new(None),
|
||||
};
|
||||
|
||||
/// Creates a new `Once` value.
|
||||
pub const fn new() -> Once<T> {
|
||||
Self::INIT
|
||||
}
|
||||
|
||||
fn force_get<'a>(&'a self) -> &'a T {
|
||||
match unsafe { &*self.data.get() }.as_ref() {
|
||||
None => unsafe { unreachable() },
|
||||
Some(p) => p,
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs an initialization routine once and only once. The given closure
|
||||
/// will be executed if this is the first time `call_once` has been called,
|
||||
/// and otherwise the routine will *not* be invoked.
|
||||
///
|
||||
/// This method will block the calling thread if another initialization
|
||||
/// routine is currently running.
|
||||
///
|
||||
/// When this function returns, it is guaranteed that some initialization
|
||||
/// has run and completed (it may not be the closure specified). The
|
||||
/// returned pointer will point to the result from the closure that was
|
||||
/// run.
|
||||
pub fn call_once<'a, F>(&'a self, builder: F) -> &'a T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
let mut status = self.state.load(Ordering::SeqCst);
|
||||
|
||||
if status == INCOMPLETE {
|
||||
status = match self.state.compare_exchange(
|
||||
INCOMPLETE,
|
||||
RUNNING,
|
||||
Ordering::SeqCst,
|
||||
Ordering::SeqCst,
|
||||
) {
|
||||
Ok(status) => {
|
||||
debug_assert_eq!(
|
||||
status, INCOMPLETE,
|
||||
"if compare_exchange succeeded, previous status must be incomplete",
|
||||
);
|
||||
// We init
|
||||
// We use a guard (Finish) to catch panics caused by builder
|
||||
let mut finish = Finish {
|
||||
state: &self.state,
|
||||
panicked: true,
|
||||
};
|
||||
unsafe { *self.data.get() = Some(builder()) };
|
||||
finish.panicked = false;
|
||||
|
||||
self.state.store(COMPLETE, Ordering::SeqCst);
|
||||
|
||||
// This next line is strictly an optimization
|
||||
return self.force_get();
|
||||
}
|
||||
Err(status) => status,
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match status {
|
||||
INCOMPLETE => unreachable!(),
|
||||
RUNNING => {
|
||||
// We spin
|
||||
spin_loop();
|
||||
status = self.state.load(Ordering::SeqCst)
|
||||
}
|
||||
PANICKED => panic!("Once has panicked"),
|
||||
COMPLETE => return self.force_get(),
|
||||
_ => unsafe { unreachable() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a pointer iff the `Once` was previously initialized
|
||||
pub fn r#try<'a>(&'a self) -> Option<&'a T> {
|
||||
match self.state.load(Ordering::SeqCst) {
|
||||
COMPLETE => Some(self.force_get()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Like try, but will spin if the `Once` is in the process of being
|
||||
/// initialized
|
||||
pub fn wait<'a>(&'a self) -> Option<&'a T> {
|
||||
loop {
|
||||
match self.state.load(Ordering::SeqCst) {
|
||||
INCOMPLETE => return None,
|
||||
|
||||
RUNNING => {
|
||||
spin_loop() // We spin
|
||||
}
|
||||
COMPLETE => return Some(self.force_get()),
|
||||
PANICKED => panic!("Once has panicked"),
|
||||
_ => unsafe { unreachable() },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Finish<'a> {
|
||||
state: &'a AtomicUsize,
|
||||
panicked: bool,
|
||||
}
|
||||
|
||||
impl<'a> Drop for Finish<'a> {
|
||||
fn drop(&mut self) {
|
||||
if self.panicked {
|
||||
self.state.store(PANICKED, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
}
|
||||
78
third-party/vendor/tracing-core/src/stdlib.rs
vendored
Normal file
78
third-party/vendor/tracing-core/src/stdlib.rs
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
//! 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 crate::spin::MutexGuard;
|
||||
pub(crate) use alloc::sync::*;
|
||||
pub(crate) use core::sync::*;
|
||||
|
||||
/// This wraps `spin::Mutex` to return a `Result`, so that it can be
|
||||
/// used with code written against `std::sync::Mutex`.
|
||||
///
|
||||
/// Since `spin::Mutex` doesn't support poisoning, the `Result` returned
|
||||
/// by `lock` will always be `Ok`.
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct Mutex<T> {
|
||||
inner: crate::spin::Mutex<T>,
|
||||
}
|
||||
|
||||
impl<T> Mutex<T> {
|
||||
// pub(crate) fn new(data: T) -> Self {
|
||||
// Self {
|
||||
// inner: crate::spin::Mutex::new(data),
|
||||
// }
|
||||
// }
|
||||
|
||||
pub(crate) fn lock(&self) -> Result<MutexGuard<'_, T>, ()> {
|
||||
Ok(self.inner.lock())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
878
third-party/vendor/tracing-core/src/subscriber.rs
vendored
Normal file
878
third-party/vendor/tracing-core/src/subscriber.rs
vendored
Normal file
|
|
@ -0,0 +1,878 @@
|
|||
//! Collectors collect and record trace data.
|
||||
use crate::{span, Dispatch, Event, LevelFilter, Metadata};
|
||||
|
||||
use crate::stdlib::{
|
||||
any::{Any, TypeId},
|
||||
boxed::Box,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
/// Trait representing the functions required to collect trace data.
|
||||
///
|
||||
/// Crates that provide implementations of methods for collecting or recording
|
||||
/// trace data should implement the `Subscriber` interface. This trait is
|
||||
/// intended to represent fundamental primitives for collecting trace events and
|
||||
/// spans — other libraries may offer utility functions and types to make
|
||||
/// subscriber implementations more modular or improve the ergonomics of writing
|
||||
/// subscribers.
|
||||
///
|
||||
/// A subscriber is responsible for the following:
|
||||
/// - Registering new spans as they are created, and providing them with span
|
||||
/// IDs. Implicitly, this means the subscriber may determine the strategy for
|
||||
/// determining span equality.
|
||||
/// - Recording the attachment of field values and follows-from annotations to
|
||||
/// spans.
|
||||
/// - Filtering spans and events, and determining when those filters must be
|
||||
/// invalidated.
|
||||
/// - Observing spans as they are entered, exited, and closed, and events as
|
||||
/// they occur.
|
||||
///
|
||||
/// When a span is entered or exited, the subscriber is provided only with the
|
||||
/// [ID] with which it tagged that span when it was created. This means
|
||||
/// that it is up to the subscriber to determine whether and how span _data_ —
|
||||
/// the fields and metadata describing the span — should be stored. The
|
||||
/// [`new_span`] function is called when a new span is created, and at that
|
||||
/// point, the subscriber _may_ choose to store the associated data if it will
|
||||
/// be referenced again. However, if the data has already been recorded and will
|
||||
/// not be needed by the implementations of `enter` and `exit`, the subscriber
|
||||
/// may freely discard that data without allocating space to store it.
|
||||
///
|
||||
/// ## Overriding default impls
|
||||
///
|
||||
/// Some trait methods on `Subscriber` have default implementations, either in
|
||||
/// order to reduce the surface area of implementing `Subscriber`, or for
|
||||
/// backward-compatibility reasons. However, many subscribers will likely want
|
||||
/// to override these default implementations.
|
||||
///
|
||||
/// The following methods are likely of interest:
|
||||
///
|
||||
/// - [`register_callsite`] is called once for each callsite from which a span
|
||||
/// event may originate, and returns an [`Interest`] value describing whether or
|
||||
/// not the subscriber wishes to see events or spans from that callsite. By
|
||||
/// default, it calls [`enabled`], and returns `Interest::always()` if
|
||||
/// `enabled` returns true, or `Interest::never()` if enabled returns false.
|
||||
/// However, if the subscriber's interest can change dynamically at runtime,
|
||||
/// it may want to override this function to return `Interest::sometimes()`.
|
||||
/// Additionally, subscribers which wish to perform a behaviour once for each
|
||||
/// callsite, such as allocating storage for data related to that callsite,
|
||||
/// can perform it in `register_callsite`.
|
||||
///
|
||||
/// See also the [documentation on the callsite registry][cs-reg] for details
|
||||
/// on [`register_callsite`].
|
||||
///
|
||||
/// - [`event_enabled`] is called once before every call to the [`event`]
|
||||
/// method. This can be used to implement filtering on events once their field
|
||||
/// values are known, but before any processing is done in the `event` method.
|
||||
/// - [`clone_span`] is called every time a span ID is cloned, and [`try_close`]
|
||||
/// is called when a span ID is dropped. By default, these functions do
|
||||
/// nothing. However, they can be used to implement reference counting for
|
||||
/// spans, allowing subscribers to free storage for span data and to determine
|
||||
/// when a span has _closed_ permanently (rather than being exited).
|
||||
/// Subscribers which store per-span data or which need to track span closures
|
||||
/// should override these functions together.
|
||||
///
|
||||
/// [ID]: super::span::Id
|
||||
/// [`new_span`]: Subscriber::new_span
|
||||
/// [`register_callsite`]: Subscriber::register_callsite
|
||||
/// [`enabled`]: Subscriber::enabled
|
||||
/// [`clone_span`]: Subscriber::clone_span
|
||||
/// [`try_close`]: Subscriber::try_close
|
||||
/// [cs-reg]: crate::callsite#registering-callsites
|
||||
/// [`event`]: Subscriber::event
|
||||
/// [`event_enabled`]: Subscriber::event_enabled
|
||||
pub trait Subscriber: 'static {
|
||||
/// Invoked when this subscriber becomes a [`Dispatch`].
|
||||
///
|
||||
/// ## Avoiding Memory Leaks
|
||||
///
|
||||
/// `Subscriber`s should not store their own [`Dispatch`]. Because the
|
||||
/// `Dispatch` owns the `Subscriber`, storing the `Dispatch` within the
|
||||
/// `Subscriber` will create a reference count cycle, preventing the `Dispatch`
|
||||
/// from ever being dropped.
|
||||
///
|
||||
/// Instead, when it is necessary to store a cyclical reference to the
|
||||
/// `Dispatch` within a `Subscriber`, use [`Dispatch::downgrade`] to convert a
|
||||
/// `Dispatch` into a [`WeakDispatch`]. This type is analogous to
|
||||
/// [`std::sync::Weak`], and does not create a reference count cycle. A
|
||||
/// [`WeakDispatch`] can be stored within a `Subscriber` without causing a
|
||||
/// memory leak, and can be [upgraded] into a `Dispatch` temporarily when
|
||||
/// the `Dispatch` must be accessed by the `Subscriber`.
|
||||
///
|
||||
/// [`WeakDispatch`]: crate::dispatcher::WeakDispatch
|
||||
/// [upgraded]: crate::dispatcher::WeakDispatch::upgrade
|
||||
fn on_register_dispatch(&self, subscriber: &Dispatch) {
|
||||
let _ = subscriber;
|
||||
}
|
||||
|
||||
/// Registers a new [callsite] with this subscriber, returning whether or not
|
||||
/// the subscriber is interested in being notified about the callsite.
|
||||
///
|
||||
/// By default, this function assumes that the subscriber's [filter]
|
||||
/// represents an unchanging view of its interest in the callsite. However,
|
||||
/// if this is not the case, subscribers may override this function to
|
||||
/// indicate different interests, or to implement behaviour that should run
|
||||
/// once for every callsite.
|
||||
///
|
||||
/// This function is guaranteed to be called at least once per callsite on
|
||||
/// every active subscriber. The subscriber may store the keys to fields it
|
||||
/// cares about in order to reduce the cost of accessing fields by name,
|
||||
/// preallocate storage for that callsite, or perform any other actions it
|
||||
/// wishes to perform once for each callsite.
|
||||
///
|
||||
/// The subscriber should then return an [`Interest`], indicating
|
||||
/// whether it is interested in being notified about that callsite in the
|
||||
/// future. This may be `Always` indicating that the subscriber always
|
||||
/// wishes to be notified about the callsite, and its filter need not be
|
||||
/// re-evaluated; `Sometimes`, indicating that the subscriber may sometimes
|
||||
/// care about the callsite but not always (such as when sampling), or
|
||||
/// `Never`, indicating that the subscriber never wishes to be notified about
|
||||
/// that callsite. If all active subscribers return `Never`, a callsite will
|
||||
/// never be enabled unless a new subscriber expresses interest in it.
|
||||
///
|
||||
/// `Subscriber`s which require their filters to be run every time an event
|
||||
/// occurs or a span is entered/exited should return `Interest::sometimes`.
|
||||
/// If a subscriber returns `Interest::sometimes`, then its [`enabled`] method
|
||||
/// will be called every time an event or span is created from that callsite.
|
||||
///
|
||||
/// For example, suppose a sampling subscriber is implemented by
|
||||
/// incrementing a counter every time `enabled` is called and only returning
|
||||
/// `true` when the counter is divisible by a specified sampling rate. If
|
||||
/// that subscriber returns `Interest::always` from `register_callsite`, then
|
||||
/// the filter will not be re-evaluated once it has been applied to a given
|
||||
/// set of metadata. Thus, the counter will not be incremented, and the span
|
||||
/// or event that corresponds to the metadata will never be `enabled`.
|
||||
///
|
||||
/// `Subscriber`s that need to change their filters occasionally should call
|
||||
/// [`rebuild_interest_cache`] to re-evaluate `register_callsite` for all
|
||||
/// callsites.
|
||||
///
|
||||
/// Similarly, if a `Subscriber` has a filtering strategy that can be
|
||||
/// changed dynamically at runtime, it would need to re-evaluate that filter
|
||||
/// if the cached results have changed.
|
||||
///
|
||||
/// A subscriber which manages fanout to multiple other subscribers
|
||||
/// should proxy this decision to all of its child subscribers,
|
||||
/// returning `Interest::never` only if _all_ such children return
|
||||
/// `Interest::never`. If the set of subscribers to which spans are
|
||||
/// broadcast may change dynamically, the subscriber should also never
|
||||
/// return `Interest::Never`, as a new subscriber may be added that _is_
|
||||
/// interested.
|
||||
///
|
||||
/// See the [documentation on the callsite registry][cs-reg] for more
|
||||
/// details on how and when the `register_callsite` method is called.
|
||||
///
|
||||
/// # Notes
|
||||
/// This function may be called again when a new subscriber is created or
|
||||
/// when the registry is invalidated.
|
||||
///
|
||||
/// If a subscriber returns `Interest::never` for a particular callsite, it
|
||||
/// _may_ still see spans and events originating from that callsite, if
|
||||
/// another subscriber expressed interest in it.
|
||||
///
|
||||
/// [callsite]: crate::callsite
|
||||
/// [filter]: Self::enabled
|
||||
/// [metadata]: super::metadata::Metadata
|
||||
/// [`enabled`]: Subscriber::enabled()
|
||||
/// [`rebuild_interest_cache`]: super::callsite::rebuild_interest_cache
|
||||
/// [cs-reg]: crate::callsite#registering-callsites
|
||||
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
|
||||
if self.enabled(metadata) {
|
||||
Interest::always()
|
||||
} else {
|
||||
Interest::never()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if a span or event with the specified [metadata] would be
|
||||
/// recorded.
|
||||
///
|
||||
/// By default, it is assumed that this filter needs only be evaluated once
|
||||
/// for each callsite, so it is called by [`register_callsite`] when each
|
||||
/// callsite is registered. The result is used to determine if the subscriber
|
||||
/// is always [interested] or never interested in that callsite. This is intended
|
||||
/// primarily as an optimization, so that expensive filters (such as those
|
||||
/// involving string search, et cetera) need not be re-evaluated.
|
||||
///
|
||||
/// However, if the subscriber's interest in a particular span or event may
|
||||
/// change, or depends on contexts only determined dynamically at runtime,
|
||||
/// then the `register_callsite` method should be overridden to return
|
||||
/// [`Interest::sometimes`]. In that case, this function will be called every
|
||||
/// time that span or event occurs.
|
||||
///
|
||||
/// [metadata]: super::metadata::Metadata
|
||||
/// [interested]: Interest
|
||||
/// [`Interest::sometimes`]: Interest::sometimes
|
||||
/// [`register_callsite`]: Subscriber::register_callsite()
|
||||
fn enabled(&self, metadata: &Metadata<'_>) -> bool;
|
||||
|
||||
/// Returns the highest [verbosity level][level] that this `Subscriber` will
|
||||
/// enable, or `None`, if the subscriber does not implement level-based
|
||||
/// filtering or chooses not to implement this method.
|
||||
///
|
||||
/// If this method returns a [`Level`][level], it will be used as a hint to
|
||||
/// determine the most verbose level that will be enabled. This will allow
|
||||
/// spans and events which are more verbose than that level to be skipped
|
||||
/// more efficiently. Subscribers which perform filtering are strongly
|
||||
/// encouraged to provide an implementation of this method.
|
||||
///
|
||||
/// If the maximum level the subscriber will enable can change over the
|
||||
/// course of its lifetime, it is free to return a different value from
|
||||
/// multiple invocations of this method. However, note that changes in the
|
||||
/// maximum level will **only** be reflected after the callsite [`Interest`]
|
||||
/// cache is rebuilt, by calling the [`callsite::rebuild_interest_cache`][rebuild]
|
||||
/// function. Therefore, if the subscriber will change the value returned by
|
||||
/// this method, it is responsible for ensuring that
|
||||
/// [`rebuild_interest_cache`][rebuild] is called after the value of the max
|
||||
/// level changes.
|
||||
///
|
||||
/// [level]: super::Level
|
||||
/// [rebuild]: super::callsite::rebuild_interest_cache
|
||||
fn max_level_hint(&self) -> Option<LevelFilter> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Visit the construction of a new span, returning a new [span ID] for the
|
||||
/// span being constructed.
|
||||
///
|
||||
/// The provided [`Attributes`] contains any field values that were provided
|
||||
/// when the span was created. The subscriber may pass a [visitor] to the
|
||||
/// `Attributes`' [`record` method] to record these values.
|
||||
///
|
||||
/// IDs are used to uniquely identify spans and events within the context of a
|
||||
/// subscriber, so span equality will be based on the returned ID. Thus, if
|
||||
/// the subscriber wishes for all spans with the same metadata to be
|
||||
/// considered equal, it should return the same ID every time it is given a
|
||||
/// particular set of metadata. Similarly, if it wishes for two separate
|
||||
/// instances of a span with the same metadata to *not* be equal, it should
|
||||
/// return a distinct ID every time this function is called, regardless of
|
||||
/// the metadata.
|
||||
///
|
||||
/// Note that the subscriber is free to assign span IDs based on whatever
|
||||
/// scheme it sees fit. Any guarantees about uniqueness, ordering, or ID
|
||||
/// reuse are left up to the subscriber implementation to determine.
|
||||
///
|
||||
/// [span ID]: super::span::Id
|
||||
/// [`Attributes`]: super::span::Attributes
|
||||
/// [visitor]: super::field::Visit
|
||||
/// [`record` method]: super::span::Attributes::record
|
||||
fn new_span(&self, span: &span::Attributes<'_>) -> span::Id;
|
||||
|
||||
// === Notification methods ===============================================
|
||||
|
||||
/// Record a set of values on a span.
|
||||
///
|
||||
/// This method will be invoked when value is recorded on a span.
|
||||
/// Recording multiple values for the same field is possible,
|
||||
/// but the actual behaviour is defined by the subscriber implementation.
|
||||
///
|
||||
/// Keep in mind that a span might not provide a value
|
||||
/// for each field it declares.
|
||||
///
|
||||
/// The subscriber is expected to provide a [visitor] to the `Record`'s
|
||||
/// [`record` method] in order to record the added values.
|
||||
///
|
||||
/// # Example
|
||||
/// "foo = 3" will be recorded when [`record`] is called on the
|
||||
/// `Attributes` passed to `new_span`.
|
||||
/// Since values are not provided for the `bar` and `baz` fields,
|
||||
/// the span's `Metadata` will indicate that it _has_ those fields,
|
||||
/// but values for them won't be recorded at this time.
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// # use tracing::span;
|
||||
///
|
||||
/// let mut span = span!("my_span", foo = 3, bar, baz);
|
||||
///
|
||||
/// // `Subscriber::record` will be called with a `Record`
|
||||
/// // containing "bar = false"
|
||||
/// span.record("bar", &false);
|
||||
///
|
||||
/// // `Subscriber::record` will be called with a `Record`
|
||||
/// // containing "baz = "a string""
|
||||
/// span.record("baz", &"a string");
|
||||
/// ```
|
||||
///
|
||||
/// [visitor]: super::field::Visit
|
||||
/// [`record`]: super::span::Attributes::record
|
||||
/// [`record` method]: super::span::Record::record
|
||||
fn record(&self, span: &span::Id, values: &span::Record<'_>);
|
||||
|
||||
/// Adds an indication that `span` follows from the span with the id
|
||||
/// `follows`.
|
||||
///
|
||||
/// This relationship differs somewhat from the parent-child relationship: a
|
||||
/// span may have any number of prior spans, rather than a single one; and
|
||||
/// spans are not considered to be executing _inside_ of the spans they
|
||||
/// follow from. This means that a span may close even if subsequent spans
|
||||
/// that follow from it are still open, and time spent inside of a
|
||||
/// subsequent span should not be included in the time its precedents were
|
||||
/// executing. This is used to model causal relationships such as when a
|
||||
/// single future spawns several related background tasks, et cetera.
|
||||
///
|
||||
/// If the subscriber has spans corresponding to the given IDs, it should
|
||||
/// record this relationship in whatever way it deems necessary. Otherwise,
|
||||
/// if one or both of the given span IDs do not correspond to spans that the
|
||||
/// subscriber knows about, or if a cyclical relationship would be created
|
||||
/// (i.e., some span _a_ which proceeds some other span _b_ may not also
|
||||
/// follow from _b_), it may silently do nothing.
|
||||
fn record_follows_from(&self, span: &span::Id, follows: &span::Id);
|
||||
|
||||
/// Determine if an [`Event`] should be recorded.
|
||||
///
|
||||
/// By default, this returns `true` and `Subscriber`s can filter events in
|
||||
/// [`event`][Self::event] without any penalty. However, when `event` is
|
||||
/// more complicated, this can be used to determine if `event` should be
|
||||
/// called at all, separating out the decision from the processing.
|
||||
fn event_enabled(&self, event: &Event<'_>) -> bool {
|
||||
let _ = event;
|
||||
true
|
||||
}
|
||||
|
||||
/// Records that an [`Event`] has occurred.
|
||||
///
|
||||
/// This method will be invoked when an Event is constructed by
|
||||
/// the `Event`'s [`dispatch` method]. For example, this happens internally
|
||||
/// when an event macro from `tracing` is called.
|
||||
///
|
||||
/// The key difference between this method and `record` is that `record` is
|
||||
/// called when a value is recorded for a field defined by a span,
|
||||
/// while `event` is called when a new event occurs.
|
||||
///
|
||||
/// The provided `Event` struct contains any field values attached to the
|
||||
/// event. The subscriber may pass a [visitor] to the `Event`'s
|
||||
/// [`record` method] to record these values.
|
||||
///
|
||||
/// [`Event`]: super::event::Event
|
||||
/// [visitor]: super::field::Visit
|
||||
/// [`record` method]: super::event::Event::record
|
||||
/// [`dispatch` method]: super::event::Event::dispatch
|
||||
fn event(&self, event: &Event<'_>);
|
||||
|
||||
/// Records that a span has been entered.
|
||||
///
|
||||
/// When entering a span, this method is called to notify the subscriber
|
||||
/// that the span has been entered. The subscriber is provided with the
|
||||
/// [span ID] of the entered span, and should update any internal state
|
||||
/// tracking the current span accordingly.
|
||||
///
|
||||
/// [span ID]: super::span::Id
|
||||
fn enter(&self, span: &span::Id);
|
||||
|
||||
/// Records that a span has been exited.
|
||||
///
|
||||
/// When exiting a span, this method is called to notify the subscriber
|
||||
/// that the span has been exited. The subscriber is provided with the
|
||||
/// [span ID] of the exited span, and should update any internal state
|
||||
/// tracking the current span accordingly.
|
||||
///
|
||||
/// Exiting a span does not imply that the span will not be re-entered.
|
||||
///
|
||||
/// [span ID]: super::span::Id
|
||||
fn exit(&self, span: &span::Id);
|
||||
|
||||
/// Notifies the subscriber that a [span ID] has been cloned.
|
||||
///
|
||||
/// This function is guaranteed to only be called with span IDs that were
|
||||
/// returned by this subscriber's `new_span` function.
|
||||
///
|
||||
/// Note that the default implementation of this function this is just the
|
||||
/// identity function, passing through the identifier. However, it can be
|
||||
/// used in conjunction with [`try_close`] to track the number of handles
|
||||
/// capable of `enter`ing a span. When all the handles have been dropped
|
||||
/// (i.e., `try_close` has been called one more time than `clone_span` for a
|
||||
/// given ID), the subscriber may assume that the span will not be entered
|
||||
/// again. It is then free to deallocate storage for data associated with
|
||||
/// that span, write data from that span to IO, and so on.
|
||||
///
|
||||
/// For more unsafe situations, however, if `id` is itself a pointer of some
|
||||
/// kind this can be used as a hook to "clone" the pointer, depending on
|
||||
/// what that means for the specified pointer.
|
||||
///
|
||||
/// [span ID]: super::span::Id
|
||||
/// [`try_close`]: Subscriber::try_close
|
||||
fn clone_span(&self, id: &span::Id) -> span::Id {
|
||||
id.clone()
|
||||
}
|
||||
|
||||
/// **This method is deprecated.**
|
||||
///
|
||||
/// Using `drop_span` may result in subscribers composed using
|
||||
/// `tracing-subscriber` crate's `Layer` trait from observing close events.
|
||||
/// Use [`try_close`] instead.
|
||||
///
|
||||
/// The default implementation of this function does nothing.
|
||||
///
|
||||
/// [`try_close`]: Subscriber::try_close
|
||||
#[deprecated(since = "0.1.2", note = "use `Subscriber::try_close` instead")]
|
||||
fn drop_span(&self, _id: span::Id) {}
|
||||
|
||||
/// Notifies the subscriber that a [span ID] has been dropped, and returns
|
||||
/// `true` if there are now 0 IDs that refer to that span.
|
||||
///
|
||||
/// Higher-level libraries providing functionality for composing multiple
|
||||
/// subscriber implementations may use this return value to notify any
|
||||
/// "layered" subscribers that this subscriber considers the span closed.
|
||||
///
|
||||
/// The default implementation of this method calls the subscriber's
|
||||
/// [`drop_span`] method and returns `false`. This means that, unless the
|
||||
/// subscriber overrides the default implementation, close notifications
|
||||
/// will never be sent to any layered subscribers. In general, if the
|
||||
/// subscriber tracks reference counts, this method should be implemented,
|
||||
/// rather than `drop_span`.
|
||||
///
|
||||
/// This function is guaranteed to only be called with span IDs that were
|
||||
/// returned by this subscriber's `new_span` function.
|
||||
///
|
||||
/// It's guaranteed that if this function has been called once more than the
|
||||
/// number of times `clone_span` was called with the same `id`, then no more
|
||||
/// handles that can enter the span with that `id` exist. This means that it
|
||||
/// can be used in conjunction with [`clone_span`] to track the number of
|
||||
/// handles capable of `enter`ing a span. When all the handles have been
|
||||
/// dropped (i.e., `try_close` has been called one more time than
|
||||
/// `clone_span` for a given ID), the subscriber may assume that the span
|
||||
/// will not be entered again, and should return `true`. It is then free to
|
||||
/// deallocate storage for data associated with that span, write data from
|
||||
/// that span to IO, and so on.
|
||||
///
|
||||
/// **Note**: since this function is called when spans are dropped,
|
||||
/// implementations should ensure that they are unwind-safe. Panicking from
|
||||
/// inside of a `try_close` function may cause a double panic, if the span
|
||||
/// was dropped due to a thread unwinding.
|
||||
///
|
||||
/// [span ID]: super::span::Id
|
||||
/// [`clone_span`]: Subscriber::clone_span
|
||||
/// [`drop_span`]: Subscriber::drop_span
|
||||
fn try_close(&self, id: span::Id) -> bool {
|
||||
#[allow(deprecated)]
|
||||
self.drop_span(id);
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns a type representing this subscriber's view of the current span.
|
||||
///
|
||||
/// If subscribers track a current span, they should override this function
|
||||
/// to return [`Current::new`] if the thread from which this method is
|
||||
/// called is inside a span, or [`Current::none`] if the thread is not
|
||||
/// inside a span.
|
||||
///
|
||||
/// By default, this returns a value indicating that the subscriber
|
||||
/// does **not** track what span is current. If the subscriber does not
|
||||
/// implement a current span, it should not override this method.
|
||||
///
|
||||
/// [`Current::new`]: super::span::Current#tymethod.new
|
||||
/// [`Current::none`]: super::span::Current#tymethod.none
|
||||
fn current_span(&self) -> span::Current {
|
||||
span::Current::unknown()
|
||||
}
|
||||
|
||||
// === Downcasting methods ================================================
|
||||
|
||||
/// If `self` is the same type as the provided `TypeId`, returns an untyped
|
||||
/// `*const` pointer to that type. Otherwise, returns `None`.
|
||||
///
|
||||
/// If you wish to downcast a `Subscriber`, it is strongly advised to use
|
||||
/// the safe API provided by [`downcast_ref`] instead.
|
||||
///
|
||||
/// This API is required for `downcast_raw` to be a trait method; a method
|
||||
/// signature like [`downcast_ref`] (with a generic type parameter) is not
|
||||
/// object-safe, and thus cannot be a trait method for `Subscriber`. This
|
||||
/// means that if we only exposed `downcast_ref`, `Subscriber`
|
||||
/// implementations could not override the downcasting behavior
|
||||
///
|
||||
/// This method may be overridden by "fan out" or "chained" subscriber
|
||||
/// implementations which consist of multiple composed types. Such
|
||||
/// subscribers might allow `downcast_raw` by returning references to those
|
||||
/// component if they contain components with the given `TypeId`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The [`downcast_ref`] method expects that the pointer returned by
|
||||
/// `downcast_raw` is non-null and points to a valid instance of the type
|
||||
/// with the provided `TypeId`. Failure to ensure this will result in
|
||||
/// undefined behaviour, so implementing `downcast_raw` is unsafe.
|
||||
///
|
||||
/// [`downcast_ref`]: #method.downcast_ref
|
||||
unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
|
||||
if id == TypeId::of::<Self>() {
|
||||
Some(self as *const Self as *const ())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl dyn Subscriber {
|
||||
/// Returns `true` if this `Subscriber` is the same type as `T`.
|
||||
pub fn is<T: Any>(&self) -> bool {
|
||||
self.downcast_ref::<T>().is_some()
|
||||
}
|
||||
|
||||
/// Returns some reference to this `Subscriber` value if it is of type `T`,
|
||||
/// or `None` if it isn't.
|
||||
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
|
||||
unsafe {
|
||||
let raw = self.downcast_raw(TypeId::of::<T>())?;
|
||||
if raw.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&*(raw as *const _))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl dyn Subscriber + Send {
|
||||
/// Returns `true` if this [`Subscriber`] is the same type as `T`.
|
||||
pub fn is<T: Any>(&self) -> bool {
|
||||
self.downcast_ref::<T>().is_some()
|
||||
}
|
||||
|
||||
/// Returns some reference to this [`Subscriber`] value if it is of type `T`,
|
||||
/// or `None` if it isn't.
|
||||
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
|
||||
unsafe {
|
||||
let raw = self.downcast_raw(TypeId::of::<T>())?;
|
||||
if raw.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&*(raw as *const _))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl dyn Subscriber + Sync {
|
||||
/// Returns `true` if this [`Subscriber`] is the same type as `T`.
|
||||
pub fn is<T: Any>(&self) -> bool {
|
||||
self.downcast_ref::<T>().is_some()
|
||||
}
|
||||
|
||||
/// Returns some reference to this `[`Subscriber`] value if it is of type `T`,
|
||||
/// or `None` if it isn't.
|
||||
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
|
||||
unsafe {
|
||||
let raw = self.downcast_raw(TypeId::of::<T>())?;
|
||||
if raw.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&*(raw as *const _))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl dyn Subscriber + Send + Sync {
|
||||
/// Returns `true` if this [`Subscriber`] is the same type as `T`.
|
||||
pub fn is<T: Any>(&self) -> bool {
|
||||
self.downcast_ref::<T>().is_some()
|
||||
}
|
||||
|
||||
/// Returns some reference to this [`Subscriber`] value if it is of type `T`,
|
||||
/// or `None` if it isn't.
|
||||
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
|
||||
unsafe {
|
||||
let raw = self.downcast_raw(TypeId::of::<T>())?;
|
||||
if raw.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(&*(raw as *const _))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates a [`Subscriber`]'s interest in a particular callsite.
|
||||
///
|
||||
/// `Subscriber`s return an `Interest` from their [`register_callsite`] methods
|
||||
/// in order to determine whether that span should be enabled or disabled.
|
||||
///
|
||||
/// [`Subscriber`]: super::Subscriber
|
||||
/// [`register_callsite`]: super::Subscriber::register_callsite
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Interest(InterestKind);
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
enum InterestKind {
|
||||
Never = 0,
|
||||
Sometimes = 1,
|
||||
Always = 2,
|
||||
}
|
||||
|
||||
impl Interest {
|
||||
/// Returns an `Interest` indicating that the subscriber is never interested
|
||||
/// in being notified about a callsite.
|
||||
///
|
||||
/// If all active subscribers are `never()` interested in a callsite, it will
|
||||
/// be completely disabled unless a new subscriber becomes active.
|
||||
#[inline]
|
||||
pub fn never() -> Self {
|
||||
Interest(InterestKind::Never)
|
||||
}
|
||||
|
||||
/// Returns an `Interest` indicating the subscriber is sometimes interested
|
||||
/// in being notified about a callsite.
|
||||
///
|
||||
/// If all active subscribers are `sometimes` or `never` interested in a
|
||||
/// callsite, the currently active subscriber will be asked to filter that
|
||||
/// callsite every time it creates a span. This will be the case until a new
|
||||
/// subscriber expresses that it is `always` interested in the callsite.
|
||||
#[inline]
|
||||
pub fn sometimes() -> Self {
|
||||
Interest(InterestKind::Sometimes)
|
||||
}
|
||||
|
||||
/// Returns an `Interest` indicating the subscriber is always interested in
|
||||
/// being notified about a callsite.
|
||||
///
|
||||
/// If any subscriber expresses that it is `always()` interested in a given
|
||||
/// callsite, then the callsite will always be enabled.
|
||||
#[inline]
|
||||
pub fn always() -> Self {
|
||||
Interest(InterestKind::Always)
|
||||
}
|
||||
|
||||
/// Returns `true` if the subscriber is never interested in being notified
|
||||
/// about this callsite.
|
||||
#[inline]
|
||||
pub fn is_never(&self) -> bool {
|
||||
matches!(self.0, InterestKind::Never)
|
||||
}
|
||||
|
||||
/// Returns `true` if the subscriber is sometimes interested in being notified
|
||||
/// about this callsite.
|
||||
#[inline]
|
||||
pub fn is_sometimes(&self) -> bool {
|
||||
matches!(self.0, InterestKind::Sometimes)
|
||||
}
|
||||
|
||||
/// Returns `true` if the subscriber is always interested in being notified
|
||||
/// about this callsite.
|
||||
#[inline]
|
||||
pub fn is_always(&self) -> bool {
|
||||
matches!(self.0, InterestKind::Always)
|
||||
}
|
||||
|
||||
/// Returns the common interest between these two Interests.
|
||||
///
|
||||
/// If both interests are the same, this propagates that interest.
|
||||
/// Otherwise, if they differ, the result must always be
|
||||
/// `Interest::sometimes` --- if the two subscribers differ in opinion, we
|
||||
/// will have to ask the current subscriber what it thinks, no matter what.
|
||||
pub(crate) fn and(self, rhs: Interest) -> Self {
|
||||
if self.0 == rhs.0 {
|
||||
self
|
||||
} else {
|
||||
Interest::sometimes()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A no-op [`Subscriber`].
|
||||
///
|
||||
/// [`NoSubscriber`] implements the [`Subscriber`] trait by never being enabled,
|
||||
/// never being interested in any callsite, and dropping all spans and events.
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct NoSubscriber(());
|
||||
|
||||
impl Subscriber for NoSubscriber {
|
||||
#[inline]
|
||||
fn register_callsite(&self, _: &'static Metadata<'static>) -> Interest {
|
||||
Interest::never()
|
||||
}
|
||||
|
||||
fn new_span(&self, _: &span::Attributes<'_>) -> span::Id {
|
||||
span::Id::from_u64(0xDEAD)
|
||||
}
|
||||
|
||||
fn event(&self, _event: &Event<'_>) {}
|
||||
|
||||
fn record(&self, _span: &span::Id, _values: &span::Record<'_>) {}
|
||||
|
||||
fn record_follows_from(&self, _span: &span::Id, _follows: &span::Id) {}
|
||||
|
||||
#[inline]
|
||||
fn enabled(&self, _metadata: &Metadata<'_>) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn enter(&self, _span: &span::Id) {}
|
||||
fn exit(&self, _span: &span::Id) {}
|
||||
}
|
||||
|
||||
impl NoSubscriber {
|
||||
/// Returns a new `NoSubscriber`.
|
||||
#[must_use]
|
||||
pub const fn new() -> Self {
|
||||
Self(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Subscriber for Box<S>
|
||||
where
|
||||
S: Subscriber + ?Sized,
|
||||
{
|
||||
#[inline]
|
||||
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
|
||||
self.as_ref().register_callsite(metadata)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enabled(&self, metadata: &Metadata<'_>) -> bool {
|
||||
self.as_ref().enabled(metadata)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn max_level_hint(&self) -> Option<LevelFilter> {
|
||||
self.as_ref().max_level_hint()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn new_span(&self, span: &span::Attributes<'_>) -> span::Id {
|
||||
self.as_ref().new_span(span)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn record(&self, span: &span::Id, values: &span::Record<'_>) {
|
||||
self.as_ref().record(span, values)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn record_follows_from(&self, span: &span::Id, follows: &span::Id) {
|
||||
self.as_ref().record_follows_from(span, follows)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn event_enabled(&self, event: &Event<'_>) -> bool {
|
||||
self.as_ref().event_enabled(event)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn event(&self, event: &Event<'_>) {
|
||||
self.as_ref().event(event)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enter(&self, span: &span::Id) {
|
||||
self.as_ref().enter(span)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn exit(&self, span: &span::Id) {
|
||||
self.as_ref().exit(span)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn clone_span(&self, id: &span::Id) -> span::Id {
|
||||
self.as_ref().clone_span(id)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_close(&self, id: span::Id) -> bool {
|
||||
self.as_ref().try_close(id)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
fn drop_span(&self, id: span::Id) {
|
||||
self.as_ref().try_close(id);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn current_span(&self) -> span::Current {
|
||||
self.as_ref().current_span()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
|
||||
if id == TypeId::of::<Self>() {
|
||||
return Some(self as *const Self as *const _);
|
||||
}
|
||||
|
||||
self.as_ref().downcast_raw(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Subscriber for Arc<S>
|
||||
where
|
||||
S: Subscriber + ?Sized,
|
||||
{
|
||||
#[inline]
|
||||
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
|
||||
self.as_ref().register_callsite(metadata)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enabled(&self, metadata: &Metadata<'_>) -> bool {
|
||||
self.as_ref().enabled(metadata)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn max_level_hint(&self) -> Option<LevelFilter> {
|
||||
self.as_ref().max_level_hint()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn new_span(&self, span: &span::Attributes<'_>) -> span::Id {
|
||||
self.as_ref().new_span(span)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn record(&self, span: &span::Id, values: &span::Record<'_>) {
|
||||
self.as_ref().record(span, values)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn record_follows_from(&self, span: &span::Id, follows: &span::Id) {
|
||||
self.as_ref().record_follows_from(span, follows)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn event_enabled(&self, event: &Event<'_>) -> bool {
|
||||
self.as_ref().event_enabled(event)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn event(&self, event: &Event<'_>) {
|
||||
self.as_ref().event(event)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn enter(&self, span: &span::Id) {
|
||||
self.as_ref().enter(span)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn exit(&self, span: &span::Id) {
|
||||
self.as_ref().exit(span)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn clone_span(&self, id: &span::Id) -> span::Id {
|
||||
self.as_ref().clone_span(id)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn try_close(&self, id: span::Id) -> bool {
|
||||
self.as_ref().try_close(id)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
fn drop_span(&self, id: span::Id) {
|
||||
self.as_ref().try_close(id);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn current_span(&self) -> span::Current {
|
||||
self.as_ref().current_span()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
|
||||
if id == TypeId::of::<Self>() {
|
||||
return Some(self as *const Self as *const _);
|
||||
}
|
||||
|
||||
self.as_ref().downcast_raw(id)
|
||||
}
|
||||
}
|
||||
30
third-party/vendor/tracing-core/tests/common/mod.rs
vendored
Normal file
30
third-party/vendor/tracing-core/tests/common/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
use tracing_core::{metadata::Metadata, span, subscriber::Subscriber, Event};
|
||||
|
||||
pub struct TestSubscriberA;
|
||||
impl Subscriber for TestSubscriberA {
|
||||
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) {}
|
||||
}
|
||||
pub struct TestSubscriberB;
|
||||
impl Subscriber for TestSubscriberB {
|
||||
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) {}
|
||||
}
|
||||
56
third-party/vendor/tracing-core/tests/dispatch.rs
vendored
Normal file
56
third-party/vendor/tracing-core/tests/dispatch.rs
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#![cfg(feature = "std")]
|
||||
mod common;
|
||||
|
||||
use common::*;
|
||||
use tracing_core::dispatcher::*;
|
||||
|
||||
#[test]
|
||||
fn set_default_dispatch() {
|
||||
set_global_default(Dispatch::new(TestSubscriberA)).expect("global dispatch set failed");
|
||||
get_default(|current| {
|
||||
assert!(
|
||||
current.is::<TestSubscriberA>(),
|
||||
"global dispatch get failed"
|
||||
)
|
||||
});
|
||||
|
||||
let guard = set_default(&Dispatch::new(TestSubscriberB));
|
||||
get_default(|current| assert!(current.is::<TestSubscriberB>(), "set_default get failed"));
|
||||
|
||||
// Drop the guard, setting the dispatch back to the global dispatch
|
||||
drop(guard);
|
||||
|
||||
get_default(|current| {
|
||||
assert!(
|
||||
current.is::<TestSubscriberA>(),
|
||||
"global dispatch get failed"
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_set_default() {
|
||||
let _guard = set_default(&Dispatch::new(TestSubscriberA));
|
||||
get_default(|current| {
|
||||
assert!(
|
||||
current.is::<TestSubscriberA>(),
|
||||
"set_default for outer subscriber failed"
|
||||
)
|
||||
});
|
||||
|
||||
let inner_guard = set_default(&Dispatch::new(TestSubscriberB));
|
||||
get_default(|current| {
|
||||
assert!(
|
||||
current.is::<TestSubscriberB>(),
|
||||
"set_default inner subscriber failed"
|
||||
)
|
||||
});
|
||||
|
||||
drop(inner_guard);
|
||||
get_default(|current| {
|
||||
assert!(
|
||||
current.is::<TestSubscriberA>(),
|
||||
"set_default outer subscriber failed"
|
||||
)
|
||||
});
|
||||
}
|
||||
34
third-party/vendor/tracing-core/tests/global_dispatch.rs
vendored
Normal file
34
third-party/vendor/tracing-core/tests/global_dispatch.rs
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
mod common;
|
||||
|
||||
use common::*;
|
||||
use tracing_core::dispatcher::*;
|
||||
#[test]
|
||||
fn global_dispatch() {
|
||||
set_global_default(Dispatch::new(TestSubscriberA)).expect("global dispatch set failed");
|
||||
get_default(|current| {
|
||||
assert!(
|
||||
current.is::<TestSubscriberA>(),
|
||||
"global dispatch get failed"
|
||||
)
|
||||
});
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
with_default(&Dispatch::new(TestSubscriberB), || {
|
||||
get_default(|current| {
|
||||
assert!(
|
||||
current.is::<TestSubscriberB>(),
|
||||
"thread-local override of global dispatch failed"
|
||||
)
|
||||
});
|
||||
});
|
||||
|
||||
get_default(|current| {
|
||||
assert!(
|
||||
current.is::<TestSubscriberA>(),
|
||||
"reset to global override failed"
|
||||
)
|
||||
});
|
||||
|
||||
set_global_default(Dispatch::new(TestSubscriberA))
|
||||
.expect_err("double global dispatch set succeeded");
|
||||
}
|
||||
43
third-party/vendor/tracing-core/tests/local_dispatch_before_init.rs
vendored
Normal file
43
third-party/vendor/tracing-core/tests/local_dispatch_before_init.rs
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
mod common;
|
||||
|
||||
use common::*;
|
||||
use tracing_core::{
|
||||
dispatcher::{self, Dispatch},
|
||||
subscriber::NoSubscriber,
|
||||
};
|
||||
|
||||
/// This test reproduces the following issues:
|
||||
/// - https://github.com/tokio-rs/tracing/issues/2587
|
||||
/// - https://github.com/tokio-rs/tracing/issues/2411
|
||||
/// - https://github.com/tokio-rs/tracing/issues/2436
|
||||
#[test]
|
||||
fn local_dispatch_before_init() {
|
||||
dispatcher::get_default(|current| assert!(dbg!(current).is::<NoSubscriber>()));
|
||||
|
||||
// Temporarily override the default dispatcher with a scoped dispatcher.
|
||||
// Using a scoped dispatcher makes the thread local state attempt to cache
|
||||
// the scoped default.
|
||||
#[cfg(feature = "std")]
|
||||
{
|
||||
dispatcher::with_default(&Dispatch::new(TestSubscriberB), || {
|
||||
dispatcher::get_default(|current| {
|
||||
assert!(
|
||||
dbg!(current).is::<TestSubscriberB>(),
|
||||
"overriden subscriber not set",
|
||||
);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
dispatcher::get_default(|current| assert!(current.is::<NoSubscriber>()));
|
||||
|
||||
dispatcher::set_global_default(Dispatch::new(TestSubscriberA))
|
||||
.expect("set global dispatch failed");
|
||||
|
||||
dispatcher::get_default(|current| {
|
||||
assert!(
|
||||
dbg!(current).is::<TestSubscriberA>(),
|
||||
"default subscriber not set"
|
||||
);
|
||||
});
|
||||
}
|
||||
48
third-party/vendor/tracing-core/tests/macros.rs
vendored
Normal file
48
third-party/vendor/tracing-core/tests/macros.rs
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
use tracing_core::{
|
||||
callsite::Callsite,
|
||||
metadata,
|
||||
metadata::{Kind, Level, Metadata},
|
||||
subscriber::Interest,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn metadata_macro_api() {
|
||||
// This test should catch any inadvertent breaking changes
|
||||
// caused by changes to the macro.
|
||||
struct TestCallsite;
|
||||
|
||||
impl Callsite for TestCallsite {
|
||||
fn set_interest(&self, _: Interest) {
|
||||
unimplemented!("test")
|
||||
}
|
||||
fn metadata(&self) -> &Metadata<'_> {
|
||||
unimplemented!("test")
|
||||
}
|
||||
}
|
||||
|
||||
static CALLSITE: TestCallsite = TestCallsite;
|
||||
let _metadata = metadata! {
|
||||
name: "test_metadata",
|
||||
target: "test_target",
|
||||
level: Level::DEBUG,
|
||||
fields: &["foo", "bar", "baz"],
|
||||
callsite: &CALLSITE,
|
||||
kind: Kind::SPAN,
|
||||
};
|
||||
let _metadata = metadata! {
|
||||
name: "test_metadata",
|
||||
target: "test_target",
|
||||
level: Level::TRACE,
|
||||
fields: &[],
|
||||
callsite: &CALLSITE,
|
||||
kind: Kind::EVENT,
|
||||
};
|
||||
let _metadata = metadata! {
|
||||
name: "test_metadata",
|
||||
target: "test_target",
|
||||
level: Level::INFO,
|
||||
fields: &[],
|
||||
callsite: &CALLSITE,
|
||||
kind: Kind::EVENT
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue