libdd_sampling/types.rs
1// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
2// SPDX-License-Identifier: Apache-2.0
3
4//! Type definitions and traits for sampling
5
6use std::borrow::Cow;
7
8/// A trait for converting trace IDs to a numeric representation.
9///
10/// Provides a common interface for converting trace IDs from different tracing systems
11/// into a 128-bit unsigned integer for use in hash-based operations.
12///
13/// # Examples
14///
15/// ```
16/// use libdd_sampling::TraceIdLike;
17///
18/// #[derive(Clone, PartialEq, Eq)]
19/// struct MyTraceId(u128);
20///
21/// impl TraceIdLike for MyTraceId {
22/// fn to_u128(&self) -> u128 {
23/// self.0
24/// }
25/// }
26/// ```
27pub trait TraceIdLike: Eq {
28 /// Converts the trace ID to a 128-bit unsigned integer.
29 ///
30 /// The conversion should be deterministic: the same trace ID must always produce
31 /// the same `u128` value. Typically implemented by interpreting the trace ID's
32 /// bytes as a big-endian integer.
33 fn to_u128(&self) -> u128;
34}
35
36/// A trait for accessing span attribute key-value pairs.
37///
38/// Provides methods for retrieving the key and value of a span attribute.
39pub trait AttributeLike {
40 /// The type of the value that implements `ValueLike`.
41 type Value: ValueLike;
42
43 /// Returns the attribute key as a string.
44 fn key(&self) -> &str;
45
46 /// Returns a reference to the attribute value.
47 fn value(&self) -> &Self::Value;
48}
49
50impl<T: AttributeLike> AttributeLike for &T {
51 type Value = T::Value;
52
53 fn key(&self) -> &str {
54 (**self).key()
55 }
56
57 fn value(&self) -> &Self::Value {
58 (**self).value()
59 }
60}
61
62/// A trait for extracting typed values from attribute values.
63///
64/// Provides methods for converting attribute values to common types used in sampling logic.
65pub trait ValueLike {
66 /// Returns the value as `f64`, if representable as a float.
67 fn as_float(&self) -> Option<f64>;
68
69 /// Returns the value as a string, if representable.
70 fn as_str(&self) -> Option<Cow<'_, str>>;
71}
72
73/// A trait for creating sampling attributes.
74///
75/// This trait abstracts the creation of attributes for sampling tags,
76/// allowing different implementations for different attribute types.
77pub trait AttributeFactory {
78 /// The type of attribute created by this factory.
79 type Attribute: Sized;
80
81 /// Creates an attribute with an i64 value.
82 fn create_i64(&self, key: &'static str, value: i64) -> Self::Attribute;
83
84 /// Creates an attribute with an f64 value.
85 fn create_f64(&self, key: &'static str, value: f64) -> Self::Attribute;
86
87 /// Creates an attribute with a string value.
88 fn create_string(&self, key: &'static str, value: Cow<'static, str>) -> Self::Attribute;
89}
90
91/// A trait for accessing span properties needed for sampling decisions.
92///
93/// Provides methods for retrieving span metadata like operation name, service, environment,
94/// resource name, and status codes used by sampling rules.
95pub trait SpanProperties {
96 /// The type of attribute that implements `AttributeLike`.
97 type Attribute<'a>: AttributeLike
98 where
99 Self: 'a;
100
101 /// Returns the operation name for the span.
102 ///
103 /// The operation name is derived from span attributes and kind according to
104 /// OpenTelemetry semantic conventions.
105 fn operation_name(&self) -> Cow<'_, str>;
106
107 /// Returns the service name for the span.
108 ///
109 /// The service name is extracted from resource attributes.
110 fn service(&self) -> Cow<'_, str>;
111
112 /// Returns the environment name for the span.
113 ///
114 /// The environment is extracted from span or resource attributes.
115 fn env(&self) -> Cow<'_, str>;
116
117 /// Returns the resource name for the span.
118 ///
119 /// The resource name is derived from span attributes and kind.
120 fn resource(&self) -> Cow<'_, str>;
121
122 /// Returns the HTTP status code if present.
123 ///
124 /// Returns `None` if the span does not have an HTTP status code attribute.
125 fn status_code(&self) -> Option<u32>;
126
127 /// Returns an iterator over span attributes.
128 fn attributes(&self) -> impl Iterator<Item = Self::Attribute<'_>> + '_;
129
130 /// Returns an alternate key for the given attribute key.
131 ///
132 /// This is used for mapping between different attribute naming conventions
133 /// (e.g., OpenTelemetry to Datadog). Returns `Some(alternate_key)` if a mapping exists,
134 /// or `None` if the attribute key has no alternate mapping.
135 fn get_alternate_key<'b>(&self, key: &'b str) -> Option<Cow<'b, str>>;
136}
137
138/// A trait for accessing sampling data, combining trace ID and span properties.
139///
140/// This trait provides unified access to both the trace ID and span properties
141/// needed for making sampling decisions.
142pub trait SamplingData {
143 /// The type that implements `TraceIdLike`.
144 type TraceId: TraceIdLike;
145
146 /// The type that implements `SpanProperties`.
147 type Properties<'a>: SpanProperties
148 where
149 Self: 'a;
150
151 /// Returns whether the parent span was sampled.
152 ///
153 /// Returns:
154 /// - `Some(true)` if the parent span was sampled
155 /// - `Some(false)` if the parent span was not sampled
156 /// - `None` if there is no parent sampling information
157 fn is_parent_sampled(&self) -> Option<bool>;
158
159 /// Returns a reference to the trace ID.
160 fn trace_id(&self) -> &Self::TraceId;
161
162 /// Returns the span properties via a callback.
163 ///
164 /// This method constructs the span properties and passes them to the provided
165 /// callback function. The properties are only valid for the duration of the callback.
166 fn with_span_properties<S, T, F>(&self, s: &S, f: F) -> T
167 where
168 F: Fn(&S, &Self::Properties<'_>) -> T;
169}