payload-loader 0.1.0

Production-ready Rust loader with cryptography, configuration, and security features
Documentation
//! Metrics and observability for loader operations.
//!
//! Tracks timing, throughput, and other operational metrics.

use std::time::{Duration, Instant};
use tracing::info;

/// Metrics for a decryption operation
#[derive(Debug, Clone)]
pub struct OperationMetrics {
    pub operation_type: String,
    pub bytes_processed: usize,
    pub duration: Duration,
}

impl OperationMetrics {
    /// Create new metrics
    pub fn new(operation_type: impl Into<String>, bytes_processed: usize, duration: Duration) -> Self {
        Self {
            operation_type: operation_type.into(),
            bytes_processed,
            duration,
        }
    }

    /// Log metrics in a structured way
    pub fn log(&self) {
        let throughput_mbps = if self.duration.as_secs_f64() > 0.0 {
            (self.bytes_processed as f64 / (1024.0 * 1024.0)) / self.duration.as_secs_f64()
        } else {
            0.0
        };

        info!(
            operation = %self.operation_type,
            bytes = self.bytes_processed,
            duration_ms = self.duration.as_millis(),
            throughput_mbps = format!("{:.2}", throughput_mbps),
            "operation completed"
        );
    }

    /// Get throughput in MB/s
    pub fn throughput_mbps(&self) -> f64 {
        if self.duration.as_secs_f64() > 0.0 {
            (self.bytes_processed as f64 / (1024.0 * 1024.0)) / self.duration.as_secs_f64()
        } else {
            0.0
        }
    }
}

/// Timer for measuring operation duration
pub struct Timer {
    start: Instant,
}

impl Timer {
    /// Start a new timer
    pub fn start() -> Self {
        Self {
            start: Instant::now(),
        }
    }

    /// Stop timer and return elapsed duration
    pub fn stop(self) -> Duration {
        self.start.elapsed()
    }

    /// Stop timer and create metrics
    pub fn stop_with_metrics(self, operation_type: impl Into<String>, bytes: usize) -> OperationMetrics {
        OperationMetrics::new(operation_type, bytes, self.stop())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_metrics_throughput() {
        let metrics = OperationMetrics::new(
            "test_op",
            1_000_000, // 1 MB
            Duration::from_millis(100),
        );

        let throughput = metrics.throughput_mbps();
        assert!(throughput > 9.0 && throughput < 11.0); // ~10 MB/s
    }

    #[test]
    fn test_timer() {
        let timer = Timer::start();
        std::thread::sleep(Duration::from_millis(10));
        let duration = timer.stop();

        assert!(duration.as_millis() >= 10);
    }
}