Open
Description
What happened?
I was experimenting with OpenTelemetry Counters and found out that it is possible to decrement the value of f64 counters. The bug can be reproduced with this code:
use std::thread;
use std::time::Duration;
use opentelemetry::metrics::MeterProvider;
use opentelemetry_sdk::metrics::SdkMeterProvider;
fn main() {
let exporter = opentelemetry_stdout::MetricExporterBuilder::default()
.build();
let meter_provider = SdkMeterProvider::builder()
.with_periodic_exporter(exporter)
.build();
let meter = meter_provider.meter("test_meter");
let counter = meter.f64_counter("test_counter").build();
let mut taskset = Vec::new();
taskset.push(thread::spawn(move || {
for i in 0..100 {
let value = if i % 2 == 0 {
i as f64
} else {
-i as f64
};
counter.add(value, &[]);
thread::sleep(Duration::from_secs(1));
}
}));
for t in taskset {
t.join().unwrap();
}
}
OpenTelemetry API Version (i.e version of opentelemetry
crate)
opentelemetry = { version = "0.30.0" , default-features = false, features = ["metrics"] }
OpenTelemetry SDK Version (i.e version of opentelemetry_sdk
crate)
opentelemetry_sdk = { version = "0.30.0", default-features = false, features = ["experimental_metrics_custom_reader", "metrics"] }
What Exporter(s) are you seeing the problem on?
stdout
Relevant log output
Metrics
Resource
-> service.name=String(Static("unknown_service"))
-> telemetry.sdk.version=String(Static("0.30.0"))
-> telemetry.sdk.name=String(Static("opentelemetry"))
-> telemetry.sdk.language=String(Static("rust"))
Instrumentation Scope #0
Name : test_meter
Metric #0
Name : test_counter
Description :
Unit :
Type : Sum
Sum DataPoints
Monotonic : true
Temporality : Cumulative
StartTime : 2025-06-24 08:28:07.849672
EndTime : 2025-06-24 08:28:08.849881
DataPoint #0
Value : 0.0
Attributes :
Metrics
Resource
-> service.name=String(Static("unknown_service"))
-> telemetry.sdk.version=String(Static("0.30.0"))
-> telemetry.sdk.name=String(Static("opentelemetry"))
-> telemetry.sdk.language=String(Static("rust"))
Instrumentation Scope #0
Name : test_meter
Metric #0
Name : test_counter
Description :
Unit :
Type : Sum
Sum DataPoints
Monotonic : true
Temporality : Cumulative
StartTime : 2025-06-24 08:28:07.849672
EndTime : 2025-06-24 08:28:09.850013
DataPoint #0
Value : -1.0
Attributes :
Metrics
Resource
-> service.name=String(Static("unknown_service"))
-> telemetry.sdk.version=String(Static("0.30.0"))
-> telemetry.sdk.name=String(Static("opentelemetry"))
-> telemetry.sdk.language=String(Static("rust"))
Instrumentation Scope #0
Name : test_meter
Metric #0
Name : test_counter
Description :
Unit :
Type : Sum
Sum DataPoints
Monotonic : true
Temporality : Cumulative
StartTime : 2025-06-24 08:28:07.849672
EndTime : 2025-06-24 08:28:10.850155
DataPoint #0
Value : 1.0
Attributes :