darpan 0.1.0

Linux developer service monitoring utility with auto-detection, real-time health checks, and interactive TUI for databases, APIs, Docker containers, and more
Documentation
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::time::Duration;

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum HealthStatus {
    /// All checks passed
    Healthy,
    /// Some checks passed, some warnings
    Degraded,
    /// Critical checks failed
    Unhealthy,
    /// Cannot determine status
    Unknown,
    /// Service process not found
    NotRunning,
}

impl HealthStatus {
    pub fn symbol(&self) -> &str {
        match self {
            HealthStatus::Healthy => "",
            HealthStatus::Degraded => "",
            HealthStatus::Unhealthy => "",
            HealthStatus::Unknown => "?",
            HealthStatus::NotRunning => "",
        }
    }

    pub fn color(&self) -> &str {
        match self {
            HealthStatus::Healthy => "green",
            HealthStatus::Degraded => "yellow",
            HealthStatus::Unhealthy => "red",
            HealthStatus::Unknown => "gray",
            HealthStatus::NotRunning => "red",
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthResult {
    pub status: HealthStatus,
    pub response_time_ms: u64,
    pub last_checked: DateTime<Utc>,
    pub details: Option<String>,
    pub suggestion: Option<String>,
}

impl HealthResult {
    pub fn healthy(response_time_ms: u64) -> Self {
        Self {
            status: HealthStatus::Healthy,
            response_time_ms,
            last_checked: Utc::now(),
            details: None,
            suggestion: None,
        }
    }

    pub fn unhealthy(reason: String, suggestion: Option<String>) -> Self {
        Self {
            status: HealthStatus::Unhealthy,
            response_time_ms: 0,
            last_checked: Utc::now(),
            details: Some(reason),
            suggestion,
        }
    }

    pub fn not_running(suggestion: Option<String>) -> Self {
        Self {
            status: HealthStatus::NotRunning,
            response_time_ms: 0,
            last_checked: Utc::now(),
            details: Some("Process not found".to_string()),
            suggestion,
        }
    }

    pub fn degraded(response_time_ms: u64, reason: String) -> Self {
        Self {
            status: HealthStatus::Degraded,
            response_time_ms,
            last_checked: Utc::now(),
            details: Some(reason),
            suggestion: None,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthCheckConfig {
    pub check_type: HealthCheckType,
    pub interval: Duration,
    pub timeout: Duration,
    pub retry_count: u32,
}

impl Default for HealthCheckConfig {
    fn default() -> Self {
        Self {
            check_type: HealthCheckType::Port,
            interval: Duration::from_secs(30),
            timeout: Duration::from_secs(3),
            retry_count: 2,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum HealthCheckType {
    Port,
    Process,
    Http {
        path: String,
        expected_status: Option<u16>,
    },
    Postgres {
        database: Option<String>,
    },
    Redis,
    MySQL {
        database: Option<String>,
    },
    MongoDB {
        database: Option<String>,
    },
    Custom {
        script: String,
    },
}