- Prometheus: new pulse_route_fallbacks_total counter - Zabbix: extend response with route_requests_total, route_fallbacks_total, uptime_seconds - Docs: update Prometheus metrics table and Zabbix response example
109 lines
3.7 KiB
Go
109 lines
3.7 KiB
Go
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,
|
|
})
|
|
}
|
|
|
|
stats := a.engine.GetHealthStats()
|
|
writeJSON(w, http.StatusOK, models.ZabbixResponse{
|
|
Data: data,
|
|
RouteRequests: stats.RouteRequests,
|
|
RouteFallbacks: stats.RouteFallbacks,
|
|
UptimeSeconds: stats.UptimeSeconds,
|
|
})
|
|
}
|
|
|
|
// 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
|
|
|
|
// Общие метрики (counter gauge)
|
|
stats := a.engine.GetHealthStats()
|
|
fmt.Fprintf(&sb, "# HELP pulse_route_requests_total Total number of route requests.\n")
|
|
fmt.Fprintf(&sb, "# TYPE pulse_route_requests_total counter\n")
|
|
fmt.Fprintf(&sb, "pulse_route_requests_total %d\n", stats.RouteRequests)
|
|
|
|
fmt.Fprintf(&sb, "# HELP pulse_nodes_total Total nodes registered.\n")
|
|
fmt.Fprintf(&sb, "# TYPE pulse_nodes_total gauge\n")
|
|
fmt.Fprintf(&sb, "pulse_nodes_total %d\n", stats.TotalNodes)
|
|
|
|
fmt.Fprintf(&sb, "# HELP pulse_nodes_healthy Healthy nodes count.\n")
|
|
fmt.Fprintf(&sb, "# TYPE pulse_nodes_healthy gauge\n")
|
|
fmt.Fprintf(&sb, "pulse_nodes_healthy %d\n", stats.HealthyNodes)
|
|
|
|
fmt.Fprintf(&sb, "# HELP pulse_route_fallbacks_total Total number of fallback route requests.\n")
|
|
fmt.Fprintf(&sb, "# TYPE pulse_route_fallbacks_total counter\n")
|
|
fmt.Fprintf(&sb, "pulse_route_fallbacks_total %d\n", stats.RouteFallbacks)
|
|
|
|
fmt.Fprintf(&sb, "# HELP pulse_uptime_seconds Uptime in seconds.\n")
|
|
fmt.Fprintf(&sb, "# TYPE pulse_uptime_seconds gauge\n")
|
|
fmt.Fprintf(&sb, "pulse_uptime_seconds %d\n", stats.UptimeSeconds)
|
|
|
|
fmt.Fprintf(&sb, "\n")
|
|
|
|
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, ".", "_"), "-", "_")
|
|
}
|