diff --git a/pkg/services/cron_service.go b/pkg/services/cron_service.go index 627bd46..f84bcdd 100644 --- a/pkg/services/cron_service.go +++ b/pkg/services/cron_service.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "log" + "sort" "strconv" "time" @@ -11,6 +12,12 @@ import ( "github.com/sujit-baniya/fiber-boilerplate/pkg/models" ) +type cronProcInfo struct { + Nombre string `json:"nombre"` + CPU float64 `json:"cpu"` + RAMMB float64 `json:"ram_mb"` +} + var cronScheduler *cron.Cron // IniciarCron arranca el scheduler de tareas. Llamar desde app.go o main.go. @@ -257,16 +264,17 @@ func VerificarSaludServidores() { Porcentaje float64 `json:"porcentaje"` Ruta string `json:"ruta"` } `json:"discos"` + TopProcs []cronProcInfo `json:"top_procs"` } if jsonErr := json.Unmarshal([]byte(srv.MetricasJson), &m); jsonErr == nil { - checkRecurso(srv.Nombre, "CPU", m.CPU.Porcentaje, cfg.UmbralCPU) - checkRecurso(srv.Nombre, "RAM", m.RAM.Porcentaje, cfg.UmbralRAM) + checkRecurso(srv.Nombre, "CPU", m.CPU.Porcentaje, cfg.UmbralCPU, m.TopProcs, "cpu") + checkRecurso(srv.Nombre, "RAM", m.RAM.Porcentaje, cfg.UmbralRAM, m.TopProcs, "ram") for _, d := range m.Discos { label := "Disco" if d.Ruta != "" && d.Ruta != "/" { label = "Disco " + d.Ruta } - checkRecurso(srv.Nombre, label, d.Porcentaje, cfg.UmbralDisco) + checkRecurso(srv.Nombre, label, d.Porcentaje, cfg.UmbralDisco, nil, "") } } } @@ -292,15 +300,34 @@ func VerificarSaludServidores() { } } -func checkRecurso(nombre, recurso string, valor float64, umbral int) { +func checkRecurso(nombre, recurso string, valor float64, umbral int, procs []cronProcInfo, ordenar string) { if valor < float64(umbral) { return } titulo := fmt.Sprintf("⚠️ %s alto en %s (%.0f%%)", recurso, nombre, valor) if !models.YaExisteAlertaServidor(titulo, 1) { - crearNotifServidor(titulo, - fmt.Sprintf("%s al %.0f%% (umbral: %d%%)", recurso, valor, umbral), - "servidor_recurso_alto") + cuerpo := fmt.Sprintf("%s al %.0f%% (umbral: %d%%)", recurso, valor, umbral) + if len(procs) > 0 { + cp := make([]cronProcInfo, len(procs)) + copy(cp, procs) + if ordenar == "cpu" { + sort.Slice(cp, func(i, j int) bool { return cp[i].CPU > cp[j].CPU }) + } else { + sort.Slice(cp, func(i, j int) bool { return cp[i].RAMMB > cp[j].RAMMB }) + } + if len(cp) > 3 { + cp = cp[:3] + } + cuerpo += "\n\nTop procesos:" + for i, p := range cp { + if ordenar == "cpu" { + cuerpo += fmt.Sprintf("\n%d. %s — CPU: %.1f%%, RAM: %.0f MB", i+1, p.Nombre, p.CPU, p.RAMMB) + } else { + cuerpo += fmt.Sprintf("\n%d. %s — RAM: %.0f MB, CPU: %.1f%%", i+1, p.Nombre, p.RAMMB, p.CPU) + } + } + } + crearNotifServidor(titulo, cuerpo, "servidor_recurso_alto") } }