fix: Detectar loop de reinicios en systemd como estado Failed

Un servicio que aparece como 'activating' con NRestarts > 3
se reporta como Failed en lugar de Activating, evitando que
loops de reinicio pasen desapercibidos en el monitor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-21 09:05:20 -05:00
parent 400f677666
commit 03fc92b3fc

View File

@@ -148,12 +148,44 @@ impl SystemCtl {
match output { match output {
Ok(out) => { Ok(out) => {
let status_str = String::from_utf8_lossy(&out.stdout).trim().to_string(); let status_str = String::from_utf8_lossy(&out.stdout).trim().to_string();
ServiceStatus::from_str(&status_str) let status = ServiceStatus::from_str(&status_str);
// Si está "activating", verificar si está en un loop de reinicios
if status == ServiceStatus::Activating {
if Self::is_in_restart_loop(service_name) {
return ServiceStatus::Failed;
}
}
status
} }
Err(_) => ServiceStatus::Unknown, Err(_) => ServiceStatus::Unknown,
} }
} }
/// Verifica si un servicio está en un loop de reinicios (restart counter > 3)
fn is_in_restart_loop(service_name: &str) -> bool {
let output = Command::new("systemctl")
.arg("show")
.arg(service_name)
.arg("--property=NRestarts")
.output();
match output {
Ok(out) => {
let output_str = String::from_utf8_lossy(&out.stdout);
// Formato: NRestarts=48
if let Some(count_str) = output_str.trim().strip_prefix("NRestarts=") {
if let Ok(count) = count_str.parse::<u32>() {
return count > 3;
}
}
false
}
Err(_) => false,
}
}
pub fn is_service_exists(service_name: &str) -> bool { pub fn is_service_exists(service_name: &str) -> bool {
let output = Command::new("systemctl") let output = Command::new("systemctl")
.arg("list-unit-files") .arg("list-unit-files")