diff --git a/opentelemetry-appender-log/src/lib.rs b/opentelemetry-appender-log/src/lib.rs index 66f58feb22..c6692dc29c 100644 --- a/opentelemetry-appender-log/src/lib.rs +++ b/opentelemetry-appender-log/src/lib.rs @@ -49,12 +49,10 @@ where { pub fn new(provider: &P) -> Self { OpenTelemetryLogBridge { - logger: provider.versioned_logger( - "opentelemetry-log-appender", - Some(Cow::Borrowed(env!("CARGO_PKG_VERSION"))), - None, - None, - ), + logger: provider + .logger_builder("opentelemetry-log-appender") + .with_version(Cow::Borrowed(env!("CARGO_PKG_VERSION"))) + .build(), _phantom: Default::default(), } } diff --git a/opentelemetry-appender-tracing/src/layer.rs b/opentelemetry-appender-tracing/src/layer.rs index 107a82a737..ef2a691dcc 100644 --- a/opentelemetry-appender-tracing/src/layer.rs +++ b/opentelemetry-appender-tracing/src/layer.rs @@ -138,12 +138,10 @@ where { pub fn new(provider: &P) -> Self { OpenTelemetryTracingBridge { - logger: provider.versioned_logger( - INSTRUMENTATION_LIBRARY_NAME, - Some(Cow::Borrowed(env!("CARGO_PKG_VERSION"))), - None, - None, - ), + logger: provider + .logger_builder(INSTRUMENTATION_LIBRARY_NAME) + .with_version(Cow::Borrowed(env!("CARGO_PKG_VERSION"))) + .build(), _phantom: Default::default(), } } diff --git a/opentelemetry-jaeger/src/exporter/config/mod.rs b/opentelemetry-jaeger/src/exporter/config/mod.rs index 3ee1a65f0c..93218867af 100644 --- a/opentelemetry-jaeger/src/exporter/config/mod.rs +++ b/opentelemetry-jaeger/src/exporter/config/mod.rs @@ -85,13 +85,13 @@ fn build_config_and_process( pub(crate) fn install_tracer_provider_and_get_tracer( tracer_provider: TracerProvider, ) -> Result { - let tracer = opentelemetry::trace::TracerProvider::versioned_tracer( + let tracer = opentelemetry::trace::TracerProvider::tracer_builder( &tracer_provider, "opentelemetry-jaeger", - Some(env!("CARGO_PKG_VERSION")), - Some(semcov::SCHEMA_URL), - None, - ); + ) + .with_version(env!("CARGO_PKG_VERSION")) + .with_schema_url(semcov::SCHEMA_URL) + .build(); let _ = global::set_tracer_provider(tracer_provider); Ok(tracer) } diff --git a/opentelemetry-otlp/src/logs.rs b/opentelemetry-otlp/src/logs.rs index a9ec267d0c..cc3cc0364d 100644 --- a/opentelemetry-otlp/src/logs.rs +++ b/opentelemetry-otlp/src/logs.rs @@ -183,12 +183,10 @@ fn build_simple_with_exporter( provider_builder = provider_builder.with_config(config); } let provider = provider_builder.build(); - let logger = provider.versioned_logger( - Cow::Borrowed("opentelemetry-otlp"), - Some(Cow::Borrowed(env!("CARGO_PKG_VERSION"))), - None, - None, - ); + let logger = provider + .logger_builder(Cow::Borrowed("opentelemetry-otlp")) + .with_version(Cow::Borrowed(env!("CARGO_PKG_VERSION"))) + .build(); let _ = global::set_logger_provider(provider); logger } @@ -209,12 +207,10 @@ fn build_batch_with_exporter( provider_builder = provider_builder.with_config(config); } let provider = provider_builder.build(); - let logger = provider.versioned_logger( - Cow::Borrowed("opentelemetry-otlp"), - Some(Cow::Borrowed(env!("CARGO_PKG_VERSION"))), - None, - None, - ); + let logger = provider + .logger_builder(Cow::Borrowed("opentelemetry-otlp")) + .with_version(Cow::Borrowed(env!("CARGO_PKG_VERSION"))) + .build(); let _ = global::set_logger_provider(provider); logger } diff --git a/opentelemetry-otlp/src/span.rs b/opentelemetry-otlp/src/span.rs index 76383f2f04..2c66b1f72f 100644 --- a/opentelemetry-otlp/src/span.rs +++ b/opentelemetry-otlp/src/span.rs @@ -140,12 +140,11 @@ fn build_simple_with_exporter( provider_builder = provider_builder.with_config(config); } let provider = provider_builder.build(); - let tracer = provider.versioned_tracer( - "opentelemetry-otlp", - Some(env!("CARGO_PKG_VERSION")), - Some(SCHEMA_URL), - None, - ); + let tracer = provider + .tracer_builder("opentelemetry-otlp") + .with_version(env!("CARGO_PKG_VERSION")) + .with_schema_url(SCHEMA_URL) + .build(); let _ = global::set_tracer_provider(provider); tracer } @@ -166,12 +165,11 @@ fn build_batch_with_exporter( provider_builder = provider_builder.with_config(config); } let provider = provider_builder.build(); - let tracer = provider.versioned_tracer( - "opentelemetry-otlp", - Some(env!("CARGO_PKG_VERSION")), - Some(SCHEMA_URL), - None, - ); + let tracer = provider + .tracer_builder("opentelemetry-otlp") + .with_version(env!("CARGO_PKG_VERSION")) + .with_schema_url(SCHEMA_URL) + .build(); let _ = global::set_tracer_provider(provider); tracer } diff --git a/opentelemetry-sdk/src/logs/log_emitter.rs b/opentelemetry-sdk/src/logs/log_emitter.rs index 983d50827b..8c5f4ebe85 100644 --- a/opentelemetry-sdk/src/logs/log_emitter.rs +++ b/opentelemetry-sdk/src/logs/log_emitter.rs @@ -43,12 +43,19 @@ impl opentelemetry::logs::LoggerProvider for LoggerProvider { name }; - self.library_logger(Arc::new(InstrumentationLibrary::new( - component_name, - version, - schema_url, - attributes, - ))) + let mut builder = self.logger_builder(component_name); + + if let Some(v) = version { + builder = builder.with_version(v); + } + if let Some(s) = schema_url { + builder = builder.with_schema_url(s); + } + if let Some(a) = attributes { + builder = builder.with_attributes(a); + } + + builder.build() } fn library_logger(&self, library: Arc) -> Self::Logger { diff --git a/opentelemetry-sdk/src/metrics/meter_provider.rs b/opentelemetry-sdk/src/metrics/meter_provider.rs index 13a14c1739..9d7dd44919 100644 --- a/opentelemetry-sdk/src/metrics/meter_provider.rs +++ b/opentelemetry-sdk/src/metrics/meter_provider.rs @@ -125,7 +125,19 @@ impl MeterProvider for SdkMeterProvider { return Meter::new(Arc::new(NoopMeterCore::new())); } - let scope = Scope::new(name, version, schema_url, attributes); + let mut builder = Scope::builder(name); + + if let Some(v) = version { + builder = builder.with_version(v); + } + if let Some(s) = schema_url { + builder = builder.with_schema_url(s); + } + if let Some(a) = attributes { + builder = builder.with_attributes(a); + } + + let scope = builder.build(); if let Ok(mut meters) = self.meters.lock() { let meter = meters diff --git a/opentelemetry-sdk/src/trace/provider.rs b/opentelemetry-sdk/src/trace/provider.rs index cc0991acd7..bab9e2047d 100644 --- a/opentelemetry-sdk/src/trace/provider.rs +++ b/opentelemetry-sdk/src/trace/provider.rs @@ -136,12 +136,19 @@ impl opentelemetry::trace::TracerProvider for TracerProvider { name }; - self.library_tracer(Arc::new(InstrumentationLibrary::new( - component_name, - version, - schema_url, - attributes, - ))) + let mut builder = self.tracer_builder(component_name); + + if let Some(v) = version { + builder = builder.with_version(v); + } + if let Some(s) = schema_url { + builder = builder.with_schema_url(s); + } + if let Some(a) = attributes { + builder = builder.with_attributes(a); + } + + builder.build() } fn library_tracer(&self, library: Arc) -> Self::Tracer { diff --git a/opentelemetry-zipkin/src/exporter/mod.rs b/opentelemetry-zipkin/src/exporter/mod.rs index 1fdc602cca..0bd2d19016 100644 --- a/opentelemetry-zipkin/src/exporter/mod.rs +++ b/opentelemetry-zipkin/src/exporter/mod.rs @@ -151,13 +151,11 @@ impl ZipkinPipelineBuilder { let mut provider_builder = TracerProvider::builder().with_simple_exporter(exporter); provider_builder = provider_builder.with_config(config); let provider = provider_builder.build(); - let tracer = opentelemetry::trace::TracerProvider::versioned_tracer( - &provider, - "opentelemetry-zipkin", - Some(env!("CARGO_PKG_VERSION")), - Some(semcov::SCHEMA_URL), - None, - ); + let tracer = + opentelemetry::trace::TracerProvider::tracer_builder(&provider, "opentelemetry-zipkin") + .with_version(env!("CARGO_PKG_VERSION")) + .with_schema_url(semcov::SCHEMA_URL) + .build(); let _ = global::set_tracer_provider(provider); Ok(tracer) } @@ -170,13 +168,11 @@ impl ZipkinPipelineBuilder { let mut provider_builder = TracerProvider::builder().with_batch_exporter(exporter, runtime); provider_builder = provider_builder.with_config(config); let provider = provider_builder.build(); - let tracer = opentelemetry::trace::TracerProvider::versioned_tracer( - &provider, - "opentelemetry-zipkin", - Some(env!("CARGO_PKG_VERSION")), - Some(semcov::SCHEMA_URL), - None, - ); + let tracer = + opentelemetry::trace::TracerProvider::tracer_builder(&provider, "opentelemetry-zipkin") + .with_version(env!("CARGO_PKG_VERSION")) + .with_schema_url(semcov::SCHEMA_URL) + .build(); let _ = global::set_tracer_provider(provider); Ok(tracer) } diff --git a/opentelemetry/src/common.rs b/opentelemetry/src/common.rs index ba7338d6b2..d18d95cb40 100644 --- a/opentelemetry/src/common.rs +++ b/opentelemetry/src/common.rs @@ -449,12 +449,10 @@ pub struct InstrumentationLibrary { /// # Examples /// /// ``` - /// let library = opentelemetry::InstrumentationLibrary::new( - /// "my-crate", - /// Some(env!("CARGO_PKG_VERSION")), - /// Some("https://opentelemetry.io/schemas/1.17.0"), - /// None, - /// ); + /// let library = opentelemetry::InstrumentationLibrary::builder("my-crate"). + /// with_version(env!("CARGO_PKG_VERSION")). + /// with_schema_url("https://opentelemetry.io/schemas/1.17.0"). + /// build(); /// ``` pub version: Option>, @@ -487,7 +485,10 @@ impl hash::Hash for InstrumentationLibrary { } impl InstrumentationLibrary { + /// Deprecated, use [`InstrumentationLibrary::builder()`] + /// /// Create an new instrumentation library. + #[deprecated(since = "0.23.0", note = "Please use builder() instead")] pub fn new( name: impl Into>, version: Option>>, @@ -501,4 +502,92 @@ impl InstrumentationLibrary { attributes: attributes.unwrap_or_default(), } } + + /// Create a new builder to create an [InstrumentationLibrary] + pub fn builder(name: impl Into>) -> InstrumentationLibraryBuilder { + InstrumentationLibraryBuilder { + name: name.into(), + version: None, + schema_url: None, + attributes: None, + } + } +} + +/// Configuration options for [InstrumentationLibrary]. +/// +/// An instrumentation library is a library or crate providing instrumentation. +/// It should be named to follow any naming conventions of the instrumented +/// library (e.g. 'middleware' for a web framework). +/// +/// Apart from the name, all other fields are optional. +/// +/// See the [instrumentation libraries] spec for more information. +/// +/// [instrumentation libraries]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/overview.md#instrumentation-libraries +#[derive(Debug)] +pub struct InstrumentationLibraryBuilder { + name: Cow<'static, str>, + + version: Option>, + + schema_url: Option>, + + attributes: Option>, +} + +impl InstrumentationLibraryBuilder { + /// Configure the version for the instrumentation library + /// + /// # Examples + /// + /// ``` + /// let library = opentelemetry::InstrumentationLibrary::builder("my-crate") + /// .with_version("v0.1.0") + /// .build(); + /// ``` + pub fn with_version(mut self, version: impl Into>) -> Self { + self.version = Some(version.into()); + self + } + + /// Configure the Schema URL for the instrumentation library + /// + /// # Examples + /// + /// ``` + /// let library = opentelemetry::InstrumentationLibrary::builder("my-crate") + /// .with_schema_url("https://opentelemetry.io/schemas/1.17.0") + /// .build(); + /// ``` + pub fn with_schema_url(mut self, schema_url: impl Into>) -> Self { + self.schema_url = Some(schema_url.into()); + self + } + + /// Configure the attributes for the instrumentation library + /// + /// # Examples + /// + /// ``` + /// use opentelemetry::KeyValue; + /// + /// let library = opentelemetry::InstrumentationLibrary::builder("my-crate") + /// .with_attributes(vec![KeyValue::new("k", "v")]) + /// .build(); + /// ``` + pub fn with_attributes(mut self, attributes: impl Into>) -> Self { + self.attributes = Some(attributes.into()); + self + } + + /// Create a new [InstrumentationLibrary] from this configuration + pub fn build(self) -> InstrumentationLibrary { + InstrumentationLibrary { + name: self.name, + version: self.version, + schema_url: self.schema_url, + attributes: self.attributes.unwrap_or_default(), + } + } } diff --git a/opentelemetry/src/global/mod.rs b/opentelemetry/src/global/mod.rs index 790343968c..3eca63adc3 100644 --- a/opentelemetry/src/global/mod.rs +++ b/opentelemetry/src/global/mod.rs @@ -56,12 +56,10 @@ //! pub fn my_traced_library_function() { //! // End users of your library will configure their global tracer provider //! // so you can use the global tracer without any setup -//! let tracer = global::tracer_provider().versioned_tracer( -//! "my-library-name", -//! Some(env!("CARGO_PKG_VERSION")), -//! Some("https://opentelemetry.io/schemas/1.17.0"), -//! None, -//! ); +//! let tracer = global::tracer_provider().tracer_builder("my-library-name"). +//! with_version(env!("CARGO_PKG_VERSION")). +//! with_schema_url("https://opentelemetry.io/schemas/1.17.0"). +//! build(); //! //! tracer.in_span("doing_library_work", |cx| { //! // Traced library logic here... diff --git a/opentelemetry/src/lib.rs b/opentelemetry/src/lib.rs index 09c8b58770..2b61b62602 100644 --- a/opentelemetry/src/lib.rs +++ b/opentelemetry/src/lib.rs @@ -222,7 +222,10 @@ mod common; #[doc(hidden)] pub mod testing; -pub use common::{Array, ExportError, InstrumentationLibrary, Key, KeyValue, StringValue, Value}; +pub use common::{ + Array, ExportError, InstrumentationLibrary, InstrumentationLibraryBuilder, Key, KeyValue, + StringValue, Value, +}; #[cfg(feature = "metrics")] #[cfg_attr(docsrs, doc(cfg(feature = "metrics")))] diff --git a/opentelemetry/src/logs/logger.rs b/opentelemetry/src/logs/logger.rs index b9321e348d..0f789eb8ec 100644 --- a/opentelemetry/src/logs/logger.rs +++ b/opentelemetry/src/logs/logger.rs @@ -1,6 +1,6 @@ use std::{borrow::Cow, sync::Arc}; -use crate::{logs::LogRecord, InstrumentationLibrary, KeyValue}; +use crate::{logs::LogRecord, InstrumentationLibrary, InstrumentationLibraryBuilder, KeyValue}; #[cfg(feature = "logs_level_enabled")] use super::Severity; @@ -25,11 +25,15 @@ pub trait LoggerProvider { /// The [`Logger`] type that this provider will return. type Logger: Logger; + /// Deprecated, use [`LoggerProvider::logger_builder()`] + /// /// Returns a new versioned logger with a given name. /// /// The `name` should be the application name or the name of the library /// providing instrumentation. If the name is empty, then an /// implementation-defined default name may be used instead. + /// Create a new versioned `Logger` instance. + #[deprecated(since = "0.23.0", note = "Please use logger_builder() instead")] fn versioned_logger( &self, name: impl Into>, @@ -37,9 +41,46 @@ pub trait LoggerProvider { schema_url: Option>, attributes: Option>, ) -> Self::Logger { - self.library_logger(Arc::new(InstrumentationLibrary::new( - name, version, schema_url, attributes, - ))) + let mut builder = InstrumentationLibrary::builder(name); + if let Some(v) = version { + builder = builder.with_version(v); + } + if let Some(s) = schema_url { + builder = builder.with_schema_url(s); + } + if let Some(a) = attributes { + builder = builder.with_attributes(a); + } + self.library_logger(Arc::new(builder.build())) + } + + /// Returns a new builder for creating a [`Logger`] instance + /// + /// The `name` should be the application name or the name of the library + /// providing instrumentation. If the name is empty, then an + /// implementation-defined default name may be used instead. + /// + /// # Examples + /// + /// ``` + /// use opentelemetry::{global, logs::LoggerProvider}; + /// + /// let provider = global::logger_provider(); + /// + /// // logger used in applications/binaries + /// let tracer = provider.logger_builder("my_app").build(); + /// + /// // logger used in libraries/crates that optionally includes version and schema url + /// let tracer = provider.logger_builder("my_library") + /// .with_version(env!("CARGO_PKG_VERSION")) + /// .with_schema_url("https://opentelemetry.io/schema/1.0.0") + /// .build(); + /// ``` + fn logger_builder(&self, name: impl Into>) -> LoggerBuilder<'_, Self> { + LoggerBuilder { + provider: self, + library_builder: InstrumentationLibrary::builder(name), + } } /// Returns a new versioned logger with the given instrumentation library. @@ -53,13 +94,14 @@ pub trait LoggerProvider { /// /// // logger used in applications/binaries /// let logger = provider.logger("my_app"); + /// /// // logger used in libraries/crates that optionally includes version and schema url - /// let library = std::sync::Arc::new(InstrumentationLibrary::new( - /// env!("CARGO_PKG_NAME"), - /// Some(env!("CARGO_PKG_VERSION")), - /// Some("https://opentelemetry.io/schema/1.0.0"), - /// None, - /// )); + /// let library = std::sync::Arc::new( + /// InstrumentationLibrary::builder(env!("CARGO_PKG_NAME")) + /// .with_version(env!("CARGO_PKG_VERSION")) + /// .with_schema_url("https://opentelemetry.io/schema/1.0.0") + /// .build(), + /// ); /// let logger = provider.library_logger(library); /// ``` fn library_logger(&self, library: Arc) -> Self::Logger; @@ -70,6 +112,34 @@ pub trait LoggerProvider { /// providing instrumentation. If the name is empty, then an /// implementation-defined default name may be used instead. fn logger(&self, name: impl Into>) -> Self::Logger { - self.versioned_logger(name, None, None, None) + self.logger_builder(name).build() + } +} + +#[derive(Debug)] +pub struct LoggerBuilder<'a, T: LoggerProvider + ?Sized> { + provider: &'a T, + library_builder: InstrumentationLibraryBuilder, +} + +impl<'a, T: LoggerProvider + ?Sized> LoggerBuilder<'a, T> { + pub fn with_version(mut self, version: impl Into>) -> Self { + self.library_builder = self.library_builder.with_version(version); + self + } + + pub fn with_schema_url(mut self, schema_url: impl Into>) -> Self { + self.library_builder = self.library_builder.with_schema_url(schema_url); + self + } + + pub fn with_attributes(mut self, attributes: impl Into>) -> Self { + self.library_builder = self.library_builder.with_attributes(attributes); + self + } + + pub fn build(self) -> T::Logger { + self.provider + .library_logger(Arc::new(self.library_builder.build())) } } diff --git a/opentelemetry/src/trace/mod.rs b/opentelemetry/src/trace/mod.rs index 3b959d3e0f..af6dbf1402 100644 --- a/opentelemetry/src/trace/mod.rs +++ b/opentelemetry/src/trace/mod.rs @@ -51,12 +51,10 @@ //! let tracer_provider = global::tracer_provider(); //! //! // Get a tracer for this library -//! let tracer = tracer_provider.versioned_tracer( -//! "my_name", -//! Some(env!("CARGO_PKG_VERSION")), -//! Some("https://opentelemetry.io/schemas/1.17.0"), -//! None -//! ); +//! let tracer = tracer_provider.tracer_builder("my_name"). +//! with_version(env!("CARGO_PKG_VERSION")). +//! with_schema_url("https://opentelemetry.io/schemas/1.17.0"). +//! build(); //! //! // Create spans //! let mut span = tracer.start("doing_work"); diff --git a/opentelemetry/src/trace/tracer_provider.rs b/opentelemetry/src/trace/tracer_provider.rs index 5f18264be1..9e515d2d39 100644 --- a/opentelemetry/src/trace/tracer_provider.rs +++ b/opentelemetry/src/trace/tracer_provider.rs @@ -1,4 +1,4 @@ -use crate::{trace::Tracer, InstrumentationLibrary, KeyValue}; +use crate::{trace::Tracer, InstrumentationLibrary, InstrumentationLibraryBuilder, KeyValue}; use std::{borrow::Cow, sync::Arc}; /// Types that can create instances of [`Tracer`]. @@ -29,22 +29,18 @@ pub trait TracerProvider { /// let tracer = provider.tracer("my_app"); /// /// // tracer used in libraries/crates that optionally includes version and schema url - /// let tracer = provider.versioned_tracer( - /// "my_library", - /// Some(env!("CARGO_PKG_VERSION")), - /// Some("https://opentelemetry.io/schema/1.0.0"), - /// Some(vec![KeyValue::new("key", "value")]), - /// ); + /// let tracer = provider.tracer_builder("my_library"). + /// with_version(env!("CARGO_PKG_VERSION")). + /// with_schema_url("https://opentelemetry.io/schema/1.0.0"). + /// with_attributes(vec![KeyValue::new("key", "value")]). + /// build(); /// ``` fn tracer(&self, name: impl Into>) -> Self::Tracer { - self.versioned_tracer( - name, - None::>, - None::>, - None, - ) + self.tracer_builder(name).build() } + /// Deprecated, use [`TracerProvider::tracer_builder()`] + /// /// Returns a new versioned tracer with a given name. /// /// The `name` should be the application name or the name of the library @@ -69,6 +65,7 @@ pub trait TracerProvider { /// None, /// ); /// ``` + #[deprecated(since = "0.23.0", note = "Please use tracer_builder() instead")] fn versioned_tracer( &self, name: impl Into>, @@ -76,9 +73,47 @@ pub trait TracerProvider { schema_url: Option>>, attributes: Option>, ) -> Self::Tracer { - self.library_tracer(Arc::new(InstrumentationLibrary::new( - name, version, schema_url, attributes, - ))) + let mut builder = InstrumentationLibrary::builder(name); + if let Some(v) = version { + builder = builder.with_version(v); + } + if let Some(s) = schema_url { + builder = builder.with_version(s); + } + if let Some(a) = attributes { + builder = builder.with_attributes(a); + } + + self.library_tracer(Arc::new(builder.build())) + } + + /// Returns a new builder for creating a [`Tracer`] instance + /// + /// The `name` should be the application name or the name of the library + /// providing instrumentation. If the name is empty, then an + /// implementation-defined default name may be used instead. + /// + /// # Examples + /// + /// ``` + /// use opentelemetry::{global, trace::TracerProvider}; + /// + /// let provider = global::tracer_provider(); + /// + /// // tracer used in applications/binaries + /// let tracer = provider.tracer_builder("my_app").build(); + /// + /// // tracer used in libraries/crates that optionally includes version and schema url + /// let tracer = provider.tracer_builder("my_library") + /// .with_version(env!("CARGO_PKG_VERSION")) + /// .with_schema_url("https://opentelemetry.io/schema/1.0.0") + /// .build(); + /// ``` + fn tracer_builder(&self, name: impl Into>) -> TracerBuilder<'_, Self> { + TracerBuilder { + provider: self, + library_builder: InstrumentationLibrary::builder(name), + } } /// Returns a new versioned tracer with the given instrumentation library. @@ -94,13 +129,42 @@ pub trait TracerProvider { /// let tracer = provider.tracer("my_app"); /// /// // tracer used in libraries/crates that optionally includes version and schema url - /// let library = std::sync::Arc::new(InstrumentationLibrary::new( - /// env!("CARGO_PKG_NAME"), - /// Some(env!("CARGO_PKG_VERSION")), - /// Some("https://opentelemetry.io/schema/1.0.0"), - /// None, - /// )); + /// let library = std::sync::Arc::new( + /// InstrumentationLibrary::builder(env!("CARGO_PKG_NAME")) + /// .with_version(env!("CARGO_PKG_VERSION")) + /// .with_schema_url("https://opentelemetry.io/schema/1.0.0") + /// .build(), + /// ); + /// /// let tracer = provider.library_tracer(library); /// ``` fn library_tracer(&self, library: Arc) -> Self::Tracer; } + +#[derive(Debug)] +pub struct TracerBuilder<'a, T: TracerProvider + ?Sized> { + provider: &'a T, + library_builder: InstrumentationLibraryBuilder, +} + +impl<'a, T: TracerProvider + ?Sized> TracerBuilder<'a, T> { + pub fn with_version(mut self, version: impl Into>) -> Self { + self.library_builder = self.library_builder.with_version(version); + self + } + + pub fn with_schema_url(mut self, schema_url: impl Into>) -> Self { + self.library_builder = self.library_builder.with_schema_url(schema_url); + self + } + + pub fn with_attributes(mut self, attributes: impl Into>) -> Self { + self.library_builder = self.library_builder.with_attributes(attributes); + self + } + + pub fn build(self) -> T::Tracer { + self.provider + .library_tracer(Arc::new(self.library_builder.build())) + } +}