1#![cfg_attr(test, allow(non_snake_case))]
2use std::{
3 collections::VecDeque,
4 sync::{Arc, Mutex},
5};
6use tracing_core::{event, span, subscriber};
7use tracing_subscriber::layer;
8use visitor::FieldValueVisitor;
9
10pub use visitor::FieldValueMap;
11
12pub use lazy_static;
13pub use tracing;
14pub use tracing_subscriber;
15
16pub mod debug_fmt_ext;
17#[cfg(test)]
18mod tests;
19pub mod visitor;
20
21#[derive(Default)]
22pub struct Layer<T> {
23 log: Arc<Mutex<VecDeque<T>>>,
24}
25
26impl<T> Layer<T> {
27 pub fn new() -> Self {
28 Self {
29 log: Arc::new(Mutex::new(VecDeque::new())),
30 }
31 }
32
33 pub fn capture(&self, entry: T) {
34 let mut log = self.log.lock().expect("log mutex shouldn't be poisoned");
35 log.push_back(entry);
36 }
37}
38
39impl Layer<Notification> {
40 pub fn drain_events(&self) -> Vec<Event> {
41 let mut log = self.log.lock().expect("log mutex shouldn't be poisoned");
42 let events: Vec<Event> = log
43 .drain(..)
44 .filter_map(|val| match val {
45 Notification::Event { event, ctx: _ } => Some(event),
46 _ => None,
47 })
48 .collect();
49 events
50 }
51}
52
53pub trait LayerTransform<S> {
60 fn from_new_span(
61 attrs: &span::Attributes<'_>,
62 id: &span::Id,
63 ctx: layer::Context<'_, S>,
64 ) -> Self;
65
66 fn from_on_record(
67 span: &span::Id,
68 values: &span::Record<'_>,
69 ctx: layer::Context<'_, S>,
70 ) -> Self;
71
72 fn from_on_follows_from(
73 span: &span::Id,
74 follows: &span::Id,
75 ctx: layer::Context<'_, S>,
76 ) -> Self;
77
78 fn from_on_event(event: &event::Event<'_>, ctx: layer::Context<'_, S>) -> Self;
79
80 fn from_on_enter(id: &span::Id, ctx: layer::Context<'_, S>) -> Self;
81
82 fn from_on_exit(id: &span::Id, ctx: layer::Context<'_, S>) -> Self;
83
84 fn from_on_close(id: span::Id, ctx: layer::Context<'_, S>) -> Self;
85
86 fn from_on_id_change(old: &span::Id, new: &span::Id, ctx: layer::Context<'_, S>) -> Self;
87}
88
89#[derive(Debug)]
90pub struct FieldSet {}
91
92impl From<&tracing_core::field::FieldSet> for FieldSet {
93 fn from(_fields: &tracing_core::field::FieldSet) -> Self {
94 Self {}
97 }
98}
99
100#[derive(Debug)]
101pub struct ValueSet {}
102
103impl From<&tracing_core::field::ValueSet<'_>> for ValueSet {
104 fn from(_values: &tracing_core::field::ValueSet<'_>) -> Self {
105 Self {}
109 }
110}
111
112#[derive(Debug)]
113#[allow(dead_code)] pub struct Metadata {
115 name: String,
116 target: String,
117 level: tracing_core::Level,
118 module_path: Option<String>,
119 file: Option<String>,
120 line: Option<u32>,
121 fields: FieldSet,
122}
123
124impl From<&'static tracing_core::Metadata<'static>> for Metadata {
125 fn from(metadata: &'static tracing_core::Metadata<'static>) -> Self {
126 Self {
127 name: metadata.name().to_string(),
128 target: metadata.target().to_string(),
129 level: *metadata.level(),
130 module_path: metadata.module_path().map(ToString::to_string),
131 file: metadata.file().map(ToString::to_string),
132 line: metadata.line(),
133 fields: metadata.fields().into(),
134 }
135 }
136}
137
138#[derive(Debug)]
139#[allow(dead_code)] pub struct Attributes {
141 metadata: Metadata,
142 values: ValueSet,
143 parent: Option<span::Id>,
144}
145
146impl From<&span::Attributes<'_>> for Attributes {
147 fn from(attrs: &span::Attributes<'_>) -> Self {
148 Self {
149 metadata: attrs.metadata().into(),
150 values: attrs.values().into(),
151 parent: attrs.parent().map(Clone::clone),
152 }
153 }
154}
155
156#[derive(Debug)]
157pub struct Context {}
158
159impl<S> From<layer::Context<'_, S>> for Context {
160 fn from(_ctx: layer::Context<'_, S>) -> Self {
161 Self {}
165 }
166}
167
168#[derive(Debug)]
169#[allow(dead_code)] pub struct Event {
171 fields: FieldValueMap,
172 metadata: Metadata,
173 parent: Option<span::Id>,
174}
175
176impl Event {
177 pub fn fields(&self) -> &FieldValueMap {
178 &self.fields
179 }
180}
181
182impl From<&event::Event<'_>> for Event {
183 fn from(event: &event::Event<'_>) -> Self {
184 let mut visitor = FieldValueVisitor::default();
186 event.record(&mut visitor);
187
188 Self {
189 fields: visitor.take_data(),
190 metadata: event.metadata().into(),
191 parent: event.parent().map(Clone::clone),
192 }
193 }
194}
195
196#[derive(Debug)]
197pub struct RecordValues {}
198
199impl From<&span::Record<'_>> for RecordValues {
200 fn from(_record: &span::Record<'_>) -> Self {
201 Self {}
203 }
204}
205
206#[derive(Debug)]
207pub enum Notification {
208 NewSpan {
209 id: span::Id,
210 attributes: Attributes,
211 ctx: Context,
212 },
213 Record {
214 id: span::Id,
215 values: RecordValues,
216 ctx: Context,
217 },
218 Enter {
219 id: span::Id,
220 ctx: Context,
221 },
222 Exit {
223 id: span::Id,
224 ctx: Context,
225 },
226 Close {
227 id: span::Id,
228 ctx: Context,
229 },
230 FollowsFrom {
231 span: span::Id,
232 follows: span::Id,
233 ctx: Context,
234 },
235 Event {
236 event: Event,
237 ctx: Context,
238 },
239 IdChange {
240 old: span::Id,
241 new: span::Id,
242 ctx: Context,
243 },
244}
245
246impl<S> LayerTransform<S> for Notification {
247 fn from_new_span(
248 attrs: &span::Attributes<'_>,
249 id: &span::Id,
250 ctx: layer::Context<'_, S>,
251 ) -> Self {
252 Notification::NewSpan {
253 id: id.clone(),
254 attributes: attrs.into(),
255 ctx: ctx.into(),
256 }
257 }
258
259 fn from_on_record(
260 span: &span::Id,
261 values: &span::Record<'_>,
262 ctx: layer::Context<'_, S>,
263 ) -> Self {
264 Notification::Record {
265 id: span.clone(),
266 values: values.into(),
267 ctx: ctx.into(),
268 }
269 }
270
271 fn from_on_follows_from(
272 span: &span::Id,
273 follows: &span::Id,
274 ctx: layer::Context<'_, S>,
275 ) -> Self {
276 Notification::FollowsFrom {
277 span: span.clone(),
278 follows: follows.clone(),
279 ctx: ctx.into(),
280 }
281 }
282
283 fn from_on_event(event: &event::Event<'_>, ctx: layer::Context<'_, S>) -> Self {
284 Notification::Event {
285 event: event.into(),
286 ctx: ctx.into(),
287 }
288 }
289
290 fn from_on_enter(id: &span::Id, ctx: layer::Context<'_, S>) -> Self {
291 Notification::Enter {
292 id: id.clone(),
293 ctx: ctx.into(),
294 }
295 }
296
297 fn from_on_exit(id: &span::Id, ctx: layer::Context<'_, S>) -> Self {
298 Notification::Exit {
299 id: id.clone(),
300 ctx: ctx.into(),
301 }
302 }
303
304 fn from_on_close(id: span::Id, ctx: layer::Context<'_, S>) -> Self {
305 Notification::Close {
306 id,
307 ctx: ctx.into(),
308 }
309 }
310
311 fn from_on_id_change(old: &span::Id, new: &span::Id, ctx: layer::Context<'_, S>) -> Self {
312 Notification::IdChange {
313 old: old.clone(),
314 new: new.clone(),
315 ctx: ctx.into(),
316 }
317 }
318}
319
320impl<S, T> layer::Layer<S> for &'static Layer<T>
321where
322 S: subscriber::Subscriber,
323 T: LayerTransform<S>,
324{
325 fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: layer::Context<'_, S>) {
328 self.capture(T::from_on_record(span, values, ctx))
329 }
330
331 fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: layer::Context<'_, S>) {
332 self.capture(T::from_on_follows_from(span, follows, ctx))
333 }
334
335 fn on_event(&self, event: &event::Event<'_>, ctx: layer::Context<'_, S>) {
336 self.capture(T::from_on_event(event, ctx))
337 }
338
339 fn on_enter(&self, id: &span::Id, ctx: layer::Context<'_, S>) {
340 self.capture(T::from_on_enter(id, ctx))
341 }
342
343 fn on_exit(&self, id: &span::Id, ctx: layer::Context<'_, S>) {
344 self.capture(T::from_on_exit(id, ctx))
345 }
346
347 fn on_close(&self, id: span::Id, ctx: layer::Context<'_, S>) {
348 self.capture(T::from_on_close(id, ctx))
349 }
350
351 fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: layer::Context<'_, S>) {
352 self.capture(T::from_on_id_change(old, new, ctx))
353 }
354}