Files
2026-10-10 18:47:56 -04:00

276 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Metrics
Metrics is under **Analytics** at `/metrics` (keyboard shortcut: `g m`).
Choose the past 24 hours, 7 days, or 30 days. The page refreshes every minute.
## Overview and filters
**Lobbies running** shows the average and peak number of recorded lobbies in the
selected scope. The average divides captured lobby-hours, including unknown
status, by captured wall time. Empty spares are deliberate supply for new groups:
the card shows their hours and share of all captured lobby-hours, rather than
treating them as failed utilization. Unknown status can include lobbies starting
or unavailable, so this count does not guarantee every lobby was ready to join.
**Player-hours** integrates reported player counts over time. **No empty lobby**
shows the share of known map time when no tracked lobby reported zero players.
Each game/map is measured separately, then its durations are pooled. This is not
elapsed fleet time or a count of rejected joins. A partly occupied Zombies lobby
does not count as an empty spare, even if player slots remain.
**Last collected** is the newest recorded batch, including unknown checks;
**Report refreshed** is when this report was calculated. Collection stops when no
servers are registered. Earliest retained observations do not prove continuous
history or the original installation date.
Background refresh keeps the last successful report visible on failure and offers
Retry. Returning to a visible tab refreshes immediately. Game and map filters apply
to the whole report, including comparisons, signals, and the heatmap. Map choices
preserve the exact recorded game/map pair and include retained occupancy, match,
and autoscaling Provisioning history. Range and scope are shareable through the URL; refreshes preserve table
controls and chart selection.
## Autoscaling operations
The **Autoscaling** section follows the selected period, game, and map and links
to the policies. **Lobbies added** and **Lobbies removed** count successful create
and remove operations, including completions with warnings. Failed and cancelled
operations appear separately. Counts come from retained Provisioning records
linked to autoscaling, independently of occupancy samples; manual operations and
changes in sampled lobby counts do not contribute.
An operation belongs to the period containing its finish time, including both
endpoints. A request made before the period still counts if it finishes within it;
pending operations and finishes outside the period do not count. **Request to
ready** shows the average and maximum request-to-finish duration of successful
creates with valid timestamps, including queue time. Each create has equal weight.
Without valid completed creates, these timings are unavailable, not zero. Verified
readiness does not establish browser visibility or successful external joins.
Scope uses the operation's recorded server name, which encodes its game and map
variant. Game-wide policies do not combine different variants when filtering by
map. Friendly map names, slugs, and unambiguous canonical map names are supported;
an ambiguous engine label such as `zm_transit` is not assigned to a variant.
History survives server removal and policy deletion, subject to Provisioning
retention. Missing or purged operations are not estimated. The policy card's
31-day spare-deficit measurements remain separate from this section.
## Matches and groups
**Matches started** counts retained matches whose recorded start falls within the
selected period, including both endpoints. A missing start event uses the first
recorded match observation, which may be later than the actual start. Active,
completed, and interrupted matches all count, including matches that never reach
round 2 and matches on removed servers. These counts do not use the leaderboard's
completed-match or round qualification rules.
**Average group size** is the average number of distinct recorded player GUIDs per
match. A player counts once across all reports for that match, including late
joins and players who left before its end. Each match has equal weight in the
fleet average; the average is not an average of map averages. This measures
recorded participation over the match's lifetime, not its starting squad or peak
simultaneous occupancy. Active matches can change as more players are recorded.
**Solo games** counts matches with exactly one distinct recorded player. Its share
uses only matches with at least one recorded player. Matches with no recorded
players still count as started, but their group size is unknown and they are
excluded from both the average and solo-share denominator. If no matches have
recorded players, those two values are unavailable rather than zero.
The map table includes these same match statistics. A map with match history in
the selected period remains visible even without occupancy samples; its match
statistics do not establish lobby-hours, availability, or an autoscaling shortage.
Match statistics cover the selected period only and have no previous-period
comparison.
## Players over time
The player chart uses the lobby chart's periods: hourly for 24 hours, and UTC-aligned
24-hour periods for 7 or 30 days. Labels use the report timezone. **Unique players**
counts distinct player GUIDs in every period overlapped by their recorded match
participation, from first to last sighting. Multiple matches in one period count
once, and the same GUID across Black Ops I and II is one player. Matches that began
before the range still contribute participation inside it. These are recorded
participants, not concurrent player counts or the lobby chart's player-hours.
**New players** counts a GUID at its earliest recorded sighting across both games.
Game and Map filters limit unique players to matching retained matches; new players
count only when their original sighting was in a matching match. A regular's first
visit to another map or game does not make them new again. Period boundaries belong
to the following period; a sighting exactly at the range's end counts in the final
period. Range totals count distinct GUIDs across the entire window independently:
daily unique counts cannot be added to get the range total.
Periods before the earliest retained match are gaps, not zero players. This history
boundary is fleet-wide, so filtering to a quiet map does not hide recorded zeroes.
The chart notes limited history and marks periods clipped by the selected range or
the retained-history boundary with hollow points. Totals cover available history
only. Select a point, use Left/Right or Home/End, or open **Inspect a period** for
the exact interval and counts. **View exact time data** provides the same values
in a keyboard-accessible table, with missing history shown as a dash.
History begins when leaderboard recording started; earlier play cannot be recovered.
Players already playing then count as new when first recorded. Participation spans
do not prove continuous presence between reports, and unrecorded matches are absent.
Match retention removes participation, which can shorten or leave holes in this
history. The durable first-seen player identities survive retention, so removing an
old match cannot make a returning player new again. The original map cannot be
recovered from an expired match. The chart remains available without occupancy samples.
## Timeline and tables
The timeline defaults to **Average lobbies running**, split into **With players**,
**Empty spare**, and **Unknown**. Each bucket divides those lobby-hours by its
captured wall time, so changing lobby counts remain visible. Collection gaps are
excluded from that denominator. The average-lobby axis uses whole-number ticks;
period details preserve fractional averages. Switch to the share view to compare proportions,
or hours to compare absolute lobby time. Periods without captured time remain gaps.
The timeline has labelled axes and marks partial edge periods. Select a bar or use
Previous/Next to inspect its exact interval and values. The time table supplies
the same figures for comparison and assistive technology. Zero captured time is
distinct from an observed empty lobby. Short durations use seconds or minutes so
a real observation is not rounded to zero.
The map table supports numeric sorting and local search. **Lobbies (avg · peak)**
shows the time-weighted average and peak concurrent lobby count for each recorded
game/map pair, with empty lobby-hours beneath. Sort this column by average count.
The average divides all captured lobby-hours, including unknown occupancy, by
that map's captured wall time; collection gaps and periods without recorded lobbies
for that map are excluded. Peak is the largest captured concurrent count, not the
number of distinct lobby names. Empty lobby-hours sum time with zero reported
players across the map's lobbies. Unknown occupancy is not counted as empty;
empty time is unavailable when no occupancy is known. Lobby counts are unavailable
without captured time. Per-lobby match and activity history is available on server pages.
The map table's
**No empty lobby** column uses occupancy alone and retains the known map-time
denominator in its details. Unknown map availability stays distinct from zero
time without a spare. Evidence can be limited by short observations or unknown
occupancy, never by missing player limits.
## Comparisons and activity
Previous-period comparisons use the preceding equally long window with identical
filters. Average lobby counts compare recorded supply, while player-hours changes
are relative percentages. A previous observed zero can show **New**. Missing
evidence remains unavailable. Partial retained history is labelled; a 30-day
comparison usually has little previous history because default retention is
31 days. Collection gaps are excluded, and comparisons do not prove uninterrupted
collection or adjust player-hours for fleet size.
The activity heatmap groups captured time by weekday and hour in its displayed
timezone. Color represents occupied / known lobby time. Exact cell values include
unknown time and contributing dates. No-data cells differ from observed zero;
repeated DST hours contribute their actual elapsed time. Occupancy share describes
how the fleet was used, but can change simply because a policy adds or removes
spares. Read it alongside player-hours, lobby counts, and empty-lobby availability.
## Autoscaling signals
Signals compare each map's observations with its **current** applicable policy.
Game-wide policies apply independently to each supported map variant. Each signal
links to the policy on **Fleet → Autoscaling**; a map without a policy gets a link
to add one. Signals are advisory and never change a policy or a lobby.
A global pause appears once above the signals. Historical shortage signals remain
visible while the fleet is paused, including suggestions to review the maximum
or spare target. Review these findings and current settings before resuming.
An individual policy's own pause or disabled state still prompts a policy review.
| Recorded condition | Suggested action |
| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| No empty lobby for at least 2% of known map time, mostly at or above the current maximum | Review raising the policy maximum. |
| No empty lobby for at least 2% of known map time, mostly below the current maximum | Review the spare target and check creation time or blockers. |
| An applicable policy is off or paused | Review the policy and its pause or activation conditions. |
| No applicable policy and known occupancy is available | Consider adding an autoscaling policy to keep spares available. |
| Occupancy unavailable | Check telemetry/RCON reporting and wait for known player counts. |
| No shortage signal | Keep watching empty-lobby availability. |
Evidence includes no-empty map time and how it splits above/below the current
maximum. Less than one hour of known map availability, less than 80% known map
availability, or less than 80% known lobby time makes advice tentative. Player limits are not needed. These
thresholds are advisory rules, not demand forecasts.
Policy settings may have changed during the selected period. Comparing historical
counts against today's maximum does not establish which settings applied then or
whether autoscaling was enabled. No reported empty lobby also does not prove
failed joins or unmet demand. Review provisioning delays, blockers, host resources,
and game-key availability before changing targets.
## Definitions and collection
- **With players:** a successful observation reported at least one player.
- **Empty spare:** an observation reported zero players.
- **Unknown:** failed checks, provisioning, or otherwise unavailable occupancy.
- **Player-hours:** reported players × observed time. Bots count if the server includes them.
- **Empty lobby available:** at least one lobby on the game/map reported zero players.
- **No empty lobby:** at least one lobby reported occupancy, and none reported zero. Mixed positive and unknown counts mean no empty lobby was reported; an unknown lobby might actually have been empty.
- **Unknown map availability:** every lobby on the game/map had unknown occupancy. This interval is excluded from the known-map denominator and is never counted as a spare shortage.
Observations come from the existing status worker. Each complete collection stays
valid until the next collection, up to the 90-second freshness limit. Longer gaps
are excluded, not counted as unknown or zero lobbies. Captured wall time includes
intervals with at least one recorded lobby in the selected scope. Unknown lobby
time and unknown map time use different units: several unknown lobbies on one map
contribute several lobby-hours but only one interval of unknown map availability.
Charts split time at UTC hour/day boundaries; partial periods remain partial.
Map variants use the configured variant when it matches the reported map. Player
capacity may be retained in raw samples, but no metric or signal requires
`sv_maxclients` or an assumed four-player limit.
Occupancy collection begins after this feature is installed; earlier occupancy cannot be
reconstructed. Samples default to 31 days of retention; **Admin → Settings** can
change this period. Cleanup runs during collection and in the background. Samples
survive removal of a server and contain no player identities.
Match statistics use existing saved match history, independently of occupancy
samples and raw telemetry diagnostics. **Match history retention** under
**Admin → Settings → Matches & players** defaults to indefinite. Expiring a
completed or interrupted match also removes its player participation and changes
these statistics; active matches are protected. Increasing retention cannot
restore expired matches. Saved match history survives removal of a server.
## API
`GET /api/metrics` supplies the same report as the page and disables HTTP response
caching. Query parameters are `days` (1, 7, or 30), `game`, `map` (requires game),
and `timeZone` (an IANA zone). Invalid ranges and zones fall back to the defaults;
invalid scope syntax is normalized. Fleet collection timestamps remain separate
from selected-scope evidence timestamps. Collection boundaries are determined
before scope filtering, so samples from other groups still end a batch interval.
`running` contains `average`, `peak`, and `capturedHours`; timeline points include
their own `capturedHours`. Report-level `matches` and each map row's `matches`
contain `started`, `withRecordedPlayers`, `averageGroupSize`, `solo`, and
`soloShare`. `withRecordedPlayers` is the denominator for the group average and
solo share; `soloShare` is a percentage from 0 to 100. When that denominator is
zero, `averageGroupSize` and `soloShare` are `null`, `solo` is zero, and `started`
retains the recorded number of starts. Match scope uses the exact saved `game` and `map_name`
labels, and its time window uses the saved `started_at` timestamp. Occupancy
collection and evidence timestamps remain independent of match history.
`players` contains the separately deduplicated range totals `uniquePlayers` and
`newPlayers`, plus `historyStartAt` (the earliest retained match, in epoch
milliseconds). Every `points` entry also has `uniquePlayers`, `newPlayers`, and
`playerHistoryPartial`. Counts before retained history are `null`; known periods
with no scoped participation are zero. Player charts treat either `partial` or
`playerHistoryPartial` as partial. Participation timestamp changes and durable
first-seen identity changes invalidate the report cache.
Map rows expose `noEmpty`, `availabilityObserved`, and
`availabilityUnknown` durations, plus current `policy` context and
`noEmptyAtMaximum` / `noEmptyBelowMaximum` durations. `pooledAvailability` combines
map durations and coverage. `autoscalingPaused` reports the current global pause
separately from each policy's own `pausedReason`. Policy edits and global pause changes invalidate
cached metrics reports, as do changes to the match and player participation data
used by the report.
`autoscaling` contains `added`, `removed`, `failed`, `cancelled`, `readinessSamples`,
`readinessMeanSeconds`, and `readinessMaxSeconds`. Counts use `finished_at` in the
selected window; readiness uses `finished_at - started_at` for successful creates
with nonnegative, valid durations. Both timing values are `null` when there are
no readiness samples. Changes to Provisioning outcomes or autoscaling source
links invalidate cached reports, including when no new occupancy is collected.