Files
mesh/agent/src/debug.rs
Gilles Soulier 1d177e96a6 first
2026-01-05 13:20:54 +01:00

105 lines
3.3 KiB
Rust

// Created by: Claude
// Date: 2026-01-04
// Purpose: Debug utilities for development
// Refs: AGENT.md
use crate::mesh::types::Event;
use quinn::Connection;
use tracing::info;
/// Dump event details for debugging
pub fn dump_event(event: &Event) {
info!("━━━━━━━━━━━━━━━━━━━━━━━━");
info!("Event: {}", event.event_type);
info!("ID: {}", event.id);
info!("From: {} → To: {}", event.from, event.to);
info!("Timestamp: {}", event.timestamp);
if let Ok(pretty) = serde_json::to_string_pretty(&event.payload) {
info!("Payload:\n{}", pretty);
} else {
info!("Payload: {:?}", event.payload);
}
info!("━━━━━━━━━━━━━━━━━━━━━━━━");
}
/// Dump QUIC connection statistics
pub fn dump_quic_stats(connection: &Connection) {
let stats = connection.stats();
info!("━━━ QUIC Connection Stats ━━━");
info!("Remote: {}", connection.remote_address());
info!("RTT: {:?}", stats.path.rtt);
info!("Congestion window: {} bytes", stats.path.cwnd);
info!("Sent: {} bytes ({} datagrams)", stats.udp_tx.bytes, stats.udp_tx.datagrams);
info!("Received: {} bytes ({} datagrams)", stats.udp_rx.bytes, stats.udp_rx.datagrams);
info!("Lost packets: {}", stats.path.lost_packets);
info!("Lost bytes: {}", stats.path.lost_bytes);
info!("━━━━━━━━━━━━━━━━━━━━━━━━━━");
}
/// Format bytes in human-readable format
pub fn format_bytes(bytes: u64) -> String {
const KB: u64 = 1024;
const MB: u64 = KB * 1024;
const GB: u64 = MB * 1024;
if bytes >= GB {
format!("{:.2} GB", bytes as f64 / GB as f64)
} else if bytes >= MB {
format!("{:.2} MB", bytes as f64 / MB as f64)
} else if bytes >= KB {
format!("{:.2} KB", bytes as f64 / KB as f64)
} else {
format!("{} B", bytes)
}
}
/// Calculate transfer speed
pub fn calculate_speed(bytes: u64, duration_secs: f64) -> String {
if duration_secs <= 0.0 {
return "N/A".to_string();
}
let bytes_per_sec = bytes as f64 / duration_secs;
format_bytes(bytes_per_sec as u64) + "/s"
}
/// Dump session token cache status (for debugging P2P)
pub fn dump_session_cache_info(session_id: &str, ttl_remaining_secs: i64) {
info!("━━━ Session Token Cache ━━━");
info!("Session ID: {}", session_id);
if ttl_remaining_secs > 0 {
info!("TTL remaining: {} seconds", ttl_remaining_secs);
info!("Status: VALID");
} else {
info!("TTL remaining: EXPIRED ({} seconds ago)", ttl_remaining_secs.abs());
info!("Status: EXPIRED");
}
info!("━━━━━━━━━━━━━━━━━━━━━━━━━━");
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_format_bytes() {
assert_eq!(format_bytes(512), "512 B");
assert_eq!(format_bytes(1024), "1.00 KB");
assert_eq!(format_bytes(1536), "1.50 KB");
assert_eq!(format_bytes(1024 * 1024), "1.00 MB");
assert_eq!(format_bytes(1024 * 1024 * 1024), "1.00 GB");
}
#[test]
fn test_calculate_speed() {
assert_eq!(calculate_speed(1024 * 1024, 1.0), "1.00 MB/s");
assert_eq!(calculate_speed(1024, 2.0), "512 B/s");
assert_eq!(calculate_speed(1000, 0.0), "N/A");
}
}