opentelemetry/trace/
tracer_provider.rs

1use crate::{trace::Tracer, InstrumentationLibrary, InstrumentationLibraryBuilder, KeyValue};
2use std::{borrow::Cow, sync::Arc};
3
4/// Types that can create instances of [`Tracer`].
5///
6/// See the [`global`] module for examples of storing and retrieving tracer
7/// provider instances.
8///
9/// [`global`]: crate::global
10pub trait TracerProvider {
11    /// The [`Tracer`] type that this provider will return.
12    type Tracer: Tracer;
13
14    /// Returns a new tracer with the given name.
15    ///
16    /// The `name` should be the application name or the name of the library
17    /// providing instrumentation. If the name is empty, then an
18    /// implementation-defined default name may be used instead.
19    ///
20    /// # Examples
21    ///
22    /// ```
23    /// use opentelemetry::{global, trace::TracerProvider};
24    /// use opentelemetry::KeyValue;
25    ///
26    /// let provider = global::tracer_provider();
27    ///
28    /// // tracer used in applications/binaries
29    /// let tracer = provider.tracer("my_app");
30    ///
31    /// // tracer used in libraries/crates that optionally includes version and schema url
32    /// let tracer = provider.tracer_builder("my_library").
33    ///     with_version(env!("CARGO_PKG_VERSION")).
34    ///     with_schema_url("https://opentelemetry.io/schema/1.0.0").
35    ///     with_attributes(vec![KeyValue::new("key", "value")]).
36    ///     build();
37    /// ```
38    fn tracer(&self, name: impl Into<Cow<'static, str>>) -> Self::Tracer {
39        self.tracer_builder(name).build()
40    }
41
42    /// Deprecated, use [`TracerProvider::tracer_builder()`]
43    ///
44    /// Returns a new versioned tracer with a given name.
45    ///
46    /// The `name` should be the application name or the name of the library
47    /// providing instrumentation. If the name is empty, then an
48    /// implementation-defined default name may be used instead.
49    ///
50    /// # Examples
51    ///
52    /// ```
53    /// use opentelemetry::{global, trace::TracerProvider};
54    ///
55    /// let provider = global::tracer_provider();
56    ///
57    /// // tracer used in applications/binaries
58    /// let tracer = provider.tracer("my_app");
59    ///
60    /// // tracer used in libraries/crates that optionally includes version and schema url
61    /// let tracer = provider.versioned_tracer(
62    ///     "my_library",
63    ///     Some(env!("CARGO_PKG_VERSION")),
64    ///     Some("https://opentelemetry.io/schema/1.0.0"),
65    ///     None,
66    /// );
67    /// ```
68    #[deprecated(since = "0.23.0", note = "Please use tracer_builder() instead")]
69    fn versioned_tracer(
70        &self,
71        name: impl Into<Cow<'static, str>>,
72        version: Option<impl Into<Cow<'static, str>>>,
73        schema_url: Option<impl Into<Cow<'static, str>>>,
74        attributes: Option<Vec<KeyValue>>,
75    ) -> Self::Tracer {
76        let mut builder = self.tracer_builder(name);
77        if let Some(v) = version {
78            builder = builder.with_version(v);
79        }
80        if let Some(s) = schema_url {
81            builder = builder.with_version(s);
82        }
83        if let Some(a) = attributes {
84            builder = builder.with_attributes(a);
85        }
86
87        builder.build()
88    }
89
90    /// Returns a new builder for creating a [`Tracer`] instance
91    ///
92    /// The `name` should be the application name or the name of the library
93    /// providing instrumentation. If the name is empty, then an
94    /// implementation-defined default name may be used instead.
95    ///
96    /// # Examples
97    ///
98    /// ```
99    /// use opentelemetry::{global, trace::TracerProvider};
100    ///
101    /// let provider = global::tracer_provider();
102    ///
103    /// // tracer used in applications/binaries
104    /// let tracer = provider.tracer_builder("my_app").build();
105    ///
106    /// // tracer used in libraries/crates that optionally includes version and schema url
107    /// let tracer = provider.tracer_builder("my_library")
108    ///     .with_version(env!("CARGO_PKG_VERSION"))
109    ///     .with_schema_url("https://opentelemetry.io/schema/1.0.0")
110    ///     .build();
111    /// ```
112    fn tracer_builder(&self, name: impl Into<Cow<'static, str>>) -> TracerBuilder<'_, Self> {
113        TracerBuilder {
114            provider: self,
115            library_builder: InstrumentationLibrary::builder(name),
116        }
117    }
118
119    /// Returns a new versioned tracer with the given instrumentation library.
120    ///
121    /// # Examples
122    ///
123    /// ```
124    /// use opentelemetry::{global, InstrumentationLibrary, trace::TracerProvider};
125    ///
126    /// let provider = global::tracer_provider();
127    ///
128    /// // tracer used in applications/binaries
129    /// let tracer = provider.tracer("my_app");
130    ///
131    /// // tracer used in libraries/crates that optionally includes version and schema url
132    /// let library = std::sync::Arc::new(
133    ///     InstrumentationLibrary::builder(env!("CARGO_PKG_NAME"))
134    ///         .with_version(env!("CARGO_PKG_VERSION"))
135    ///         .with_schema_url("https://opentelemetry.io/schema/1.0.0")
136    ///         .build(),
137    /// );
138    ///
139    /// let tracer = provider.library_tracer(library);
140    /// ```
141    fn library_tracer(&self, library: Arc<InstrumentationLibrary>) -> Self::Tracer;
142}
143
144#[derive(Debug)]
145pub struct TracerBuilder<'a, T: TracerProvider + ?Sized> {
146    provider: &'a T,
147    library_builder: InstrumentationLibraryBuilder,
148}
149
150impl<'a, T: TracerProvider + ?Sized> TracerBuilder<'a, T> {
151    pub fn with_version(mut self, version: impl Into<Cow<'static, str>>) -> Self {
152        self.library_builder = self.library_builder.with_version(version);
153        self
154    }
155
156    pub fn with_schema_url(mut self, schema_url: impl Into<Cow<'static, str>>) -> Self {
157        self.library_builder = self.library_builder.with_schema_url(schema_url);
158        self
159    }
160
161    pub fn with_attributes<I>(mut self, attributes: I) -> Self
162    where
163        I: IntoIterator<Item = KeyValue>,
164    {
165        self.library_builder = self.library_builder.with_attributes(attributes);
166        self
167    }
168
169    pub fn build(self) -> T::Tracer {
170        self.provider
171            .library_tracer(Arc::new(self.library_builder.build()))
172    }
173}