Skip to content

feat: expose per-app session counts - #29351

Draft
EhabY wants to merge 6 commits into
feat/arbitrary-session-count-producersfrom
feat/expose-app-session-counts
Draft

EhabY wants to merge 6 commits into
feat/arbitrary-session-count-producersfrom
feat/expose-app-session-counts

Conversation

@EhabY

@EhabY EhabY commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Expose per-app session counts in deployment stats, Prometheus, telemetry payloads, and the deployment banner. A single server-owned app registry supplies family attribution, display names, and bundled icons; unrecognized names remain visible without guessed icon URLs.

The banner shows the four busiest apps with stable alphabetical tie-breaks, a keyboard-accessible +N more popover, and an icon-based family summary on hover/focus using existing help-popover styling. Overlay content hides when its trigger scrolls out of view using the shared primitive. Apps without a bundled icon (for example the Web Terminal) render a generic icon next to their name so they stay distinguishable. Existing API family fields and the four family Prometheus gauges remain available.

The new coderd_agentstats_session_count gauge carries both app_name and family, sums rows that share the configured identity labels, and follows the other coderd_agentstats_* gauges: a collection with reports replaces the series, a collection with no reports keeps the previous ones.

Depends on #28338 (on top of #29109). Targets feat/arbitrary-session-count-producers, not main.
Refs https://linear.app/codercom/issue/DEVEX-641

Before merge: confirm the compatibility/removal release tracked in https://linear.app/codercom/issue/DEVEX-980 and obtain telemetry receiver/schema/privacy approval. Sender tests do not establish production ingestion compatibility. Arbitrary app names increase metric cardinality; the per-report cap of 64 names (workspacestats.maxSessionCountEntries) is not a deployment-wide or historical bound.

Line-count breakdown

Diff against the stack base feat/arbitrary-session-count-producers at head a5de245ebc. Counts include comments and blank lines.

Category Added Deleted Changed
Production code +362 -160 522
Testing code +569 -107 676
Generated code / references +174 -6 180
Authored docs / metric samples +29 -0 29
Total +1,134 -273 1,407

Testing includes Go tests, a Vitest behavior test, Storybook stories, and shared fixtures. Generated output includes OpenAPI, TypeScript API types, API references, and scanned metrics.

Review follow-up (a5de245)
  • Bug fix: the per-app gauge was committed outside the len(stats) > 0 guard. The collector polls an incremental window, so every empty window wiped all per-app series while the legacy gauges kept theirs. It is now committed under the same guard; docs describe the real semantics and TestAgentStats runs at the original 1ms interval again.
  • Web Terminal no longer shares /icon/terminal.svg with SSH; it renders the generic icon plus its label.
  • A broken bundled icon now falls back to generic icon plus name, and apps?.[id] tolerates a payload without metadata.
  • One normalizing registry lookup backs both AppNameFamily and SessionCountAppMetadata. DeploymentStats() returns the snapshot without cloning maps per request. Unused SessionCountsByFamilyJSON removed.
  • Tests: internal Prometheus helpers, benchmarks, and the duplicated decode table were replaced by one collector snapshot test (agentstats_test.go) and a Vitest behavior test (ordering, overflow, icon fallback, unknown apps). Stories reduced to visual states, with static variants stacked into one story.
Verification results
  • go vet, golangci-lint, gofumpt on changed packages.
  • -race runs of coderd/prometheusmetrics (TestAgentStats, TestAgentSessionCountSnapshots), coderd/metricscache, coderd/telemetry; coderd TestDeploymentStats; full codersdk, coderd/workspacestats.
  • tsc, biome, Vitest (DeploymentBannerView.test.tsx), Storybook Chromium run of all 10 banner stories, pnpm run lint-docs.
Implementation plan and decisions

DEVEX-641: expose dynamic session counts

Status: implemented and reviewed. User selected app_name + family metric labels and server-owned display names plus local branded icon paths. Exact release numbers and telemetry ingestion sign-off remain unresolved.

Verified baseline

Decisions

  1. Registry and metadata: codersdk/appname.go owns attribution and presentation. SessionCounts map[string]int64 plus a sibling apps map of {display_name, icon} keyed by observed known app name on codersdk.SessionCountDeploymentStats. icon is an optional server-curated local asset path, never derived from reported names. Unknown names keep their normalized identifier and a generic icon. No metadata endpoint.
  2. Prometheus labels: both app_name and family. Arbitrary names remain user-controlled; the 64-name per-report cap is not a deployment-wide bound. Do not silently substitute family-only counts.
  3. Banner: positive counts only, four busiest apps first (descending count, then display name, then identifier), explicit empty state, +N more popover, known-family totals on hover/focus of Active Connections. Registry-owned icon paths rendered through ExternalImage with a generic fallback. No synthetic zero-valued entries and no hardcoded frontend app-label list.
  4. Release and telemetry approval: telemetry map is workspace_agent_stats[].session_counts alongside existing fields. Approval must cover receiver schema and arbitrary normalized app identifiers leaving the deployment.

Completion and follow-up

  • Legacy API fields and four gauges dual-publish for the confirmed release; no removals in this change.
  • File a cleanup issue before merge naming the removal release, all legacy fields/gauges, and separately coordinated telemetry removal.
  • Record ingestion-owner sign-off before declaring the telemetry acceptance criterion complete.

Generated by Coder Agents on behalf of @EhabY.

@linear-code

linear-code Bot commented Sep 15, 2026

Copy link
Copy Markdown

DEVEX-641

@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Docs preview

Check off each page once it's been reviewed. If a page changes in a later push, its checkbox clears automatically so it gets a fresh look. Pages not yet wired into the docs navigation aren't listed here.

@EhabY
EhabY added this pull request to stack #29135 September 15, 2026 14:57
Fix the per-app Prometheus gauge being cleared on empty poll windows by
committing it under the same guard as the other agentstats gauges, and
drop the test interval workaround that masked it.

Share one normalizing registry lookup for family and metadata, stop
cloning cached maps per request, and give the Web Terminal its own
generic icon plus label so it is distinguishable from SSH.

Consolidate tests: replace the internal Prometheus helpers, benchmarks
and duplicated decode table with one collector snapshot test and a
Vitest behavior test; reduce the banner stories to visual states.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant