use std::sync::Arc;
use std::time::Instant;
use tracing::{info, error};
use tokio::time::{interval, Duration};
use super::unified_monitor::{UnifiedMonitor, SystemHealthReport};
use super::config::MonitoringConfig;
use super::childs::server_monitor::ServerMonitor;
use super::health_checks::{
database_health::DatabaseHealthCheck,
network_health::NetworkHealthCheck,
memory_health::MemoryHealthCheck,
cpu_health::CpuHealthCheck,
disk_health::DiskHealthCheck,
api_health::ApiHealthCheck
};
use super::health_runner::{HealthCheckRunner, BackgroundMonitorHandle};
use super::metrics_reporter::MetricsReporter;
use super::health_check::{MonitorHealthAdapter, ComponentType};
#[derive(Clone)]
pub struct MonitorRegistry {
pub unified_monitor: Arc<UnifiedMonitor>,
pub server_monitor: Arc<ServerMonitor>,
pub health_runner: HealthCheckRunner,
pub metrics_reporter: MetricsReporter,
start_time: Instant,
}
impl MonitorRegistry {
pub async fn new() -> Self {
info!("🚀 Initializing comprehensive monitoring system...");
let config = MonitoringConfig::default();
let unified_monitor = Arc::new(UnifiedMonitor::new(config));
info!("📊 Registering core monitors...");
let server_monitor = ServerMonitor::new();
unified_monitor.register_monitor(Arc::new(server_monitor.clone())).await;
info!("🔧 Registering system health checks...");
unified_monitor.register_health_check(Arc::new(DatabaseHealthCheck::new())).await;
unified_monitor.register_health_check(Arc::new(NetworkHealthCheck::new())).await;
unified_monitor.register_health_check(Arc::new(MemoryHealthCheck::new())).await;
unified_monitor.register_health_check(Arc::new(CpuHealthCheck::new())).await;
unified_monitor.register_health_check(Arc::new(DiskHealthCheck::new())).await;
unified_monitor.register_health_check(Arc::new(ApiHealthCheck::new())).await;
unified_monitor.register_health_check(Arc::new(MonitorHealthAdapter::new(
Arc::new(server_monitor.clone()),
ComponentType::Service
))).await;
let start_time = Instant::now();
let health_runner = HealthCheckRunner::new(Arc::clone(&unified_monitor));
let metrics_reporter = MetricsReporter::new(Arc::clone(&unified_monitor), start_time);
info!("✅ All monitoring components registered successfully");
info!(" - Core Monitors: Server"); info!(" - System Checks: Database, Network, Memory, CPU, Disk, API");
Self {
unified_monitor,
server_monitor: Arc::new(server_monitor),
health_runner,
metrics_reporter,
start_time,
}
}
pub async fn health_check(&self) -> bool {
self.health_runner.run_health_check().await
}
pub async fn get_health_report(&self) -> SystemHealthReport {
self.health_runner.get_detailed_report().await
}
pub async fn print_metrics_report(&self) {
self.metrics_reporter.print_comprehensive_report().await
}
pub async fn get_web_report(&self) -> serde_json::Value {
self.metrics_reporter.get_web_report().await
}
pub fn get_uptime(&self) -> Duration {
self.metrics_reporter.get_uptime()
}
pub async fn start_background_monitoring(self: Arc<Self>) -> BackgroundMonitorHandle {
let registry = Arc::clone(&self);
tokio::spawn(async move {
tokio::time::sleep(Duration::from_secs(30)).await;
let mut interval = interval(Duration::from_secs(60)); let mut error_count = 0;
const MAX_CONSECUTIVE_ERRORS: u32 = 5;
loop {
interval.tick().await;
let report = registry.health_runner.get_detailed_report().await;
if !report.overall_health {
error_count += 1;
error!("🚨 Background health check failed! (consecutive errors: {})", error_count);
error!("Critical components: {:?}", report.critical_components);
if error_count >= MAX_CONSECUTIVE_ERRORS {
error!("Too many consecutive errors ({}), restarting monitoring loop", error_count);
error_count = 0;
tokio::time::sleep(Duration::from_secs(300)).await; continue;
}
} else {
error_count = 0; }
if registry.start_time.elapsed().as_secs() % 300 < 60 {
registry.metrics_reporter.print_comprehensive_report().await;
}
}
});
info!("🔄 Background monitoring started (first check in 30s)");
BackgroundMonitorHandle::new()
}
}
impl Default for MonitorRegistry {
fn default() -> Self {
tokio::task::block_in_place(|| {
tokio::runtime::Handle::current().block_on(async {
Self::new().await
})
})
}
}