Add experimental metrics insights, comparisons, and scope filters
This commit is contained in:
@@ -105,3 +105,5 @@ The team accepted two primary metrics, visible data-quality context, an absolute
|
||||
Defer a default percentage-only chart, fleet-wide “all full” KPI, period-over-period deltas, heatmaps, automatic hosting recommendations, and global game/map filters. A percentage-only chart can hide tiny denominators; map pressure intervals overlap and cannot be summed into a meaningful fleet total. Comparisons and heatmaps need fair coverage treatment. Global filters should follow later as a complete query scope applied consistently to summary, timeline, and both tables, with URL state.
|
||||
|
||||
Delivery can be split into three reviewable changes: (1) report metadata, measured query improvements, and calculation tests; (2) refresh handling plus summary/timeline and report states; (3) rankings, mobile/accessibility refinement, and documentation. The data contract comes first; frontend layout work can proceed against that agreed contract in parallel. The result should let an operator read utilization correctly, see its evidence limits, inspect a period, and find relevant maps or servers without treating missing data as zero.
|
||||
|
||||
After approval, the base was implemented and committed as `3922e28`. The user also authorized all previously deferred features as experiments. The panel reconvened after that commit; [the review and revised decisions](metrics-review.md) supersede the deferrals above while preserving explicit evidence and metric definitions.
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
The metrics panel reconvened after commit `3922e28` to review the implemented base and revisit the features deferred in the original plan. The user authorized proceeding with all of them, including experiments based on limited evidence.
|
||||
|
||||
The base passed 711 unit tests, Svelte checking with no errors or warnings, and a production build. Firefox checks exercised combined search/sort state, preservation across range changes, pointer and keyboard chart selection, failed background refresh with retained data, successful retry, and 390px layout without page overflow. These checks caught and fixed a shallow-URL reactivity issue before the commit. Calculation parity against the previous implementation held within `1e-7` on a 118,806-row synthetic fixture. Seven-day query time fell from approximately 1,369ms to 367–408ms in the uncontended comparison.
|
||||
|
||||
The post-commit engineering and UX reviews found no blocking issue. Two small follow-ups were accepted: neutral copy for samples with zero elapsed time, and a polite announcement when a user selects a chart period. Background refresh should not repeatedly announce the chart.
|
||||
|
||||
The team revisited the original objections as design constraints:
|
||||
|
||||
| Feature | Original concern | Agreed experiment |
|
||||
| --- | --- | --- |
|
||||
| Percentage chart | Normalization hides sample volume. | Default to share of captured server time, including unknown, with an Hours switch and exact durations in the selected-period readout. |
|
||||
| Fleet pressure score | Map intervals overlap and cannot be added into elapsed fleet time. | Pool full map-hours divided by known-capacity map-hours; name the denominator explicitly and show how many map groups contribute. |
|
||||
| Previous-period changes | Retained and observed history may differ substantially. | Show comparisons from available samples, including both denominators and a partial-history label. Utilization changes are percentage points. |
|
||||
| Activity heatmap | Sparse observations can look like stable recurring demand. | Show duration-weighted occupancy by local weekday/hour, with known/unknown time, contributing dates, and no-data cells distinct from observed zero. |
|
||||
| Hosting recommendations | Occupancy and saturation do not prove unmet demand. | Generate advisory, reversible hosting experiments from visible rules. Include evidence and tentative labels; never automatically create or remove servers. |
|
||||
| Global filters | Inconsistent scopes would make the page misleading. | Apply exact game/map scope to every aggregate, comparison, heatmap, recommendation, and ranking; preserve collection boundaries before filtering. |
|
||||
| Historical server links | A name may have been reused for a new instance. | Label the action “Open current server” and show it only when a current registration exists. Historical totals remain grouped by name. |
|
||||
|
||||
The agreed hierarchy keeps the two headline cards and core timeline. Compact scope controls sit near the time-range control. Pressure, comparisons, advisory experiments, and the secondary heatmap follow the timeline so the added features do not crowd out the primary task on mobile. Use neutral comparison colors, visible units, and concise evidence next to each recommendation.
|
||||
|
||||
The original plan remains as the record of the initial conservative scope. These decisions supersede its deferrals; limited data does not disable a feature when a defined calculation or explicitly tentative experiment is possible. An unavailable denominator still remains unavailable rather than becoming an invented number.
|
||||
|
||||
All seven additions were implemented. The expanded full suite passed 731 tests;
|
||||
subsequent refresh-response hardening passed its focused tests, including a new
|
||||
malformed-response case. Svelte checking reported no errors or warnings and the
|
||||
production build passed. Firefox exercised the percentage/Hours switch with
|
||||
preserved table state, current-registration links, whole-report game/map filters,
|
||||
empty scopes, heatmap keyboard selection and timezone changes, saved preference
|
||||
adoption, and explicit timezone precedence. The final mobile report fits at
|
||||
390px without page overflow.
|
||||
|
||||
The combined 30-day report took 443–446ms on the seven-day, 118,806-row fixture.
|
||||
A separate full-retention fixture with six servers and 535,680 rows took
|
||||
1.96–3.30 seconds for the combined 30-day report. The queries still run
|
||||
synchronously; that measured full-retention cost remains an improvement target.
|
||||
These local synthetic timings are not production guarantees.
|
||||
+55
-1
@@ -14,6 +14,14 @@ Background refresh keeps the last successful report visible on failure and offer
|
||||
Retry. Returning to a visible tab refreshes immediately. The selected range is
|
||||
stored in the URL, and refreshes preserve table controls and chart selection.
|
||||
|
||||
Game and map filters apply to the whole report, including its comparisons,
|
||||
recommendations, and heatmap. Map choices preserve the exact recorded game/map
|
||||
pair. Range and scope are shareable through the URL. Table searches remain local.
|
||||
|
||||
The timeline defaults to **Share of captured time**: each stack includes occupied,
|
||||
idle, and unknown server time, normalized to 100%. This denominator differs from the
|
||||
headline utilization percentage, which excludes unknown time. Switch to **Hours**
|
||||
to compare absolute server time. Periods without captured time remain gaps.
|
||||
The timeline has labelled axes and marks partial edge periods. Select a period,
|
||||
use Previous/Next, or select a bar to inspect its exact interval and values. The
|
||||
time table supplies the same figures for comparison and assistive technology.
|
||||
@@ -23,7 +31,46 @@ seconds or minutes so a real observation is not rounded to zero.
|
||||
Map and server tables support numeric sorting and local search. Their searches
|
||||
apply only to the named table. Known-capacity duration stays next to all-full time.
|
||||
Server identities retain the technical name; rows describe history grouped by
|
||||
name, which may include different instances if a name was reused.
|
||||
name, which may include different instances if a name was reused. **Open current
|
||||
server** appears only when that name is currently registered; its destination
|
||||
represents the current registration rather than every instance in the history.
|
||||
|
||||
**Explore this period** adds experimental decision aids below the main timeline:
|
||||
|
||||
- **Map capacity pressure** pools all-full map-hours divided by known-capacity
|
||||
map-hours across the selected map groups. Overlapping map intervals are counted
|
||||
separately. The score is not elapsed fleet time or a fleet health score; its
|
||||
denominator and contributing map count remain visible.
|
||||
- **Previous-period comparisons** use the preceding equally long window with
|
||||
identical filters. Utilization changes are percentage points; 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 retention is
|
||||
only 31 days. Both periods' known time is shown. Bounds cannot establish that
|
||||
collection was uninterrupted, and changes are not adjusted for fleet size.
|
||||
- **Activity heatmap** groups captured time by weekday and hour in its displayed
|
||||
timezone. Color represents occupied / known server time. Exact cell values
|
||||
include unknown time and contributing dates. No-data cells differ from observed
|
||||
zero utilization; repeated DST hours contribute their actual elapsed time.
|
||||
- **Hosting experiments** are generated automatically from the selected map
|
||||
observations. They are advisory and never create, restart, or destroy a server.
|
||||
|
||||
Hosting Rules v1 deliberately offer experiments even with small samples:
|
||||
|
||||
| Recorded condition | Suggested experiment |
|
||||
| --- | --- |
|
||||
| At least 20% of known capacity time had every lobby full | Trial one additional lobby during busy hours. |
|
||||
| Capacity unavailable and players present for at least 80% of known server time | Tentatively trial an extra lobby using occupancy as a proxy. |
|
||||
| Players present for at most 10% of known time, with under 1% measured pressure or unavailable capacity | Review one idle lobby or a shorter hosting window while preserving access to the map. |
|
||||
| Occupancy unavailable | Check telemetry/RCON reporting and watch for known player counts. |
|
||||
| Other observations | Check missing capacity or keep the lineup and watch peaks. |
|
||||
|
||||
Each suggestion includes evidence and an outcome to watch. Unknown capacity,
|
||||
less than one hour of relevant known evidence, or substantial unknown captured
|
||||
status makes the suggestion tentative. These thresholds are product hypotheses;
|
||||
occupancy does not establish failed joins or a need for additional capacity.
|
||||
Suggestions use historical observations. Check the current lineup before trying
|
||||
a change; a retained map may no longer have a hosted lobby.
|
||||
|
||||
- Utilized means a successful status response reported at least one player.
|
||||
- Idle means a successful response reported zero players.
|
||||
@@ -36,3 +83,10 @@ Observations are recorded by the existing status worker. Each remains valid unti
|
||||
Capacity comes from `sv_maxclients` / `sv_maxClients` in the status response. When unavailable, the UI displays unknown rather than assuming a four-player limit. Capacity coverage is the map time for which every tracked lobby reported both occupancy and capacity.
|
||||
|
||||
Collection begins after this feature is installed; previous occupancy cannot be reconstructed. Samples are retained for 31 days and pruned during collection. They survive removal of a server and contain no player identities. The additive database table is created automatically on startup.
|
||||
|
||||
`GET /api/metrics` supplies the same report as the page and disables 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.
|
||||
|
||||
Reference in New Issue
Block a user