feat(cron): include top 3 processes in CPU/RAM alert Telegram messages
When CPU or RAM exceeds the threshold, the alert now lists the top 3 processes sorted by the relevant metric (CPU% or RAM MB). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
73fe73b04f
commit
4b98161070
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user