Skip to content

example: add temporality selector option to metrics-basic #2217

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
5 changes: 2 additions & 3 deletions examples/metrics-advanced/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use opentelemetry::global;
use opentelemetry::Key;
use opentelemetry::KeyValue;
use opentelemetry_sdk::metrics::reader::DeltaTemporalitySelector;
use opentelemetry_sdk::metrics::{
Aggregation, Instrument, PeriodicReader, SdkMeterProvider, Stream,
data::Temporality, Aggregation, Instrument, PeriodicReader, SdkMeterProvider, Stream,
};
use opentelemetry_sdk::{runtime, Resource};
use std::error::Error;
Expand Down Expand Up @@ -47,7 +46,7 @@ fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {

// Build exporter using Delta Temporality.
let exporter = opentelemetry_stdout::MetricsExporterBuilder::default()
.with_temporality_selector(DeltaTemporalitySelector::new())
.with_temporality(Temporality::Delta)
.build();

let reader = PeriodicReader::builder(exporter, runtime::Tokio).build();
Expand Down
5 changes: 4 additions & 1 deletion examples/metrics-basic/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use std::error::Error;
use std::vec;

fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {
let exporter = opentelemetry_stdout::MetricsExporterBuilder::default().build();
let exporter = opentelemetry_stdout::MetricsExporterBuilder::default()
// Build exporter using Delta Temporality (Defaults to Temporality::Cumulative)
// .with_temporality(data::Temporality::Delta)
.build();
let reader = PeriodicReader::builder(exporter, runtime::Tokio).build();
let provider = SdkMeterProvider::builder()
.with_reader(reader)
Expand Down
10 changes: 10 additions & 0 deletions opentelemetry-otlp/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ Released 2024-Sep-30
- Update `opentelemetry-http` dependency version to 0.26
- Update `opentelemetry-proto` dependency version to 0.26
- Bump MSRV to 1.71.1 [2140](https://github.com/open-telemetry/opentelemetry-rust/pull/2140)
- **BREAKING**: [#2217](https://github.com/open-telemetry/opentelemetry-rust/pull/2217)
- **Replaced**: The `MetricsExporterBuilder` interface is modified from `with_temporality_selector` to `with_temporality` example can be seen below:
Previous Signature:
```rust
MetricsExporterBuilder::default().with_temporality_selector(DeltaTemporalitySelector::new())
```
Updated Signature:
```rust
MetricsExporterBuilder::default().with_temporality(Temporality::Delta)
```

## v0.25.0

Expand Down
14 changes: 5 additions & 9 deletions opentelemetry-otlp/src/exporter/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
use opentelemetry_sdk::export::logs::LogBatch;
#[cfg(feature = "trace")]
use opentelemetry_sdk::export::trace::SpanData;
#[cfg(feature = "metrics")]
use opentelemetry_sdk::metrics::data::ResourceMetrics;
use prost::Message;
use std::collections::HashMap;
use std::env;
Expand Down Expand Up @@ -77,9 +75,7 @@
///
/// ```
/// # #[cfg(feature="metrics")]
/// use opentelemetry_sdk::metrics::reader::{
/// DefaultTemporalitySelector,
/// };
/// use opentelemetry_sdk::metrics::data::Temporality;
///
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// // Create a span exporter you can use to when configuring tracer providers
Expand All @@ -91,7 +87,7 @@
/// let metrics_exporter = opentelemetry_otlp::new_exporter()
/// .http()
/// .build_metrics_exporter(
/// Box::new(DefaultTemporalitySelector::new()),
/// Temporality::default(),
/// )?;
///
/// // Create a log exporter you can use when configuring logger providers
Expand Down Expand Up @@ -251,7 +247,7 @@
#[cfg(feature = "metrics")]
pub fn build_metrics_exporter(
mut self,
temporality_selector: Box<dyn opentelemetry_sdk::metrics::reader::TemporalitySelector>,
temporality: opentelemetry_sdk::metrics::data::Temporality,

Check warning on line 250 in opentelemetry-otlp/src/exporter/http/mod.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/exporter/http/mod.rs#L250

Added line #L250 was not covered by tests
) -> opentelemetry::metrics::Result<crate::MetricsExporter> {
use crate::{
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_HEADERS,
Expand All @@ -265,7 +261,7 @@
OTEL_EXPORTER_OTLP_METRICS_HEADERS,
)?;

Ok(crate::MetricsExporter::new(client, temporality_selector))
Ok(crate::MetricsExporter::new(client, temporality))

Check warning on line 264 in opentelemetry-otlp/src/exporter/http/mod.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/exporter/http/mod.rs#L264

Added line #L264 was not covered by tests
}
}

Expand Down Expand Up @@ -341,7 +337,7 @@
#[cfg(feature = "metrics")]
fn build_metrics_export_body(
&self,
metrics: &mut ResourceMetrics,
metrics: &mut opentelemetry_sdk::metrics::data::ResourceMetrics,

Check warning on line 340 in opentelemetry-otlp/src/exporter/http/mod.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/exporter/http/mod.rs#L340

Added line #L340 was not covered by tests
) -> opentelemetry::metrics::Result<(Vec<u8>, &'static str)> {
use opentelemetry_proto::tonic::collector::metrics::v1::ExportMetricsServiceRequest;

Expand Down
10 changes: 4 additions & 6 deletions opentelemetry-otlp/src/exporter/tonic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,7 @@
///
/// ```no_run
/// # #[cfg(feature="metrics")]
/// use opentelemetry_sdk::metrics::reader::{
/// DefaultTemporalitySelector,
/// };
/// use opentelemetry_sdk::metrics::data::Temporality;
///
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// // Create a span exporter you can use to when configuring tracer providers
Expand All @@ -110,7 +108,7 @@
/// let metrics_exporter = opentelemetry_otlp::new_exporter()
/// .tonic()
/// .build_metrics_exporter(
/// Box::new(DefaultTemporalitySelector::new()),
/// Temporality::default(),
/// )?;
///
/// // Create a log exporter you can use when configuring logger providers
Expand Down Expand Up @@ -331,7 +329,7 @@
#[cfg(feature = "metrics")]
pub fn build_metrics_exporter(
self,
temporality_selector: Box<dyn opentelemetry_sdk::metrics::reader::TemporalitySelector>,
temporality: opentelemetry_sdk::metrics::data::Temporality,

Check warning on line 332 in opentelemetry-otlp/src/exporter/tonic/mod.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/exporter/tonic/mod.rs#L332

Added line #L332 was not covered by tests
) -> opentelemetry::metrics::Result<crate::MetricsExporter> {
use crate::MetricsExporter;
use metrics::TonicMetricsClient;
Expand All @@ -345,7 +343,7 @@

let client = TonicMetricsClient::new(channel, interceptor, compression);

Ok(MetricsExporter::new(client, temporality_selector))
Ok(MetricsExporter::new(client, temporality))

Check warning on line 346 in opentelemetry-otlp/src/exporter/tonic/mod.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/exporter/tonic/mod.rs#L346

Added line #L346 was not covered by tests
}

/// Build a new tonic span exporter
Expand Down
3 changes: 1 addition & 2 deletions opentelemetry-otlp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@
//! use opentelemetry::{global, KeyValue, trace::Tracer};
//! use opentelemetry_sdk::{trace::{self, RandomIdGenerator, Sampler}, Resource};
//! # #[cfg(feature = "metrics")]
//! use opentelemetry_sdk::metrics::reader::DefaultTemporalitySelector;
//! use opentelemetry_sdk::metrics::data::Temporality;
//! use opentelemetry_otlp::{Protocol, WithExportConfig, ExportConfig};
//! use std::time::Duration;
//! # #[cfg(feature = "grpc-tonic")]
Expand Down Expand Up @@ -183,7 +183,6 @@
//! .with_resource(Resource::new(vec![KeyValue::new("service.name", "example")]))
//! .with_period(Duration::from_secs(3))
//! .with_timeout(Duration::from_secs(10))
//! .with_temporality_selector(DefaultTemporalitySelector::new())
//! .build();
//! # }
//!
Expand Down
66 changes: 21 additions & 45 deletions opentelemetry-otlp/src/metric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
metrics::{
data::{ResourceMetrics, Temporality},
exporter::PushMetricsExporter,
reader::{DefaultTemporalitySelector, DeltaTemporalitySelector, TemporalitySelector},
InstrumentKind, PeriodicReader, SdkMeterProvider,
PeriodicReader, SdkMeterProvider,
},
runtime::Runtime,
Resource,
Expand Down Expand Up @@ -47,7 +46,7 @@
{
OtlpMetricPipeline {
rt,
temporality_selector: None,
temporality: None,

Check warning on line 49 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L49

Added line #L49 was not covered by tests
exporter_pipeline: NoExporterConfig(()),
resource: None,
period: None,
Expand Down Expand Up @@ -75,22 +74,15 @@

impl MetricsExporterBuilder {
/// Build a OTLP metrics exporter with given configuration.
pub fn build_metrics_exporter(
self,
temporality_selector: Box<dyn TemporalitySelector>,
) -> Result<MetricsExporter> {
pub fn build_metrics_exporter(self, temporality: Temporality) -> Result<MetricsExporter> {

Check warning on line 77 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L77

Added line #L77 was not covered by tests
match self {
#[cfg(feature = "grpc-tonic")]
MetricsExporterBuilder::Tonic(builder) => {
builder.build_metrics_exporter(temporality_selector)
}
MetricsExporterBuilder::Tonic(builder) => builder.build_metrics_exporter(temporality),

Check warning on line 80 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L80

Added line #L80 was not covered by tests
#[cfg(feature = "http-proto")]
MetricsExporterBuilder::Http(builder) => {
builder.build_metrics_exporter(temporality_selector)
}
MetricsExporterBuilder::Http(builder) => builder.build_metrics_exporter(temporality),

Check warning on line 82 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L82

Added line #L82 was not covered by tests
#[cfg(not(any(feature = "http-proto", feature = "grpc-tonic")))]
MetricsExporterBuilder::Unconfigured => {
drop(temporality_selector);
let _ = temporality;
Err(opentelemetry::metrics::MetricsError::Other(
"no configured metrics exporter, enable `http-proto` or `grpc-tonic` feature to configure a metrics exporter".into(),
))
Expand Down Expand Up @@ -119,7 +111,7 @@
/// runtime.
pub struct OtlpMetricPipeline<RT, EB> {
rt: RT,
temporality_selector: Option<Box<dyn TemporalitySelector>>,
temporality: Option<Temporality>,
exporter_pipeline: EB,
resource: Option<Resource>,
period: Option<time::Duration>,
Expand Down Expand Up @@ -154,23 +146,13 @@
}
}

/// Build with the given temporality selector
pub fn with_temporality_selector<T: TemporalitySelector + 'static>(self, selector: T) -> Self {
/// Set the [Temporality] of the exporter.
pub fn with_temporality(self, temporality: Temporality) -> Self {

Check warning on line 150 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L150

Added line #L150 was not covered by tests
OtlpMetricPipeline {
temporality_selector: Some(Box::new(selector)),
temporality: Some(temporality),

Check warning on line 152 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L152

Added line #L152 was not covered by tests
..self
}
}

/// Build with delta temporality selector.
///
/// This temporality selector is equivalent to OTLP Metrics Exporter's
/// `Delta` temporality preference (see [its documentation][exporter-docs]).
///
/// [exporter-docs]: https://github.com/open-telemetry/opentelemetry-specification/blob/a1c13d59bb7d0fb086df2b3e1eaec9df9efef6cc/specification/metrics/sdk_exporters/otlp.md#additional-configuration
pub fn with_delta_temporality(self) -> Self {
self.with_temporality_selector(DeltaTemporalitySelector::new())
}
}

impl<RT> OtlpMetricPipeline<RT, NoExporterConfig>
Expand All @@ -185,7 +167,7 @@
OtlpMetricPipeline {
exporter_pipeline: pipeline.into(),
rt: self.rt,
temporality_selector: self.temporality_selector,
temporality: self.temporality,

Check warning on line 170 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L170

Added line #L170 was not covered by tests
resource: self.resource,
period: self.period,
timeout: self.timeout,
Expand All @@ -199,10 +181,9 @@
{
/// Build MeterProvider
pub fn build(self) -> Result<SdkMeterProvider> {
let exporter = self.exporter_pipeline.build_metrics_exporter(
self.temporality_selector
.unwrap_or_else(|| Box::new(DefaultTemporalitySelector::new())),
)?;
let exporter = self
.exporter_pipeline
.build_metrics_exporter(self.temporality.unwrap_or_default())?;

Check warning on line 186 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L184-L186

Added lines #L184 - L186 were not covered by tests

let mut builder = PeriodicReader::builder(exporter, self.rt);

Expand Down Expand Up @@ -247,7 +228,7 @@
/// Export metrics in OTEL format.
pub struct MetricsExporter {
client: Box<dyn MetricsClient>,
temporality_selector: Box<dyn TemporalitySelector>,
temporality: Temporality,
}

impl Debug for MetricsExporter {
Expand All @@ -256,12 +237,6 @@
}
}

impl TemporalitySelector for MetricsExporter {
fn temporality(&self, kind: InstrumentKind) -> Temporality {
self.temporality_selector.temporality(kind)
}
}

#[async_trait]
impl PushMetricsExporter for MetricsExporter {
async fn export(&self, metrics: &mut ResourceMetrics) -> Result<()> {
Expand All @@ -276,17 +251,18 @@
fn shutdown(&self) -> Result<()> {
self.client.shutdown()
}

fn temporality(&self) -> Temporality {
self.temporality
}

Check warning on line 257 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L255-L257

Added lines #L255 - L257 were not covered by tests
}

impl MetricsExporter {
/// Create a new metrics exporter
pub fn new(
client: impl MetricsClient,
temporality_selector: Box<dyn TemporalitySelector>,
) -> MetricsExporter {
pub fn new(client: impl MetricsClient, temporality: Temporality) -> MetricsExporter {

Check warning on line 262 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L262

Added line #L262 was not covered by tests
MetricsExporter {
client: Box::new(client),
temporality_selector,
temporality,

Check warning on line 265 in opentelemetry-otlp/src/metric.rs

View check run for this annotation

Codecov / codecov/patch

opentelemetry-otlp/src/metric.rs#L265

Added line #L265 was not covered by tests
}
}
}
2 changes: 2 additions & 0 deletions opentelemetry-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- Bump MSRV to 1.70 [#2179](https://github.com/open-telemetry/opentelemetry-rust/pull/2179)
- Implement `LogRecord::set_trace_context` for `LogRecord`. Respect any trace context set on a `LogRecord` when emitting through a `Logger`.
- Improved `LoggerProvider` shutdown handling to prevent redundant shutdown calls when `drop` is invoked. [#2195](https://github.com/open-telemetry/opentelemetry-rust/pull/2195)
- **BREAKING**: [#2217](https://github.com/open-telemetry/opentelemetry-rust/pull/2217)
- **Replaced**: Removed `{Delta,Cumulative}TemporalitySelector::new()` in favor of directly using `Temporality` enum to simplify the configuration of MetricExporterBuilder with different temporalities.

## v0.26.0
Released 2024-Sep-30
Expand Down
14 changes: 6 additions & 8 deletions opentelemetry-sdk/benches/metric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use opentelemetry_sdk::{
metrics::{
data::{ResourceMetrics, Temporality},
new_view,
reader::{DeltaTemporalitySelector, MetricReader, TemporalitySelector},
reader::MetricReader,
Aggregation, Instrument, InstrumentKind, ManualReader, Pipeline, SdkMeterProvider, Stream,
View,
},
Expand All @@ -20,12 +20,6 @@ use opentelemetry_sdk::{
#[derive(Clone, Debug)]
struct SharedReader(Arc<dyn MetricReader>);

impl TemporalitySelector for SharedReader {
fn temporality(&self, kind: InstrumentKind) -> Temporality {
self.0.temporality(kind)
}
}

impl MetricReader for SharedReader {
fn register_pipeline(&self, pipeline: Weak<Pipeline>) {
self.0.register_pipeline(pipeline)
Expand All @@ -42,6 +36,10 @@ impl MetricReader for SharedReader {
fn shutdown(&self) -> Result<()> {
self.0.shutdown()
}

fn temporality(&self, kind: InstrumentKind) -> Temporality {
self.0.temporality(kind)
}
}

// * Summary *
Expand Down Expand Up @@ -118,7 +116,7 @@ fn bench_counter(view: Option<Box<dyn View>>, temporality: &str) -> (SharedReade
} else {
SharedReader(Arc::new(
ManualReader::builder()
.with_temporality_selector(DeltaTemporalitySelector::new())
.with_temporality(Temporality::Delta)
.build(),
))
};
Expand Down
8 changes: 7 additions & 1 deletion opentelemetry-sdk/src/metrics/data/temporality.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
/// Defines the window that an aggregation was calculated over.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Temporality {
/// A measurement interval that continues to expand forward in time from a
/// starting point.
///
/// New measurements are added to all previous measurements since a start time.
#[default]
Cumulative,

/// A measurement interval that resets each cycle.
///
/// Measurements from one cycle are recorded independently, measurements from
/// other cycles do not affect them.
Delta,

/// Configures Synchronous Counter and Histogram instruments to use
/// Delta aggregation temporality, which allows them to shed memory
/// following a cardinality explosion, thus use less memory.
LowMemory,
}
Loading
Loading