saluki_core/data_model/event/trace/
mod.rs1use std::sync::Arc;
4
5use saluki_common::collections::FastHashMap;
6use stringtheory::MetaString;
7
8#[derive(Clone, Debug, PartialEq)]
13pub enum AttributeValue {
14 String(MetaString),
16 Bool(bool),
18 Int(i64),
20 Float(f64),
22 Bytes(Vec<u8>),
24 Array(Vec<AttributeValue>),
26 KeyValueList(Vec<(MetaString, AttributeValue)>),
28}
29
30impl AttributeValue {
31 pub fn as_string(&self) -> Option<&MetaString> {
33 if let AttributeValue::String(s) = self {
34 Some(s)
35 } else {
36 None
37 }
38 }
39
40 pub fn as_float(&self) -> Option<f64> {
46 if let AttributeValue::Float(f) = self {
47 Some(*f)
48 } else {
49 None
50 }
51 }
52
53 pub fn as_bool(&self) -> Option<bool> {
55 if let AttributeValue::Bool(b) = self {
56 Some(*b)
57 } else {
58 None
59 }
60 }
61
62 pub fn as_int(&self) -> Option<i64> {
64 if let AttributeValue::Int(i) = self {
65 Some(*i)
66 } else {
67 None
68 }
69 }
70
71 pub fn as_num(&self) -> Option<f64> {
76 match self {
77 AttributeValue::Float(f) => Some(*f),
78 AttributeValue::Int(i) => Some(*i as f64),
79 _ => None,
80 }
81 }
82
83 pub fn as_bytes(&self) -> Option<&[u8]> {
85 if let AttributeValue::Bytes(b) = self {
86 Some(b)
87 } else {
88 None
89 }
90 }
91}
92
93#[derive(Clone, Debug, PartialEq, Default)]
98pub struct PayloadFields {
99 pub container_id: MetaString,
101 pub language_name: MetaString,
103 pub language_version: MetaString,
105 pub tracer_version: MetaString,
107 pub runtime_id: MetaString,
109 pub env: MetaString,
111 pub hostname: MetaString,
113 pub app_version: MetaString,
115 pub client_dropped_p0s_weight: f64,
117}
118
119#[derive(Clone, Copy, Debug, PartialEq)]
124pub enum TraceIngestInfo {
125 Datadog,
127
128 Otlp {
130 receiver_sampling_rate: f64,
135 },
136}
137
138#[derive(Clone, Debug, PartialEq)]
142pub struct Trace {
143 spans: Vec<Span>,
145 pub trace_id_high: u64,
147 pub trace_id_low: u64,
149 pub origin: MetaString,
151 pub payload: PayloadFields,
153 pub attributes: Arc<FastHashMap<MetaString, AttributeValue>>,
155 pub priority: Option<i32>,
157 pub dropped_trace: bool,
159 pub sampling_mechanism: u32,
161 pub decision_maker: Option<MetaString>,
163 ingest_info: TraceIngestInfo,
165}
166
167impl Trace {
168 pub fn new(spans: Vec<Span>, ingest_info: TraceIngestInfo) -> Self {
173 Self {
174 spans,
175 trace_id_high: 0,
176 trace_id_low: 0,
177 origin: MetaString::empty(),
178 payload: PayloadFields::default(),
179 attributes: Arc::new(FastHashMap::default()),
180 priority: None,
181 dropped_trace: false,
182 sampling_mechanism: 0,
183 decision_maker: None,
184 ingest_info,
185 }
186 }
187
188 pub fn ingest_info(&self) -> TraceIngestInfo {
192 self.ingest_info
193 }
194
195 pub fn spans(&self) -> &[Span] {
197 &self.spans
198 }
199
200 pub fn spans_mut(&mut self) -> &mut [Span] {
202 &mut self.spans
203 }
204
205 pub fn set_spans(&mut self, spans: Vec<Span>) {
207 self.spans = spans;
208 }
209
210 pub fn retain_spans<F>(&mut self, mut f: F) -> usize
214 where
215 F: FnMut(&Trace, &Span) -> bool,
216 {
217 if self.spans.is_empty() {
218 return 0;
219 }
220
221 let mut has_match = false;
222 for span in self.spans.iter() {
223 if f(self, span) {
224 has_match = true;
225 break;
226 }
227 }
228
229 if !has_match {
230 return 0;
231 }
232
233 let mut spans = std::mem::take(&mut self.spans);
234 spans.retain(|span| f(self, span));
235 spans.shrink_to_fit();
236 let _ = std::mem::replace(&mut self.spans, spans);
237
238 self.spans.len()
239 }
240
241 pub fn remove_spans<F>(&mut self, mut f: F)
243 where
244 F: FnMut(&Trace, &Span) -> bool,
245 {
246 if self.spans.is_empty() {
247 return;
248 }
249
250 let mut spans = std::mem::take(&mut self.spans);
251 spans.retain(|span| !f(self, span));
252 spans.shrink_to_fit();
253 let _ = std::mem::replace(&mut self.spans, spans);
254 }
255}
256
257#[derive(Clone, Debug, PartialEq, Default)]
259pub struct Span {
260 service: MetaString,
262 name: MetaString,
264 resource: MetaString,
266 span_id: u64,
268 parent_id: u64,
270 start: u64,
272 duration: u64,
274 error: i32,
276 span_type: MetaString,
278 span_links: Vec<SpanLink>,
280 span_events: Vec<SpanEvent>,
282 pub env: MetaString,
284 pub version: MetaString,
286 pub component: MetaString,
288 pub kind: u32,
290 pub attributes: FastHashMap<MetaString, AttributeValue>,
292}
293
294impl Span {
295 #[allow(clippy::too_many_arguments)]
297 pub fn new(
298 service: impl Into<MetaString>, name: impl Into<MetaString>, resource: impl Into<MetaString>,
299 span_type: impl Into<MetaString>, span_id: u64, parent_id: u64, start: u64, duration: u64, error: i32,
300 ) -> Self {
301 Self {
302 service: service.into(),
303 name: name.into(),
304 resource: resource.into(),
305 span_type: span_type.into(),
306 span_id,
307 parent_id,
308 start,
309 duration,
310 error,
311 ..Self::default()
312 }
313 }
314
315 pub fn with_service(mut self, service: impl Into<MetaString>) -> Self {
317 self.service = service.into();
318 self
319 }
320
321 pub fn with_name(mut self, name: impl Into<MetaString>) -> Self {
323 self.name = name.into();
324 self
325 }
326
327 pub fn with_resource(mut self, resource: impl Into<MetaString>) -> Self {
329 self.resource = resource.into();
330 self
331 }
332
333 pub fn with_span_id(mut self, span_id: u64) -> Self {
335 self.span_id = span_id;
336 self
337 }
338
339 pub fn with_parent_id(mut self, parent_id: u64) -> Self {
341 self.parent_id = parent_id;
342 self
343 }
344
345 pub fn with_start(mut self, start: u64) -> Self {
347 self.start = start;
348 self
349 }
350
351 pub fn with_duration(mut self, duration: u64) -> Self {
353 self.duration = duration;
354 self
355 }
356
357 pub fn with_error(mut self, error: i32) -> Self {
359 self.error = error;
360 self
361 }
362
363 pub fn with_span_type(mut self, span_type: impl Into<MetaString>) -> Self {
365 self.span_type = span_type.into();
366 self
367 }
368
369 pub fn with_attributes(mut self, attributes: impl Into<Option<FastHashMap<MetaString, AttributeValue>>>) -> Self {
371 self.attributes = attributes.into().unwrap_or_default();
372 self
373 }
374
375 pub fn with_span_links(mut self, span_links: impl Into<Option<Vec<SpanLink>>>) -> Self {
377 self.span_links = span_links.into().unwrap_or_default();
378 self
379 }
380
381 pub fn with_span_events(mut self, span_events: impl Into<Option<Vec<SpanEvent>>>) -> Self {
383 self.span_events = span_events.into().unwrap_or_default();
384 self
385 }
386
387 pub fn with_env(mut self, env: impl Into<MetaString>) -> Self {
389 self.env = env.into();
390 self
391 }
392
393 pub fn with_version(mut self, version: impl Into<MetaString>) -> Self {
395 self.version = version.into();
396 self
397 }
398
399 pub fn with_component(mut self, component: impl Into<MetaString>) -> Self {
401 self.component = component.into();
402 self
403 }
404
405 pub fn with_kind(mut self, kind: u32) -> Self {
407 self.kind = kind;
408 self
409 }
410
411 pub fn service(&self) -> &str {
413 &self.service
414 }
415
416 pub fn name(&self) -> &str {
418 &self.name
419 }
420
421 pub fn resource(&self) -> &str {
423 &self.resource
424 }
425
426 pub fn set_resource(&mut self, resource: impl Into<MetaString>) {
428 self.resource = resource.into();
429 }
430
431 pub fn span_id(&self) -> u64 {
433 self.span_id
434 }
435
436 pub fn parent_id(&self) -> u64 {
438 self.parent_id
439 }
440
441 pub fn start(&self) -> u64 {
443 self.start
444 }
445
446 pub fn duration(&self) -> u64 {
448 self.duration
449 }
450
451 pub fn error(&self) -> i32 {
453 self.error
454 }
455
456 pub fn span_type(&self) -> &str {
458 &self.span_type
459 }
460
461 pub fn span_links(&self) -> &[SpanLink] {
463 &self.span_links
464 }
465
466 pub fn span_events(&self) -> &[SpanEvent] {
468 &self.span_events
469 }
470
471 pub fn span_events_mut(&mut self) -> &mut Vec<SpanEvent> {
473 &mut self.span_events
474 }
475}
476
477#[derive(Clone, Debug, PartialEq, Default)]
479pub struct SpanLink {
480 trace_id: u64,
482 trace_id_high: u64,
484 span_id: u64,
486 attributes: FastHashMap<MetaString, AttributeValue>,
488 tracestate: MetaString,
490 flags: u32,
492}
493
494impl SpanLink {
495 pub fn new(trace_id: u64, span_id: u64) -> Self {
497 Self {
498 trace_id,
499 span_id,
500 ..Self::default()
501 }
502 }
503
504 pub fn with_trace_id(mut self, trace_id: u64) -> Self {
506 self.trace_id = trace_id;
507 self
508 }
509
510 pub fn with_trace_id_high(mut self, trace_id_high: u64) -> Self {
512 self.trace_id_high = trace_id_high;
513 self
514 }
515
516 pub fn with_span_id(mut self, span_id: u64) -> Self {
518 self.span_id = span_id;
519 self
520 }
521
522 pub fn with_attributes(mut self, attributes: impl Into<Option<FastHashMap<MetaString, AttributeValue>>>) -> Self {
524 self.attributes = attributes.into().unwrap_or_default();
525 self
526 }
527
528 pub fn with_tracestate(mut self, tracestate: impl Into<MetaString>) -> Self {
530 self.tracestate = tracestate.into();
531 self
532 }
533
534 pub fn with_flags(mut self, flags: u32) -> Self {
536 self.flags = flags;
537 self
538 }
539
540 pub fn trace_id(&self) -> u64 {
542 self.trace_id
543 }
544
545 pub fn trace_id_high(&self) -> u64 {
547 self.trace_id_high
548 }
549
550 pub fn span_id(&self) -> u64 {
552 self.span_id
553 }
554
555 pub fn attributes(&self) -> &FastHashMap<MetaString, AttributeValue> {
557 &self.attributes
558 }
559
560 pub fn tracestate(&self) -> &str {
562 &self.tracestate
563 }
564
565 pub fn flags(&self) -> u32 {
567 self.flags
568 }
569}
570
571#[derive(Clone, Debug, PartialEq, Default)]
573pub struct SpanEvent {
574 time_unix_nano: u64,
576 name: MetaString,
578 attributes: FastHashMap<MetaString, AttributeValue>,
580}
581
582impl SpanEvent {
583 pub fn new(time_unix_nano: u64, name: impl Into<MetaString>) -> Self {
585 Self {
586 time_unix_nano,
587 name: name.into(),
588 ..Self::default()
589 }
590 }
591
592 pub fn with_time_unix_nano(mut self, time_unix_nano: u64) -> Self {
594 self.time_unix_nano = time_unix_nano;
595 self
596 }
597
598 pub fn with_name(mut self, name: impl Into<MetaString>) -> Self {
600 self.name = name.into();
601 self
602 }
603
604 pub fn with_attributes(mut self, attributes: impl Into<Option<FastHashMap<MetaString, AttributeValue>>>) -> Self {
606 self.attributes = attributes.into().unwrap_or_default();
607 self
608 }
609
610 pub fn time_unix_nano(&self) -> u64 {
612 self.time_unix_nano
613 }
614
615 pub fn name(&self) -> &str {
617 &self.name
618 }
619
620 pub fn attributes(&self) -> &FastHashMap<MetaString, AttributeValue> {
622 &self.attributes
623 }
624
625 pub fn attributes_mut(&mut self) -> &mut FastHashMap<MetaString, AttributeValue> {
627 &mut self.attributes
628 }
629}