Repository navigation
feat(analytics): print a session's agent metrics under --experimental-auth - #1023
Merged
Merged
Conversation
Topherhindman
force-pushed
the
devx-798-cli-session-metrics
branch
from
October 9, 2026 02:57
12c69e1 to
32f6772
Compare
Topherhindman
force-pushed
the
devx-797-cli-session-traces
branch
2 times, most recently
from
October 9, 2026 05:10
168fe22 to
8b6a3c3
Compare
Topherhindman
force-pushed
the
devx-798-cli-session-metrics
branch
from
October 9, 2026 05:11
32f6772 to
279bb7d
Compare
Topherhindman
marked this pull request as ready for review
October 9, 2026 06:27
Topherhindman
force-pushed
the
devx-798-cli-session-metrics
branch
from
October 9, 2026 20:26
279bb7d to
bbfc89f
Compare
Topherhindman
force-pushed
the
devx-797-cli-session-traces
branch
from
October 9, 2026 20:26
8b6a3c3 to
48aeddc
Compare
Topherhindman
force-pushed
the
devx-798-cli-session-metrics
branch
from
October 9, 2026 20:50
bbfc89f to
a17eb17
Compare
Topherhindman
force-pushed
the
devx-797-cli-session-traces
branch
from
October 9, 2026 20:50
48aeddc to
8c8d0b5
Compare
JackNDwyer
approved these changes
Oct 10, 2026
Topherhindman
force-pushed
the
devx-797-cli-session-traces
branch
from
October 10, 2026 03:11
8c8d0b5 to
d920038
Compare
Topherhindman
force-pushed
the
devx-798-cli-session-metrics
branch
from
October 10, 2026 03:11
a17eb17 to
411b38b
Compare
Topherhindman
force-pushed
the
devx-797-cli-session-traces
branch
from
October 10, 2026 03:12
d920038 to
7fe5029
Compare
Topherhindman
force-pushed
the
devx-798-cli-session-metrics
branch
2 times, most recently
from
October 10, 2026 03:48
79dae47 to
9b007b1
Compare
Topherhindman
force-pushed
the
devx-797-cli-session-traces
branch
2 times, most recently
from
October 10, 2026 04:21
8d0101c to
fc1094c
Compare
Topherhindman
force-pushed
the
devx-798-cli-session-metrics
branch
from
October 10, 2026 04:21
9b007b1 to
39ae30b
Compare
Topherhindman
force-pushed
the
devx-797-cli-session-traces
branch
from
October 10, 2026 04:37
fc1094c to
c293aa8
Compare
Topherhindman
force-pushed
the
devx-798-cli-session-metrics
branch
from
October 10, 2026 04:37
39ae30b to
0eb7b58
Compare
Picks up GetSessionMetrics as the server now serves it: the session's agent metrics come back as typed MetricPoints instead of livekit MetricsBatches. Each point carries its metric's name, unit and kind (gauge, sum, histogram or exponential histogram), its start and end times and its typed attributes with its resource's and scope's merged in, plus either a gauge's or sum's value or a histogram's count, sum, min, max and buckets. The request gains a names filter, which takes at most 50 names, each 1 to 256 characters: an empty name is rejected. Points come by end time; points that end together by start time, then by kind and a hash of what they recorded, not by name. The docs also say an attribute integer beyond ±2^53 comes as its decimal string, and that on an ACTIVE session a point exported mid-read with an earlier time than the read has reached is missed until a new read. They name the upstream aggregator's limits too: several metrics that share their attributes can come back under one name (an LLM's input, output and cached token counts all as lk.agents.usage.llm_input_tokens), points of one series at the same time with equal values collapse into one, and with two agents in one session a point can carry the other agent's resource attributes. Nothing hand-written reads the changed types, so only oapi.gen.go changes. Generated from livekit/public-api-server@3e3abf0
GetSessionMetrics returns one page of the OpenTelemetry metric points a session's agents exported, by end time, and the cursor for the next. MetricOptions embeds PageOptions and adds the metric names to keep, matched exactly, and Validate rejects a negative limit or a blank name before any request is sent. The generated point is a union that hides whether it holds a value or a histogram, so the body is decoded again into MetricPoints that say, as the transcript's items are: each carries its metric's name, unit and kind, its start and end times and its typed attributes, and either a gauge's or sum's Value or a histogram's count, sum, min, max and buckets. A point marshals back to the API's own JSON. An unknown session is NotFound, and an empty unfiltered first page with user data recording off carries the ObservabilityDisabled detail.
…-auth
`lk analytics session metrics SESSION_ID` prints a page of the
OpenTelemetry metric points the session's agents exported, one line per
point: its end time to the millisecond, its metric's name, and a gauge's
or sum's value or a histogram's count, sum, min and max, in the metric's
unit (an annotation such as {token} loses its braces). --json prints
{items, nextCursor} with the points as the API sent them, kind, start
time, typed attributes and histogram buckets included.
--name is repeatable and keeps only the points of those metrics, matched
exactly; a blank one fails before the project lookup. --limit (default
50, the server's page size) and a hidden --cursor page through it, and a
next page says to re-run with its --cursor: the user's own command
already repeats the names a cursor was made for. The help says these are
the raw metrics agents emit, so they won't exactly match the dashboard's
metrics panel.
An empty page says why: no points for the metrics asked for, no agent
metrics at all (only agents that export OpenTelemetry metrics to LiveKit
Cloud produce them), or no more pages. With user data recording off it
says so and links the project's observability settings, an unknown
session says there's no such session in the project, and a permission
denial says reading the agent metrics requires being a project admin,
through the shared sessionReadError.
Only the Public API serves agent metrics, so the command runs only under
--experimental-auth, through sessionRead, with the signed-in user's
session token, and refuses to run otherwise before reading its
arguments.
A metric's name and unit are whatever the agent's code declared, and the metrics read printed them as they came, so in a terminal an escape sequence in one could set the window title or clear the screen. Both now go through oneLine, which strips control characters, and the names are measured after stripping so the values still line up.
Topherhindman
force-pushed
the
devx-798-cli-session-metrics
branch
from
October 10, 2026 04:53
0eb7b58 to
d73b173
Compare
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.
Fixes DEVX-798
Stacked on #1022.
Depends on livekit/public-api-server#53.
lk analytics session metrics SESSION_IDprints a page of the OpenTelemetry metric points a session's agents exported, one line per point. These are the raw metrics agents emit, so they won't exactly match the dashboard's metrics panel, and the help says so. The command runs only under--experimental-auth, since only the Public API serves agent metrics.What changed
Regenerated client (
chore(public)):oapi.gen.gois regenerated from livekit/public-api-server@3e3abf0, livekit/public-api-server#53's merge commit onmain. It picks upGetSessionMetricsas the server now serves it:MetricPoints instead of livekitMetricsBatchesnamesfilter (at most 50 names, each 1 to 256 characters), and points come by end timeNothing hand-written reads the changed types, so only
oapi.gen.gochanges.Client (
feat(public)):GetSessionMetricsreturns one page of points, by end time, and the cursor for the next.MetricOptionsembedsPageOptionsand adds the metric names to keep, matched exactly.Validaterejects a negative limit or a blank name before any request is sent.MetricPoints that say, as the transcript's items do. A point marshals back to the API's own JSON.ObservabilityDisableddetail.Command (
feat(analytics)):{token}loses its braces.--jsonprints{items, nextCursor}with the points as the API sent them, kind, start time, typed attributes and histogram buckets included.--nameis repeatable and keeps only those metrics' points, matched exactly. A blank one fails before the project lookup.--cursor. The user's own command already repeats the names the cursor was made for.sessionReadError: with user data recording off it says so and links the project's observability settings. An unknown session says there's no such session in the project, and names the project. A permission denial says reading the agent metrics requires being a project admin.--experimental-auth, throughsessionRead.Usage
--limitdefaults to 50, the server's page size.--cursoris hidden.Since review
Testing
go build ./...,go vet ./pkg/... ./cmd/lk/andgo test ./pkg/... ./cmd/lk/pass on every commit.pkg/public:TestGetSessionMetrics(values and histograms decoded),TestMetricPointJSON,TestGetSessionMetricsRejectsBadOptionsandTestGetSessionMetricsErrors.pkg/public/render:TestSessionMetricsText,TestSessionMetricsEmptyandTestSessionMetricsJSON.cmd/lk:TestSessionMetricsCommand,TestSessionMetricsRequiresExperimentalAuth,TestMetricOptions,TestFetchSessionMetrics(each empty-page reason),TestFetchSessionMetricsJSONandTestFetchSessionMetricsErrors.job_entrypoint's span events, which these reads return. Metrics are the known exception: the aggregator files several token and TTS series under one name, which the dashboard avoids by deriving usage from the transcript and traces.