Initial commit

This commit is contained in:
redclawsystems
2026-03-04 00:08:42 +00:00
commit 4d88dc0584
4449 changed files with 1556714 additions and 0 deletions
+305
View File
@@ -0,0 +1,305 @@
//! # RTX Monitoring - Observability and Metrics Collection
//!
//! RTX Monitoring provides comprehensive observability for RustyTorch production
//! deployments, including metrics collection, distributed tracing, health checks,
//! and alerting.
//!
//! ## Core Features
//!
//! - Prometheus metrics collection and export
//! - OpenTelemetry distributed tracing
//! - System and application health monitoring
//! - Custom metrics and dashboards
//! - Alert management and notification
//! - Performance monitoring and SLI/SLO tracking
#![deny(clippy::unwrap_used)]
#![cfg_attr(test, allow(clippy::unwrap_used))]
pub mod alerts;
pub mod collector;
pub mod error;
pub mod health;
pub mod metrics;
pub mod telemetry;
pub mod trace_utils;
pub use alerts::{
AlertCondition, AlertManager, AlertRule, AlertSeverity, AlertState, ChannelType, Notification,
NotificationChannel, presets as alert_presets,
};
pub use collector::{CollectorConfig, MetricsCollector, SystemMetrics};
pub use error::{MonitoringError, MonitoringResult};
pub use health::{HealthCheck, HealthManager, HealthStatus};
pub use metrics::{
BATCH_SIZE_BUCKETS, CustomMetric, INFERENCE_LATENCY_BUCKETS, InferenceMetrics, MetricRegistry,
MetricType, TrainingMetrics,
};
pub use telemetry::{
SpanContext, SpanData, SpanEvent, SpanGuard, SpanStatus, TelemetryManager, TraceConfig,
generate_span_id, generate_trace_id,
};
use std::sync::Arc;
// Import tracing macros with alias to avoid conflict with local tracing module
/// Shared monitoring system instance
pub type SharedMonitoringSystem = Arc<MonitoringSystem>;
/// Main monitoring system that coordinates all observability components
#[derive(Debug)]
pub struct MonitoringSystem {
/// Metrics collector
pub metrics: Arc<MetricsCollector>,
/// Health manager
pub health: Arc<HealthManager>,
/// Alert manager
pub alerts: Arc<AlertManager>,
/// Telemetry manager
pub telemetry: Arc<TelemetryManager>,
/// System configuration
config: MonitoringConfig,
}
/// Configuration for the monitoring system
#[derive(Debug, Clone)]
pub struct MonitoringConfig {
/// Enable Prometheus metrics
pub enable_prometheus: bool,
/// Enable OpenTelemetry tracing
pub enable_telemetry: bool,
/// Enable health checks
pub enable_health_checks: bool,
/// Enable alerting
pub enable_alerting: bool,
/// Metrics collection interval
pub collection_interval: std::time::Duration,
/// Health check interval
pub health_check_interval: std::time::Duration,
/// Metrics server port
pub metrics_port: u16,
/// Health check port
pub health_port: u16,
}
impl Default for MonitoringConfig {
fn default() -> Self {
Self {
enable_prometheus: true,
enable_telemetry: true,
enable_health_checks: true,
enable_alerting: false,
collection_interval: std::time::Duration::from_secs(30),
health_check_interval: std::time::Duration::from_secs(10),
metrics_port: 9090,
health_port: 8080,
}
}
}
impl MonitoringSystem {
/// Create a new monitoring system
pub async fn new(config: MonitoringConfig) -> MonitoringResult<Self> {
let metrics = Arc::new(
MetricsCollector::new(CollectorConfig {
enable_prometheus: config.enable_prometheus,
collection_interval: config.collection_interval,
..Default::default()
})
.await?,
);
let health = Arc::new(HealthManager::new().await?);
let alerts = Arc::new(AlertManager::new().await?);
let telemetry = Arc::new(TelemetryManager::new(TraceConfig::default()).await?);
let enable_prometheus = config.enable_prometheus;
let enable_health_checks = config.enable_health_checks;
let system = Self {
metrics,
health,
alerts,
telemetry,
config,
};
// Start background tasks
if enable_prometheus {
system.start_metrics_server().await?;
}
if enable_health_checks {
system.start_health_checks().await?;
}
Ok(system)
}
/// Start the metrics HTTP server
async fn start_metrics_server(&self) -> MonitoringResult<()> {
let metrics = self.metrics.clone();
let port = self.config.metrics_port;
tokio::spawn(async move {
if let Err(e) = run_metrics_server(metrics, port).await {
tracing::error!("Metrics server error: {}", e);
}
});
Ok(())
}
/// Start health check background tasks
async fn start_health_checks(&self) -> MonitoringResult<()> {
let health = self.health.clone();
let interval = self.config.health_check_interval;
tokio::spawn(async move {
let mut ticker = tokio::time::interval(interval);
loop {
ticker.tick().await;
if let Err(e) = health.run_all_checks().await {
tracing::error!("Health check error: {}", e);
}
}
});
Ok(())
}
/// Get system metrics summary
pub async fn get_metrics_summary(&self) -> MonitoringResult<MetricsSummary> {
let system_metrics = self.metrics.collect_system_metrics().await?;
let health_status = self.health.overall_status().await?;
let active_alerts = self.alerts.active_alerts().await?;
Ok(MetricsSummary {
system_metrics,
health_status,
active_alerts: active_alerts.len(),
uptime: self.get_uptime(),
})
}
/// Get system uptime
fn get_uptime(&self) -> std::time::Duration {
// Placeholder implementation
std::time::Duration::from_secs(3600)
}
}
/// Summary of system metrics
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct MetricsSummary {
pub system_metrics: SystemMetrics,
pub health_status: HealthStatus,
pub active_alerts: usize,
pub uptime: std::time::Duration,
}
/// Run the metrics HTTP server
async fn run_metrics_server(metrics: Arc<MetricsCollector>, port: u16) -> MonitoringResult<()> {
use axum::{Router, routing::get};
let app = Router::new().route(
"/metrics",
get(move || async move {
match metrics.export_prometheus().await {
Ok(metrics_text) => axum::response::Response::builder()
.header("Content-Type", "text/plain; version=0.0.4; charset=utf-8")
.body(metrics_text)
.expect("failed to build successful metrics response"),
Err(e) => {
tracing::error!("Failed to export Prometheus metrics: {}", e);
axum::response::Response::builder()
.status(500)
.body("Internal Server Error".to_string())
.expect("failed to build error response")
}
}
}),
);
let addr = format!("0.0.0.0:{port}");
let listener =
tokio::net::TcpListener::bind(&addr)
.await
.map_err(|e| MonitoringError::ConfigError {
details: format!("Failed to bind metrics server to {addr}: {e}"),
})?;
tracing::info!("Metrics server listening on {}", addr);
axum::serve(listener, app)
.await
.map_err(|e| MonitoringError::ServerError {
details: e.to_string(),
})?;
Ok(())
}
/// Create a production-ready monitoring system
pub async fn create_production_monitoring() -> MonitoringResult<MonitoringSystem> {
let config = MonitoringConfig {
enable_prometheus: true,
enable_telemetry: true,
enable_health_checks: true,
enable_alerting: true,
collection_interval: std::time::Duration::from_secs(15),
health_check_interval: std::time::Duration::from_secs(5),
metrics_port: 9090,
health_port: 8080,
};
MonitoringSystem::new(config).await
}
/// Create a development monitoring system
pub async fn create_development_monitoring() -> MonitoringResult<MonitoringSystem> {
let config = MonitoringConfig {
enable_prometheus: true,
enable_telemetry: false,
enable_health_checks: true,
enable_alerting: false,
collection_interval: std::time::Duration::from_secs(60),
health_check_interval: std::time::Duration::from_secs(30),
metrics_port: 9090,
health_port: 8080,
};
MonitoringSystem::new(config).await
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_monitoring_system_creation() {
let config = MonitoringConfig::default();
let system = MonitoringSystem::new(config).await.unwrap();
assert!(system.metrics.is_enabled());
assert!(system.health.is_enabled());
}
#[tokio::test]
async fn test_production_monitoring_setup() {
let system = create_production_monitoring().await.unwrap();
assert!(system.config.enable_prometheus);
assert!(system.config.enable_telemetry);
assert!(system.config.enable_health_checks);
assert!(system.config.enable_alerting);
}
#[tokio::test]
async fn test_development_monitoring_setup() {
let system = create_development_monitoring().await.unwrap();
assert!(system.config.enable_prometheus);
assert!(!system.config.enable_telemetry);
assert!(system.config.enable_health_checks);
assert!(!system.config.enable_alerting);
}
}