tuwunel_core/log/capture/data.rs
1//! Captured tracing-event data and common accessors.
2//!
3//! Values borrow the event, current span, and fields for one filter or callback
4//! invocation. They must not escape that invocation.
5
6use tracing::Level;
7use tracing_core::{Event, span::Current};
8
9use super::{Layer, layer::Value};
10use crate::{info, utils::string::EMPTY};
11
12/// Presents one tracing event to a capture filter or callback.
13///
14/// The value borrows tracing metadata and any fields recorded for the current
15/// capture phase. Accessor methods provide common event attributes with empty
16/// fallbacks.
17pub struct Data<'a> {
18 /// Capture layer that observed the event.
19 ///
20 /// The reference identifies the subscriber layer that dispatched the event.
21 pub layer: &'a Layer,
22
23 /// Tracing event being filtered or delivered.
24 ///
25 /// Its metadata supplies the level, target, and module path.
26 pub event: &'a Event<'a>,
27
28 /// Subscriber's current span at the time of the event.
29 ///
30 /// Metadata is absent when no span is entered or the subscriber does not
31 /// track the current span.
32 pub current: &'a Current,
33
34 /// Field names and formatted values recorded from the event.
35 ///
36 /// Values are populated for callback delivery and can be empty during
37 /// filtering.
38 pub values: &'a [Value],
39
40 /// Span names in the event's subscriber scope.
41 ///
42 /// Scope names are populated while filtering and can be empty during
43 /// callback delivery.
44 pub scope: &'a [&'static str],
45}
46
47impl Data<'_> {
48 /// Reports whether the event originated in a Tuwunel crate.
49 ///
50 /// The check compares the event module path with the shared crate prefix.
51 /// An event without module metadata does not match.
52 #[must_use]
53 pub fn our_modules(&self) -> bool { self.mod_name().starts_with(info::CRATE_PREFIX) }
54
55 /// Returns the event's tracing level.
56 ///
57 /// The level is copied from static tracing metadata and does not depend on
58 /// the active subscriber filter.
59 #[must_use]
60 pub fn level(&self) -> Level { *self.event.metadata().level() }
61
62 /// Returns the event's Rust module path.
63 ///
64 /// Events without module metadata produce an empty string. The returned
65 /// value borrows static tracing metadata.
66 #[must_use]
67 pub fn mod_name(&self) -> &str {
68 self.event
69 .metadata()
70 .module_path()
71 .unwrap_or_default()
72 }
73
74 /// Returns the current span's name.
75 ///
76 /// An empty string is returned when the subscriber has no current span or
77 /// no metadata for it.
78 #[must_use]
79 pub fn span_name(&self) -> &str {
80 self.current
81 .metadata()
82 .map_or(EMPTY, |s| s.name())
83 }
84
85 /// Returns the event's recorded message field.
86 ///
87 /// The first field named `message` is selected. Events without that field
88 /// produce an empty string.
89 #[must_use]
90 pub fn message(&self) -> &str {
91 self.values
92 .iter()
93 .find(|(k, _)| *k == "message")
94 .map_or(EMPTY, |(_, v)| v.as_str())
95 }
96}