Skip to content

Commit

Permalink
Improve tracer and meter creation ergonomics from #1018 (#1037)
Browse files Browse the repository at this point in the history
  • Loading branch information
jtescher authored Apr 24, 2023
1 parent f42c11d commit d560ff3
Show file tree
Hide file tree
Showing 33 changed files with 193 additions and 126 deletions.
2 changes: 1 addition & 1 deletion examples/hyper-prometheus/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let provider = MeterProvider::builder().with_reader(exporter).build();
let cx = Context::new();

let meter = provider.meter("hyper-prometheus-example".into());
let meter = provider.meter("hyper-prometheus-example");
let state = Arc::new(AppState {
registry,
http_counter: meter
Expand Down
15 changes: 6 additions & 9 deletions opentelemetry-api/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ pub struct InstrumentationLibrary {
/// let library = opentelemetry_api::InstrumentationLibrary::new(
/// "my-crate",
/// Some(env!("CARGO_PKG_VERSION")),
/// None,
/// Some("https://opentelemetry.io/schemas/1.17.0"),
/// None,
/// );
/// ```
Expand Down Expand Up @@ -478,15 +478,12 @@ impl hash::Hash for InstrumentationLibrary {

impl InstrumentationLibrary {
/// Create an new instrumentation library.
pub fn new<T>(
name: T,
version: Option<T>,
schema_url: Option<T>,
pub fn new(
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> InstrumentationLibrary
where
T: Into<Cow<'static, str>>,
{
) -> InstrumentationLibrary {
InstrumentationLibrary {
name: name.into(),
version: version.map(Into::into),
Expand Down
74 changes: 60 additions & 14 deletions opentelemetry-api/src/global/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,41 @@ static GLOBAL_METER_PROVIDER: Lazy<RwLock<GlobalMeterProvider>> = Lazy::new(|| {
))
});

/// Allows a specific [MeterProvider] to be used generically by the
/// [GlobalMeterProvider] by mirroring the interface and boxing the return types.
pub trait ObjectSafeMeterProvider {
/// Creates a versioned named meter instance that is a trait object through the underlying
/// [MeterProvider].
fn versioned_meter_cow(
&self,
name: Cow<'static, str>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter;
}

impl<P> ObjectSafeMeterProvider for P
where
P: MeterProvider,
{
/// Return a versioned boxed tracer
fn versioned_meter_cow(
&self,
name: Cow<'static, str>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter {
self.versioned_meter(name, version, schema_url, attributes)
}
}

/// Represents the globally configured [`MeterProvider`] instance for this
/// application.
#[derive(Clone)]
pub struct GlobalMeterProvider {
provider: Arc<dyn MeterProvider + Send + Sync>,
provider: Arc<dyn ObjectSafeMeterProvider + Send + Sync>,
}

impl fmt::Debug for GlobalMeterProvider {
Expand All @@ -30,13 +60,17 @@ impl fmt::Debug for GlobalMeterProvider {
impl MeterProvider for GlobalMeterProvider {
fn versioned_meter(
&self,
name: Cow<'static, str>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter {
self.provider
.versioned_meter(name, version, schema_url, attributes)
self.provider.versioned_meter_cow(
name.into(),
version.map(Into::into),
schema_url.map(Into::into),
attributes,
)
}
}

Expand Down Expand Up @@ -77,7 +111,7 @@ pub fn meter_provider() -> GlobalMeterProvider {
///
/// If the name is an empty string, the provider will use a default name.
///
/// This is a more convenient way of expressing `global::meter_provider().meter(name, None, None, None)`.
/// This is a more convenient way of expressing `global::meter_provider().versioned_meter(name, None, None, None)`.
pub fn meter(name: impl Into<Cow<'static, str>>) -> Meter {
meter_provider().meter(name.into())
}
Expand All @@ -88,19 +122,31 @@ pub fn meter(name: impl Into<Cow<'static, str>>) -> Meter {
/// - version specifies the version of the instrumentation scope if the scope has a version
/// - schema url specifies the Schema URL that should be recorded in the emitted telemetry.
///
/// This is a convenient way of `global::meter_provider().meter(...)`
/// This is a convenient way of `global::meter_provider().versioned_meter(...)`
///
/// # Example
/// ```rust
///
/// ```
/// use opentelemetry_api::global::meter_with_version;
/// use opentelemetry_api::KeyValue;
/// let meter = meter_with_version("io.opentelemetry", Some("0.17".into()), Some("https://opentelemetry.io/schemas/1.2.0".into()), Some(vec![KeyValue::new("key", "value")]));
/// ```
///
/// let meter = meter_with_version(
/// "io.opentelemetry",
/// Some("0.17"),
/// Some("https://opentelemetry.io/schemas/1.2.0"),
/// Some(vec![KeyValue::new("key", "value")]),
/// );
/// ```
pub fn meter_with_version(
name: impl Into<Cow<'static, str>>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter {
meter_provider().versioned_meter(name.into(), version, schema_url, attributes)
meter_provider().versioned_meter(
name.into(),
version.map(Into::into),
schema_url.map(Into::into),
attributes,
)
}
17 changes: 6 additions & 11 deletions opentelemetry-api/src/global/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@
//! // 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".into(),
//! Some(env!("CARGO_PKG_VERSION").into()),
//! None,
//! "my-library-name",
//! Some(env!("CARGO_PKG_VERSION")),
//! Some("https://opentelemetry.io/schemas/1.17.0"),
//! None,
//! );
//!
Expand Down Expand Up @@ -152,15 +152,10 @@ mod trace;
pub use error_handler::{handle_error, set_error_handler, Error};
#[cfg(feature = "metrics")]
#[cfg_attr(docsrs, doc(cfg(feature = "metrics")))]
pub use metrics::{
meter, meter_provider, meter_with_version, set_meter_provider, GlobalMeterProvider,
};
pub use metrics::*;
#[cfg(feature = "trace")]
#[cfg_attr(docsrs, doc(cfg(feature = "trace")))]
pub use propagation::{get_text_map_propagator, set_text_map_propagator};
pub use propagation::*;
#[cfg(feature = "trace")]
#[cfg_attr(docsrs, doc(cfg(feature = "trace")))]
pub use trace::{
set_tracer_provider, shutdown_tracer_provider, tracer, tracer_provider, BoxedSpan, BoxedTracer,
GlobalTracerProvider, ObjectSafeTracer, ObjectSafeTracerProvider,
};
pub use trace::*;
20 changes: 12 additions & 8 deletions opentelemetry-api/src/global/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use std::mem;
use std::sync::{Arc, RwLock};
use std::time::SystemTime;

/// Allows a specific [`crate::trace::Span`] to be used generically by [`BoxedSpan`]
/// instances by mirroring the interface and boxing the return types.
pub trait ObjectSafeSpan {
/// An API to record events at a specific time in the context of a given `Span`.
///
Expand Down Expand Up @@ -101,7 +103,7 @@ pub trait ObjectSafeSpan {
///
/// For more details, refer to [`Span::end`]
///
/// [`Span::end`]: Span::end()
/// [`Span::end`]: trace::Span::end
fn end_with_timestamp(&mut self, timestamp: SystemTime);
}

Expand Down Expand Up @@ -351,15 +353,17 @@ impl trace::TracerProvider for GlobalTracerProvider {
/// Create a versioned tracer using the global provider.
fn versioned_tracer(
&self,
name: Cow<'static, str>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> Self::Tracer {
BoxedTracer(
self.provider
.versioned_tracer_boxed(name, version, schema_url, attributes),
)
BoxedTracer(self.provider.versioned_tracer_boxed(
name.into(),
version.map(Into::into),
schema_url.map(Into::into),
attributes,
))
}
}

Expand Down
15 changes: 10 additions & 5 deletions opentelemetry-api/src/metrics/meter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@ pub trait MeterProvider {
///
/// If the name is empty, then an implementation defined default name will
/// be used instead.
fn meter(&self, name: Cow<'static, str>) -> Meter {
self.versioned_meter(name, None, None, None)
fn meter(&self, name: impl Into<Cow<'static, str>>) -> Meter {
self.versioned_meter(
name,
None::<Cow<'static, str>>,
None::<Cow<'static, str>>,
None,
)
}

/// Creates an implementation of the [`Meter`] interface.
Expand All @@ -34,9 +39,9 @@ pub trait MeterProvider {
/// default name will be used instead.
fn versioned_meter(
&self,
name: Cow<'static, str>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> Meter;
}
Expand Down
6 changes: 3 additions & 3 deletions opentelemetry-api/src/metrics/noop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ impl NoopMeterProvider {
impl MeterProvider for NoopMeterProvider {
fn versioned_meter(
&self,
_name: Cow<'static, str>,
_version: Option<Cow<'static, str>>,
_schema_url: Option<Cow<'static, str>>,
_name: impl Into<Cow<'static, str>>,
_version: Option<impl Into<Cow<'static, str>>>,
_schema_url: Option<impl Into<Cow<'static, str>>>,
_attributes: Option<Vec<KeyValue>>,
) -> Meter {
Meter::new(Arc::new(NoopMeterCore::new()))
Expand Down
6 changes: 3 additions & 3 deletions opentelemetry-api/src/trace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@
//!
//! // Get a tracer for this library
//! let tracer = tracer_provider.versioned_tracer(
//! "my_name".into(),
//! Some(env!("CARGO_PKG_VERSION").into()),
//! None,
//! "my_name",
//! Some(env!("CARGO_PKG_VERSION")),
//! Some("https://opentelemetry.io/schemas/1.17.0"),
//! None
//! );
//!
Expand Down
6 changes: 3 additions & 3 deletions opentelemetry-api/src/trace/noop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ impl trace::TracerProvider for NoopTracerProvider {
/// Returns a new `NoopTracer` instance.
fn versioned_tracer(
&self,
_name: Cow<'static, str>,
_version: Option<Cow<'static, str>>,
_schema_url: Option<Cow<'static, str>>,
_name: impl Into<Cow<'static, str>>,
_version: Option<impl Into<Cow<'static, str>>>,
_schema_url: Option<impl Into<Cow<'static, str>>>,
_attributes: Option<Vec<KeyValue>>,
) -> Self::Tracer {
NoopTracer::new()
Expand Down
31 changes: 18 additions & 13 deletions opentelemetry-api/src/trace/tracer_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,23 @@ pub trait TracerProvider {
/// let provider = global::tracer_provider();
///
/// // tracer used in applications/binaries
/// let tracer = provider.tracer("my_app".into());
/// 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".into(),
/// Some(env!("CARGO_PKG_VERSION").into()),
/// Some("https://opentelemetry.io/schema/1.0.0".into()),
/// "my_library",
/// Some(env!("CARGO_PKG_VERSION")),
/// Some("https://opentelemetry.io/schema/1.0.0"),
/// Some(vec![KeyValue::new("key", "value")]),
/// );
/// ```
fn tracer(&self, name: Cow<'static, str>) -> Self::Tracer {
self.versioned_tracer(name, None, None, None)
fn tracer(&self, name: impl Into<Cow<'static, str>>) -> Self::Tracer {
self.versioned_tracer(
name,
None::<Cow<'static, str>>,
None::<Cow<'static, str>>,
None,
)
}

/// Returns a new versioned tracer with a given name.
Expand All @@ -54,21 +59,21 @@ pub trait TracerProvider {
/// let provider = global::tracer_provider();
///
/// // tracer used in applications/binaries
/// let tracer = provider.tracer("my_app".into());
/// 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".into(),
/// Some(env!("CARGO_PKG_VERSION").into()),
/// Some("https://opentelemetry.io/schema/1.0.0".into()),
/// "my_library",
/// Some(env!("CARGO_PKG_VERSION")),
/// Some("https://opentelemetry.io/schema/1.0.0"),
/// None,
/// );
/// ```
fn versioned_tracer(
&self,
name: Cow<'static, str>,
version: Option<Cow<'static, str>>,
schema_url: Option<Cow<'static, str>>,
name: impl Into<Cow<'static, str>>,
version: Option<impl Into<Cow<'static, str>>>,
schema_url: Option<impl Into<Cow<'static, str>>>,
attributes: Option<Vec<KeyValue>>,
) -> Self::Tracer;
}
2 changes: 1 addition & 1 deletion opentelemetry-aws/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
//! let provider = TracerProvider::builder()
//! .with_simple_exporter(SpanExporter::default())
//! .build();
//! let tracer = provider.tracer("readme_example".into());
//! let tracer = provider.tracer("readme_example");
//!
//! let mut req = hyper::Request::builder().uri("http://127.0.0.1:3000");
//! tracer.in_span("doing_work", |cx| {
Expand Down
3 changes: 2 additions & 1 deletion opentelemetry-contrib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ rustdoc-args = ["--cfg", "docsrs"]
default = []
base64_format = ["base64", "binary_propagator"]
binary_propagator = []
jaeger_json_exporter = ["serde_json", "futures", "async-trait"]
jaeger_json_exporter = ["serde_json", "futures", "async-trait", "opentelemetry-semantic-conventions"]
rt-tokio = ["tokio", "opentelemetry/rt-tokio"]
rt-tokio-current-thread = ["tokio", "opentelemetry/rt-tokio-current-thread"]
rt-async-std = ["async-std", "opentelemetry/rt-async-std"]
Expand All @@ -35,6 +35,7 @@ futures = { version = "0.3", optional = true }
once_cell = "1.17.1"
opentelemetry = { version = "0.19", path = "../opentelemetry", features = ["trace"] }
opentelemetry_api = { version = "0.19", path = "../opentelemetry-api" }
opentelemetry-semantic-conventions = { version = "0.11", path = "../opentelemetry-semantic-conventions", optional = true }
serde_json = { version = "1", optional = true }
tokio = { version = "1.0", features = ["fs", "io-util"], optional = true }

Expand Down
Loading

0 comments on commit d560ff3

Please sign in to comment.