Skip to content

Support per-signal OTLP exporter endpoints for Hyperdx internal telemetry#2098

Open
vinzee wants to merge 1 commit intohyperdxio:mainfrom
vinzee:va/otlp_endpoints
Open

Support per-signal OTLP exporter endpoints for Hyperdx internal telemetry#2098
vinzee wants to merge 1 commit intohyperdxio:mainfrom
vinzee:va/otlp_endpoints

Conversation

@vinzee
Copy link
Copy Markdown
Contributor

@vinzee vinzee commented Apr 10, 2026

Summary

This change allows for more granular control over OpenTelemetry data routing by enabling independent configuration of traces, metrics, and logs endpoints. This is particularly useful for complex networking environments or when using different backends for different telemetry types.

Additionally, the browser instrumentation has been updated to a local wrapper to better manage these signal-specific configurations and improve internal consistency.

How to test locally or on Vercel

1. Verify default behavior (no per-signal env vars set)

  1. Start HyperDX
  2. Confirm the app loads and works as before (login, search, navigate).
  3. curl http://localhost:8080/api/config | jq . -- verify collectorUrl is present and collectorTracesUrl / collectorMetricsUrl / collectorLogsUrl are absent (undefined values are omitted from JSON).

2. Verify per-signal env vars are exposed via the config API

  1. Stop the app. Set per-signal env vars and restart:
    export NEXT_PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://localhost:4318/v1/traces"
    export NEXT_PUBLIC_OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="http://localhost:4318/v1/logs"
    yarn dev
  2. curl http://localhost:8080/api/config | jq . -- confirm collectorTracesUrl and collectorLogsUrl now appear with the values set above.

3. Verify browser telemetry routes to separate endpoints

  1. Set the per-signal env vars to two different ports:
    export NEXT_PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://localhost:4318/v1/traces"
    export NEXT_PUBLIC_OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="http://localhost:4319/v1/logs"
    yarn dev
  2. Open the app in a browser with DevTools -> Network tab open.
  3. Navigate around, then filter requests by v1/traces and v1/logs. Confirm trace exports hit :4318 and session replay log exports hit :4319.

4. Verify server-side Node.js telemetry (API + Next.js server)

  1. @hyperdx/node-opentelemetry natively reads per-signal env vars. Set them and start:
    export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://localhost:4318/v1/traces"
    export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT="http://localhost:4319/v1/logs"
    export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT="http://localhost:4320/v1/metrics"
    yarn dev
  2. Confirm in otel-collector logs that each signal arrives at its respective endpoint.

References

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 10, 2026

@vinzee is attempting to deploy a commit to the HyperDX Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 10, 2026

🦋 Changeset detected

Latest commit: 6904bd7

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 Patch
@hyperdx/api Patch
@hyperdx/otel-collector Patch

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 10, 2026

PR Review

PR #2098 — Support per-signal OTLP exporter endpoints for HyperDX internal telemetry

  • ⚠️ collectorMetricsUrl is dead code — It's defined in config.ts, typed in types.ts, and exposed via /api/config, but never consumed in _app.tsx (only tracesUrl and logsUrl are passed to the browser SDK init). Either pass metricsUrl to the browser SDK if it supports it, or remove HDX_METRICS_COLLECTOR_URL / collectorMetricsUrl from the API response and type to avoid exposing unused infrastructure URLs to clients.

  • ⚠️ Missing EOF newline in packages/app/.env.development — The diff shows \ No newline at end of file. Add a trailing newline to keep consistent with project conventions.

✅ The core logic is correct: the fallback chain (NEXT_PUBLIC_*OTEL_* without prefix) is the right pattern for Next.js to support both build-time baking (Dockerfile) and runtime injection (docker-compose environment vars via the server-side API route).

@vinzee vinzee force-pushed the va/otlp_endpoints branch from a7c35a8 to e965f04 Compare April 13, 2026 22:14
@karl-power karl-power self-requested a review April 14, 2026 10:30
@vinzee vinzee force-pushed the va/otlp_endpoints branch from e965f04 to 6a2a41c Compare April 15, 2026 01:04
@karl-power
Copy link
Copy Markdown
Contributor

Hi @vinzee - thanks for the PR! This is a good idea. I think it would be better to update hyperdx-js directly to support this feature rather than re-implementing it here.

@github-actions github-actions Bot added the review/tier-3 Standard — full human review required label Apr 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🟡 Tier 3 — Standard

Introduces new logic, modifies core functionality, or touches areas with non-trivial risk.

Why this tier:

  • Cross-layer change: touches frontend (packages/app) + backend (packages/api)

Review process: Full human review — logic, architecture, edge cases.
SLA: First-pass feedback within 1 business day.

Stats
  • Production files changed: 11
  • Production lines changed: 212
  • Branch: va/otlp_endpoints
  • Author: vinzee

