From 720ca4ad01ad5f83ea85fd1510d5a9271d935480 Mon Sep 17 00:00:00 2001 From: Diego Ongaro Date: Fri, 14 Nov 2025 16:50:13 -0800 Subject: [PATCH 1/4] feat: Add `#[must_use]` to AsyncInstrumentBuilder This prevents code like the following from compiling: ```rust meter .i64_observable_up_down_counter("my_counter") .with_callback(|observer| { observer.observe(1, &[]); }); ``` This code is missing the `.build()` at the end. Before this commit, it would compile, but the callback would never be called. After this commit, it will cause a mostly helpful compile error: ``` warning: unused `AsyncInstrumentBuilder` that must be used --> examples/metrics-basic/src/main.rs:71:5 | 71 | / meter 72 | | .i64_observable_up_down_counter("my_counter") 73 | | .with_callback(|observer| { 74 | | observer.observe(1, &[]); 75 | | }); | |__________^ | = note: AsyncInstrumentBuilder must be built to receive callbacks. = note: `#[warn(unused_must_use)]` on by default help: use `let _ = ...` to ignore the resulting value | 71 | let _ = meter | +++++++ ``` Most builders need to be built to be useful. Normal metrics are built and then observations are reported to them, where a failure to call `build()` would be discovered at compile-time. However, observable metrics (async instruments) don't have that natural use point, as the result of building an `AsyncInstrumentBuilder` isn't typically needed. This makes `AsyncInstrumentBuilder` especially error-prone without the `#[must_use]` declaration. --- opentelemetry/src/metrics/instruments/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/opentelemetry/src/metrics/instruments/mod.rs b/opentelemetry/src/metrics/instruments/mod.rs index 48d238ef5b..47873c5f80 100644 --- a/opentelemetry/src/metrics/instruments/mod.rs +++ b/opentelemetry/src/metrics/instruments/mod.rs @@ -241,6 +241,7 @@ impl fmt::Debug for HistogramBuilder<'_, T> { pub type Callback = Box) + Send + Sync>; /// Configuration for building an async instrument. +#[must_use = "AsyncInstrumentBuilder must be built to receive callbacks."] #[non_exhaustive] // We expect to add more configuration fields in the future pub struct AsyncInstrumentBuilder<'a, I, M> { /// Instrument provider is used to create the instrument. From 38bc6984c1a680863c318342af15335230d0b4c5 Mon Sep 17 00:00:00 2001 From: Diego Ongaro Date: Mon, 17 Nov 2025 10:59:33 -0800 Subject: [PATCH 2/4] Add CHANGELOG entry --- opentelemetry/CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/opentelemetry/CHANGELOG.md b/opentelemetry/CHANGELOG.md index 94d93c8dac..4b8ccc0194 100644 --- a/opentelemetry/CHANGELOG.md +++ b/opentelemetry/CHANGELOG.md @@ -6,6 +6,7 @@ - **Breaking** Removed the following public fields and methods from the `SpanBuilder` [#3227][3227]: - `trace_id`, `span_id`, `end_time`, `status`, `sampling_result` - `with_trace_id`, `with_span_id`, `with_end_time`, `with_status`, `with_sampling_result` +- **Breaking** Added `#[must_use]` to `opentelemetry::metrics::AsyncInstrumentBuilder`, since unbuilt async instruments will not have their callbacks called. This may cause compile errors for buggy or suspicious code. [3227]: https://github.com/open-telemetry/opentelemetry-rust/pull/3227 @@ -117,10 +118,10 @@ let counter = meter.u64_counter("my_counter").build(); - Replaced `global::meter_with_version` with `global::meter_with_scope` - Added `global::tracer_with_scope` - Refer to PR description for migration guide. -- **Breaking change**: replaced `InstrumentationScope` public attributes by getters [#2275](https://github.com/open-telemetry/opentelemetry-rust/pull/2275) +- **Breaking change**: replaced `InstrumentationScope` public attributes by getters [#2275](https://github.com/open-telemetry/opentelemetry-rust/pull/2275) - **Breaking change**: [#2260](https://github.com/open-telemetry/opentelemetry-rust/pull/2260) - - Removed `global::set_error_handler` and `global::handle_error`. + - Removed `global::set_error_handler` and `global::handle_error`. - `global::handle_error` usage inside the opentelemetry crates has been replaced with `global::otel_info`, `otel_warn`, `otel_debug` and `otel_error` macros based on the severity of the internal logs. - The default behavior of `global::handle_error` was to log the error using `eprintln!`. With otel macros, the internal logs get emitted via `tracing` macros of matching severity. Users now need to configure a `tracing` layer/subscriber to capture these logs. - Refer to PR description for migration guide. Also refer to [self-diagnostics](https://github.com/open-telemetry/opentelemetry-rust/tree/main/examples/self-diagnostics) example to learn how to view internal logs in stdout using `tracing::fmt` layer. @@ -220,7 +221,7 @@ to learn how to provide Observable callbacks. opaque string. Migration: Replace `.with_unit(Unit::new("myunit"))` with `.with_unit("myunit")`. -- [1869](https://github.com/open-telemetry/opentelemetry-rust/pull/1869) Introduced the `LogRecord::set_target()` method in the log bridge API. +- [1869](https://github.com/open-telemetry/opentelemetry-rust/pull/1869) Introduced the `LogRecord::set_target()` method in the log bridge API. This method allows appenders to set the target/component emitting the logs. ## v0.23.0 @@ -241,7 +242,7 @@ This method allows appenders to set the target/component emitting the logs. - opentelemetry::global::shutdown_logger_provider - opentelemetry::global::logger_provider - opentelemetry::global::GlobalLoggerProvider - - opentelemetry::global::ObjectSafeLoggerProvider + - opentelemetry::global::ObjectSafeLoggerProvider For creating appenders using Logging bridge API, refer to the opentelemetry-tracing-appender [example](https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-appender-tracing/examples/basic.rs) ### Changed From 9163031a9b68ca2ac39361e1f5dc6e5c4faabb70 Mon Sep 17 00:00:00 2001 From: ongardie-atomix Date: Mon, 17 Nov 2025 12:12:02 -0800 Subject: [PATCH 3/4] Update `must_use` message from suggestion Co-authored-by: Cijo Thomas --- opentelemetry/src/metrics/instruments/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry/src/metrics/instruments/mod.rs b/opentelemetry/src/metrics/instruments/mod.rs index 47873c5f80..dc5a5ff0bb 100644 --- a/opentelemetry/src/metrics/instruments/mod.rs +++ b/opentelemetry/src/metrics/instruments/mod.rs @@ -241,7 +241,7 @@ impl fmt::Debug for HistogramBuilder<'_, T> { pub type Callback = Box) + Send + Sync>; /// Configuration for building an async instrument. -#[must_use = "AsyncInstrumentBuilder must be built to receive callbacks."] +#[must_use = "Callbacks will not be invoked unless you call .build() on this async instrument builder."] #[non_exhaustive] // We expect to add more configuration fields in the future pub struct AsyncInstrumentBuilder<'a, I, M> { /// Instrument provider is used to create the instrument. From f5a2c8b36c2df9cbd0d7bce85a5da1c2b62212d6 Mon Sep 17 00:00:00 2001 From: Diego Ongaro Date: Mon, 17 Nov 2025 12:10:18 -0800 Subject: [PATCH 4/4] Update CHANGELOG with suggestion from cijothomas --- opentelemetry/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry/CHANGELOG.md b/opentelemetry/CHANGELOG.md index 4b8ccc0194..a3686a9169 100644 --- a/opentelemetry/CHANGELOG.md +++ b/opentelemetry/CHANGELOG.md @@ -6,7 +6,7 @@ - **Breaking** Removed the following public fields and methods from the `SpanBuilder` [#3227][3227]: - `trace_id`, `span_id`, `end_time`, `status`, `sampling_result` - `with_trace_id`, `with_span_id`, `with_end_time`, `with_status`, `with_sampling_result` -- **Breaking** Added `#[must_use]` to `opentelemetry::metrics::AsyncInstrumentBuilder`, since unbuilt async instruments will not have their callbacks called. This may cause compile errors for buggy or suspicious code. +- **Added** `#[must_use]` attribute to `opentelemetry::metrics::AsyncInstrumentBuilder` to add compile time warning when `.build()` is not called on observable instrument builders, preventing silent failures where callbacks are never registered and metrics are never reported. [3227]: https://github.com/open-telemetry/opentelemetry-rust/pull/3227