admin dashboard, metrics and telemetry
Cross Compile Go / build (push) Canceled after 0s

- embedded React admin UI at /admin/ui (go:embed), login with ADMIN_SECRET
  via signed HttpOnly session cookie, X-ADMIN-KEY still works for scripts
- admin API: overview stats, indexing queue, addon management (priority,
  reindex, delete/restore/purge, bulk), whitelist CRUD, duplicate hashes,
  traffic, metrics explorer, services, events/audit log, system info
- built-in metrics: request latency per route, visitors, top addons and
  searches, indexer/scraper counters; minute buckets in the DB with hourly
  rollups and retention; optional Prometheus /metrics (METRICS_TOKEN)
- POST /back/telemetry for indexers/scrapers (metrics, events, heartbeat)
  and a stdlib-only Go client in telemetry/
- auth hardening: empty secrets no longer allow access, constant-time
  compare, CORS not applied to /admin and /back, TRUSTED_PROXIES setting
- Dockerfile builds the UI and no longer bakes config.yaml into the image;
  CI builds the UI, runs tests and builds arm64 with CGO
This commit is contained in:
ilbinek committed 2026-10-03 18:10:57 +02:00
1 parent 0ef27b0072
commit 56d9e10621
79 files changed
+13146 -118

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
package models
// TelemetryBatch is the payload of POST /back/telemetry. The client lives in
// the telemetry/ module; keep both definitions in sync.
type TelemetryBatch struct {
Service string `json:"service"`
Instance string `json:"instance"`
Version string `json:"version"`
StartedAt int64 `json:"startedAt"`
HeartbeatIntervalSec int `json:"heartbeatIntervalSec"`
Status string `json:"status"`
StatusMessage string `json:"statusMessage"`
Meta map[string]any `json:"meta"`
Metrics []TelemetryMetric `json:"metrics"`
Events []TelemetryEvent `json:"events"`
}
// TelemetryMetric is one sample. Type "counter" carries a delta since the last
// push, "gauge" the current value, "summary" client-side pre-aggregated
// Count/Sum/Min/Max. Ts is unix seconds or milliseconds, optional.
type TelemetryMetric struct {
Name string `json:"name"`
Type string `json:"type"`
Help string `json:"help"`
Value float64 `json:"value"`
Count int64 `json:"count"`
Sum float64 `json:"sum"`
Min float64 `json:"min"`
Max float64 `json:"max"`
Labels map[string]string `json:"labels"`
Ts int64 `json:"ts"`
}
type TelemetryEvent struct {
Level string `json:"level"`
Message string `json:"message"`
Ts int64 `json:"ts"`
Fields map[string]any `json:"fields"`
}