diff --git a/src/config.rs b/src/config.rs index 7e67534..d5c39a4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,11 +2,16 @@ use serde::{Serialize, Deserialize}; use std::fs::{self, create_dir_all}; use std::path::Path; use std::sync::{Arc, RwLock, OnceLock}; +use crate::logger::get_logger; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MonitoredApp { pub name: String, pub port: i32, + #[serde(skip_serializing_if = "Option::is_none")] + pub systemd_service: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub created_at: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -17,10 +22,7 @@ pub struct AppConfig { impl Default for AppConfig { fn default() -> Self { AppConfig { - apps: vec![ - MonitoredApp { name: "app_tareas".to_string(), port: 3000 }, - MonitoredApp { name: "fidelizacion".to_string(), port: 3001 }, - ] + apps: vec![] } } } @@ -32,9 +34,17 @@ pub struct ConfigManager { impl ConfigManager { pub fn new(config_path: &str) -> Self { + let logger = get_logger(); + // Crear directorio config si no existe if let Some(parent) = Path::new(config_path).parent() { - let _ = create_dir_all(parent); + if !parent.exists() { + logger.info("Config", &format!("Creando directorio: {}", parent.display())); + match create_dir_all(parent) { + Ok(_) => logger.info("Config", &format!("✅ Directorio creado: {}", parent.display())), + Err(e) => logger.error("Config", "Error creando directorio", Some(&e.to_string())), + } + } } // Cargar o crear configuración @@ -47,23 +57,31 @@ impl ConfigManager { } fn load_config(path: &str) -> AppConfig { + let logger = get_logger(); + match fs::read_to_string(path) { Ok(content) => { match serde_json::from_str(&content) { Ok(config) => { - println!("✅ Configuración cargada desde: {}", path); + let app_count = if let AppConfig { apps } = &config { apps.len() } else { 0 }; + logger.info("Config", &format!("✅ Configuración cargada: {} apps desde {}", app_count, path)); config } Err(e) => { - eprintln!("⚠️ Error parseando config: {}. Usando default.", e); - AppConfig::default() + logger.error("Config", "Error parseando JSON, creando vacío", Some(&e.to_string())); + let default_config = AppConfig::default(); + let _ = Self::save_config_to_file(path, &default_config); + default_config } } } - Err(_) => { - println!("ℹ️ Archivo de config no encontrado. Creando uno nuevo..."); + Err(e) => { + logger.warning("Config", &format!("Archivo no encontrado ({}), creando vacío en: {}", e.kind(), path), None); let default_config = AppConfig::default(); - let _ = Self::save_config_to_file(path, &default_config); + match Self::save_config_to_file(path, &default_config) { + Ok(_) => logger.info("Config", &format!("✅ Archivo de configuración creado: {}", path)), + Err(save_err) => logger.error("Config", "Error al crear archivo", Some(&save_err.to_string())), + } default_config } } @@ -89,7 +107,15 @@ impl ConfigManager { return Err(format!("La app '{}' ya está siendo monitoreada", name)); } - config.apps.push(MonitoredApp { name, port }); + let systemd_service = format!("siax-app-{}.service", name); + let created_at = chrono::Local::now().to_rfc3339(); + + config.apps.push(MonitoredApp { + name, + port, + systemd_service: Some(systemd_service), + created_at: Some(created_at), + }); // Guardar en disco match Self::save_config_to_file(&self.config_path, &config) { @@ -123,7 +149,31 @@ impl ConfigManager { // Singleton global del ConfigManager static CONFIG_MANAGER: OnceLock = OnceLock::new(); +/// Determina la ruta del archivo de configuración +fn get_config_path() -> String { + // Prioridad de rutas: + // 1. Variable de entorno SIAX_CONFIG_PATH + // 2. /opt/siax-agent/config/monitored_apps.json (producción) + // 3. ./config/monitored_apps.json (desarrollo) + + if let Ok(env_path) = std::env::var("SIAX_CONFIG_PATH") { + return env_path; + } + + let prod_path = "/opt/siax-agent/config/monitored_apps.json"; + if Path::new("/opt/siax-agent").exists() { + return prod_path.to_string(); + } + + "config/monitored_apps.json".to_string() +} + // ⚠️ IMPORTANTE: Esta función DEBE ser pública pub fn get_config_manager() -> &'static ConfigManager { - CONFIG_MANAGER.get_or_init(|| ConfigManager::new("config/monitored_apps.json")) -} \ No newline at end of file + CONFIG_MANAGER.get_or_init(|| { + let config_path = get_config_path(); + let logger = get_logger(); + logger.info("Config", &format!("Usando archivo de configuración: {}", config_path)); + ConfigManager::new(&config_path) + }) +}