Skip to content

Commit dc2cba3

Browse files
committed
Add encoding for Summary metric
Signed-off-by: Palash Nigam <[email protected]>
1 parent c08728c commit dc2cba3

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed

src/encoding/text.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use crate::metrics::exemplar::{CounterWithExemplar, Exemplar, HistogramWithExemp
2929
use crate::metrics::family::{Family, MetricConstructor};
3030
use crate::metrics::gauge::{self, Gauge};
3131
use crate::metrics::histogram::Histogram;
32+
use crate::metrics::summary::Summary;
3233
use crate::metrics::info::Info;
3334
use crate::metrics::{MetricType, TypedMetric};
3435
use crate::registry::{Registry, Unit};
@@ -332,6 +333,23 @@ impl<'a> BucketEncoder<'a> {
332333
})
333334
}
334335

336+
/// Encode a quantile. Used for the [`Summary`] metric type.
337+
pub fn encode_quantile(&mut self, quantile: f64) -> Result<ValueEncoder, std::io::Error> {
338+
if self.opened_curly_brackets {
339+
self.writer.write_all(b",")?;
340+
} else {
341+
self.writer.write_all(b"{")?;
342+
}
343+
344+
self.writer.write_all(b"quantile=\"")?;
345+
quantile.encode(self.writer)?;
346+
self.writer.write_all(b"\"}")?;
347+
348+
Ok(ValueEncoder {
349+
writer: self.writer,
350+
})
351+
}
352+
335353
/// Signal that the metric type has no bucket.
336354
pub fn no_bucket(&mut self) -> Result<ValueEncoder, std::io::Error> {
337355
if self.opened_curly_brackets {
@@ -581,6 +599,40 @@ fn encode_histogram_with_maybe_exemplars<S: Encode>(
581599
Ok(())
582600
}
583601

602+
/////////////////////////////////////////////////////////////////////////////////
603+
// Summary
604+
605+
impl EncodeMetric for Summary {
606+
fn encode(&self, mut encoder: Encoder) -> Result<(), std::io::Error> {
607+
let (sum, count, quantiles) = self.get();
608+
609+
encoder
610+
.encode_suffix("sum")?
611+
.no_bucket()?
612+
.encode_value(sum)?
613+
.no_exemplar()?;
614+
encoder
615+
.encode_suffix("count")?
616+
.no_bucket()?
617+
.encode_value(count)?
618+
.no_exemplar()?;
619+
620+
for (_, (quantile, result)) in quantiles.iter().enumerate() {
621+
let mut bucket_encoder = encoder.no_suffix()?;
622+
let mut value_encoder = bucket_encoder.encode_quantile(*quantile)?;
623+
let mut exemplar_encoder = value_encoder.encode_value(*result)?;
624+
exemplar_encoder.no_exemplar()?
625+
}
626+
627+
Result::Ok(())
628+
}
629+
630+
fn metric_type(&self) -> MetricType {
631+
Self::TYPE
632+
}
633+
}
634+
635+
584636
/////////////////////////////////////////////////////////////////////////////////
585637
// Info
586638

@@ -821,6 +873,30 @@ mod tests {
821873
parse_with_python_client(String::from_utf8(encoded).unwrap());
822874
}
823875

876+
#[test]
877+
fn encode_summary() {
878+
let mut registry = Registry::default();
879+
let summary = Summary::new(3, 10, vec![0.5, 0.9, 0.99], 0.0);
880+
registry.register("my_summary", "My summary", summary.clone());
881+
summary.observe(0.10);
882+
summary.observe(0.20);
883+
summary.observe(0.30);
884+
885+
let mut encoded = Vec::new();
886+
887+
encode(&mut encoded, &registry).unwrap();
888+
889+
let expected = "# HELP my_summary My summary.\n".to_owned()
890+
+ "# TYPE my_summary summary\n"
891+
+ "my_summary_sum 0.6000000000000001\n"
892+
+ "my_summary_count 3\n"
893+
+ "my_summary{quantile=\"0.5\"} 0.2\n"
894+
+ "my_summary{quantile=\"0.9\"} 0.3\n"
895+
+ "my_summary{quantile=\"0.99\"} 0.3\n"
896+
+ "# EOF\n";
897+
assert_eq!(expected, String::from_utf8(encoded.clone()).unwrap());
898+
}
899+
824900
fn parse_with_python_client(input: String) {
825901
pyo3::prepare_freethreaded_python();
826902

src/metrics/summary.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl Summary {
6060
}
6161
}
6262

63-
pub fn observe(&mut self, v: f64) {
63+
pub fn observe(&self, v: f64) {
6464
let mut inner = self.inner.lock().unwrap();
6565
inner.sum += v;
6666
inner.count += 1;
@@ -101,7 +101,7 @@ mod tests {
101101

102102
#[test]
103103
fn basic() {
104-
let mut summary = Summary::new(5, 10, vec![0.5, 0.9, 0.99], 0.01);
104+
let summary = Summary::new(5, 10, vec![0.5, 0.9, 0.99], 0.01);
105105
summary.observe(5.0);
106106
summary.observe(15.0);
107107
summary.observe(25.0);

0 commit comments

Comments
 (0)