To override this classification, remove the review/tier-3 label and apply a different review/tier-* label. Manual overrides are preserved on subsequent pushes.

vinzee added a commit to vinzee/hyperdx-js that referenced this pull request Apr 17, 2026
Add optional `tracesUrl` and `logsUrl` config options to allow
independent configuration of trace and log export endpoints. When
omitted, the existing `${url}/v1/traces` and `${url}/v1/logs`
fallback behavior is preserved.

Refs: hyperdxio/hyperdx#2076, hyperdxio/hyperdx#2098
Made-with: Cursor
@vinzee
Copy link
Copy Markdown
Contributor Author

vinzee commented Apr 17, 2026

@karl-power created a PR for hyperdx-js. Will update this PR once the other one gets merged.
hyperdxio/hyperdx-js#234

vinzee added a commit to vinzee/hyperdx-js that referenced this pull request Apr 17, 2026
Add optional `tracesUrl` and `logsUrl` config options to allow
independent configuration of trace and log export endpoints. When
omitted, the existing `${url}/v1/traces` and `${url}/v1/logs`
fallback behavior is preserved.

Refs: hyperdxio/hyperdx#2076, hyperdxio/hyperdx#2098
Made-with: Cursor
@vinzee
Copy link
Copy Markdown
Contributor Author

vinzee commented Apr 21, 2026

@karl-power I dont see a new release for @hyperdx/browser having the changes from hyperdxio/hyperdx-js#234. would it possible to trigger a release manually? Not sure if that is automated. Thanks

@karl-power
Copy link
Copy Markdown
Contributor

@karl-power I dont see a new release for @hyperdx/browser having the changes from hyperdxio/hyperdx-js#234. would it possible to trigger a release manually? Not sure if that is automated. Thanks

Hi @vinzee Our release workflow was broken. I merged a PR to fix. Will get a release out ASAP.

@karl-power
Copy link
Copy Markdown
Contributor

@vinzee The release it out! Thanks for your patience 🙏🏻

@vinzee
Copy link
Copy Markdown
Contributor Author

vinzee commented Apr 21, 2026

@karl-power seems like npmMinimalAgeGate: 7d blocks from using recently published packages https://github.com/hyperdxio/hyperdx/blob/main/.yarnrc.yml#L5

I was able to test it locally by changing npmMinimalAgeGate temporarily. But i think the build will break in CI.

@vinzee vinzee force-pushed the va/otlp_endpoints branch from 6a2a41c to a3171b2 Compare April 21, 2026 19:51
@karl-power
Copy link
Copy Markdown
Contributor

karl-power commented Apr 22, 2026

@vinzee I've opened merged #2142

@vinzee vinzee force-pushed the va/otlp_endpoints branch 3 times, most recently from 0929059 to e69b147 Compare April 24, 2026 02:44
@vinzee
Copy link
Copy Markdown
Contributor Author

vinzee commented Apr 24, 2026

@karl-power rebased with master and clean up the diff. Please review whenever you get a chance. thanks!

Copy link
Copy Markdown
Contributor

@karl-power karl-power left a comment

Choose a reason for hiding this comment

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

Thanks @vinzee - looks good! Can you run yarn up @hyperdx/browser to bump it to 0.22.1

