package api import ( "fmt" "net/http" "strings" "github.com/pulse-lets-go/internal/models" ) // handleZabbix — GET /api/monitoring/zabbix — возвращает JSON для Zabbix LLD + items. func (a *API) handleZabbix(w http.ResponseWriter, r *http.Request) { nodes := a.engine.GetAllNodes() data := make([]models.ZabbixNode, 0, len(nodes)) for _, n := range nodes { data = append(data, models.ZabbixNode{ NodeID: n.NodeID, Status: n.Status, ActiveCalls: n.ActiveCalls, MaxCalls: n.MaxCalls, IdleCPU: n.IdleCPU, LoadAvg: n.LoadAvg, CallFailureRate: n.CallFailureRate, Score: n.Score, Disabled: n.Disabled, IsStale: n.IsStale, SecondsAgo: n.SecondsAgo, }) } writeJSON(w, http.StatusOK, models.ZabbixResponse{Data: data}) } // handlePrometheus — GET /api/monitoring/prometheus — text/plain метрики для Prometheus. func (a *API) handlePrometheus(w http.ResponseWriter, r *http.Request) { nodes := a.engine.GetAllNodes() var sb strings.Builder for _, n := range nodes { id := sanitizePromLabel(n.NodeID) fmt.Fprintf(&sb, "pulse_node_active_calls{node=\"%s\"} %d\n", id, n.ActiveCalls) fmt.Fprintf(&sb, "pulse_node_max_calls{node=\"%s\"} %d\n", id, n.MaxCalls) fmt.Fprintf(&sb, "pulse_node_idle_cpu{node=\"%s\"} %.2f\n", id, n.IdleCPU) fmt.Fprintf(&sb, "pulse_node_load_avg{node=\"%s\"} %.2f\n", id, n.LoadAvg) fmt.Fprintf(&sb, "pulse_node_call_failure_rate{node=\"%s\"} %.2f\n", id, n.CallFailureRate) fmt.Fprintf(&sb, "pulse_node_score{node=\"%s\"} %.2f\n", id, n.Score) fmt.Fprintf(&sb, "pulse_node_seconds_ago{node=\"%s\"} %.2f\n", id, n.SecondsAgo) disabledVal := 0 staleVal := 0 statusVal := 1 // ok if n.Disabled { disabledVal = 1 } if n.IsStale { staleVal = 1 } if n.Status != "ok" { statusVal = 0 } fmt.Fprintf(&sb, "pulse_node_disabled{node=\"%s\"} %d\n", id, disabledVal) fmt.Fprintf(&sb, "pulse_node_stale{node=\"%s\"} %d\n", id, staleVal) fmt.Fprintf(&sb, "pulse_node_status_ok{node=\"%s\"} %d\n", id, statusVal) } w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusOK) w.Write([]byte(sb.String())) } // sanitizePromLabel заменяет символы, недопустимые в Prometheus-лейблах. func sanitizePromLabel(s string) string { return strings.ReplaceAll(strings.ReplaceAll(s, ".", "_"), "-", "_") }