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, Debug, PartialEq)]
123pub struct Trace {
124 spans: Vec<Span>,
126 pub trace_id_high: u64,
128 pub trace_id_low: u64,
130 pub origin: MetaString,
132 pub payload: PayloadFields,
134 pub attributes: Arc<FastHashMap<MetaString, AttributeValue>>,
136 pub priority: Option<i32>,
138 pub dropped_trace: bool,
140 pub sampling_mechanism: u32,
142 pub decision_maker: Option<MetaString>,
144 pub otlp_sampling_rate: Option<f64>,
146}
147
148impl Trace {
149 pub fn new(spans: Vec<Span>) -> Self {
154 Self {
155 spans,
156 trace_id_high: 0,
157 trace_id_low: 0,
158 origin: MetaString::empty(),
159 payload: PayloadFields::default(),
160 attributes: Arc::new(FastHashMap::default()),
161 priority: None,
162 dropped_trace: false,
163 sampling_mechanism: 0,
164 decision_maker: None,
165 otlp_sampling_rate: None,
166 }
167 }
168
169 pub fn spans(&self) -> &[Span] {
171 &self.spans
172 }
173
174 pub fn spans_mut(&mut self) -> &mut [Span] {
176 &mut self.spans
177 }
178
179 pub fn set_spans(&mut self, spans: Vec<Span>) {
181 self.spans = spans;
182 }
183
184 pub fn retain_spans<F>(&mut self, mut f: F) -> usize
188 where
189 F: FnMut(&Trace, &Span) -> bool,
190 {
191 if self.spans.is_empty() {
192 return 0;
193 }
194
195 let mut has_match = false;
196 for span in self.spans.iter() {
197 if f(self, span) {
198 has_match = true;
199 break;
200 }
201 }
202
203 if !has_match {
204 return 0;
205 }
206
207 let mut spans = std::mem::take(&mut self.spans);
208 spans.retain(|span| f(self, span));
209 spans.shrink_to_fit();
210 let _ = std::mem::replace(&mut self.spans, spans);
211
212 self.spans.len()
213 }
214
215 pub fn remove_spans<F>(&mut self, mut f: F)
217 where
218 F: FnMut(&Trace, &Span) -> bool,
219 {
220 if self.spans.is_empty() {
221 return;
222 }
223
224 let mut spans = std::mem::take(&mut self.spans);
225 spans.retain(|span| !f(self, span));
226 spans.shrink_to_fit();
227 let _ = std::mem::replace(&mut self.spans, spans);
228 }
229}
230
231#[derive(Clone, Debug, PartialEq, Default)]
233pub struct Span {
234 service: MetaString,
236 name: MetaString,
238 resource: MetaString,
240 span_id: u64,
242 parent_id: u64,
244 start: u64,
246 duration: u64,
248 error: i32,
250 span_type: MetaString,
252 span_links: Vec<SpanLink>,
254 span_events: Vec<SpanEvent>,
256 pub env: MetaString,
258 pub version: MetaString,
260 pub component: MetaString,
262 pub kind: u32,
264 pub attributes: FastHashMap<MetaString, AttributeValue>,
266}
267
268impl Span {
269 #[allow(clippy::too_many_arguments)]
271 pub fn new(
272 service: impl Into<MetaString>, name: impl Into<MetaString>, resource: impl Into<MetaString>,
273 span_type: impl Into<MetaString>, span_id: u64, parent_id: u64, start: u64, duration: u64, error: i32,
274 ) -> Self {
275 Self {
276 service: service.into(),
277 name: name.into(),
278 resource: resource.into(),
279 span_type: span_type.into(),
280 span_id,
281 parent_id,
282 start,
283 duration,
284 error,
285 ..Self::default()
286 }
287 }
288
289 pub fn with_service(mut self, service: impl Into<MetaString>) -> Self {
291 self.service = service.into();
292 self
293 }
294
295 pub fn with_name(mut self, name: impl Into<MetaString>) -> Self {
297 self.name = name.into();
298 self
299 }
300
301 pub fn with_resource(mut self, resource: impl Into<MetaString>) -> Self {
303 self.resource = resource.into();
304 self
305 }
306
307 pub fn with_span_id(mut self, span_id: u64) -> Self {
309 self.span_id = span_id;
310 self
311 }
312
313 pub fn with_parent_id(mut self, parent_id: u64) -> Self {
315 self.parent_id = parent_id;
316 self
317 }
318
319 pub fn with_start(mut self, start: u64) -> Self {
321 self.start = start;
322 self
323 }
324
325 pub fn with_duration(mut self, duration: u64) -> Self {
327 self.duration = duration;
328 self
329 }
330
331 pub fn with_error(mut self, error: i32) -> Self {
333 self.error = error;
334 self
335 }
336
337 pub fn with_span_type(mut self, span_type: impl Into<MetaString>) -> Self {
339 self.span_type = span_type.into();
340 self
341 }
342
343 pub fn with_attributes(mut self, attributes: impl Into<Option<FastHashMap<MetaString, AttributeValue>>>) -> Self {
345 self.attributes = attributes.into().unwrap_or_default();
346 self
347 }
348
349 pub fn with_span_links(mut self, span_links: impl Into<Option<Vec<SpanLink>>>) -> Self {
351 self.span_links = span_links.into().unwrap_or_default();
352 self
353 }
354
355 pub fn with_span_events(mut self, span_events: impl Into<Option<Vec<SpanEvent>>>) -> Self {
357 self.span_events = span_events.into().unwrap_or_default();
358 self
359 }
360
361 pub fn with_env(mut self, env: impl Into<MetaString>) -> Self {
363 self.env = env.into();
364 self
365 }
366
367 pub fn with_version(mut self, version: impl Into<MetaString>) -> Self {
369 self.version = version.into();
370 self
371 }
372
373 pub fn with_component(mut self, component: impl Into<MetaString>) -> Self {
375 self.component = component.into();
376 self
377 }
378
379 pub fn with_kind(mut self, kind: u32) -> Self {
381 self.kind = kind;
382 self
383 }
384
385 pub fn service(&self) -> &str {
387 &self.service
388 }
389
390 pub fn name(&self) -> &str {
392 &self.name
393 }
394
395 pub fn resource(&self) -> &str {
397 &self.resource
398 }
399
400 pub fn set_resource(&mut self, resource: impl Into<MetaString>) {
402 self.resource = resource.into();
403 }
404
405 pub fn span_id(&self) -> u64 {
407 self.span_id
408 }
409
410 pub fn parent_id(&self) -> u64 {
412 self.parent_id
413 }
414
415 pub fn start(&self) -> u64 {
417 self.start
418 }
419
420 pub fn duration(&self) -> u64 {
422 self.duration
423 }
424
425 pub fn error(&self) -> i32 {
427 self.error
428 }
429
430 pub fn span_type(&self) -> &str {
432 &self.span_type
433 }
434
435 pub fn span_links(&self) -> &[SpanLink] {
437 &self.span_links
438 }
439
440 pub fn span_events(&self) -> &[SpanEvent] {
442 &self.span_events
443 }
444}
445
446#[derive(Clone, Debug, PartialEq, Default)]
448pub struct SpanLink {
449 trace_id: u64,
451 trace_id_high: u64,
453 span_id: u64,
455 attributes: FastHashMap<MetaString, AttributeValue>,
457 tracestate: MetaString,
459 flags: u32,
461}
462
463impl SpanLink {
464 pub fn new(trace_id: u64, span_id: u64) -> Self {
466 Self {
467 trace_id,
468 span_id,
469 ..Self::default()
470 }
471 }
472
473 pub fn with_trace_id(mut self, trace_id: u64) -> Self {
475 self.trace_id = trace_id;
476 self
477 }
478
479 pub fn with_trace_id_high(mut self, trace_id_high: u64) -> Self {
481 self.trace_id_high = trace_id_high;
482 self
483 }
484
485 pub fn with_span_id(mut self, span_id: u64) -> Self {
487 self.span_id = span_id;
488 self
489 }
490
491 pub fn with_attributes(mut self, attributes: impl Into<Option<FastHashMap<MetaString, AttributeValue>>>) -> Self {
493 self.attributes = attributes.into().unwrap_or_default();
494 self
495 }
496
497 pub fn with_tracestate(mut self, tracestate: impl Into<MetaString>) -> Self {
499 self.tracestate = tracestate.into();
500 self
501 }
502
503 pub fn with_flags(mut self, flags: u32) -> Self {
505 self.flags = flags;
506 self
507 }
508
509 pub fn trace_id(&self) -> u64 {
511 self.trace_id
512 }
513
514 pub fn trace_id_high(&self) -> u64 {
516 self.trace_id_high
517 }
518
519 pub fn span_id(&self) -> u64 {
521 self.span_id
522 }
523
524 pub fn attributes(&self) -> &FastHashMap<MetaString, AttributeValue> {
526 &self.attributes
527 }
528
529 pub fn tracestate(&self) -> &str {
531 &self.tracestate
532 }
533
534 pub fn flags(&self) -> u32 {
536 self.flags
537 }
538}
539
540#[derive(Clone, Debug, PartialEq, Default)]
542pub struct SpanEvent {
543 time_unix_nano: u64,
545 name: MetaString,
547 attributes: FastHashMap<MetaString, AttributeValue>,
549}
550
551impl SpanEvent {
552 pub fn new(time_unix_nano: u64, name: impl Into<MetaString>) -> Self {
554 Self {
555 time_unix_nano,
556 name: name.into(),
557 ..Self::default()
558 }
559 }
560
561 pub fn with_time_unix_nano(mut self, time_unix_nano: u64) -> Self {
563 self.time_unix_nano = time_unix_nano;
564 self
565 }
566
567 pub fn with_name(mut self, name: impl Into<MetaString>) -> Self {
569 self.name = name.into();
570 self
571 }
572
573 pub fn with_attributes(mut self, attributes: impl Into<Option<FastHashMap<MetaString, AttributeValue>>>) -> Self {
575 self.attributes = attributes.into().unwrap_or_default();
576 self
577 }
578
579 pub fn time_unix_nano(&self) -> u64 {
581 self.time_unix_nano
582 }
583
584 pub fn name(&self) -> &str {
586 &self.name
587 }
588
589 pub fn attributes(&self) -> &FastHashMap<MetaString, AttributeValue> {
591 &self.attributes
592 }
593}