From ac60da5f554c2f8b57beb4e87e417504c8924788 Mon Sep 17 00:00:00 2001 From: Riccardo Mancini Date: Fri, 11 Jul 2025 11:01:03 +0100 Subject: [PATCH] refactor(metrics): avoid temporary buffer when serializing metrics Metrics are currently written in a temporary buffer (String) before being written to the file. There is no need for this temporary buffer, as the metrics can be serialized directly into the writer. I found this as I saw Firecracker was allocating and freeing memory every minute, causing pages to be mmap/munmap-ed periodically (and unnecessarily). Signed-off-by: Riccardo Mancini --- src/vmm/src/logger/metrics.rs | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/src/vmm/src/logger/metrics.rs b/src/vmm/src/logger/metrics.rs index e793495e1f1..c4e0546e590 100644 --- a/src/vmm/src/logger/metrics.rs +++ b/src/vmm/src/logger/metrics.rs @@ -141,28 +141,11 @@ impl Metrics { /// known deadlock potential. pub fn write(&self) -> Result { if let Some(lock) = self.metrics_buf.get() { - match serde_json::to_string(&self.app_metrics) { - Ok(msg) => { - if let Ok(mut guard) = lock.lock() { - // No need to explicitly call flush because the underlying LineWriter - // flushes automatically whenever a newline is - // detected (and we always end with a newline the - // current write). - guard - .write_all(format!("{msg}\n",).as_bytes()) - .map_err(MetricsError::Write) - .map(|_| true) - } else { - // We have not incremented `missed_metrics_count` as there is no way to push - // metrics if destination lock got poisoned. - panic!( - "Failed to write to the provided metrics destination due to poisoned \ - lock" - ); - } - } - Err(err) => Err(MetricsError::Serde(err.to_string())), - } + let mut writer = lock.lock().expect("poisoned lock"); + serde_json::to_writer(writer.by_ref(), &self.app_metrics) + .map_err(|err| MetricsError::Serde(err.to_string()))?; + writer.write_all(b"\n").map_err(MetricsError::Write)?; + Ok(true) } else { // If the metrics are not initialized, no error is thrown but we do let the user know // that metrics were not written.