ops: export Prometheus metrics (system + game KPIs) for Grafana #157
Labels
No labels
alpha:wave-0
alpha:wave-1
alpha:wave-2
alpha:wave-3
area:assets
area:combat
area:ecology
area:infra
area:render
area:scripting
area:ui
area:world
enhancement
epic
migration
post-alpha
roadmap
tech-debt
type:bug
type:chore
type:design
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
marco/IsoMmo#157
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Export Prometheus metrics from both servers (Auth + GameServer) for the homelab Grafana/Prometheus stack, alongside the structured logs (#156, Loki). Observability only — read-only, no gameplay/wire surface.
Scope (what to do)
Program.cs: runtime + ASP.NET instrumentation, Prometheus exporter,/metricsscraping endpoint. Auth uses only the free instrumentation (login rate/latency viahttp.server.request.duration).GameMetricsserver-infra singleton owning oneMeter+ instruments; injected intoWorldTick,WorldPersister,ConnectionManager/GameSessionHandler.World/Gameplaynever reference it.tick_duration_ms(histogram),tick_overruns_total.players_connected(gauge),player_connects_total,player_disconnects_total,player_session_seconds(histogram).save_duration_ms(histogram),seconds_since_last_save(gauge),saves_total,save_failures_total,save_bytes.creatures_count,ground_items_count,corpses_count(gauges).malformed_messages_total,chat_rate_limited_total,intents_rejected_total{reason},gm_commands_total{command,authorized}.docs/deploy.md: the/metricsendpoint, a sample Prometheus scrape job, and the constraint that the reverse proxy must NOT route/metrics(internal scrape only).Design constraints (from the review)
ObservableGauges read a sim-thread-updated snapshot, neverWorldfrom the scrape thread.ConnectionManager.Count(ConcurrentDictionary) is safe to read directly. Tick-side recording uses in-memoryMeterinstruments only — no lock, no I/O in the tick loop./metricsis unauthenticated → internal-only; not on the public proxy.Invariants Check (persisted from the critical-design-review)
gm_commands_total{command,authorized}observes the existingCanExecute; adds no authority path.Definition of Done
GET /metricson both Auth (:5080) and GameServer (:5100) returns Prometheus text exposition (HTTP 200,# TYPElines)./metricsexposes every custom KPI listed above (verifiable: connect a client, move, trigger a save, and the corresponding series change —players_connected≥ 1, atick_duration_msbucket populated,saves_totalincrements,seconds_since_last_saveresets)./-command incrementsmalformed_messages_total/gm_commands_total{authorized="false"}respectively.Worldoff the sim thread (code review: gauge callbacks read the snapshot only)./metricsis documented indocs/deploy.mdas internal-only (proxy must not route it) with a sample scrape job.dotnet testgreen, whole solution builds, zero warnings; multi-platform preserved.