Vendor dependencies for 0.3.0 release

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

618
vendor/tracing-core/src/callsite.rs vendored Normal file
View File

@@ -0,0 +1,618 @@
//! 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::dispatcher::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) {
// 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);
} else {
CALLSITES.push_dyn(callsite);
}
rebuild_callsite_interest(callsite, &DISPATCHERS.rebuilder());
}
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.
///
/// [`tracing_core::callsite::register`]: crate::callsite::register
/// [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.
CALLSITES.push_default(self);
rebuild_callsite_interest(self, &DISPATCHERS.rebuilder());
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)
}
}
}
}

1068
vendor/tracing-core/src/dispatcher.rs vendored Normal file

File diff suppressed because it is too large Load Diff

128
vendor/tracing-core/src/event.rs vendored Normal file
View 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,
}
}
}

1320
vendor/tracing-core/src/field.rs vendored Normal file

File diff suppressed because it is too large Load Diff

76
vendor/tracing-core/src/lazy.rs vendored Normal file
View 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)
}
}
}

302
vendor/tracing-core/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,302 @@
//! 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.65+][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.65. 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/main/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_interfaces,
private_bounds,
unconditional_recursion,
unused,
unused_allocation,
unused_comparisons,
unused_parens,
while_true
)]
#[cfg(not(feature = "std"))]
extern crate alloc;
#[doc(hidden)]
pub mod __macro_support {
// Re-export the `core` functions that are used in macros. This allows
// a crate to be named `core` and avoid name clashes.
// See here: https://github.com/tokio-rs/tracing/issues/2761
pub use core::{file, line, module_path, option::Option};
}
/// 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,
$crate::__macro_support::Option::Some($crate::__macro_support::file!()),
$crate::__macro_support::Option::Some($crate::__macro_support::line!()),
$crate::__macro_support::Option::Some($crate::__macro_support::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 {}
}

1114
vendor/tracing-core/src/metadata.rs vendored Normal file

File diff suppressed because it is too large Load Diff

11
vendor/tracing-core/src/parent.rs vendored Normal file
View 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
vendor/tracing-core/src/span.rs vendored Normal file
View 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
vendor/tracing-core/src/spin/LICENSE vendored Normal file
View 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
vendor/tracing-core/src/spin/mod.rs vendored Normal file
View File

@@ -0,0 +1,7 @@
//! Synchronization primitives based on spinning
pub(crate) use mutex::*;
pub(crate) use once::Once;
mod mutex;
mod once;

118
vendor/tracing-core/src/spin/mutex.rs vendored Normal file
View 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
vendor/tracing-core/src/spin/once.rs vendored Normal file
View 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
vendor/tracing-core/src/stdlib.rs vendored Normal file
View 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
vendor/tracing-core/src/subscriber.rs vendored Normal file
View 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)
}
}