Skip to content

Commit 0e135bc

Browse files
committed
core: document the callsite module (#2088)
Currently, there isn't a lot of documentation explaining what callsites and registration are for, and how they work. There's some documentation explaining this stuff, but it's all on the `register_callsite` *method*, rather than in the `callsite` module itself. We should fix that. This branch adds new documentation to `tracing-core`'s `callsite` module. Hopefully this should shine some light on how this part of tracing works. Thanks to @JamesHallowell for fixing some typos! Signed-off-by: Eliza Weisman <[email protected]>
1 parent 45a5df1 commit 0e135bc

File tree

2 files changed

+116
-3
lines changed

2 files changed

+116
-3
lines changed

tracing-core/src/callsite.rs

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,85 @@
11
//! Callsites represent the source locations from which spans or events
22
//! originate.
3+
//!
4+
//! # What Are Callsites?
5+
//!
6+
//! Every span or event in `tracing` is associated with a [`Callsite`]. A
7+
//! callsite is a small `static` value that is responsible for the following:
8+
//!
9+
//! * Storing the span or event's [`Metadata`],
10+
//! * Uniquely [identifying](Identifier) the span or event definition,
11+
//! * Caching the subscriber's [`Interest`][^1] in that span or event, to avoid
12+
//! re-evaluating filters,
13+
//! * Storing a [`Registration`] that allows the callsite to be part of a global
14+
//! list of all callsites in the program.
15+
//!
16+
//! # Registering Callsites
17+
//!
18+
//! When a span or event is recorded for the first time, its callsite
19+
//! [`register`]s itself with the global callsite registry. Registering a
20+
//! callsite calls the [`Subscriber::register_callsite`][`register_callsite`]
21+
//! method with that callsite's [`Metadata`] on every currently active
22+
//! subscriber. This serves two primary purposes: informing subscribers of the
23+
//! callsite's existence, and performing static filtering.
24+
//!
25+
//! ## Callsite Existence
26+
//!
27+
//! If a [`Subscriber`] implementation wishes to allocate storage for each
28+
//! unique span/event location in the program, or pre-compute some value
29+
//! that will be used to record that span or event in the future, it can
30+
//! do so in its [`register_callsite`] method.
31+
//!
32+
//! ## Performing Static Filtering
33+
//!
34+
//! The [`register_callsite`] method returns an [`Interest`] value,
35+
//! which indicates that the subscriber either [always] wishes to record
36+
//! that span or event, [sometimes] wishes to record it based on a
37+
//! dynamic filter evaluation, or [never] wishes to record it.
38+
//!
39+
//! When registering a new callsite, the [`Interest`]s returned by every
40+
//! currently active subscriber are combined, and the result is stored at
41+
//! each callsite. This way, when the span or event occurs in the
42+
//! future, the cached [`Interest`] value can be checked efficiently
43+
//! to determine if the span or event should be recorded, without
44+
//! needing to perform expensive filtering (i.e. calling the
45+
//! [`Subscriber::enabled`] method every time a span or event occurs).
46+
//!
47+
//! ### Rebuilding Cached Interest
48+
//!
49+
//! When a new [`Dispatch`] is created (i.e. a new subscriber becomes
50+
//! active), any previously cached [`Interest`] values are re-evaluated
51+
//! for all callsites in the program. This way, if the new subscriber
52+
//! will enable a callsite that was not previously enabled, the
53+
//! [`Interest`] in that callsite is updated. Similarly, when a
54+
//! subscriber is dropped, the interest cache is also re-evaluated, so
55+
//! that any callsites enabled only by that subscriber are disabled.
56+
//!
57+
//! In addition, the [`rebuild_interest_cache`] function in this module can be
58+
//! used to manually invalidate all cached interest and re-register those
59+
//! callsites. This function is useful in situations where a subscriber's
60+
//! interest can change, but it does so relatively infrequently. The subscriber
61+
//! may wish for its interest to be cached most of the time, and return
62+
//! [`Interest::always`][always] or [`Interest::never`][never] in its
63+
//! [`register_callsite`] method, so that its [`Subscriber::enabled`] method
64+
//! doesn't need to be evaluated every time a span or event is recorded.
65+
//! However, when the configuration changes, the subscriber can call
66+
//! [`rebuild_interest_cache`] to re-evaluate the entire interest cache with its
67+
//! new configuration. This is a relatively costly operation, but if the
68+
//! configuration changes infrequently, it may be more efficient than calling
69+
//! [`Subscriber::enabled`] frequently.
70+
//!
71+
//! [^1]: Returned by the [`Subscriber::register_callsite`][`register_callsite`]
72+
//! method.
73+
//!
74+
//! [`Metadata`]: crate::metadata::Metadata
75+
//! [`Interest`]: crate::subscriber::Interest
76+
//! [`Subscriber`]: crate::subscriber::Subscriber
77+
//! [`register_callsite`]: crate::subscriber::Subscriber::register_callsite
78+
//! [`Subscriber::enabled`]: crate::subscriber::Subscriber::enabled
79+
//! [always]: crate::subscriber::Interest::always
80+
//! [sometimes]: crate::subscriber::Interest::sometimes
81+
//! [never]: crate::subscriber::Interest::never
82+
//! [`Dispatch`]: crate::dispatch::Dispatch
383
use crate::stdlib::{
484
any::TypeId,
585
fmt,
@@ -23,10 +103,17 @@ use self::dispatchers::Dispatchers;
23103
///
24104
/// These functions are only intended to be called by the callsite registry, which
25105
/// correctly handles determining the common interest between all subscribers.
106+
///
107+
/// See the [module-level documentation](crate::callsite) for details on
108+
/// callsites.
26109
pub trait Callsite: Sync {
27110
/// Sets the [`Interest`] for this callsite.
28111
///
112+
/// See the [documentation on callsite interest caching][cache-docs] for
113+
/// details.
114+
///
29115
/// [`Interest`]: super::subscriber::Interest
116+
/// [cache-docs]: crate::callsite#performing-static-filtering
30117
fn set_interest(&self, interest: Interest);
31118

32119
/// Returns the [metadata] associated with the callsite.
@@ -98,19 +185,29 @@ pub struct DefaultCallsite {
98185
/// implementation at runtime, then it **must** call this function after that
99186
/// value changes, in order for the change to be reflected.
100187
///
188+
/// See the [documentation on callsite interest caching][cache-docs] for
189+
/// additional information on this function's usage.
190+
///
101191
/// [`max_level_hint`]: super::subscriber::Subscriber::max_level_hint
102192
/// [`Callsite`]: super::callsite::Callsite
103193
/// [`enabled`]: super::subscriber::Subscriber#tymethod.enabled
104194
/// [`Interest::sometimes()`]: super::subscriber::Interest::sometimes
105195
/// [`Subscriber`]: super::subscriber::Subscriber
196+
/// [cache-docs]: crate::callsite#rebuilding-cached-interest
106197
pub fn rebuild_interest_cache() {
107198
CALLSITES.rebuild_interest(DISPATCHERS.rebuilder());
108199
}
109200

110-
/// Register a new `Callsite` with the global registry.
201+
/// Register a new [`Callsite`] with the global registry.
111202
///
112203
/// This should be called once per callsite after the callsite has been
113204
/// constructed.
205+
///
206+
/// See the [documentation on callsite registration][reg-docs] for details
207+
/// on the global callsite registry.
208+
///
209+
/// [`Callsite`]: crate::callsite::Callsite
210+
/// [reg-docs]: crate::callsite#registering-callsites
114211
pub fn register(callsite: &'static dyn Callsite) {
115212
rebuild_callsite_interest(callsite, &DISPATCHERS.rebuilder());
116213

@@ -177,6 +274,12 @@ impl DefaultCallsite {
177274
///
178275
/// Other callsite implementations will generally ensure that
179276
/// callsites are not re-registered through another mechanism.
277+
///
278+
/// See the [documentation on callsite registration][reg-docs] for details
279+
/// on the global callsite registry.
280+
///
281+
/// [`Callsite`]: crate::callsite::Callsite
282+
/// [reg-docs]: crate::callsite#registering-callsites
180283
#[inline(never)]
181284
// This only happens once (or if the cached interest value was corrupted).
182285
#[cold]

tracing-core/src/subscriber.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ use crate::stdlib::{
5656
/// Additionally, subscribers which wish to perform a behaviour once for each
5757
/// callsite, such as allocating storage for data related to that callsite,
5858
/// can perform it in `register_callsite`.
59+
///
60+
/// See also the [documentation on the callsite registry][cs-reg] for details
61+
/// on [`register_callsite`].
62+
///
5963
/// - [`clone_span`] is called every time a span ID is cloned, and [`try_close`]
6064
/// is called when a span ID is dropped. By default, these functions do
6165
/// nothing. However, they can be used to implement reference counting for
@@ -70,10 +74,11 @@ use crate::stdlib::{
7074
/// [`enabled`]: Subscriber::enabled
7175
/// [`clone_span`]: Subscriber::clone_span
7276
/// [`try_close`]: Subscriber::try_close
77+
/// [cs-reg]: crate::callsite#registering-callsites
7378
pub trait Subscriber: 'static {
7479
// === Span registry methods ==============================================
7580

76-
/// Registers a new callsite with this subscriber, returning whether or not
81+
/// Registers a new [callsite] with this subscriber, returning whether or not
7782
/// the subscriber is interested in being notified about the callsite.
7883
///
7984
/// By default, this function assumes that the subscriber's [filter]
@@ -127,6 +132,9 @@ pub trait Subscriber: 'static {
127132
/// return `Interest::Never`, as a new subscriber may be added that _is_
128133
/// interested.
129134
///
135+
/// See the [documentation on the callsite registry][cs-reg] for more
136+
/// details on how and when the `register_callsite` method is called.
137+
///
130138
/// # Notes
131139
/// This function may be called again when a new subscriber is created or
132140
/// when the registry is invalidated.
@@ -135,10 +143,12 @@ pub trait Subscriber: 'static {
135143
/// _may_ still see spans and events originating from that callsite, if
136144
/// another subscriber expressed interest in it.
137145
///
138-
/// [filter]: Subscriber::enabled()
146+
/// [callsite]: crate::callsite
147+
/// [filter]: Self::enabled
139148
/// [metadata]: super::metadata::Metadata
140149
/// [`enabled`]: Subscriber::enabled()
141150
/// [`rebuild_interest_cache`]: super::callsite::rebuild_interest_cache
151+
/// [cs-reg]: crate::callsite#registering-callsites
142152
fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
143153
if self.enabled(metadata) {
144154
Interest::always()

0 commit comments

Comments
 (0)