Repository navigation
feat(metrics): publish proxy metrics on a Prometheus endpoint - #31
Merged
Merged
Conversation
mc-router counts connections arriving at a region's front door, and each
game server counts the players in its own world. Between them sits Velocity,
and nothing measured it — a proxy holding players it cannot hand to a backend
looks, from either side, like a quiet region.
The plugin now binds a Prometheus endpoint when GROUNDS_METRICS_ENABLED=true
(default false, port 9000, path /metrics):
velocity_players_online this proxy's own count. Against mc-router it
says whether the router's view matches the
proxy's; against the sum of
minecraft_players_online it says how many are
on the proxy but not on a server
velocity_servers_registered backends plugin-agones has registered. Zero
with a healthy Fleet is discovery broken, and
it is invisible everywhere else — Agones
reports the servers Ready and the proxy simply
has nowhere to send anyone
velocity_network_players what this proxy reports in the server list
plus Micrometer's JVM and process binders, under the same names the services
and the game servers publish, so one query covers all three. Every series
carries `region` when REGION is set.
Deliberately not published: players per backend. Velocity knows it, but a
backend's name is the Agones GameServer name — lobby-nl-ams1-tr9pf-s9fwt —
which changes every time the Fleet replaces a pod. That is a label that churns
with the workload, and the same breakdown already exists with stable labels
(minecraft_players_online per app, mc_router_server_active_connections per
hostname).
velocity_network_players reports NaN, not 0, before service-player's first
broadcast. Zero would claim an empty network, which is exactly the lie the
ping handler avoids.
Gauges use strongReference(true): Micrometer holds a gauge's state object
weakly, so without it the snapshot is collected and every proxy gauge reports
NaN hours later with the endpoint still up. A failure to bind is logged and
the proxy keeps running — a proxy that cannot publish metrics is degraded, one
that refuses to start takes every player in the region with it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
mc-router counts connections arriving at a region's front door. Each game server counts the players in its own world. Between them sits Velocity, and nothing measured it — a proxy holding players it cannot hand to a backend looks, from either side, like a quiet region.
What
The plugin binds a Prometheus endpoint when
GROUNDS_METRICS_ENABLED=true(default false, port 9000, path/metrics):velocity_players_onlineminecraft_players_online: how many are on the proxy but not on a server — the transfer path, where a stuck player sitsvelocity_servers_registeredvelocity_network_playersPlus Micrometer's JVM and process binders, under the same names the services and game servers publish, so one Grafana query covers all three. Every series carries
regionwhenREGIONis set.Deliberately not published: players per backend
Velocity knows it. But a backend's name is the Agones GameServer name —
lobby-nl-ams1-tr9pf-s9fwt— which changes every time the Fleet replaces a pod. That is a label that churns with the workload, for a breakdown that already exists with stable labels:minecraft_players_onlineperapp, andmc_router_server_active_connectionsper hostname.Two deliberate choices
velocity_network_playersis NaN, not 0, before the first broadcast. Zero would claim an empty network — exactly the lieonProxyPingalready avoids by falling back to Velocity's own count. NaN is Prometheus' "no value" and renders as a gap. Asserted by a test.Gauges use
strongReference(true)— Micrometer holds a gauge's state object weakly, so without it the snapshot is collected and every proxy gauge reports NaN hours later with the endpoint still up and the JVM series still correct. Same trap as the Minestom runtime.Verification
./gradlew buildgreen — spotless + 73 tests, 9 of them new.regionlabel (and its absence whenREGIONis blank), gauges re-reading on every scrape rather than at registration, the NaN case, 404 on any other path, the socket closing onclose(), and the config defaults plus a rejected path.velocity-apijar withjavap, not assumed:ProxyServer.getPlayerCount(),getAllServers().Follow-ups
charts—grounds-velocitygainsmetrics.enabled(annotations + declared containerPort + env), same contract asgrounds-gamemodegrounds-pulumi— a Proxies dashboarddeploy— turn it on for velocity and velocity-2