1use core::sync::atomic::{AtomicU32, Ordering};
4
5use tracing_core::{
6 span::{Attributes, Id, Record},
7 Event, Interest, Metadata, Subscriber,
8};
9
10use crate::{CallSiteData, MetadataId, RawSpanId, TracedValues, TracingEvent};
11
12impl TracingEvent {
13 fn new_span(span: &Attributes<'_>, metadata_id: MetadataId, id: RawSpanId) -> Self {
14 Self::NewSpan {
15 id,
16 parent_id: span.parent().map(Id::into_u64),
17 metadata_id,
18 values: TracedValues::from_values(span.values()),
19 }
20 }
21
22 fn values_recorded(id: RawSpanId, values: &Record<'_>) -> Self {
23 Self::ValuesRecorded {
24 id,
25 values: TracedValues::from_record(values),
26 }
27 }
28
29 fn new_event(event: &Event<'_>, metadata_id: MetadataId) -> Self {
30 Self::NewEvent {
31 metadata_id,
32 parent: event.parent().map(Id::into_u64),
33 values: TracedValues::from_event(event),
34 }
35 }
36}
37
38#[derive(Debug)]
51pub struct TracingEventSender<F = fn(TracingEvent)> {
52 next_span_id: AtomicU32,
53 on_event: F,
54}
55
56impl<F: Fn(TracingEvent) + 'static> TracingEventSender<F> {
57 pub fn new(on_event: F) -> Self {
59 Self {
60 next_span_id: AtomicU32::new(1), on_event,
62 }
63 }
64
65 fn metadata_id(metadata: &'static Metadata<'static>) -> MetadataId {
66 metadata as *const _ as MetadataId
67 }
68
69 fn send(&self, event: TracingEvent) {
70 (self.on_event)(event);
71 }
72}
73
74impl<F: Fn(TracingEvent) + 'static> Subscriber for TracingEventSender<F> {
75 fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
76 let id = Self::metadata_id(metadata);
77 self.send(TracingEvent::NewCallSite {
78 id,
79 data: CallSiteData::from(metadata),
80 });
81 Interest::always()
82 }
83
84 fn enabled(&self, _metadata: &Metadata<'_>) -> bool {
85 true
86 }
87
88 fn new_span(&self, span: &Attributes<'_>) -> Id {
89 let metadata_id = Self::metadata_id(span.metadata());
90 let span_id = u64::from(self.next_span_id.fetch_add(1, Ordering::SeqCst));
91 self.send(TracingEvent::new_span(span, metadata_id, span_id));
92 Id::from_u64(span_id)
93 }
94
95 fn record(&self, span: &Id, values: &Record<'_>) {
96 self.send(TracingEvent::values_recorded(span.into_u64(), values));
97 }
98
99 fn record_follows_from(&self, span: &Id, follows: &Id) {
100 self.send(TracingEvent::FollowsFrom {
101 id: span.into_u64(),
102 follows_from: follows.into_u64(),
103 });
104 }
105
106 fn event(&self, event: &Event<'_>) {
107 let metadata_id = Self::metadata_id(event.metadata());
108 self.send(TracingEvent::new_event(event, metadata_id));
109 }
110
111 fn enter(&self, span: &Id) {
112 self.send(TracingEvent::SpanEntered {
113 id: span.into_u64(),
114 });
115 }
116
117 fn exit(&self, span: &Id) {
118 self.send(TracingEvent::SpanExited {
119 id: span.into_u64(),
120 });
121 }
122
123 fn clone_span(&self, span: &Id) -> Id {
124 self.send(TracingEvent::SpanCloned {
125 id: span.into_u64(),
126 });
127 span.clone()
128 }
129
130 fn try_close(&self, span: Id) -> bool {
131 self.send(TracingEvent::SpanDropped {
132 id: span.into_u64(),
133 });
134 false
135 }
136}