libdd_trace_utils/span/v1/
mod.rs1use crate::span::vec_map::VecMap;
5use crate::span::{BytesData, SliceData, TraceData};
6pub use thin_vec::ThinVec;
7
8#[repr(u32)]
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
12pub enum SpanKind {
13 #[default]
14 Internal = 1,
15 Server = 2,
16 Client = 3,
17 Producer = 4,
18 Consumer = 5,
19}
20
21impl SpanKind {
22 pub fn from_meta(s: &str) -> Self {
25 match s {
26 "server" => SpanKind::Server,
27 "client" => SpanKind::Client,
28 "producer" => SpanKind::Producer,
29 "consumer" => SpanKind::Consumer,
30 _ => SpanKind::Internal,
31 }
32 }
33}
34
35#[derive(Debug)]
38pub enum AttributeValue<T: TraceData> {
39 String(T::Text),
40 Float(f64),
41 Int(i64),
42 Bool(bool),
43 Bytes(T::Bytes),
44 KeyValue(VecMap<T::Text, AttributeValue<T>>),
45 List(Vec<AttributeValue<T>>),
46}
47
48#[derive(Debug, Default)]
61pub struct Span<T: TraceData> {
62 pub service: T::Text,
63 pub name: T::Text,
64 pub resource: T::Text,
65 pub r#type: T::Text,
66 pub span_id: u64,
67 pub parent_id: u64,
68 pub start: i64,
69 pub duration: i64,
70 pub error: bool,
71 pub span_kind: SpanKind,
72 pub env: T::Text,
73 pub version: T::Text,
74 pub component: T::Text,
75 pub attributes: VecMap<T::Text, AttributeValue<T>>,
76 pub span_links: ThinVec<SpanLink<T>>,
77 pub span_events: ThinVec<SpanEvent<T>>,
78}
79
80#[derive(Debug, Default)]
83pub struct SpanLink<T: TraceData> {
84 pub trace_id: [u8; 16],
85 pub span_id: u64,
86 pub attributes: VecMap<T::Text, AttributeValue<T>>,
87 pub tracestate: T::Text,
88 pub flags: u32,
89}
90
91#[derive(Debug, Default)]
94pub struct SpanEvent<T: TraceData> {
95 pub time_unix_nano: u64,
96 pub name: T::Text,
97 pub attributes: VecMap<T::Text, AttributeValue<T>>,
98}
99
100#[derive(Debug, Default)]
102pub struct TraceChunk<T: TraceData> {
103 pub trace_id: [u8; 16],
104 pub priority: Option<i32>,
105 pub origin: T::Text,
106 pub sampling_mechanism: Option<u32>,
107 pub dropped_trace: bool,
108 pub attributes: VecMap<T::Text, AttributeValue<T>>,
109 pub spans: Vec<Span<T>>,
110}
111
112#[derive(Debug, Default)]
114pub struct TracerPayload<T: TraceData> {
115 pub language_name: T::Text,
116 pub language_version: T::Text,
117 pub tracer_version: T::Text,
118 pub runtime_id: T::Text,
119 pub env: T::Text,
120 pub hostname: T::Text,
121 pub app_version: T::Text,
122 pub attributes: VecMap<T::Text, AttributeValue<T>>,
123 pub chunks: Vec<TraceChunk<T>>,
124}
125
126pub type SpanBytes = Span<BytesData>;
127pub type SpanLinkBytes = SpanLink<BytesData>;
128pub type SpanEventBytes = SpanEvent<BytesData>;
129pub type AttributeValueBytes = AttributeValue<BytesData>;
130pub type TraceChunkBytes = TraceChunk<BytesData>;
131pub type TracerPayloadBytes = TracerPayload<BytesData>;
132
133pub type SpanSlice<'a> = Span<SliceData<'a>>;
134pub type SpanLinkSlice<'a> = SpanLink<SliceData<'a>>;
135pub type SpanEventSlice<'a> = SpanEvent<SliceData<'a>>;
136pub type AttributeValueSlice<'a> = AttributeValue<SliceData<'a>>;
137pub type TraceChunkSlice<'a> = TraceChunk<SliceData<'a>>;
138pub type TracerPayloadSlice<'a> = TracerPayload<SliceData<'a>>;
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143
144 #[test]
145 fn span_kind_default_is_internal() {
146 assert_eq!(SpanKind::default(), SpanKind::Internal);
147 }
148
149 #[test]
150 fn span_kind_from_meta() {
151 assert_eq!(SpanKind::from_meta("server"), SpanKind::Server);
152 assert_eq!(SpanKind::from_meta("client"), SpanKind::Client);
153 assert_eq!(SpanKind::from_meta("producer"), SpanKind::Producer);
154 assert_eq!(SpanKind::from_meta("consumer"), SpanKind::Consumer);
155 assert_eq!(SpanKind::from_meta("internal"), SpanKind::Internal);
156 assert_eq!(SpanKind::from_meta(""), SpanKind::Internal);
157 assert_eq!(SpanKind::from_meta("anything-else"), SpanKind::Internal);
158 }
159
160 #[test]
161 fn span_kind_repr_matches_otel_spec() {
162 assert_eq!(SpanKind::Internal as u32, 1);
163 assert_eq!(SpanKind::Server as u32, 2);
164 assert_eq!(SpanKind::Client as u32, 3);
165 assert_eq!(SpanKind::Producer as u32, 4);
166 assert_eq!(SpanKind::Consumer as u32, 5);
167 }
168
169 #[test]
170 fn span_default_has_internal_kind() {
171 let s = SpanBytes::default();
172 assert_eq!(s.span_kind, SpanKind::Internal);
173 assert!(!s.error);
174 assert!(s.attributes.is_empty());
175 }
176}