From 61bb08aabf078e256aa3b8eee53604b9b3c905c0 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Sun, 16 Jun 2024 13:40:00 +0200 Subject: [PATCH] metrics/log_encoder: Log metrics in JSON format too This format can be parsed by Datadog to recreate our Grafana graphs in that system too. --- src/metrics/log_encoder.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/metrics/log_encoder.rs b/src/metrics/log_encoder.rs index f2103a21a49..395aeb9fe5f 100644 --- a/src/metrics/log_encoder.rs +++ b/src/metrics/log_encoder.rs @@ -6,6 +6,7 @@ use serde::ser::SerializeSeq; use serde::{Serialize, Serializer as _}; use serde_json::Serializer; use std::cell::Cell; +use std::collections::HashMap; use std::io::Write; use std::rc::Rc; @@ -43,6 +44,22 @@ impl Encoder for LogEncoder { fn encode(&self, families: &[MetricFamily], dest: &mut W) -> prometheus::Result<()> { let events = families_to_json_events(families); + let metrics = events + .iter() + .map(|event| { + let value = MapMetric { + data: event.metric.data.clone(), + tags: event.metric.tags.clone(), + }; + (event.metric.name, value) + }) + .collect::>(); + + match serde_json::to_string(&metrics) { + Ok(json) => info!(target: "metrics", "{{\"metrics\":{json}}}"), + Err(error) => warn!(target: "metrics", "Failed to serialize metrics: {error}"), + } + let chunks = serialize_and_split_list(events.iter(), CHUNKS_MAX_SIZE_BYTES) .map_err(|e| Error::Msg(e.to_string()))?; @@ -180,6 +197,13 @@ impl Write for TrackedWriter { } } +#[derive(Serialize, Debug, PartialEq)] +struct MapMetric<'a> { + #[serde(flatten)] + data: VectorMetricData, + tags: IndexMap<&'a str, &'a str>, +} + #[derive(Serialize, Debug, PartialEq)] struct VectorEvent<'a> { metric: VectorMetric<'a>, @@ -194,7 +218,7 @@ struct VectorMetric<'a> { tags: IndexMap<&'a str, &'a str>, } -#[derive(Serialize, Debug, PartialEq)] +#[derive(Serialize, Clone, Debug, PartialEq)] #[serde(rename_all = "snake_case")] enum VectorMetricData { AggregatedHistogram {