Skip to content

feat(dashboards): deployment markers on tile charts - #2827

Open
teeohhem wants to merge 1 commit into
mainfrom
tomdeployment-markers
Open

feat(dashboards): deployment markers on tile charts#2827
teeohhem wants to merge 1 commit into
mainfrom
tomdeployment-markers

Conversation

@teeohhem

@teeohhem teeohhem commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Correlating a latency or error spike with a release currently means leaving HyperDX. Dashboard tiles can now overlay the moment each release went out, derived from changes in the OpenTelemetry service.version resource attribute, so no instrumentation change or CI integration is required. The markers reuse the annotation overlay built for alert firing/recovery lines, which was written source-agnostic for exactly this. They are off by default and toggled from the dashboard overflow menu, with the state carried in the URL as deployMarkers so a shared link keeps it.

Three rules keep the markers trustworthy rather than noisy. A marker only helps correlation if the reader can attribute it to something visible, so what a tile shows depends on what it charts:

Tile Markers
Filtered to one service That service's releases
Grouped by service Every charted service's releases, each tinted to match its own line
Aggregate line over many services None, since a marker naming a service with no visible line invites false attribution

The query runs against the tile's own source with the tile's own filters, which is what makes scoping possible: a chart filtered to one service is never annotated with another's. The version already running when the window opens is recognised and dropped rather than drawn as a deploy at the left edge. The shared annotation renderer also gains label collapsing, so dense clusters read as "N deploys" instead of overlapping text, sized from the estimated label width rather than a fixed gap.

Markers are available on log and trace sources. Metric sources resolve their table per metric type, so there is no single table to re-aggregate and no way to make a tile's filters meaningful against it; following the source correlation fields to a companion log source is the natural follow-up.

Screenshots or video

Verified against real OTLP data pushed through the collector (two services, four releases). Screenshots are captured locally and need attaching to this PR.

How to test on Vercel preview

Preview routes: /dashboards

Steps:

  1. Open /dashboards and create a new dashboard.
  2. Add a tile, choose the Logs source, and save it.
  3. Open the dashboard overflow menu (data-testid="dashboard-menu-button").
  4. Click "Show deployment markers" (data-testid="toggle-deploy-annotations-menu-item").
  5. Verify the URL gains deployMarkers=true and the menu item now reads "Hide deployment markers".
  6. Click "Hide deployment markers" and confirm deployMarkers is removed from the URL.

Note: whether marker lines actually render depends on the preview's demo data emitting the service.version resource attribute. The steps above assert the toggle and URL state, which hold regardless.

References


Compound Engineering
Claude Code

Correlating a latency or error spike with a release meant leaving the
product. Dashboard tiles can now overlay the moment each release went
out, derived from changes in the OpenTelemetry `service.version`
resource attribute, so no instrumentation change is needed.

Markers reuse the annotation overlay built for alert firing/recovery
lines, which was designed source-agnostic for exactly this.

Three properties make the markers trustworthy rather than noisy:

- Scoped to the tile. The query runs against the tile's own source with
  the tile's own filters, so a chart filtered to one service is not
  annotated with another service's releases.
- Tinted to the series. On a chart grouped by service, each marker takes
  its service's line color, so a release of one service cannot be read
  as another's.
- Suppressed when unattributable. An aggregate line spanning several
  services gets no markers at all, since a marker naming a service with
  no visible line invites false attribution.

The shared annotation renderer also gains label collapsing, so dense
clusters read as "N deploys" instead of overlapping text, sized from
the estimated label width rather than a fixed gap.
@changeset-bot

changeset-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 80a18e7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@hyperdx/app Minor
@hyperdx/api Minor
@hyperdx/otel-collector Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hyperdx-oss Ready Ready Preview Aug 6, 2026 4:05pm
hyperdx-storybook Ready Ready Preview Aug 6, 2026 4:05pm

Request Review

@greptile-apps

greptile-apps Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Dashboard time-series tiles can now query OpenTelemetry service-version data and overlay URL-controlled deployment markers alongside alert annotations.

  • Adds deployment query construction, tile scoping, version-row conversion, and empty-result notifications.
  • Adds series-aware marker coloring, annotation merging, and width-aware label collapsing.
  • Adds unit and end-to-end coverage for marker derivation, rendering, and dashboard toggle state.

Confidence Score: 4/5

The repeated-version transition defect should be fixed before merging because rollbacks and redeployments can silently disappear from the chart.

The query reduces every service/version pair to its earliest timestamp, so a later return to the same version cannot produce the deployment marker promised by the feature; the oversized hook is an additional maintainability concern.

Files Needing Attention: packages/app/src/hooks/useDeploymentAnnotations.tsx

Important Files Changed

Filename Overview
packages/app/src/hooks/useDeploymentAnnotations.tsx Adds deployment query and annotation mapping, but grouping by version and service loses later transitions back to an already-seen version.
packages/app/src/components/charts/chartAnnotations.tsx Adds annotation merging, series resolution, invalid-time filtering, and density-aware label collapsing with focused tests.
packages/app/src/DBDashboardPage.tsx Wires deployment annotations into dashboard tiles and exposes the URL-backed overflow-menu toggle.
packages/app/src/HDXMultiSeriesTimeChart.tsx Resolves annotation colors against visible series and supplies measured plot width for label layout.
packages/app/src/ChartUtils.tsx Adds a helper that maps annotation groups to current-period series colors.

Sequence Diagram

sequenceDiagram
  participant URL as Dashboard URL state
  participant Tile as Dashboard Tile
  participant Hook as useDeploymentAnnotations
  participant CH as ClickHouse
  participant Chart as Time Chart
  URL->>Tile: "deployMarkers=true"
  Tile->>Hook: source, filters, date range
  Hook->>CH: group service.version by service
  CH-->>Hook: firstSeen/version/service rows
  Hook-->>Tile: deployment annotations
  Tile->>Chart: merged alert and deployment annotations
  Chart->>Chart: resolve series colors and collapse labels
Loading

Fix All in Claude Code Fix All in Conductor Fix All in Cursor Fix All in Codex

Reviews (1): Last reviewed commit: "feat(dashboards): deployment markers on ..." | Re-trigger Greptile

Comment on lines +133 to +149
select: [
`min(${timestampExpression}) AS firstSeen`,
`${versionExpression} AS version`,
...(serviceExpression ? [`${serviceExpression} AS service`] : []),
].join(', '),
where: `${versionExpression} != ''`,
whereLanguage: 'sql',
...(scopeFilters.length ? { filters: scopeFilters } : {}),
groupBy: [
versionExpression,
...(serviceExpression ? [serviceExpression] : []),
].join(', '),
// The group-by columns are already spelled out in `select`; without this
// the renderer appends them a second time.
selectGroupBy: false,
orderBy: 'firstSeen ASC',
limit: { limit: MAX_DEPLOY_ROWS },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Version grouping hides rollbacks

When a service returns to a version already present in the query range, grouping by service and version with min(timestamp) collapses the later transition into its earliest occurrence, causing the rollback or redeployment marker to be omitted.

Knowledge Base Used: App Components and Charts

Fix in Claude Code Fix in Conductor Fix in Cursor Fix in Codex

}, [enabled, isFetching, data, annotations]);

return annotations;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Deployment hook exceeds size limit

This new 319-line file combines query construction, row conversion, notification behavior, and the React hook, exceeding the repository's 300-line limit and making these independent responsibilities harder to maintain.

Context Used: CLAUDE.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code Fix in Conductor Fix in Cursor Fix in Codex

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