diff --git a/fact-ebpf/src/lib.rs b/fact-ebpf/src/lib.rs index f38fe801..8b66d92b 100644 --- a/fact-ebpf/src/lib.rs +++ b/fact-ebpf/src/lib.rs @@ -135,20 +135,28 @@ impl metrics_by_hook_t { } } -impl metrics_t { - pub fn accumulate(mut self, other: &metrics_t) -> metrics_t { - self.file_open = self.file_open.accumulate(&other.file_open); - self.path_unlink = self.path_unlink.accumulate(&other.path_unlink); - self.path_chmod = self.path_chmod.accumulate(&other.path_chmod); - self.path_chown = self.path_chown.accumulate(&other.path_chown); - self.path_rename = self.path_rename.accumulate(&other.path_rename); - self.path_mkdir = self.path_mkdir.accumulate(&other.path_mkdir); - self.path_rmdir = self.path_rmdir.accumulate(&other.path_rmdir); - self.d_instantiate = self.d_instantiate.accumulate(&other.d_instantiate); - self - } +macro_rules! impl_metrics_t { + ($($hook:ident),+ $(,)?) => { + impl metrics_t { + pub fn accumulate(mut self, other: &metrics_t) -> metrics_t { + $(self.$hook = self.$hook.accumulate(&other.$hook);)+ + self + } + } + }; } +impl_metrics_t!( + file_open, + path_unlink, + path_chmod, + path_chown, + path_rename, + path_mkdir, + path_rmdir, + d_instantiate, +); + unsafe impl Pod for metrics_t {} pub const EBPF_OBJ: &[u8] = aya::include_bytes_aligned!(concat!(env!("OUT_DIR"), "/main.o")); diff --git a/fact/src/metrics/kernel_metrics.rs b/fact/src/metrics/kernel_metrics.rs index 15da3993..9a01369f 100644 --- a/fact/src/metrics/kernel_metrics.rs +++ b/fact/src/metrics/kernel_metrics.rs @@ -7,132 +7,67 @@ use crate::metrics::MetricEvents; use super::{EventCounter, LabelValues}; -pub struct KernelMetrics { - file_open: EventCounter, - path_unlink: EventCounter, - path_chmod: EventCounter, - path_chown: EventCounter, - path_rename: EventCounter, - path_mkdir: EventCounter, - path_rmdir: EventCounter, - d_instantiate: EventCounter, - map: PerCpuArray, -} - -impl KernelMetrics { - pub fn new(reg: &mut Registry, kernel_metrics: PerCpuArray) -> Self { - let file_open = EventCounter::new( - "kernel_file_open_events", - "Events processed by the file_open LSM hook", - &[], // Labels are not needed since `collect` will add them all - ); - let path_unlink = EventCounter::new( - "kernel_path_unlink_events", - "Events processed by the path_unlink LSM hook", - &[], // Labels are not needed since `collect` will add them all - ); - let path_chmod = EventCounter::new( - "kernel_path_chmod_events", - "Events processed by the path_chmod LSM hook", - &[], // Labels are not needed since `collect` will add them all - ); - let path_chown = EventCounter::new( - "kernel_path_chown_events", - "Events processed by the path_chown LSM hook", - &[], // Labels are not needed since `collect` will add them all - ); - let path_rename = EventCounter::new( - "kernel_path_rename_events", - "Events processed by the path_rename LSM hook", - &[], // Labels are not needed since `collect` will add them all - ); - let path_mkdir = EventCounter::new( - "kernel_path_mkdir_events", - "Events processed by the path_mkdir LSM hook", - &[], // Labels are not needed since `collect` will add them all - ); - let path_rmdir = EventCounter::new( - "kernel_path_rmdir_events", - "Events processed by the path_rmdir LSM hook", - &[], // Labels are not needed since `collect` will add them all - ); - let d_instantiate = EventCounter::new( - "kernel_d_instantiate_events", - "Events processed by the d_instantiate LSM hook", - &[], // Labels are not needed since `collect` will add them all - ); - - file_open.register(reg); - path_unlink.register(reg); - path_chmod.register(reg); - path_chown.register(reg); - path_rename.register(reg); - path_mkdir.register(reg); - path_rmdir.register(reg); - d_instantiate.register(reg); - - KernelMetrics { - file_open, - path_unlink, - path_chmod, - path_chown, - path_rename, - path_mkdir, - path_rmdir, - d_instantiate, - map: kernel_metrics, +macro_rules! define_kernel_metrics { + ($($hook:ident),+ $(,)?) => { + pub struct KernelMetrics { + $($hook: EventCounter,)+ + map: PerCpuArray, } - } - fn refresh_labels(ec: &EventCounter, m: &metrics_by_hook_t) { - ec.counter.clear(); - ec.counter - .get_or_create(&MetricEvents { - label: LabelValues::Total, - }) - .inc_by(m.total); + impl KernelMetrics { + pub fn new(reg: &mut Registry, kernel_metrics: PerCpuArray) -> Self { + $( + let $hook = EventCounter::new( + concat!("kernel_", stringify!($hook), "_events"), + concat!("Events processed by the ", stringify!($hook), " LSM hook"), + &[], + ); + $hook.register(reg); + )+ - ec.counter - .get_or_create(&MetricEvents { - label: LabelValues::Added, - }) - .inc_by(m.added); + KernelMetrics { + $($hook,)+ + map: kernel_metrics, + } + } - ec.counter - .get_or_create(&MetricEvents { - label: LabelValues::Error, - }) - .inc_by(m.error); + pub fn collect(&self) -> anyhow::Result<()> { + let metrics = self + .map + .get(&0, 0)? + .iter() + .fold(metrics_t::default(), |acc, x| acc.accumulate(x)); - ec.counter - .get_or_create(&MetricEvents { - label: LabelValues::Ignored, - }) - .inc_by(m.ignored); + $(Self::refresh_labels(&self.$hook, &metrics.$hook);)+ - ec.counter - .get_or_create(&MetricEvents { - label: LabelValues::RingbufferFull, - }) - .inc_by(m.ringbuffer_full); - } + Ok(()) + } - pub fn collect(&self) -> anyhow::Result<()> { - let metrics = self - .map - .get(&0, 0)? - .iter() - .fold(metrics_t::default(), |acc, x| acc.accumulate(x)); - - KernelMetrics::refresh_labels(&self.file_open, &metrics.file_open); - KernelMetrics::refresh_labels(&self.path_unlink, &metrics.path_unlink); - KernelMetrics::refresh_labels(&self.path_chmod, &metrics.path_chmod); - KernelMetrics::refresh_labels(&self.path_chown, &metrics.path_chown); - KernelMetrics::refresh_labels(&self.path_rename, &metrics.path_rename); - KernelMetrics::refresh_labels(&self.path_mkdir, &metrics.path_mkdir); - KernelMetrics::refresh_labels(&self.path_rmdir, &metrics.path_rmdir); - KernelMetrics::refresh_labels(&self.d_instantiate, &metrics.d_instantiate); - - Ok(()) - } + fn refresh_labels(ec: &EventCounter, m: &metrics_by_hook_t) { + ec.counter.clear(); + for (label, value) in [ + (LabelValues::Total, m.total), + (LabelValues::Added, m.added), + (LabelValues::Error, m.error), + (LabelValues::Ignored, m.ignored), + (LabelValues::RingbufferFull, m.ringbuffer_full), + ] { + ec.counter + .get_or_create(&MetricEvents { label }) + .inc_by(value); + } + } + } + }; } + +define_kernel_metrics!( + file_open, + path_unlink, + path_chmod, + path_chown, + path_rename, + path_mkdir, + path_rmdir, + d_instantiate, +); diff --git a/fact/src/metrics/mod.rs b/fact/src/metrics/mod.rs index 9fce7719..98297329 100644 --- a/fact/src/metrics/mod.rs +++ b/fact/src/metrics/mod.rs @@ -57,70 +57,42 @@ impl EventCounter { } } - /// Register the counter in the given registry. - /// - /// # Arguments - /// - /// * `reg` - A prometheus Registry that the counter will be registered into. fn register(&self, reg: &mut Registry) { reg.register(self.name, self.help, self.counter.clone()); } - /// Increment the counter for the Added label. - /// - /// Panics if the counter did not add the Added label as part of its - /// creation step. - pub fn added(&self) { + fn inc_label(&self, label: LabelValues) { self.counter - .get(&MetricEvents { - label: LabelValues::Added, - }) - .unwrap() + .get(&MetricEvents { label }) + .expect("label not found") .inc(); } - /// Increment the counter for the Dropped label. - /// - /// Panics if the counter did not add the Dropped label as part of - /// its creation step. - pub fn dropped(&self) { + fn inc_label_by(&self, label: LabelValues, n: u64) { self.counter - .get(&MetricEvents { - label: LabelValues::Dropped, - }) - .unwrap() - .inc(); + .get(&MetricEvents { label }) + .expect("label not found") + .inc_by(n); + } + + pub fn added(&self) { + self.inc_label(LabelValues::Added); + } + + pub fn dropped(&self) { + self.inc_label(LabelValues::Dropped); } pub fn dropped_n(&self, n: u64) { - self.counter - .get(&MetricEvents { - label: LabelValues::Dropped, - }) - .unwrap() - .inc_by(n); + self.inc_label_by(LabelValues::Dropped, n); } - /// Increment the counter for the Ignored label. - /// - /// Panics if the counter did not add the Ignored label as part of - /// its creation step. pub fn ignored(&self) { - self.counter - .get(&MetricEvents { - label: LabelValues::Ignored, - }) - .expect("Ignored label not found") - .inc(); + self.inc_label(LabelValues::Ignored); } pub fn errored(&self) { - self.counter - .get(&MetricEvents { - label: LabelValues::Error, - }) - .expect("Error label not found") - .inc(); + self.inc_label(LabelValues::Error); } }