Skip to content

Commit 238a8f2

Browse files
authored
Make PeriodicReader with own Thread the default (#2403)
1 parent d67d1fc commit 238a8f2

File tree

15 files changed

+1167
-1114
lines changed

15 files changed

+1167
-1114
lines changed

examples/metrics-advanced/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use opentelemetry::KeyValue;
44
use opentelemetry_sdk::metrics::{
55
Aggregation, Instrument, PeriodicReader, SdkMeterProvider, Stream, Temporality,
66
};
7-
use opentelemetry_sdk::{runtime, Resource};
7+
use opentelemetry_sdk::Resource;
88
use std::error::Error;
99

1010
fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {
@@ -49,7 +49,7 @@ fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {
4949
.with_temporality(Temporality::Delta)
5050
.build();
5151

52-
let reader = PeriodicReader::builder(exporter, runtime::Tokio).build();
52+
let reader = PeriodicReader::builder(exporter).build();
5353
let provider = SdkMeterProvider::builder()
5454
.with_reader(reader)
5555
.with_resource(Resource::new([KeyValue::new(

examples/metrics-basic/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use opentelemetry::{global, KeyValue};
22
use opentelemetry_sdk::metrics::{PeriodicReader, SdkMeterProvider};
3-
use opentelemetry_sdk::{runtime, Resource};
3+
use opentelemetry_sdk::Resource;
44
use std::error::Error;
55
use std::vec;
66

@@ -9,7 +9,7 @@ fn init_meter_provider() -> opentelemetry_sdk::metrics::SdkMeterProvider {
99
// Build exporter using Delta Temporality (Defaults to Temporality::Cumulative)
1010
// .with_temporality(opentelemetry_sdk::metrics::Temporality::Delta)
1111
.build();
12-
let reader = PeriodicReader::builder(exporter, runtime::Tokio).build();
12+
let reader = PeriodicReader::builder(exporter).build();
1313
let provider = SdkMeterProvider::builder()
1414
.with_reader(reader)
1515
.with_resource(Resource::new([KeyValue::new(

opentelemetry-otlp/examples/basic-otlp-http/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ publish = false
99
default = ["reqwest"]
1010
reqwest = ["opentelemetry-otlp/reqwest-client"]
1111
hyper = ["opentelemetry-otlp/hyper-client"]
12+
experimental_metrics_periodicreader_with_async_runtime = ["opentelemetry_sdk/experimental_metrics_periodicreader_with_async_runtime"]
1213

1314

1415
[dependencies]
1516
once_cell = { workspace = true }
1617
opentelemetry = { path = "../../../opentelemetry" }
17-
opentelemetry_sdk = { path = "../../../opentelemetry-sdk", features = ["rt-tokio", "metrics", "logs"]}
18+
opentelemetry_sdk = { path = "../../../opentelemetry-sdk", features = ["rt-tokio", "metrics", "logs", "experimental_metrics_periodicreader_with_async_runtime"]}
1819
opentelemetry-http = { path = "../../../opentelemetry-http", optional = true, default-features = false}
1920
opentelemetry-otlp = { path = "../..", features = ["http-proto", "http-json", "logs"] , default-features = false}
2021
opentelemetry-appender-tracing = { path = "../../../opentelemetry-appender-tracing", default-features = false}

opentelemetry-otlp/examples/basic-otlp-http/src/main.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use opentelemetry_otlp::WithExportConfig;
1010
use opentelemetry_otlp::{LogExporter, MetricExporter, Protocol, SpanExporter};
1111
use opentelemetry_sdk::{
1212
logs::LoggerProvider,
13-
metrics::{MetricError, PeriodicReader, SdkMeterProvider},
13+
metrics::{MetricError, SdkMeterProvider},
1414
runtime,
1515
trace::{self as sdktrace, TracerProvider},
1616
};
@@ -63,8 +63,19 @@ fn init_metrics() -> Result<opentelemetry_sdk::metrics::SdkMeterProvider, Metric
6363
.with_endpoint("http://localhost:4318/v1/metrics")
6464
.build()?;
6565

66+
#[cfg(feature = "experimental_metrics_periodicreader_with_async_runtime")]
67+
let reader =
68+
opentelemetry_sdk::metrics::periodic_reader_with_async_runtime::PeriodicReader::builder(
69+
exporter,
70+
runtime::Tokio,
71+
)
72+
.build();
73+
// TODO: This does not work today. See https://github.com/open-telemetry/opentelemetry-rust/issues/2400
74+
#[cfg(not(feature = "experimental_metrics_periodicreader_with_async_runtime"))]
75+
let reader = opentelemetry_sdk::metrics::PeriodicReader::builder(exporter).build();
76+
6677
Ok(SdkMeterProvider::builder()
67-
.with_reader(PeriodicReader::builder(exporter, runtime::Tokio).build())
78+
.with_reader(reader)
6879
.with_resource(RESOURCE.clone())
6980
.build())
7081
}

opentelemetry-otlp/examples/basic-otlp/src/main.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ fn init_traces() -> Result<sdktrace::TracerProvider, TraceError> {
3434

3535
fn init_metrics() -> Result<opentelemetry_sdk::metrics::SdkMeterProvider, MetricError> {
3636
let exporter = MetricExporter::builder().with_tonic().build()?;
37-
38-
let reader = PeriodicReader::builder(exporter, runtime::Tokio).build();
37+
let reader = PeriodicReader::builder(exporter).build();
3938

4039
Ok(SdkMeterProvider::builder()
4140
.with_reader(reader)

opentelemetry-otlp/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@
179179
//! .build()
180180
//! .unwrap();
181181
//!
182-
//! let reader = opentelemetry_sdk::metrics::PeriodicReader::builder(exporter, opentelemetry_sdk::runtime::Tokio)
182+
//! let reader = opentelemetry_sdk::metrics::PeriodicReader::builder(exporter)
183183
//! .with_interval(std::time::Duration::from_secs(3))
184184
//! .with_timeout(Duration::from_secs(10))
185185
//! .build();

opentelemetry-sdk/CHANGELOG.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,52 @@
2828
Migration Guidance:
2929
- These methods were intended for log appenders. Keep the clone of the provider handle, instead of depending on above methods.
3030

31+
- *Breaking* - `PeriodicReader` Updates
32+
33+
`PeriodicReader` no longer requires an async runtime by default. Instead, it
34+
now creates its own background thread for execution. This change allows
35+
metrics to be used in environments without async runtimes.
36+
37+
For users who prefer the previous behavior of relying on a specific
38+
`Runtime`, they can do so by enabling the feature flag
39+
**`experimental_metrics_periodicreader_with_async_runtime`**.
40+
41+
Migration Guide:
42+
43+
1. *Default Implementation, requires no async runtime* (**Recommended**) The
44+
new default implementation does not require a runtime argument. Replace the
45+
builder method accordingly:
46+
- *Before:*
47+
```rust
48+
let reader = opentelemetry_sdk::metrics::PeriodicReader::builder(exporter, runtime::Tokio).build();
49+
```
50+
- *After:*
51+
```rust
52+
let reader = opentelemetry_sdk::metrics::PeriodicReader::builder(exporter).build();
53+
```
54+
55+
2. *Async Runtime Support*
56+
If your application cannot spin up new threads or you prefer using async
57+
runtimes, enable the
58+
"experimental_metrics_periodicreader_with_async_runtime" feature flag and
59+
adjust code as below.
60+
61+
- *Before:*
62+
```rust
63+
let reader = opentelemetry_sdk::metrics::PeriodicReader::builder(exporter, runtime::Tokio).build();
64+
```
65+
66+
- *After:*
67+
```rust
68+
let reader = opentelemetry_sdk::metrics::periodic_reader_with_async_runtime::PeriodicReader::builder(exporter, runtime::Tokio).build();
69+
```
70+
71+
*Requirements:*
72+
- Enable the feature flag:
73+
`experimental_metrics_periodicreader_with_async_runtime`.
74+
- Continue enabling one of the async runtime feature flags: `rt-tokio`,
75+
`rt-tokio-current-thread`, or `rt-async-std`.
76+
3177
## 0.27.1
3278

3379
Released 2024-Nov-27

opentelemetry-sdk/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ rt-tokio-current-thread = ["tokio", "tokio-stream"]
5454
rt-async-std = ["async-std"]
5555
internal-logs = ["tracing"]
5656
experimental_metrics_periodic_reader_no_runtime = ["metrics"]
57+
experimental_metrics_periodicreader_with_async_runtime = ["metrics"]
5758
spec_unstable_metrics_views = ["metrics"]
5859

5960
[[bench]]

opentelemetry-sdk/src/metrics/mod.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ pub(crate) mod meter;
5050
mod meter_provider;
5151
pub(crate) mod noop;
5252
pub(crate) mod periodic_reader;
53-
#[cfg(feature = "experimental_metrics_periodic_reader_no_runtime")]
54-
pub(crate) mod periodic_reader_with_own_thread;
53+
#[cfg(feature = "experimental_metrics_periodicreader_with_async_runtime")]
54+
/// Module for periodic reader with async runtime.
55+
pub mod periodic_reader_with_async_runtime;
5556
pub(crate) mod pipeline;
5657
pub mod reader;
5758
pub(crate) mod view;
@@ -61,8 +62,6 @@ pub use error::{MetricError, MetricResult};
6162
pub use manual_reader::*;
6263
pub use meter_provider::*;
6364
pub use periodic_reader::*;
64-
#[cfg(feature = "experimental_metrics_periodic_reader_no_runtime")]
65-
pub use periodic_reader_with_own_thread::*;
6665
pub use pipeline::Pipeline;
6766

6867
pub use instrument::InstrumentKind;
@@ -107,8 +106,8 @@ mod tests {
107106
use self::data::{HistogramDataPoint, ScopeMetrics, SumDataPoint};
108107
use super::*;
109108
use crate::metrics::data::ResourceMetrics;
109+
use crate::testing::metrics::InMemoryMetricExporter;
110110
use crate::testing::metrics::InMemoryMetricExporterBuilder;
111-
use crate::{runtime, testing::metrics::InMemoryMetricExporter};
112111
use data::GaugeDataPoint;
113112
use opentelemetry::metrics::{Counter, Meter, UpDownCounter};
114113
use opentelemetry::InstrumentationScope;
@@ -513,7 +512,7 @@ mod tests {
513512
}
514513

515514
let exporter = InMemoryMetricExporter::default();
516-
let reader = PeriodicReader::builder(exporter.clone(), runtime::Tokio).build();
515+
let reader = PeriodicReader::builder(exporter.clone()).build();
517516
let meter_provider = SdkMeterProvider::builder().with_reader(reader).build();
518517

519518
// Test Meter creation in 2 ways, both with empty string as meter name
@@ -529,7 +528,7 @@ mod tests {
529528
async fn counter_duplicate_instrument_merge() {
530529
// Arrange
531530
let exporter = InMemoryMetricExporter::default();
532-
let reader = PeriodicReader::builder(exporter.clone(), runtime::Tokio).build();
531+
let reader = PeriodicReader::builder(exporter.clone()).build();
533532
let meter_provider = SdkMeterProvider::builder().with_reader(reader).build();
534533

535534
// Act
@@ -580,7 +579,7 @@ mod tests {
580579
async fn counter_duplicate_instrument_different_meter_no_merge() {
581580
// Arrange
582581
let exporter = InMemoryMetricExporter::default();
583-
let reader = PeriodicReader::builder(exporter.clone(), runtime::Tokio).build();
582+
let reader = PeriodicReader::builder(exporter.clone()).build();
584583
let meter_provider = SdkMeterProvider::builder().with_reader(reader).build();
585584

586585
// Act
@@ -669,7 +668,7 @@ mod tests {
669668
async fn instrumentation_scope_identity_test() {
670669
// Arrange
671670
let exporter = InMemoryMetricExporter::default();
672-
let reader = PeriodicReader::builder(exporter.clone(), runtime::Tokio).build();
671+
let reader = PeriodicReader::builder(exporter.clone()).build();
673672
let meter_provider = SdkMeterProvider::builder().with_reader(reader).build();
674673

675674
// Act
@@ -753,7 +752,7 @@ mod tests {
753752

754753
// Arrange
755754
let exporter = InMemoryMetricExporter::default();
756-
let reader = PeriodicReader::builder(exporter.clone(), runtime::Tokio).build();
755+
let reader = PeriodicReader::builder(exporter.clone()).build();
757756
let criteria = Instrument::new().name("test_histogram");
758757
let stream_invalid_aggregation = Stream::new()
759758
.aggregation(Aggregation::ExplicitBucketHistogram {
@@ -803,7 +802,7 @@ mod tests {
803802

804803
// Arrange
805804
let exporter = InMemoryMetricExporter::default();
806-
let reader = PeriodicReader::builder(exporter.clone(), runtime::Tokio).build();
805+
let reader = PeriodicReader::builder(exporter.clone()).build();
807806
let criteria = Instrument::new().name("my_observable_counter");
808807
// View drops all attributes.
809808
let stream_invalid_aggregation = Stream::new().allowed_attribute_keys(vec![]);
@@ -878,7 +877,7 @@ mod tests {
878877

879878
// Arrange
880879
let exporter = InMemoryMetricExporter::default();
881-
let reader = PeriodicReader::builder(exporter.clone(), runtime::Tokio).build();
880+
let reader = PeriodicReader::builder(exporter.clone()).build();
882881
let criteria = Instrument::new().name("my_counter");
883882
// View drops all attributes.
884883
let stream_invalid_aggregation = Stream::new().allowed_attribute_keys(vec![]);
@@ -2433,7 +2432,7 @@ mod tests {
24332432
let exporter = InMemoryMetricExporterBuilder::new().with_temporality(temporality);
24342433

24352434
let exporter = exporter.build();
2436-
let reader = PeriodicReader::builder(exporter.clone(), runtime::Tokio).build();
2435+
let reader = PeriodicReader::builder(exporter.clone()).build();
24372436
let meter_provider = SdkMeterProvider::builder().with_reader(reader).build();
24382437

24392438
TestContext {

0 commit comments

Comments
 (0)