pub struct SpanCache<P: EnabledPredicate = LevelPredicate> { /* private fields */ }Expand description
A tracing::Subscriber that funnels closed spans to live consumers.
Open spans live in a sharded Box<[Mutex<Slab<SpanRecord>>]>, with
the lane count set by CacheConfig::lane_count (default
crate::DEFAULT_LANE_COUNT). The shard is picked by a thread-local
key; the slab gives an O(1) cache-friendly index, and the user-facing
tracing::span::Id packs (shard, slab_idx+2) into a single u64 so
SPAN_STACK push/pop and trait-method dispatch don’t need a separate
lookup. When a span closes it moves to a per-thread buffer and is
flushed to the Driver via a spillway channel.
The cache itself holds no closed spans — the driver fans each one
out to SpanCache::subscribe receivers and then drops it. Late
events (an event whose parent span has already been fanned out)
have nowhere to land and are dropped.
SpanRecord.id is an actual_id (separate from the tracing id),
monotonic within a thread’s ID_BATCH-sized reservation; across
threads they interleave, so subscriber-observed order is
driver-commit (close-time) order, not strict global open order.
Create with SpanCache::new / SpanCache::with_predicate
(defaults) or SpanCache::with_config /
SpanCache::with_predicate_and_config (custom batch sizes & lane
count). Each returns (SpanCache, Driver); spawn the Driver as
a background task to fan closed spans out to subscribers.
Implementations§
Source§impl SpanCache<LevelPredicate>
impl SpanCache<LevelPredicate>
Sourcepub fn with_config(capacity: usize, config: CacheConfig) -> (Self, Driver)
pub fn with_config(capacity: usize, config: CacheConfig) -> (Self, Driver)
Default predicate (TRACE) with a custom CacheConfig.
Source§impl<P: EnabledPredicate> SpanCache<P>
impl<P: EnabledPredicate> SpanCache<P>
Sourcepub fn with_predicate(capacity: usize, predicate: P) -> (Self, Driver)
pub fn with_predicate(capacity: usize, predicate: P) -> (Self, Driver)
Custom predicate, default CacheConfig.
Sourcepub fn with_predicate_and_config(
capacity: usize,
predicate: P,
config: CacheConfig,
) -> (Self, Driver)
pub fn with_predicate_and_config( capacity: usize, predicate: P, config: CacheConfig, ) -> (Self, Driver)
Custom predicate and custom CacheConfig.
Sourcepub fn lane_count(&self) -> usize
pub fn lane_count(&self) -> usize
Number of in-flight slab shards this cache uses.
Sourcepub fn actual_id_for(&self, tracing_id: u64) -> Option<u64>
pub fn actual_id_for(&self, tracing_id: u64) -> Option<u64>
Resolve the actual_id (i.e. the SpanRecord::id published
on the fan-out stream) for an in-flight span addressed by
its tracing::span::Id u64. Lock-free Acquire load from the
per-shard sidecar — does not touch the slab Mutex.
Sourcepub fn subscribe(&self, capacity: u64) -> Receiver<SpanRecord>
pub fn subscribe(&self, capacity: u64) -> Receiver<SpanRecord>
Register a new subscriber. The returned Receiver yields
every closed span the cache produces from this call onward,
in the driver’s commit (close-time) order. The cache holds
no history — if you need to see spans from before the call,
subscribe earlier.
Replaces the previous page(after_id, _) API, which keyed on
open-order actual_id and so silently dropped spans whenever
close order diverged from open order — the norm under async
workloads.
capacity is the soft cap on in-flight spans for this
subscriber. When the receiver falls behind by that much, the
driver logs and drops a whole batch — slow consumers don’t back
up the pipeline. Drop the receiver to unsubscribe; the driver
prunes the sender lazily on the next fan-out.
Sourcepub fn flush_pending(&self)
pub fn flush_pending(&self)
Drains the calling thread’s two PENDING buffers (spans + events)
into their respective spillway channels. Must be called before
Driver::drain_sync in tests to ensure all recently-closed
spans and emitted events are delivered.
Trait Implementations§
Source§impl<P: EnabledPredicate> Subscriber for SpanCache<P>
impl<P: EnabledPredicate> Subscriber for SpanCache<P>
Source§fn max_level_hint(&self) -> Option<LevelFilter>
fn max_level_hint(&self) -> Option<LevelFilter>
Subscriber will
enable, or None, if the subscriber does not implement level-based
filtering or chooses not to implement this method. Read moreSource§fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest
Source§fn event_enabled(&self, event: &Event<'_>) -> bool
fn event_enabled(&self, event: &Event<'_>) -> bool
Source§fn new_span(&self, attrs: &Attributes<'_>) -> Id
fn new_span(&self, attrs: &Attributes<'_>) -> Id
Source§fn record_follows_from(&self, _span: &Id, _follows: &Id)
fn record_follows_from(&self, _span: &Id, _follows: &Id)
Source§fn on_register_dispatch(&self, subscriber: &Dispatch)
fn on_register_dispatch(&self, subscriber: &Dispatch)
Source§fn clone_span(&self, id: &Id) -> Id
fn clone_span(&self, id: &Id) -> Id
Source§fn drop_span(&self, _id: Id)
fn drop_span(&self, _id: Id)
use Subscriber::try_close instead