tracing_tunnel/sender/
mod.rs1use core::{
4 ptr,
5 sync::atomic::{AtomicU32, Ordering},
6};
7
8use tracing_core::{
9 Event, Interest, Metadata, Subscriber,
10 span::{Attributes, Id, Record},
11};
12
13#[cfg(feature = "std")]
14pub use self::sync::Synced;
15use crate::{CallSiteData, MetadataId, RawSpanId, TracedValues, TracingEvent};
16
17#[cfg(feature = "std")]
18mod sync;
19
20impl TracingEvent {
21 fn new_span(span: &Attributes<'_>, metadata_id: MetadataId, id: RawSpanId) -> Self {
22 Self::NewSpan {
23 id,
24 parent_id: span.parent().map(Id::into_u64),
25 metadata_id,
26 values: TracedValues::from_values(span.values()),
27 }
28 }
29
30 fn values_recorded(id: RawSpanId, values: &Record<'_>) -> Self {
31 Self::ValuesRecorded {
32 id,
33 values: TracedValues::from_record(values),
34 }
35 }
36
37 fn new_event(event: &Event<'_>, metadata_id: MetadataId) -> Self {
38 Self::NewEvent {
39 metadata_id,
40 parent: event.parent().map(Id::into_u64),
41 values: TracedValues::from_event(event),
42 }
43 }
44}
45
46pub trait EventSync: 'static + Send + Sync {
54 #[doc(hidden)] fn register_callsite(
57 &self,
58 metadata: &'static Metadata<'static>,
59 sender: impl Fn(TracingEvent),
60 );
61
62 #[doc(hidden)] fn ensure_callsite_registered(
65 &self,
66 metadata: &'static Metadata<'static>,
67 sender: impl Fn(TracingEvent),
68 );
69}
70
71impl EventSync for () {
73 fn register_callsite(
74 &self,
75 metadata: &'static Metadata<'static>,
76 sender: impl Fn(TracingEvent),
77 ) {
78 sender(TracingEvent::NewCallSite {
79 id: metadata_id(metadata),
80 data: CallSiteData::from(metadata),
81 });
82 }
83
84 fn ensure_callsite_registered(
85 &self,
86 _metadata: &'static Metadata<'static>,
87 _sender: impl Fn(TracingEvent),
88 ) {
89 }
91}
92
93fn metadata_id(metadata: &'static Metadata<'static>) -> MetadataId {
94 ptr::from_ref(metadata) as MetadataId
95}
96
97#[derive(Debug)]
110pub struct TracingEventSender<F = fn(TracingEvent), S = ()> {
111 next_span_id: AtomicU32,
112 on_event: F,
113 sync: S,
114}
115
116impl<F: Fn(TracingEvent) + 'static> TracingEventSender<F> {
117 pub fn new(on_event: F) -> Self {
119 Self {
120 next_span_id: AtomicU32::new(1), on_event,
122 sync: (),
123 }
124 }
125}
126
127#[cfg(feature = "std")]
128impl<F: Fn(TracingEvent) + 'static> TracingEventSender<F, Synced> {
129 pub fn sync(on_event: F) -> Self {
131 Self {
132 next_span_id: AtomicU32::new(1), on_event,
134 sync: Synced::default(),
135 }
136 }
137}
138
139impl<F: Fn(TracingEvent) + 'static, S: EventSync> TracingEventSender<F, S> {
140 fn send(&self, event: TracingEvent) {
141 (self.on_event)(event);
142 }
143}
144
145impl<F: Fn(TracingEvent) + 'static, S: EventSync> Subscriber for TracingEventSender<F, S> {
146 fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest {
147 self.sync.register_callsite(metadata, &self.on_event);
149 Interest::always()
150 }
151
152 fn enabled(&self, _metadata: &Metadata<'_>) -> bool {
153 true
154 }
155
156 fn new_span(&self, span: &Attributes<'_>) -> Id {
157 self.sync
162 .ensure_callsite_registered(span.metadata(), &self.on_event);
163
164 let metadata_id = metadata_id(span.metadata());
165 let span_id = u64::from(self.next_span_id.fetch_add(1, Ordering::SeqCst));
166 self.send(TracingEvent::new_span(span, metadata_id, span_id));
167 Id::from_u64(span_id)
168 }
169
170 fn record(&self, span: &Id, values: &Record<'_>) {
171 self.send(TracingEvent::values_recorded(span.into_u64(), values));
172 }
173
174 fn record_follows_from(&self, span: &Id, follows: &Id) {
175 self.send(TracingEvent::FollowsFrom {
176 id: span.into_u64(),
177 follows_from: follows.into_u64(),
178 });
179 }
180
181 fn event(&self, event: &Event<'_>) {
182 self.sync
187 .ensure_callsite_registered(event.metadata(), &self.on_event);
188
189 let metadata_id = metadata_id(event.metadata());
190 self.send(TracingEvent::new_event(event, metadata_id));
191 }
192
193 fn enter(&self, span: &Id) {
194 self.send(TracingEvent::SpanEntered {
195 id: span.into_u64(),
196 });
197 }
198
199 fn exit(&self, span: &Id) {
200 self.send(TracingEvent::SpanExited {
201 id: span.into_u64(),
202 });
203 }
204
205 fn clone_span(&self, span: &Id) -> Id {
206 self.send(TracingEvent::SpanCloned {
207 id: span.into_u64(),
208 });
209 span.clone()
210 }
211
212 fn try_close(&self, span: Id) -> bool {
213 self.send(TracingEvent::SpanDropped {
214 id: span.into_u64(),
215 });
216 false
217 }
218}