…ered options (hyperdxio#2015)

Merges the separate "section" and "group" container types into a single **DashboardContainer** concept with configurable options:

- **Collapsible** (optional, default true) — chevron toggle with URL-based collapse state
- **Bordered** (optional, default true) — visual border around the container
- **Tabbed** (optional) — add tabs to any container; tab bar appears with 2+ tabs. Active tab is per-viewer via URL state.
- **Alert indicators** — red dot on tabs (multi-tab groups) and on the group header (plain/collapsed) when a tile is in `AlertState.ALERT`, so an alerting group is visible at a glance even when the alerting tile is below the fold

This addresses the UX concern from hyperdxio#1972 that "section" and "group" are near-synonyms that force users to choose between two similar concepts.

**Dashboard with groups and tabs (expanded):**

![Groups with tabs](https://raw.githubusercontent.com/hyperdxio/hyperdx/feat/unified-group-backup/pr-screenshots/01-groups-with-tabs.png)

**Overflow menu (Add Tab, Collapse, Border, Delete):**

![Overflow menu](https://raw.githubusercontent.com/hyperdxio/hyperdx/feat/unified-group-backup/pr-screenshots/02-overflow-menu.png)

**Collapsed with pipe-separated tab names (Overview | Latency | Errors):**

![Collapsed](https://raw.githubusercontent.com/hyperdxio/hyperdx/feat/unified-group-backup/pr-screenshots/05-collapsed-pipe-tabs.png)

| Area | What to review |
|------|----------------|
| **Schema** — `types.ts` | new optional fields (`tabs`, `collapsible`, `bordered`, `activeTabId`, `tabId`); `type` discriminator removed |
| **DnD infrastructure** | `DashboardDndContext.tsx`, `DashboardDndComponents.tsx`: sortable wrappers, drag handle |
| **`DashboardContainer`** | `DashboardContainer.tsx` + `GroupTabBar.tsx`: unified component with tabs, collapse, borders, alerts, a11y |
| **Hooks** | `useDashboardContainers.tsx`: container/tab CRUD. `useTileSelection.ts`: multi-select + Cmd+G (auto-deletes emptied source containers) |
| **Dashboard page** | `DBDashboardPage.tsx`: wiring, alert computation, DnD, tile positioning, URL-based active-tab + collapse state |
| **Tests** | `DashboardContainer.test.tsx`, `useDashboardContainers.test.tsx`, `useTileSelection.test.tsx`, `dashboardSections.test.tsx` |

- **No `type` discriminator** — containers are defined by properties. Extensible via additional fields later (e.g., planned variable-repeat feature could add `repeat: { filterId; as: 'tabs' \| 'sections' }` cleanly onto the same container).
- **Collapsed label** — pipe-separated tab names (max 4 + "…"), not dot-separated, no duplicate header.
- **Alert indicators** — red dot on tabs with `AlertState.ALERT` tiles. Also shown at the group-header level when no tab bar is rendered (plain/collapsed), so a single alerting tile in a large dashboard isn't hidden.
- **Accessibility** — chevron has role/tabIndex/aria-expanded/onKeyDown. Hidden controls removed from tab order.
- **Per-viewer UI state via URL** — collapse/expand and active-tab are per-viewer (URL), falling back to DB defaults. Switching tabs in your browser doesn't affect another viewer's session.
- **Tab delete confirmation** — deleting a tab with tiles opens a 3-button modal: Cancel / Move Tiles to [first remaining tab] / Delete Tab & Tiles. Destructive option is the red primary.
- **Group delete confirmation** — deleting a group with tiles opens a 3-button modal: Cancel / Ungroup Tiles / Delete Group & Tiles. Ungroup preserves tiles as top-level; Delete removes them. Works consistently for plain groups, legacy sections, and multi-tab groups (all tiles across all tabs are handled).

- Dashboards without containers render as before
- Old `type: 'section'` containers parse successfully (Zod strips extra field)
- New optional fields (`collapsible`, `bordered`, `tabs`, `activeTabId`, `tabId`) — `undefined` treated as defaults
- No Mongoose migration needed: the `containers` field is a schemaless `Schema.Types.Array`; all validation happens at the Zod layer
- Covered by tests: `useDashboardContainers.test.tsx` "legacy dashboard upgrade path" and `dashboardSections.test.tsx:273` "old dashboards with type field still parse"

- ✅ Semantic tokens everywhere (replaced raw Mantine color tokens)
- ✅ Mantine components over raw HTML / `style` props
- ✅ Component decomposition — `GroupTabBar` extracted from the main component; `DashboardContainerRow` extracted from inline render in `DBDashboardPage`
- ✅ Accessibility — chevron a11y, hidden controls removed from tab order
- ✅ URL state for per-viewer UI (`activeTabId` + collapse/expand) — the only non-structural `setDashboard` call migrated off the server
- ✅ Renamed `GroupContainer` → `DashboardContainer` to match the schema type
- ✅ Auto-delete emptied source containers after Cmd+G regrouping
- ✅ 3-option prompt for group delete (Cancel / Ungroup Tiles / Delete Group & Tiles)
- ✅ Alert dot now appears on expanded plain/single-tab group headers (previously only on collapsed)
- ✅ Fix: spurious `setDashboard` on every tile drag in multi-tab containers (layout handler was built with all-tab tiles but RGL only renders visible-tab tiles)
- ✅ Take viewer to newly-created tab after Add Tab (clears stale URL override)
- ✅ Removed redundant WHAT-style comments; kept WHY / invariant comments
- ✅ Removed dead API surface (unused `handleToggleCollapsed` export from the hook)
- ✅ Documented the `:` separator invariant in the `activeTabs` URL param

- [x] 1515 app unit tests pass
- [x] 745 common-utils unit tests pass
- [x] ESLint clean across all packages (`make ci-lint`)
- [x] TypeScript clean (app, common-utils, api)
- [x] Changeset included
- [x] Verified on Vercel preview

Builds on hyperdxio#1972
@vinzee vinzee force-pushed the va/otlp_endpoints branch from e69b147 to 6904bd7 Compare April 24, 2026 17:31
@vinzee
Copy link
Copy Markdown
Contributor Author

vinzee commented Apr 25, 2026

@karl-power bumped it to 0.22.1 ✅

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 25, 2026

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

Project Deployment Actions Updated (UTC)
hyperdx-oss Error Error Apr 25, 2026 2:10pm

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review/tier-3 Standard — full human review required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants