1use std::sync::Arc;
2
3use crate::archive::*;
4use tracing::span;
5use tracing_subscriber::{layer, registry::LookupSpan, Layer};
6
7pub struct EguiLayer {
8 _priv: (),
9}
10
11impl EguiLayer {
12 pub fn new() -> Self {
13 #[cfg(feature = "smartstring")]
14 smartstring::validate();
15 EguiLayer { _priv: () }
16 }
17}
18
19impl Default for EguiLayer {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25impl<S> Layer<S> for EguiLayer
26where
27 S: tracing::Subscriber + for<'a> LookupSpan<'a>,
28{
29 fn new_span(&self, fields: &span::Attributes<'_>, id: &span::Id, ctx: layer::Context<'_, S>) {
30 let meta = ctx.metadata(id);
31 let span = ctx.span(id).expect("ctx span");
32 let mut ext = span.extensions_mut();
33
34 if ext.get_mut::<Arc<LogSpan>>().is_none() {
35 let mut log = LogSpan {
36 meta,
37 fields: Default::default(),
38 parent: span
39 .parent()
40 .and_then(|span| span.extensions().get::<Arc<LogSpan>>().map(Arc::clone)),
41 };
42 if log.add_fields(fields).is_ok() {
43 ext.insert(Arc::new(log));
44 }
45 }
46 }
47
48 fn on_record(&self, id: &span::Id, fields: &span::Record<'_>, ctx: layer::Context<'_, S>) {
49 let meta = ctx.metadata(id);
50 let span = ctx.span(id).expect("ctx span");
51 let mut ext = span.extensions_mut();
52
53 match ext.get_mut::<Arc<LogSpan>>() {
54 Some(log) => {
55 let log = Arc::make_mut(log);
56 let _ = log.add_fields(fields);
57 }
58 None => {
59 let mut log = LogSpan {
60 meta,
61 fields: Default::default(),
62 parent: span
63 .parent()
64 .and_then(|span| span.extensions().get::<Arc<LogSpan>>().map(Arc::clone)),
65 };
66 if log.add_fields(fields).is_ok() {
67 ext.insert(Arc::new(log));
68 }
69 }
70 }
71 }
72
73 fn on_event(&self, event: &tracing::Event<'_>, ctx: layer::Context<'_, S>) {
74 let meta = event.metadata();
75 let span = ctx.event_span(event);
76
77 let mut log = LogEvent {
78 meta,
79 timestamp: chrono::Local::now().naive_local(),
80 fields: Default::default(),
81 span: span.and_then(|span| span.extensions().get::<Arc<LogSpan>>().map(Arc::clone)),
82 };
83 let _ = log.add_fields(event);
84 LOG_ENTRIES.lock().push(log);
85 }
86}