use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct PatchMetrics {
loads_attempted: Arc<AtomicU64>,
loads_successful: Arc<AtomicU64>,
loads_failed: Arc<AtomicU64>,
rollbacks: Arc<AtomicU64>,
validation_failures: Arc<AtomicU64>,
}
impl Default for PatchMetrics {
fn default() -> Self {
Self::new()
}
}
impl PatchMetrics {
pub fn new() -> Self {
Self {
loads_attempted: Arc::new(AtomicU64::new(0)),
loads_successful: Arc::new(AtomicU64::new(0)),
loads_failed: Arc::new(AtomicU64::new(0)),
rollbacks: Arc::new(AtomicU64::new(0)),
validation_failures: Arc::new(AtomicU64::new(0)),
}
}
pub fn record_load_attempt(&self) {
self.loads_attempted.fetch_add(1, Ordering::Relaxed);
}
pub fn record_load_success(&self) {
self.loads_successful.fetch_add(1, Ordering::Relaxed);
}
pub fn record_load_failure(&self) {
self.loads_failed.fetch_add(1, Ordering::Relaxed);
}
pub fn record_rollback(&self) {
self.rollbacks.fetch_add(1, Ordering::Relaxed);
}
pub fn record_validation_failure(&self) {
self.validation_failures.fetch_add(1, Ordering::Relaxed);
}
pub fn loads_attempted(&self) -> u64 {
self.loads_attempted.load(Ordering::Relaxed)
}
pub fn loads_successful(&self) -> u64 {
self.loads_successful.load(Ordering::Relaxed)
}
pub fn loads_failed(&self) -> u64 {
self.loads_failed.load(Ordering::Relaxed)
}
pub fn rollbacks(&self) -> u64 {
self.rollbacks.load(Ordering::Relaxed)
}
pub fn validation_failures(&self) -> u64 {
self.validation_failures.load(Ordering::Relaxed)
}
pub fn reset(&self) {
self.loads_attempted.store(0, Ordering::Relaxed);
self.loads_successful.store(0, Ordering::Relaxed);
self.loads_failed.store(0, Ordering::Relaxed);
self.rollbacks.store(0, Ordering::Relaxed);
self.validation_failures.store(0, Ordering::Relaxed);
}
}
static GLOBAL_METRICS: once_cell::sync::Lazy<PatchMetrics> =
once_cell::sync::Lazy::new(PatchMetrics::new);
pub fn global_metrics() -> &'static PatchMetrics {
&GLOBAL_METRICS
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_metrics() {
let metrics = PatchMetrics::new();
assert_eq!(metrics.loads_attempted(), 0);
metrics.record_load_attempt();
assert_eq!(metrics.loads_attempted(), 1);
metrics.record_load_success();
assert_eq!(metrics.loads_successful(), 1);
metrics.reset();
assert_eq!(metrics.loads_attempted(), 0);
assert_eq!(metrics.loads_successful(), 0);
}
}