Skip to content

feat(observability): add game-performance and relay signals with a complete scrape setup #725

Open

Description

@Baylem

Extend the existing Prometheus integration so operators can distinguish game performance problems, container pressure, failed scraping, and relay connectivity problems. Provide a complete enabled configuration instead of treating monitor creation as proof of successful scraping.

Existing coverage and remaining gap

#220 added the agent's real per-server gauges, and #476 moved agent scraping to a dedicated plain-HTTP metrics listener and added the NetworkPolicy exception. Those fixes are present. The agent collector exports CPU, memory, disk, and player measurements with known/unknown semantics. This issue does not request rebuilding those metrics.

Module-specific readings use a separate on-demand /status handler with a five-second cache and RCON extraction; they do not feed the Prometheus collector. The pinned Minecraft template declares seed and difficulty, not TPS. The shipped PrometheusRule focuses on reconcile errors, queues, failed servers, and backups, rather than tick performance, resource pressure, or relay service quality.

The supported Helm values already document that serviceMonitors.enabled: true needs a nonempty serviceMonitors.scrapeNamespaceSelector when network policies are enabled. The ingress exception and agent PodMonitor exist. The enhancement is to make the complete setup easier to use and validate, not to reopen the resolved mTLS scrape bug.

Static review at commit 04e41075 identified these coverage gaps. No production scrape failure, tick degradation, memory incident, or relay saturation was measured. Per-game tick support depends on the game and must not be inferred from CPU usage or fabricated when unavailable.

Recommended change

  • Publish a complete monitoring example covering serviceMonitors.enabled, monitor-selection labels, scrapeNamespaceSelector, Prometheus discovery of the games namespace, prometheusRules.enabled, and grafanaDashboards.enabled.

  • Add a clear chart note or validation path for enabled agent monitors with network policies but no scraping namespace. Preserve restrictive network defaults and support externally managed policy exceptions.

  • Define bounded numeric per-game performance metrics with explicit units, timestamps/freshness, and unsupported/unknown handling. Reuse collected samples rather than issuing costly RCON calls on every scrape.

  • Integrate existing Kubernetes/container/node metrics for throttling, OOM/restarts, resource pressure, and pending pods instead of misrepresenting process RSS as total container memory.

  • Add alerts and dashboards for scrape loss and provider connection/forward health; consume the companion tunnel-health work rather than duplicating its implementation.

Acceptance criteria

  • A CI monitoring scenario discovers and scrapes agents from a distinct namespace with default-deny policies and the documented values.

  • Missing configuration produces actionable guidance; external policy management remains supported.

  • Unsupported metrics remain absent, zero stays distinguishable from unknown, and metric labels/cardinality are bounded.

  • Rule tests cover scrape loss, pressure, game degradation where supported, relay failure/recovery, and duplicate operator replicas without double-counting.

Activity

  1. ValgulNecron commented on Oct 20, 2026

    @ValgulNecron
    Collaborator

    Thanks, confirmed on master: the agent exports 8 gauges (CPU, memory, disk, players) and no tick/TPS metric (agent/internal/metrics/metrics.go:57-70), the PrometheusRule has no pressure, throttling or relay alerts (charts/gameplane/templates/prometheusrule.yaml:23-77), the tunnel has no metrics at all, and enabling serviceMonitors with NetworkPolicies on but no scrapeNamespaceSelector renders a PodMonitor that can't be scraped, without any warning.

    Go ahead with the full proposal:

    • Scrape setup: fail validation (or at least warn in NOTES) when monitors are enabled with NetworkPolicies but no scrape selector, and document a complete working configuration.
    • Game-performance metrics: have the agent collect per-game performance signals (tick rate/TPS and similar) where the game exposes them. Please keep the collection cost bounded: gather on the agent's own interval and cache, rather than issuing an RCON call per Prometheus scrape, and let a module declare how its game reports these.
    • Relay signals: export relay connection health from the tunnel (this builds on fix(tunnel): report relay connection health and reserve tunnel resources #723's readiness work) and add alerts for relay down, CPU throttling, memory pressure and game-performance degradation.
  2. Baylem commented on Oct 25, 2026

    @Baylem
    MemberAuthor

    The full proposal is implemented in #771:

    • Scrape setup: Helm validation rejects monitors plus NetworkPolicies without a scrape namespace selector, unless the installation explicitly owns the required policy externally. docs/monitoring.md and docs/examples/monitoring/ provide matching Prometheus discovery, chart values, and ingress configuration.
    • Game performance: modules declare supported signals, units, and thresholds. The agent polls on its own schedule with bounded commands and deadlines; Prometheus reads only cached results. Failed or stale samples remain unknown, and a genuine zero is preserved. Extra scrapes do not issue additional game commands.
    • Relay and workload alerts: relay-down, supported-provider unknown health, CPU throttling, memory pressure, and game-performance alerts are included. The latest review fix keeps known Tailscale outages visible through retries and avoids a permanent unknown-health alert for Playit, whose pinned integration cannot supply that signal.

    Regression sources and the real-cluster scrape/revoke/restore scenario are included. Local compilation passed; runtime verification remains in CI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions