From 2f0b0ab3708fd587e22d8144fc316e8b927ed7ef Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Skutnik Date: Tue, 12 Aug 2025 11:10:21 +0200 Subject: [PATCH] Avoid encoding descriptor of empty family Signed-off-by: Jean-Baptiste Skutnik --- src/encoding.rs | 11 +++++++++++ src/metrics/family.rs | 4 ++++ src/registry.rs | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/encoding.rs b/src/encoding.rs index 6a131cdd..b9328b11 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -49,6 +49,17 @@ pub trait EncodeMetric { // One can not use [`TypedMetric`] directly, as associated constants are not // object safe and thus can not be used with dynamic dispatching. fn metric_type(&self) -> MetricType; + + /// Check if the metric is empty. + /// + /// An empty metric is a metric that has no data to encode, and thus should not have any + /// descriptor in the final output. + /// + /// By default, this returns `false`, ensuring the metric and its description is always + /// encoded. + fn is_empty(&self) -> bool { + false + } } impl EncodeMetric for Box { diff --git a/src/metrics/family.rs b/src/metrics/family.rs index 1d0da87e..16c923fe 100644 --- a/src/metrics/family.rs +++ b/src/metrics/family.rs @@ -377,6 +377,10 @@ where fn metric_type(&self) -> MetricType { M::TYPE } + + fn is_empty(&self) -> bool { + self.metrics.read().is_empty() + } } #[cfg(test)] diff --git a/src/registry.rs b/src/registry.rs index c7dec3ba..c4478ef5 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -287,7 +287,7 @@ impl Registry { } pub(crate) fn encode(&self, encoder: &mut DescriptorEncoder) -> Result<(), std::fmt::Error> { - for (descriptor, metric) in self.metrics.iter() { + for (descriptor, metric) in self.metrics.iter().filter(|(_, m)| !m.is_empty()) { let mut descriptor_encoder = encoder.with_prefix_and_labels(self.prefix.as_ref(), &self.labels); let metric_encoder = descriptor_encoder.encode_descriptor(