Minor Changes
-
3d61cf9: Cap high-cardinality time-chart series to protect the browser from rendering
thousands of lines at once. Time charts now materialize and draw a bounded
number of series per tile, with escape hatches to reveal the rest on demand: a
"+N more" affordance in the hover and pinned tooltips, and a "load all series"
action that lifts the cap for a chart. Tooltips also cap how many rows they
render per frame so a wide bucket can't mount thousands of popovers. The
external dashboards API exposes the per-tile series limit as a three-state value
across tile types — omit for the default cap, 0 for unlimited, or a positive N
for the top N -
fa73b84: feat(mcp): add
clickstack_emerging_signalsMCP tool — a two-window Drain pattern novelty detector that set-differences mined log/event patterns between an earlier baseline window and a current window to surface what is newly emerging or has disappeared. Shares the Drain sample-and-mine pipeline withclickstack_event_patternsvia an extractedmineWindowPatternshelper, and keys patterns across windows with anormalizeTemplatehelper. -
97ca34d: feat: Allow configuring a
seriestable for accelerating metrics -
f9c5244: feat: add /v1/prometheus/query_exemplars, and harden the Prometheus proxy
Adds a
query_exemplarsroute that proxies to Prometheus's native
/api/v1/query_exemplarsfor Prometheus-backed connections, and answers with an
empty success for ClickHouse-backed ones, where exemplars are read from the metric
table instead.Three fixes to the shared proxy while adding a route to it:
- Responses now carry
X-Content-Type-Options: nosniff, set before anything can
return so the proxy's own error bodies get it too, and the upstream content-type
is never forwarded — every response is relabelledapplication/json. The
connection host is member-configured, so its response body is untrusted output on
our own origin, and an allowlist is easy to slip past:application/json, text/htmlclears a prefix-anchored JSON test while the browser keeps the last
media type. - A client that navigates away mid-body no longer counts as a backend error.
- Proxy failures increment
prometheusQueryErrors.proxyToPrometheushandles its
own failures and returns normally, so the callers'catchnever ran and all four
proxied endpoints reported zero errors while still recording duration. Counted on
5xx only, so a user's malformed PromQL does not read as a backend fault. - The exemplar window is bounded by narrowing rather than rejecting, so a wide
dashboard range still works.
- Responses now carry
-
1af1998: Add Terraform helpers for adopting existing HyperDX resources with the ClickHouse provider. An "Export to Terraform" button on dashboards, saved searches, and saved-search alerts shows a ready-to-paste
import {}block plus collapsible provider setup, and a team settings section ("API & Agents") downloads an import file covering dashboards, alerts, saved searches, sources, connections, and webhooks.Dashboards carrying a tile the provider cannot represent, and PromQL sources, are excluded from the export and reported as skipped — in the UI and in the generated file. The provider reads a dashboard back through the external API v2, which either drops such a tile or substitutes an empty line chart, and writes tiles back whole, so importing one would destroy that tile on the next apply.
Import-only by design: resource configuration is generated by
terraform plan -generate-config-out, which reads through the provider, rather than by HyperDX — the external API's dashboard serialisation is a field allowlist, so generatingdashboard_jsonfrom it could silently drop tile settings on apply. Tile alerts are excluded because the provider models only saved-search alerts.Terraform addresses are derived from each resource's id, not its name, so renaming a resource in HyperDX and re-exporting does not produce a destroy-and-recreate plan. The generator lives in
@hyperdx/common-utilsso the API can produce the same artefact the UI does. The manifest endpoint caps each listing at 1000 rows and reports which types were capped, so a very large team is told its export is partial rather than silently receiving one.Also redacts
AuthorizationandCookieheaders from API request logs.
Patch Changes
-
3f87fe4: Return 404 when updating a missing alert.
-
94d028c: Return a not-found response when updating a missing dashboard.
-
a794562: Clear stale source-specific alert references when changing alert source.
-
2d78083: fix: Expose
seriesLimitvia external API and MCP -
1c3be6f: Key the external API and MCP rate limiters on the access key, not the raw
AuthorizationheadervalidateUserAccessKeyaccepts any text beforeBearer, so a single access
key authenticates under unlimited header spellings. The limiter bucketed on the
header value, so varying that prefix handed each request a fresh quota. Requests
that carry no usable access key now fall back to the client IP. -
1af1998: Scope
DELETE /team/invitation/:idto the caller's team. It previously deleted by id alone, so any authenticated user could revoke another team's pending invitation if they knew its id. Unknown or out-of-team ids now return 404. -
Updated dependencies [3d61cf9]
-
Updated dependencies [ed9d9a6]
-
Updated dependencies [c97789a]
-
Updated dependencies [2468b25]
-
Updated dependencies [97ca34d]
-
Updated dependencies [6a35df0]
-
Updated dependencies [d1c669d]
-
Updated dependencies [1af1998]
-
Updated dependencies [b082f70]
-
Updated dependencies [347f0a6]
- @hyperdx/common-utils@0.25.0