Files
ilbinek 56d9e10621
Cross Compile Go / build (push) Canceled after 0s
admin dashboard, metrics and telemetry
- 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
2026-10-03 18:10:57 +02:00

39 lines
2.5 KiB
Go

package metrics
// Metrics emitted by the API itself (service "main").
// HTTPBoundsMs are the latency histogram buckets in milliseconds.
var HTTPBoundsMs = []float64{1, 2, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000}
var (
HTTPDuration = NewHistogram("http_request_duration_ms", "HTTP request latency in milliseconds", HTTPBoundsMs,
"method", "route", "status", "group", "client")
HTTPResponseBytes = NewCounter("http_response_bytes_total", "HTTP response body bytes", "group")
IndexerClaims = NewCounter("indexer_claims_total", "Indexing jobs requested by indexers, by outcome", "queue")
IndexerTimeoutsReset = NewCounter("indexer_timeouts_reset_total", "Indexing claims released after the timeout")
IndexerSubmissions = NewCounter("indexer_submissions_total", "Indexing results submitted", "result")
IndexerJobDuration = NewHistogram("indexer_job_duration_seconds", "Time from claim to submitted result",
[]float64{1, 5, 15, 30, 60, 120, 300, 600, 1200, 1800, 3600})
IndexerFilesPerSubmission = NewHistogram("indexer_files_per_submission", "Files per indexing result",
[]float64{1, 10, 50, 100, 500, 1000, 5000, 10000, 50000})
IndexerBytesIndexed = NewCounter("indexer_bytes_indexed_total", "Addon bytes indexed")
ScraperAddons = NewCounter("scraper_addons_total", "Addon reports from scrapers", "action")
ScraperDeletes = NewCounter("scraper_addons_deleted_total", "Addon deletions requested by scrapers", "result")
DependencyReports = NewCounter("dependency_reports_total", "Dependency reports received")
DependencyEdges = NewCounter("dependency_edges_reported_total", "Dependency edges stored")
DuplicatesFound = NewHistogram("duplicates_found_addons", "Addons sharing files with a looked-up addon",
[]float64{0, 1, 2, 5, 10, 25, 50, 100})
DiscordWebhooks = NewCounter("discord_webhook_total", "Discord webhook sends", "kind", "result")
AdminActions = NewCounter("admin_actions_total", "Admin dashboard actions", "action")
AddonsTotal = NewGauge("addons_total", "Addons in the database (not deleted)")
QueueDepth = NewGauge("queue_depth", "Addons waiting to be indexed", "kind")
BeingIndexed = NewGauge("being_indexed", "Addons currently claimed by an indexer")
VisitorsUnique = NewGauge("visitors_unique", "Unique website visitors so far today (approximate)", "kind")
TelemetrySamples = NewCounter("telemetry_samples_total", "Telemetry samples received", "result")
PointsDropped = NewCounter("metrics_points_dropped_total", "Metric points dropped after failed writes")
)