From ebad233be09a7be44095023d7c0721daf2078662 Mon Sep 17 00:00:00 2001 From: J2ghz Date: Sat, 13 Jun 2020 20:24:12 +0200 Subject: [PATCH] Add timestamp option to render_sample --- examples/folder_size.rs | 4 ++-- examples/simple.rs | 27 ++++++++++++-------------- src/render_to_prometheus.rs | 38 ++++++++++++++++++++++++++----------- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/examples/folder_size.rs b/examples/folder_size.rs index 04f2c6a..fdcc76f 100644 --- a/examples/folder_size.rs +++ b/examples/folder_size.rs @@ -77,10 +77,10 @@ async fn main() { let mut attributes = Vec::new(); attributes.push(("folder", "/var/log/")); - s.push_str(&pc.render_sample(Some(&attributes), total_size_log)); + s.push_str(&pc.render_sample(Some(&attributes), total_size_log, None)); attributes[0].1 = "/tmp"; - s.push_str(&pc.render_sample(Some(&attributes), total_size_tmp)); + s.push_str(&pc.render_sample(Some(&attributes), total_size_tmp, None)); Ok(s) } diff --git a/examples/simple.rs b/examples/simple.rs index 79a0e48..c71468d 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -21,25 +21,22 @@ async fn main() { let addr = ([0, 0, 0, 0], 32221).into(); println!("starting exporter on {}", addr); - render_prometheus(addr, MyOptions::default(), |request, options| { - async move { - println!( - "in our render_prometheus(request == {:?}, options == {:?})", - request, options - ); + render_prometheus(addr, MyOptions::default(), |request, options| async move { + println!( + "in our render_prometheus(request == {:?}, options == {:?})", + request, options + ); - let total_size_log = calculate_file_size("/var/log").unwrap(); + let total_size_log = calculate_file_size("/var/log").unwrap(); - let pc = - PrometheusMetric::new("folder_size", MetricType::Counter, "Size of the folder"); - let mut s = pc.render_header(); + let pc = PrometheusMetric::new("folder_size", MetricType::Counter, "Size of the folder"); + let mut s = pc.render_header(); - let mut attributes = Vec::new(); - attributes.push(("folder", "/var/log/")); - s.push_str(&pc.render_sample(Some(&attributes), total_size_log)); + let mut attributes = Vec::new(); + attributes.push(("folder", "/var/log/")); + s.push_str(&pc.render_sample(Some(&attributes), total_size_log, None)); - Ok(s) - } + Ok(s) }) .await; } diff --git a/src/render_to_prometheus.rs b/src/render_to_prometheus.rs index dc690f2..d168a17 100644 --- a/src/render_to_prometheus.rs +++ b/src/render_to_prometheus.rs @@ -39,6 +39,7 @@ impl<'a> PrometheusMetric<'a> { /// * `labels` - A slice of pairs indicating Label-Value. It is optional. /// * `value` - A number that will be appended as counter value. Remember, all /// values in Prometheus are float but you can pass any num::Num values here. + /// * `timestamp` - An int64 number representing milliseconds since epoch, i.e. 1970-01-01 00:00:00 UTC, excluding leap seconds. /// /// # Example /// @@ -49,21 +50,26 @@ impl<'a> PrometheusMetric<'a> { /// let mut labels = Vec::new(); /// labels.push(("folder", "/var/log/")); - /// s.push_str(&pc.render_sample(Some(&labels), 1024)); + /// s.push_str(&pc.render_sample(Some(&labels), 1024, None)); /// labels[0].1 = "/tmp"; - /// s.push_str(&pc.render_sample(Some(&labels), 5_000_000)); + /// s.push_str(&pc.render_sample(Some(&labels), 5_000_000, Some(1592070947954))); /// ``` - pub fn render_sample(&self, labels: Option<&[(&'a str, &'a str)]>, value: N) -> String + pub fn render_sample( + &self, + labels: Option<&[(&'a str, &'a str)]>, + value: N, + timestamp: Option, + ) -> String where N: Num + std::fmt::Display, { + let mut s = format!("{}", self.counter_name); if let Some(labels) = labels { if labels.is_empty() { - format!("{} {}\n", self.counter_name, value.to_string()) + s.push_str(&format!(" {}", value.to_string())); } else { - let mut s = format!("{}{{", self.counter_name); - + s.push_str("{"); let mut first = true; for (key, val) in labels.iter() { if !first { @@ -75,12 +81,18 @@ impl<'a> PrometheusMetric<'a> { s.push_str(&format!("{}=\"{}\"", key, val)); } - s.push_str(&format!("}} {}\n", value.to_string())); - s + s.push_str(&format!("}} {}", value.to_string())); } } else { - format!("{} {}\n", self.counter_name, value.to_string()) + s.push_str(" "); + s.push_str(&value.to_string()); + } + if let Some(timestamp) = timestamp { + s.push_str(" "); + s.push_str(×tamp.to_string()); } + s.push_str("\n"); + s } } @@ -115,7 +127,7 @@ mod tests { let number_string = number.to_string(); labels.push(("instance", &number_string)); - let ret = pc.render_sample(Some(&labels), number); + let ret = pc.render_sample(Some(&labels), number, None); assert_eq!( ret, @@ -132,8 +144,12 @@ mod tests { fn test_no_labels() { let pc = PrometheusMetric::new("gigino_total", MetricType::Counter, "Number of giginos"); assert_eq!( - pc.render_sample(None, 100), + pc.render_sample(None, 100, None), format!("gigino_total {}\n", 100) ); + assert_eq!( + pc.render_sample(None, 100, Some(9223372036854775807)), + format!("gigino_total 100 9223372036854775807\n") + ); } }