You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
stats: per-track counters exposed at /metrics/track
Per-(track, iothread) TrackStats live in the stats tier, owned by a
TrackStatsRegistry that binds one TrackStatsCollector per data-plane thread and
merges them on demand — the same split as StatsRegistry/MoQStatsCollector. A
TrackStatsFilter counts on the relay ingest chain and on each downstream
subscriber, including the PUBLISH fan-out path. No read path dereferences a
registry forwarder, so counting behaves identically in single-thread,
relay-exec and local-forwarder modes.
GET /metrics/track?service=&namespace=&track=&limit= reports subscribers,
groups/subgroups/objects/datagrams/bytes in both directions, and
publish-start/last-object timestamps. Rates are left to Prometheus. A match
wider than the limit is rejected rather than truncated: an arbitrary
F14-ordered subset would reshuffle between scrapes.
Namespaces and track names are safeName()-encoded in labels and expected in the
same form on the query, so a scraped value pastes back into a query and two
tracks cannot collapse onto one label set.
Groups are counted against an LRU window of the 3 most recent group IDs, so
subgroups of concurrently-open groups do not inflate the count. Name matching
uses forEachName rather than forEach: EntryView copies a forwarder and session
shared_ptr per entry, ~72% of the walk at 100k tracks (13.7ms vs 3.9ms).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/metrics.md
+79Lines changed: 79 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -182,3 +182,82 @@ Counters with per-code breakdowns:
182
182
|--------|-------------|
183
183
|`moqx_quicActiveConnections`| Active QUIC connections |
184
184
|`moqx_quicActiveStreams`| Active QUIC streams across all connections |
185
+
186
+
## Per-Track Metrics
187
+
188
+
```
189
+
GET /metrics/track?service=<name>&namespace=<a/b>&track=<name>&limit=<N>
190
+
```
191
+
192
+
Requires `admin.track_metrics_enabled` (default true); when it is false the
193
+
counting filters are never installed and this endpoint returns `503`.
194
+
195
+
Reports counters for **live tracks** — a track's series disappear when the track
196
+
goes away, and start from zero if it comes back.
197
+
198
+
| Parameter | Required | Description |
199
+
|---|---|---|
200
+
|`namespace`| no | Namespace prefix in the safe form below. Matches every track under the prefix unless `track` is given. Default: all namespaces. |
201
+
|`service`| no | Restrict to one service. Default: all services, each labeled. |
202
+
|`track`| no | Exact track name within the namespace. |
203
+
|`limit`| no | Max tracks to report. Default `admin.track_metrics_endpoint_default_limit` (10), clamped to `admin.track_metrics_endpoint_max_limit` (1000). |
204
+
205
+
Every parameter is optional, so `GET /metrics/track?limit=20` reports every live
206
+
track when fewer than 20 match.
207
+
208
+
`limit` is a sanity guard, not a top-N selector. A query matching more tracks
209
+
than the limit returns **400** with the match count rather than truncating —
210
+
an arbitrary subset would give Prometheus a series set that reshuffles between
211
+
scrapes, producing gap-filled graphs that look like data. Narrow the namespace
212
+
or raise the limit. A query that matches nothing returns 200 with no series.
213
+
214
+
Every series carries `{service, namespace, track}` labels.
215
+
216
+
### Name encoding
217
+
218
+
Namespaces and track names are arbitrary bytes, so the `namespace` and `track`
219
+
values — both in labels and in the query parameters — use the form RECOMMENDED
220
+
by moq-transport, [Representing Namespace and Track
0 commit comments