use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Default)]
pub struct SecurityMetrics {
headers_injected: AtomicU64,
ip_rejected: AtomicU64,
audit_logged: AtomicU64,
body_too_large: AtomicU64,
}
impl SecurityMetrics {
pub fn new() -> Self {
Self::default()
}
pub fn record_headers_injected(&self) {
self.headers_injected.fetch_add(1, Ordering::Relaxed);
}
pub fn headers_injected(&self) -> u64 {
self.headers_injected.load(Ordering::Relaxed)
}
pub fn record_ip_rejected(&self) {
self.ip_rejected.fetch_add(1, Ordering::Relaxed);
}
pub fn ip_rejected(&self) -> u64 {
self.ip_rejected.load(Ordering::Relaxed)
}
pub fn record_audit_logged(&self) {
self.audit_logged.fetch_add(1, Ordering::Relaxed);
}
pub fn audit_logged(&self) -> u64 {
self.audit_logged.load(Ordering::Relaxed)
}
pub fn record_body_too_large(&self) {
self.body_too_large.fetch_add(1, Ordering::Relaxed);
}
pub fn body_too_large(&self) -> u64 {
self.body_too_large.load(Ordering::Relaxed)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_metrics_count() {
let metrics = SecurityMetrics::new();
metrics.record_headers_injected();
metrics.record_headers_injected();
metrics.record_ip_rejected();
metrics.record_audit_logged();
metrics.record_audit_logged();
metrics.record_audit_logged();
metrics.record_body_too_large();
assert_eq!(metrics.headers_injected(), 2);
assert_eq!(metrics.ip_rejected(), 1);
assert_eq!(metrics.audit_logged(), 3);
assert_eq!(metrics.body_too_large(), 1);
}
#[test]
fn test_metrics_default_zero() {
let metrics = SecurityMetrics::new();
assert_eq!(metrics.headers_injected(), 0);
assert_eq!(metrics.ip_rejected(), 0);
assert_eq!(metrics.audit_logged(), 0);
assert_eq!(metrics.body_too_large(), 0);
}
}