diff --git a/opentelemetry-sdk/src/lib.rs b/opentelemetry-sdk/src/lib.rs index 668f84a05a..930bd7eec1 100644 --- a/opentelemetry-sdk/src/lib.rs +++ b/opentelemetry-sdk/src/lib.rs @@ -44,7 +44,7 @@ //! [examples]: https://github.com/open-telemetry/opentelemetry-rust/tree/main/examples //! [`trace`]: https://docs.rs/opentelemetry/latest/opentelemetry/trace/index.html //! -//! # Metrics (Beta) +//! # Metrics (Alpha) //! //! Note: the metrics implementation is **still in progress** and **subject to major //! changes**. @@ -91,8 +91,8 @@ //! //! * `logs_level_enabled`: control the log level //! -//! Support for recording and exporting telemetry asynchronously can be added -//! via the following flags: +//! Support for recording and exporting telemetry asynchronously and perform +//! metrics aggregation can be added via the following flags: //! //! * `rt-tokio`: Spawn telemetry tasks using [tokio]'s multi-thread runtime. //! * `rt-tokio-current-thread`: Spawn telemetry tasks on a separate runtime so that the main runtime won't be blocked. diff --git a/opentelemetry-sdk/src/metrics/meter_provider.rs b/opentelemetry-sdk/src/metrics/meter_provider.rs index bd8a92d811..c693b2aa56 100644 --- a/opentelemetry-sdk/src/metrics/meter_provider.rs +++ b/opentelemetry-sdk/src/metrics/meter_provider.rs @@ -403,7 +403,12 @@ mod tests { let meter = global::meter("test"); let counter = meter.u64_counter("test_counter").init(); // no need to drop a meter for meter_provider shutdown - provider.shutdown().unwrap(); + let shutdown_res = provider.shutdown(); + assert!(shutdown_res.is_ok()); + + // shutdown once more should return an error + let shutdown_res = provider.shutdown(); + assert!(shutdown_res.is_err()); assert!(reader.is_shutdown()); // TODO Fix: the instrument is still available, and can be used. // While the reader is shutdown, and no collect is happening diff --git a/opentelemetry-sdk/src/metrics/mod.rs b/opentelemetry-sdk/src/metrics/mod.rs index 557cfc2611..8c3e68d0f1 100644 --- a/opentelemetry-sdk/src/metrics/mod.rs +++ b/opentelemetry-sdk/src/metrics/mod.rs @@ -1,4 +1,4 @@ -//! The rust of the OpenTelemetry metrics SDK. +//! The crust of the OpenTelemetry metrics SDK. //! //! ## Configuration //! @@ -9,8 +9,9 @@ //! ### Example //! //! ``` +//! use opentelemetry::global; //! use opentelemetry::{ -//! metrics::{MeterProvider, Unit}, +//! metrics::Unit, //! KeyValue, //! }; //! use opentelemetry_sdk::{metrics::SdkMeterProvider, Resource}; @@ -19,10 +20,11 @@ //! let resource = Resource::default(); // default attributes about the current process //! //! // Create a meter provider with the desired config -//! let provider = SdkMeterProvider::builder().with_resource(resource).build(); +//! let meter_provider = SdkMeterProvider::builder().with_resource(resource).build(); +//! global::set_meter_provider(meter_provider.clone()); //! //! // Use the meter provider to create meter instances -//! let meter = provider.meter("my_app"); +//! let meter = global::meter("my_app"); //! //! // Create instruments scoped to the meter //! let counter = meter @@ -32,6 +34,10 @@ //! //! // use instruments to record measurements //! counter.add(10, &[KeyValue::new("rate", "standard")]); +//! +//! // shutdown the provider at the end of the application to ensure any metrics not yet +//! // exported are flushed. +//! meter_provider.shutdown().unwrap(); //! ``` //! //! [Resource]: crate::Resource diff --git a/opentelemetry/CHANGELOG.md b/opentelemetry/CHANGELOG.md index 20f1f7f19c..d6599af17d 100644 --- a/opentelemetry/CHANGELOG.md +++ b/opentelemetry/CHANGELOG.md @@ -4,9 +4,8 @@ ### Added -- [#1623](https://github.com/open-telemetry/opentelemetry-rust/pull/1623) Add global::meter_provider_shutdown - [#1640](https://github.com/open-telemetry/opentelemetry-rust/pull/1640) Add `PropagationError` -- [#1701](https://github.com/open-telemetry/opentelemetry-rust/pull/1701) `Gauge` no longer requires `otel-unstable` feature flag, as OpenTelemetry specification for `Gauge` instrumentation is stable. +- [#1701](https://github.com/open-telemetry/opentelemetry-rust/pull/1701) `Gauge` no longer requires `otel-unstable` feature flag, as OpenTelemetry specification for `Gauge` instrument is stable. ### Removed diff --git a/opentelemetry/src/global/metrics.rs b/opentelemetry/src/global/metrics.rs index 11c21805f3..b85354bee4 100644 --- a/opentelemetry/src/global/metrics.rs +++ b/opentelemetry/src/global/metrics.rs @@ -1,4 +1,4 @@ -use crate::metrics::{self, noop::NoopMeterProvider, Meter, MeterProvider}; +use crate::metrics::{self, Meter, MeterProvider}; use crate::KeyValue; use core::fmt; use once_cell::sync::Lazy; @@ -116,11 +116,6 @@ pub fn meter(name: impl Into>) -> Meter { meter_provider().meter(name.into()) } -/// Shut down the current global [`MeterProvider`]. -pub fn shutdown_meter_provider() { - set_meter_provider(NoopMeterProvider::new()); -} - /// Creates a [`Meter`] with the name, version and schema url. /// /// - name SHOULD uniquely identify the instrumentation scope, such as the instrumentation library (e.g. io.opentelemetry.contrib.mongodb), package, module or class name. diff --git a/opentelemetry/src/global/mod.rs b/opentelemetry/src/global/mod.rs index aef0190072..a1e7b1da72 100644 --- a/opentelemetry/src/global/mod.rs +++ b/opentelemetry/src/global/mod.rs @@ -81,29 +81,18 @@ //! written against this generic API and not constrain users to a specific //! implementation choice. //! -//! ### Usage in Applications +//! ### Usage in Applications and libraries //! -//! Applications configure their meter by configuring a meter provider, -//! and calling [`set_meter_provider`] to set it as global meter provider. +//! Applications and libraries can obtain meter from the global meter provider, +//! and use the meter to create instruments to emit measurements. //! //! ``` //! # #[cfg(feature="metrics")] //! # { -//! use opentelemetry::metrics::{Meter, noop::NoopMeterProvider}; +//! use opentelemetry::metrics::{Meter}; //! use opentelemetry::{global, KeyValue}; //! -//! fn init_meter() { -//! // Swap this no-op provider with an actual meter provider, -//! // exporting to stdout, otlp, prometheus, etc. -//! let provider = NoopMeterProvider::new(); -//! -//! // Configure the global `MeterProvider` singleton when your app starts -//! // (there is a no-op default if this is not set by your application) -//! global::set_meter_provider(provider) -//! } -//! -//! fn do_something_instrumented() { -//! // You can get a named meter instance anywhere in your codebase. +//! fn do_something_instrumented() { //! let meter = global::meter("my-component"); //! // It is recommended to reuse the same counter instance for the //! // lifetime of the application @@ -111,34 +100,24 @@ //! //! // record measurements //! counter.add(1, &[KeyValue::new("mykey", "myvalue")]); +//! } //! } -//! -//! // in main or other app start -//! init_meter(); -//! do_something_instrumented(); -//! // Shutdown ensures any metrics still in memory are given to exporters -//! // before the program exits. -//! global::shutdown_meter_provider(); -//! # } //! ``` //! -//! ### Usage in Libraries -//! +//! ### Usage in Applications +//! Application owners have the responsibility to set the global meter provider. +//! The global meter provider can be set using the [`set_meter_provider`] function. +//! As set_meter_provider takes ownership of the provider, it is recommended to +//! provide a clone of the provider, if the application needs to use the provider +//! later to perform operations like shutdown. //! ``` //! # #[cfg(feature="metrics")] //! # { //! use opentelemetry::{global, KeyValue}; //! -//! pub fn my_instrumented_library_function() { -//! // End users of your library will configure their global meter provider -//! // so you can use the global meter without any setup -//! let meter = global::meter("my-library-name"); -//! // It is recommended to reuse the same counter instance for the -//! // lifetime of the application -//! let counter = meter.u64_counter("my_counter").init(); -//! -//! // record measurements -//! counter.add(1, &[KeyValue::new("mykey", "myvalue")]); +//! fn main() { +//! // Set the global meter provider +//! // global::set_meter_provider(my_meter_provider().clone()); //! } //! # } //! ```