opentelemetry_sdk/trace/
config.rs

1//! SDK Configuration
2//!
3//! Configuration represents the global tracing configuration, overrides
4//! can be set for the default OpenTelemetry limits and Sampler.
5use crate::trace::{span_limit::SpanLimits, IdGenerator, RandomIdGenerator, Sampler, ShouldSample};
6use crate::Resource;
7use opentelemetry::global::{handle_error, Error};
8use std::borrow::Cow;
9use std::env;
10use std::str::FromStr;
11
12/// Default trace configuration
13#[deprecated(since = "0.23.0", note = "Use Config::default() instead")]
14pub fn config() -> Config {
15    Config::default()
16}
17
18/// Tracer configuration
19#[derive(Debug)]
20#[non_exhaustive]
21pub struct Config {
22    /// The sampler that the sdk should use
23    pub sampler: Box<dyn ShouldSample>,
24
25    /// The id generator that the sdk should use
26    pub id_generator: Box<dyn IdGenerator>,
27
28    /// span limits
29    pub span_limits: SpanLimits,
30
31    /// Contains attributes representing an entity that produces telemetry.
32    pub resource: Cow<'static, Resource>,
33}
34
35impl Config {
36    /// Specify the sampler to be used.
37    pub fn with_sampler<T: crate::trace::ShouldSample + 'static>(mut self, sampler: T) -> Self {
38        self.sampler = Box::new(sampler);
39        self
40    }
41
42    /// Specify the id generator to be used.
43    pub fn with_id_generator<T: IdGenerator + 'static>(mut self, id_generator: T) -> Self {
44        self.id_generator = Box::new(id_generator);
45        self
46    }
47
48    /// Specify the number of events to be recorded per span.
49    pub fn with_max_events_per_span(mut self, max_events: u32) -> Self {
50        self.span_limits.max_events_per_span = max_events;
51        self
52    }
53
54    /// Specify the number of attributes to be recorded per span.
55    pub fn with_max_attributes_per_span(mut self, max_attributes: u32) -> Self {
56        self.span_limits.max_attributes_per_span = max_attributes;
57        self
58    }
59
60    /// Specify the number of events to be recorded per span.
61    pub fn with_max_links_per_span(mut self, max_links: u32) -> Self {
62        self.span_limits.max_links_per_span = max_links;
63        self
64    }
65
66    /// Specify the number of attributes one event can have.
67    pub fn with_max_attributes_per_event(mut self, max_attributes: u32) -> Self {
68        self.span_limits.max_attributes_per_event = max_attributes;
69        self
70    }
71
72    /// Specify the number of attributes one link can have.
73    pub fn with_max_attributes_per_link(mut self, max_attributes: u32) -> Self {
74        self.span_limits.max_attributes_per_link = max_attributes;
75        self
76    }
77
78    /// Specify all limit via the span_limits
79    pub fn with_span_limits(mut self, span_limits: SpanLimits) -> Self {
80        self.span_limits = span_limits;
81        self
82    }
83
84    /// Specify the attributes representing the entity that produces telemetry
85    pub fn with_resource(mut self, resource: Resource) -> Self {
86        self.resource = Cow::Owned(resource);
87        self
88    }
89}
90
91impl Default for Config {
92    /// Create default global sdk configuration.
93    fn default() -> Self {
94        let mut config = Config {
95            sampler: Box::new(Sampler::ParentBased(Box::new(Sampler::AlwaysOn))),
96            id_generator: Box::<RandomIdGenerator>::default(),
97            span_limits: SpanLimits::default(),
98            resource: Cow::Owned(Resource::default()),
99        };
100
101        if let Some(max_attributes_per_span) = env::var("OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT")
102            .ok()
103            .and_then(|count_limit| u32::from_str(&count_limit).ok())
104        {
105            config.span_limits.max_attributes_per_span = max_attributes_per_span;
106        }
107
108        if let Some(max_events_per_span) = env::var("OTEL_SPAN_EVENT_COUNT_LIMIT")
109            .ok()
110            .and_then(|max_events| u32::from_str(&max_events).ok())
111        {
112            config.span_limits.max_events_per_span = max_events_per_span;
113        }
114
115        if let Some(max_links_per_span) = env::var("OTEL_SPAN_LINK_COUNT_LIMIT")
116            .ok()
117            .and_then(|max_links| u32::from_str(&max_links).ok())
118        {
119            config.span_limits.max_links_per_span = max_links_per_span;
120        }
121
122        let sampler_arg = env::var("OTEL_TRACES_SAMPLER_ARG").ok();
123        if let Ok(sampler) = env::var("OTEL_TRACES_SAMPLER") {
124            config.sampler = match sampler.as_str() {
125                "always_on" => Box::new(Sampler::AlwaysOn),
126                "always_off" => Box::new(Sampler::AlwaysOff),
127                "traceidratio" => {
128                    let ratio = sampler_arg.and_then(|r| r.parse::<f64>().ok());
129                    if let Some(r) = ratio {
130                        Box::new(Sampler::TraceIdRatioBased(r))
131                    } else {
132                        handle_error(
133                            Error::Other(String::from(
134                                "Missing or invalid OTEL_TRACES_SAMPLER_ARG value. Falling back to default: 1.0"))
135                        );
136                        Box::new(Sampler::TraceIdRatioBased(1.0))
137                    }
138                }
139                "parentbased_always_on" => {
140                    Box::new(Sampler::ParentBased(Box::new(Sampler::AlwaysOn)))
141                }
142                "parentbased_always_off" => {
143                    Box::new(Sampler::ParentBased(Box::new(Sampler::AlwaysOff)))
144                }
145                "parentbased_traceidratio" => {
146                    let ratio = sampler_arg.and_then(|r| r.parse::<f64>().ok());
147                    if let Some(r) = ratio {
148                        Box::new(Sampler::ParentBased(Box::new(Sampler::TraceIdRatioBased(
149                            r,
150                        ))))
151                    } else {
152                        handle_error(
153                            Error::Other(String::from(
154                            "Missing or invalid OTEL_TRACES_SAMPLER_ARG value. Falling back to default: 1.0"
155                        )));
156                        Box::new(Sampler::ParentBased(Box::new(Sampler::TraceIdRatioBased(
157                            1.0,
158                        ))))
159                    }
160                }
161                "parentbased_jaeger_remote" => {
162                    handle_error(
163                        Error::Other(String::from(
164                        "Unimplemented parentbased_jaeger_remote sampler. Falling back to default: parentbased_always_on"
165                    )));
166                    Box::new(Sampler::ParentBased(Box::new(Sampler::AlwaysOn)))
167                }
168                "jaeger_remote" => {
169                    handle_error(
170                        Error::Other(String::from("Unimplemented jaeger_remote sampler. Falling back to default: parentbased_always_on")));
171                    Box::new(Sampler::ParentBased(Box::new(Sampler::AlwaysOn)))
172                }
173                "xray" => {
174                    handle_error(
175                        Error::Other(String::from("Unimplemented xray sampler. Falling back to default: parentbased_always_on")));
176                    Box::new(Sampler::ParentBased(Box::new(Sampler::AlwaysOn)))
177                }
178                s => {
179                    handle_error(
180                        Error::Other(format!("Unrecognised OTEL_TRACES_SAMPLER value: {}. Falling back to default: parentbased_always_on",
181                        s
182                    )));
183                    Box::new(Sampler::ParentBased(Box::new(Sampler::AlwaysOn)))
184                }
185            }
186        }
187
188        config
189    }
190}