1use crate::payload::{Payload, PayloadRaw};
8use std::sync::Arc;
9use uuid::Uuid;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
14pub struct TraceContext {
15 pub correlation_id: Uuid,
16 pub span_id: u64,
17 pub parent_id: Option<u64>,
18}
19
20impl TraceContext {
21 pub fn new() -> Self {
23 let correlation_id = Uuid::now_v7();
24 let span_id = correlation_id.as_u128() as u64; Self {
26 correlation_id,
27 span_id,
28 parent_id: None,
29 }
30 }
31
32 pub fn new_child(&self) -> Self {
34 Self {
35 correlation_id: self.correlation_id,
36 span_id: Uuid::now_v7().as_u128() as u64, parent_id: Some(self.span_id),
38 }
39 }
40
41 pub fn from_parts(correlation_id: Uuid, span_id: u64, parent_id: Option<u64>) -> Self {
43 Self {
44 correlation_id,
45 span_id,
46 parent_id,
47 }
48 }
49}
50
51impl Default for TraceContext {
52 fn default() -> Self {
53 Self::new()
54 }
55}
56
57pub trait LogTrace {
59 fn correlation_id(&self) -> Uuid;
60 fn span_id(&self) -> u64;
61 fn parent_id(&self) -> Option<u64>;
62 fn neuron_name(&self) -> String;
63
64 fn trace_context(&self) -> TraceContext {
66 TraceContext::from_parts(self.correlation_id(), self.span_id(), self.parent_id())
67 }
68
69 fn span_info(&self, name: &'static str) -> tracing::Span {
71 let correlation_id = self.correlation_id().to_string();
72 let span_id = self.span_id().to_string();
73 let parent_id = self
74 .parent_id()
75 .map(|id| id.to_string())
76 .unwrap_or_default();
77 let neuron = self.neuron_name();
78
79 tracing::info_span!(
80 target: "plexor::trace",
81 "plexor",
82 log_name = name,
83 correlation_id = %correlation_id,
84 span_id = %span_id,
85 parent_id = %parent_id,
86 neuron = %neuron
87 )
88 }
89
90 fn span_debug(&self, name: &'static str) -> tracing::Span {
92 let correlation_id = self.correlation_id().to_string();
93 let span_id = self.span_id().to_string();
94 let parent_id = self
95 .parent_id()
96 .map(|id| id.to_string())
97 .unwrap_or_default();
98 let neuron = self.neuron_name();
99
100 tracing::debug_span!(
101 target: "plexor::trace",
102 "plexor",
103 log_name = name,
104 correlation_id = %correlation_id,
105 span_id = %span_id,
106 parent_id = %parent_id,
107 neuron = %neuron
108 )
109 }
110}
111
112impl LogTrace for TraceContext {
113 fn correlation_id(&self) -> Uuid {
114 self.correlation_id
115 }
116 fn span_id(&self) -> u64 {
117 self.span_id
118 }
119 fn parent_id(&self) -> Option<u64> {
120 self.parent_id
121 }
122 fn neuron_name(&self) -> String {
123 "app".to_string()
124 }
125 fn trace_context(&self) -> TraceContext {
126 *self
127 }
128}
129
130impl LogTrace for Uuid {
131 fn correlation_id(&self) -> Uuid {
132 Uuid::nil()
133 }
134 fn span_id(&self) -> u64 {
135 0
136 }
137 fn parent_id(&self) -> Option<u64> {
138 None
139 }
140 fn neuron_name(&self) -> String {
141 "none".to_string()
142 }
143
144 fn span_info(&self, name: &'static str) -> tracing::Span {
145 tracing::info_span!(
146 target: "plexor::trace",
147 "plexor",
148 log_name = name,
149 ganglion_id = %self
150 )
151 }
152
153 fn span_debug(&self, name: &'static str) -> tracing::Span {
154 tracing::debug_span!(
155 target: "plexor::trace",
156 "plexor",
157 log_name = name,
158 ganglion_id = %self
159 )
160 }
161}
162
163impl<T, C> LogTrace for Payload<T, C>
164where
165 T: Send + Sync + 'static,
166 C: crate::codec::Codec<T> + crate::codec::CodecName + Send + Sync + 'static,
167{
168 fn correlation_id(&self) -> Uuid {
169 self.trace.correlation_id
170 }
171 fn span_id(&self) -> u64 {
172 self.trace.span_id
173 }
174 fn parent_id(&self) -> Option<u64> {
175 self.trace.parent_id
176 }
177 fn neuron_name(&self) -> String {
178 self.neuron.name()
179 }
180 fn trace_context(&self) -> TraceContext {
181 self.trace
182 }
183}
184
185impl<T, C> LogTrace for PayloadRaw<T, C>
186where
187 T: Send + Sync + 'static,
188 C: crate::codec::Codec<T> + crate::codec::CodecName + Send + Sync + 'static,
189{
190 fn correlation_id(&self) -> Uuid {
191 self.trace.correlation_id
192 }
193 fn span_id(&self) -> u64 {
194 self.trace.span_id
195 }
196 fn parent_id(&self) -> Option<u64> {
197 self.trace.parent_id
198 }
199 fn neuron_name(&self) -> String {
200 self.neuron.name()
201 }
202 fn trace_context(&self) -> TraceContext {
203 self.trace
204 }
205}
206
207impl LogTrace for crate::erasure::payload::SimplePayloadRawErased {
208 fn correlation_id(&self) -> Uuid {
209 self.trace.correlation_id
210 }
211 fn span_id(&self) -> u64 {
212 self.trace.span_id
213 }
214 fn parent_id(&self) -> Option<u64> {
215 self.trace.parent_id
216 }
217 fn neuron_name(&self) -> String {
218 self.neuron_name.clone()
219 }
220 fn trace_context(&self) -> TraceContext {
221 self.trace
222 }
223}
224
225impl<T, C> LogTrace for crate::erasure::payload::PayloadErasedWrapper<T, C>
226where
227 T: Send + Sync + 'static,
228 C: crate::codec::Codec<T> + crate::codec::CodecName + Send + Sync + 'static,
229{
230 fn correlation_id(&self) -> Uuid {
231 self.get_typed_payload().trace.correlation_id
232 }
233 fn span_id(&self) -> u64 {
234 self.get_typed_payload().trace.span_id
235 }
236 fn parent_id(&self) -> Option<u64> {
237 self.get_typed_payload().trace.parent_id
238 }
239 fn neuron_name(&self) -> String {
240 self.get_typed_payload().neuron.name()
241 }
242 fn trace_context(&self) -> TraceContext {
243 self.get_typed_payload().trace
244 }
245}
246
247impl<T, C> LogTrace for crate::erasure::payload::PayloadRawErasedWrapper<T, C>
248where
249 T: Send + Sync + 'static,
250 C: crate::codec::Codec<T> + crate::codec::CodecName + Send + Sync + 'static,
251{
252 fn correlation_id(&self) -> Uuid {
253 self.get_payload_raw().trace.correlation_id
254 }
255 fn span_id(&self) -> u64 {
256 self.get_payload_raw().trace.span_id
257 }
258 fn parent_id(&self) -> Option<u64> {
259 self.get_payload_raw().trace.parent_id
260 }
261 fn neuron_name(&self) -> String {
262 self.get_payload_raw().neuron.name()
263 }
264 fn trace_context(&self) -> TraceContext {
265 self.get_payload_raw().trace
266 }
267}
268
269impl<P: LogTrace + ?Sized> LogTrace for Arc<P> {
270 fn correlation_id(&self) -> Uuid {
271 (**self).correlation_id()
272 }
273 fn span_id(&self) -> u64 {
274 (**self).span_id()
275 }
276 fn parent_id(&self) -> Option<u64> {
277 (**self).parent_id()
278 }
279 fn neuron_name(&self) -> String {
280 (**self).neuron_name()
281 }
282}