Skip to content

Commit e8c1c02

Browse files
authored
Fix metrics unused instruments (#407)
1 parent 2e32e41 commit e8c1c02

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

opentelemetry-prometheus/tests/integration_test.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,33 @@ use opentelemetry::{
66
use opentelemetry_prometheus::PrometheusExporter;
77
use prometheus::{Encoder, TextEncoder};
88

9+
#[test]
10+
fn free_unused_instruments() {
11+
let exporter = opentelemetry_prometheus::exporter()
12+
.with_default_histogram_boundaries(vec![-0.5, 1.0])
13+
.with_resource(Resource::new(vec![KeyValue::new("R", "V")]))
14+
.init();
15+
let mut expected = Vec::new();
16+
17+
{
18+
let meter = exporter.provider().unwrap().meter("test", None);
19+
let counter = meter.f64_counter("counter").init();
20+
21+
let labels = vec![KeyValue::new("A", "B"), KeyValue::new("C", "D")];
22+
23+
counter.add(10.0, &labels);
24+
counter.add(5.3, &labels);
25+
26+
expected.push(r#"counter{A="B",C="D",R="V"} 15.3"#);
27+
}
28+
// Standard export
29+
compare_export(&exporter, expected.clone());
30+
// Final export before instrument dropped
31+
compare_export(&exporter, expected.clone());
32+
// Instrument dropped, but last value kept by prom exporter
33+
compare_export(&exporter, expected);
34+
}
35+
936
#[test]
1037
fn test_add() {
1138
let exporter = opentelemetry_prometheus::exporter()

opentelemetry/src/sdk/metrics/mod.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,7 @@ impl AccumulatorCore {
178178
fn collect_sync_instruments(&self, locked_processor: &mut dyn LockedProcessor) -> usize {
179179
let mut checkpointed = 0;
180180

181-
for element in self.current.iter() {
182-
let (key, value) = element.pair();
181+
self.current.retain(|_key, value| {
183182
let mods = &value.update_count.load();
184183
let coll = &value.collected_count.load();
185184

@@ -192,17 +191,17 @@ impl AccumulatorCore {
192191
// Having no updates since last collection, try to remove if
193192
// there are no bound handles
194193
if Arc::strong_count(&value) == 1 {
195-
self.current.remove(key);
196-
197194
// There's a potential race between loading collected count and
198195
// loading the strong count in this function. Since this is the
199196
// last we'll see of this record, checkpoint.
200197
if mods.partial_cmp(&NumberKind::U64, coll) != Some(Ordering::Equal) {
201198
checkpointed += self.checkpoint_record(value, locked_processor);
202199
}
200+
return false;
203201
}
204-
}
205-
}
202+
};
203+
true
204+
});
206205

207206
checkpointed
208207
}

0 commit comments

Comments
 (0)