rmm2/backend/api/metrics.go
cynfo3000 5d7a3cbcc1 SQLite durch PostgreSQL + TimescaleDB ersetzt
- Backend DB komplett auf PostgreSQL 17 + TimescaleDB 2.25.1 umgestellt
- pgx pure-Go Driver (kein CGO), modernc/sqlite entfernt
- Hypertable 'metrics' fuer Time-Series Daten
- Automatische Metrik-Extraktion bei jedem Heartbeat:
  CPU, RAM, Uptime, Disk, Network-Traffic, Gateway RTT/Loss
- Retention Policy: 90 Tage, Compression nach 7 Tagen
- Neue API-Endpoints: GET /metrics (raw) + GET /metrics/summary (aggregiert)
- time_bucket() Aggregation (5min, 1h, etc.)
- config.yaml: database-Block statt db_path
- docs/POSTGRES_SETUP.md: Installationsanleitung
- README aktualisiert
2026-02-28 12:48:14 +01:00

84 lines
2.0 KiB
Go

package api
import (
"net/http"
"strconv"
"time"
)
// GET /api/v1/agents/{id}/metrics — Metriken abfragen
func (h *Handler) getMetrics() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
agentID := r.PathValue("id")
metric := r.URL.Query().Get("metric")
// Zeitraum (default: letzte 24h)
from := time.Now().Add(-24 * time.Hour)
to := time.Now()
if f := r.URL.Query().Get("from"); f != "" {
if t, err := time.Parse(time.RFC3339, f); err == nil {
from = t
}
}
if t := r.URL.Query().Get("to"); t != "" {
if parsed, err := time.Parse(time.RFC3339, t); err == nil {
to = parsed
}
}
limit := 1000
if l := r.URL.Query().Get("limit"); l != "" {
if parsed, err := strconv.Atoi(l); err == nil && parsed > 0 {
limit = parsed
}
}
results, err := h.db.GetMetrics(agentID, metric, from, to, limit)
if err != nil {
writeError(w, http.StatusInternalServerError, "Metriken laden fehlgeschlagen")
return
}
writeJSON(w, http.StatusOK, results)
}
}
// GET /api/v1/agents/{id}/metrics/summary — Aggregierte Metriken (Durchschnitt/Min/Max)
func (h *Handler) getMetricsSummary() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
agentID := r.PathValue("id")
metric := r.URL.Query().Get("metric")
if metric == "" {
writeError(w, http.StatusBadRequest, "Parameter 'metric' erforderlich")
return
}
bucket := r.URL.Query().Get("bucket")
if bucket == "" {
bucket = "5 minutes"
}
from := time.Now().Add(-24 * time.Hour)
to := time.Now()
if f := r.URL.Query().Get("from"); f != "" {
if t, err := time.Parse(time.RFC3339, f); err == nil {
from = t
}
}
if t := r.URL.Query().Get("to"); t != "" {
if parsed, err := time.Parse(time.RFC3339, t); err == nil {
to = parsed
}
}
results, err := h.db.GetMetricsSummary(agentID, metric, bucket, from, to)
if err != nil {
writeError(w, http.StatusInternalServerError, "Metriken laden fehlgeschlagen")
return
}
writeJSON(w, http.StatusOK, results)
}
}