diff --git a/Cargo.lock b/Cargo.lock index 722d1ce6e..66e62e1f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -710,6 +710,7 @@ version = "0.1.0" dependencies = [ "flume", "libc", + "log", "serde", "serde_json", ] diff --git a/event_monitor/Cargo.toml b/event_monitor/Cargo.toml index 41d310280..18ac2567c 100644 --- a/event_monitor/Cargo.toml +++ b/event_monitor/Cargo.toml @@ -7,6 +7,7 @@ version = "0.1.0" [dependencies] flume = { workspace = true } libc = { workspace = true } +log = { workspace = true } serde = { workspace = true, features = ["derive", "rc"] } serde_json = { workspace = true } diff --git a/event_monitor/src/lib.rs b/event_monitor/src/lib.rs index 27b7f7b90..c7d634134 100644 --- a/event_monitor/src/lib.rs +++ b/event_monitor/src/lib.rs @@ -6,11 +6,12 @@ use std::borrow::Cow; use std::collections::HashMap; use std::fs::File; -use std::io; use std::os::unix::io::AsRawFd; use std::sync::{Arc, OnceLock}; use std::time::{Duration, Instant}; +use std::{fmt, io}; +use log::info; use serde::Serialize; static MONITOR: OnceLock = OnceLock::new(); @@ -88,12 +89,31 @@ pub fn set_monitor(file: Option) -> io::Result { Ok(monitor) } +struct PropertiesFormatter<'a>(&'a Option<&'a HashMap, Cow<'a, str>>>); +impl<'a> fmt::Display for PropertiesFormatter<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(map) = self.0 { + for (i, (key, value)) in map.iter().enumerate() { + if i > 0 { + write!(f, ", ")?; + } + write!(f, "{key} = {value}")?; + } + } + Ok(()) + } +} + pub fn event_log(source: &str, event: &str, properties: Option<&HashMap, Cow>>) { // `MONITOR` is always in a valid state (None or Some), because it is set // only once before any threads are spawned, and it's not mutated // afterwards. This function only creates immutable references to `MONITOR`. // Because `MONITOR.tx` is `Sync`, it's safe to share `MONITOR` across // threads, making this function thread-safe. + info!( + "Event: source = {source} event = {event} {}", + PropertiesFormatter(&properties) + ); if let Some(monitor_handle) = MONITOR.get().as_ref() { let event = Event { timestamp: monitor_handle.start.elapsed(),