diff --git a/.changeset/alert-multi-channel-api.md b/.changeset/alert-multi-channel-api.md deleted file mode 100644 index 51efda977b..0000000000 --- a/.changeset/alert-multi-channel-api.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@hyperdx/api': minor ---- - -Alerts can be configured with multiple notification channels (up to 10 webhooks) via the new `channels` field on the v2 external API, internal API, and the MCP `clickstack_save_alert` tool. The legacy singular `channel` field is still accepted on input and mirrored in responses, so existing integrations keep working unchanged. - -Note that alert updates are a full replace, not a merge. A client that sends only the legacy `channel` field when updating an alert that has several channels will reduce it to that one channel — fetch the alert and resend the complete `channels` array to preserve them. diff --git a/.changeset/alert-multi-channel-schemas.md b/.changeset/alert-multi-channel-schemas.md deleted file mode 100644 index 051b042e22..0000000000 --- a/.changeset/alert-multi-channel-schemas.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/common-utils': minor ---- - -Add plural alert notification channel schemas: `zAlertChannels` (1–10 entries), `MAX_ALERT_CHANNELS`, and a shared `channel`/`channels` cross-field validator, ahead of multi-channel alert support in the API. diff --git a/.changeset/alert-multi-channel-ui.md b/.changeset/alert-multi-channel-ui.md deleted file mode 100644 index a0e3584370..0000000000 --- a/.changeset/alert-multi-channel-ui.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/app': minor ---- - -Alert forms for saved searches and dashboard tiles can now send to several webhooks. Add or remove notification channels inline (up to 10); webhooks already chosen by the alert are greyed out in the other pickers, since duplicates are rejected. diff --git a/.changeset/api-mongo-readiness-and-retry.md b/.changeset/api-mongo-readiness-and-retry.md deleted file mode 100644 index 3077da389a..0000000000 --- a/.changeset/api-mongo-readiness-and-retry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/api': minor ---- - -The API now recovers from a MongoDB that is unreachable at startup, and exposes a Mongo-aware readiness endpoint. Previously a failed initial connect was never retried: the process kept listening while every Mongo-backed request timed out, `/health` reported 200, and Kubernetes kept the pod Ready indefinitely — cascading into OpAMP 500s and crash-looping collectors. The initial connection is now retried with capped exponential backoff until it succeeds, and both the API and OpAMP servers expose `GET /ready`, which returns 503 unless MongoDB is connected (point Kubernetes readiness probes at it; `/health` remains a pure liveness check). diff --git a/.changeset/bump-rrweb-player.md b/.changeset/bump-rrweb-player.md deleted file mode 100644 index 6e57102f68..0000000000 --- a/.changeset/bump-rrweb-player.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/app': patch ---- - -Upgrade the session replay player from `rrweb@2.0.0-alpha.8` to stable `rrweb@2.1.1`, aligning the replayer with the rrweb version used by current `@hyperdx/browser` recorders and picking up several years of upstream replayer fixes (style-sheet handling, virtual DOM, adopted stylesheets). Replay fidelity was verified for sessions recorded with both `rrweb@1.1.3` (older browser SDKs) and `rrweb@2.1.1` (current SDKs). diff --git a/.changeset/composed-outer-clauses.md b/.changeset/composed-outer-clauses.md deleted file mode 100644 index b8026c23e6..0000000000 --- a/.changeset/composed-outer-clauses.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/common-utils': patch ---- - -HAVING, ORDER BY and LIMIT on multi-series metric charts now apply to the final joined result instead of leaking into each per-series branch. They reference the chart's output columns — operand aliases, formula names/aliases, the ratio column, group-by columns and the time bucket — so a HAVING like `"err rate" > 0.5` filters the joined rows, ORDER BY actually orders the result (previously it was applied per branch and then discarded by the join), and LIMIT/OFFSET paginate one consistent group set across all series. diff --git a/.changeset/configurable-clickhouse-exporter-timeout.md b/.changeset/configurable-clickhouse-exporter-timeout.md deleted file mode 100644 index f21f328bd1..0000000000 --- a/.changeset/configurable-clickhouse-exporter-timeout.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@hyperdx/api': patch -'@hyperdx/otel-collector': patch ---- - -Allow the ClickHouse exporter request timeout to be configured with -`HYPERDX_OTEL_EXPORTER_TIMEOUT` in both OpAMP-managed and standalone collector -modes. The default remains 5 seconds. diff --git a/.changeset/copy-snippet-label-icon-ai-notebook.md b/.changeset/copy-snippet-label-icon-ai-notebook.md deleted file mode 100644 index 35656c03ea..0000000000 --- a/.changeset/copy-snippet-label-icon-ai-notebook.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@hyperdx/app': patch ---- - -Make the `CopySnippet` heading optional (omit `label` to hide it) and add -`IconAiNotebook`, a Tabler-compatible custom icon for AI notebooks. diff --git a/.changeset/dashboard-filter-variable-dependencies.md b/.changeset/dashboard-filter-variable-dependencies.md deleted file mode 100644 index e8b1eba673..0000000000 --- a/.changeset/dashboard-filter-variable-dependencies.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@hyperdx/app': patch -'@hyperdx/common-utils': patch ---- - -feat: Support dependent variable value queries diff --git a/.changeset/dashboard-variable-builder-charts.md b/.changeset/dashboard-variable-builder-charts.md deleted file mode 100644 index 8dab799fe7..0000000000 --- a/.changeset/dashboard-variable-builder-charts.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@hyperdx/app': patch -'@hyperdx/common-utils': patch ---- - -feat: Substitute dashboard variables in chart builder tiles diff --git a/.changeset/dashboard-variable-macro-args.md b/.changeset/dashboard-variable-macro-args.md deleted file mode 100644 index 1586957692..0000000000 --- a/.changeset/dashboard-variable-macro-args.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@hyperdx/app': patch -'@hyperdx/common-utils': patch ---- - -feat: Expand dashboard variables and macros nested in macro arguments diff --git a/.changeset/dull-carrots-bow.md b/.changeset/dull-carrots-bow.md deleted file mode 100644 index 950c823735..0000000000 --- a/.changeset/dull-carrots-bow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@hyperdx/api": patch ---- - -Disable mongoose autoIndex in check-alerts worker to prevent MongoExpiredSessionError diff --git a/.changeset/edit-alert-from-details-page.md b/.changeset/edit-alert-from-details-page.md deleted file mode 100644 index 26c3972e08..0000000000 --- a/.changeset/edit-alert-from-details-page.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@hyperdx/common-utils': patch -'@hyperdx/app': patch -'@hyperdx/api': patch ---- - -Allow editing and deleting alerts directly from the alert details page. An -"Edit alert" action opens a modal for changing the alert's threshold, -evaluation interval, schedule, group-by (saved-search alerts), notification -webhook, and note, and a Delete action (with confirmation) removes the alert -and returns to the alerts list. Alert API responses now include the -notification channel's webhook id and the alert's name/message template so -edits round-trip these fields. diff --git a/.changeset/eslint-react19-context-ref.md b/.changeset/eslint-react19-context-ref.md deleted file mode 100644 index 05315e43a8..0000000000 --- a/.changeset/eslint-react19-context-ref.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@hyperdx/app': patch ---- - -Adopt React 19 context and ref APIs across the app and enforce them via ESLint. -Render `` directly instead of ``, use the `use` hook -instead of `useContext`, and pass `ref` as a regular prop instead of wrapping -components in `forwardRef`. The corresponding `@eslint-react/no-context-provider`, -`no-use-context`, and `no-forward-ref` rules are promoted to `error` and the -app's `--max-warnings` ceiling is lowered. Behavior is unchanged. diff --git a/.changeset/event-source-formulas.md b/.changeset/event-source-formulas.md deleted file mode 100644 index e6d3a42023..0000000000 --- a/.changeset/event-source-formulas.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@hyperdx/common-utils': minor -'@hyperdx/app': minor ---- - -Formulas now work on log and trace sources, not just metrics. Time series, table and number charts on event sources can define derived series via letter-ref arithmetic expressions (e.g. `A / B * 100`), with the same editor controls (Add Formula, series letter badges, Show input series) previously offered only on metric sources. Event formulas compile inline into the chart's single-scan SELECT — no per-series query fan-out — with the same missing-data semantics as the existing events ratio toggle. diff --git a/.changeset/external-api-dashboard-filter-variables.md b/.changeset/external-api-dashboard-filter-variables.md deleted file mode 100644 index 5189138816..0000000000 --- a/.changeset/external-api-dashboard-filter-variables.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@hyperdx/api': patch -'@hyperdx/common-utils': patch ---- - -feat: Add dashboard variable properties to external dashboards API diff --git a/.changeset/fix-alert-marker-bucket-alignment.md b/.changeset/fix-alert-marker-bucket-alignment.md deleted file mode 100644 index 21bc168073..0000000000 --- a/.changeset/fix-alert-marker-bucket-alignment.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@hyperdx/common-utils": patch -"@hyperdx/api": patch -"@hyperdx/app": patch ---- - -Align alert firing/recovery chart markers with the evaluated data: markers are now drawn at the start of the newest evaluated bucket (matching the evaluation history table and the plotted data point) instead of at the evaluation time, which sat one bucket to the right. diff --git a/.changeset/fix-filter-facets-behind-proxy.md b/.changeset/fix-filter-facets-behind-proxy.md deleted file mode 100644 index 3460a74ba4..0000000000 --- a/.changeset/fix-filter-facets-behind-proxy.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@hyperdx/common-utils": patch ---- - -Fix filter sidebar values disappearing behind query proxies. Batched facet-value -queries (KV rollup and map text-index lookups) previously bound one query -parameter per key; with ~100 keys this exceeded the ClickHouse web client's URL -parameter budget, silently promoting the request to a multipart/form-data body -that proxy gateways can reject — every LowCardinality-column and map-attribute -filter then vanished without an error. Keys are now inlined as SQL-escaped -literals so the query rides the POST body with a constant parameter count. Also -fixes an operator-precedence bug that applied the KV rollup time filter (and -notEmpty guard) to only the last OR branch. diff --git a/.changeset/fix-filter-parser-paren-depth.md b/.changeset/fix-filter-parser-paren-depth.md deleted file mode 100644 index 73515f1d2d..0000000000 --- a/.changeset/fix-filter-parser-paren-depth.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@hyperdx/app': patch -'@hyperdx/common-utils': patch ---- - -Fix dashboard filter selection state breaking on complex expressions. The -filter parser (shared with the search page) now tracks parenthesis depth in -addition to quote depth, so selections stored for expression-based filters such -as `if(SeverityText = 'error' OR SeverityText = 'fatal', 'Errors', 'Non-errors')` -or `if(SeverityText IN ('error', 'fatal'), 'Errors', 'Non-errors')` are parsed -correctly instead of being dropped or split on operators/keywords nested inside -the expression. diff --git a/.changeset/fix-mcp-tool-schema-draft-2020-12.md b/.changeset/fix-mcp-tool-schema-draft-2020-12.md deleted file mode 100644 index 0978371567..0000000000 --- a/.changeset/fix-mcp-tool-schema-draft-2020-12.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@hyperdx/common-utils': patch -'@hyperdx/api': patch ---- - -Fix MCP tool schemas being rejected by strict JSON Schema draft 2020-12 clients. The number-tile `colorRules` `between` rule declared its `value` as a Zod tuple, which `zod-to-json-schema` renders in the draft-07 tuple form (`items: [ ... ]`). Draft 2020-12 requires `items` to be a schema rather than an array, so `clickstack_save_dashboard` and `clickstack_patch_dashboard` failed validation — and clients that forward MCP tool schemas straight to an LLM provider (e.g. the Anthropic API) rejected the entire tool list with `tools.N.custom.input_schema: JSON schema is invalid`, making the MCP server unusable. `value` is now a fixed-length array, which validates identically and serializes to the same `[min, max]` wire format. A new test validates every MCP tool's input schema against the 2020-12 metaschema so this cannot regress. diff --git a/.changeset/fix-multi-series-mixed-value-types.md b/.changeset/fix-multi-series-mixed-value-types.md deleted file mode 100644 index 5de81fda5f..0000000000 --- a/.changeset/fix-multi-series-mixed-value-types.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@hyperdx/common-utils': patch -'@hyperdx/app': patch ---- - -Fix multi-series metric charts mixing float and integer aggregations (e.g. histogram quantile + histogram count) failing with "No value columns found in result column metadata". The composed UNION ALL query now normalizes every series value to Float64, so the merged column type is deterministic instead of erroring with NO_COMMON_TYPE or producing a Variant(Float64, Int64) column depending on the ClickHouse server's `use_variant_as_common_type` setting. As a defensive layer, all-numeric `Variant(...)` result columns (e.g. from raw-SQL charts) are now also classified as numeric. diff --git a/.changeset/fix-surrounding-context-filters.md b/.changeset/fix-surrounding-context-filters.md deleted file mode 100644 index f7e9019156..0000000000 --- a/.changeset/fix-surrounding-context-filters.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@hyperdx/app": patch ---- - -Fix Surrounding Context filters for non-OTEL schemas by using the source's serviceNameExpression for the "Service" filter instead of hardcoded ResourceAttributes lookup. Also adds quick event attribute filters that let users toggle attributes from the current event to narrow surrounding context results. diff --git a/.changeset/formula-api-surfaces.md b/.changeset/formula-api-surfaces.md deleted file mode 100644 index 5094a9b34a..0000000000 --- a/.changeset/formula-api-surfaces.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@hyperdx/common-utils': minor -'@hyperdx/api': minor -'@hyperdx/cli': patch ---- - -Chart formulas are now supported across every API surface that persists or accepts chart configs. The external dashboards API v2 and the MCP `save_dashboard` / `patch_dashboard` tools accept `formulas` (letter-ref arithmetic over the tile's select items, e.g. `A / (A + B) * 100`) and `showOperandSeries` on line, stacked bar, table and number builder tiles, round-trip them through GET/PUT, and validate the expressions on write — unknown series refs, malformed syntax, combining formulas with `asRatio`, multiple formulas on a number tile, and formulas on formula-incapable source kinds (anything other than metric, log, or trace) are all rejected with actionable errors. MCP `query_tile` computes formula columns for both metric and log/trace event tiles, the query-guide prompt documents the feature, and the OpenAPI spec includes the new `Formula` schema. The CLI's dashboard tile pipeline now delegates its number/table config transforms to the shared common-utils implementations, so formula tiles render with operand-hiding behavior identical to the web. diff --git a/.changeset/formula-tile-alerts.md b/.changeset/formula-tile-alerts.md deleted file mode 100644 index b144dd6606..0000000000 --- a/.changeset/formula-tile-alerts.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/api': patch ---- - -Tile alerts on metric charts with formulas now evaluate the formula value instead of the last raw operand series: the alert task previously dropped `formulas`/`showOperandSeries` when rebuilding the tile's chart config, so an alert on a formula tile compared the threshold against a raw operand (e.g. bytes) rather than the derived value. Grouped ratio tile alerts also now honor `ratioMode` (`share_of_total` previously evaluated as `per_group`). diff --git a/.changeset/gate-clickhouse-query-debug-log.md b/.changeset/gate-clickhouse-query-debug-log.md deleted file mode 100644 index a0751f17df..0000000000 --- a/.changeset/gate-clickhouse-query-debug-log.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -'@hyperdx/common-utils': patch -'@hyperdx/api': patch -'@hyperdx/app': patch ---- - -fix: route per-query SQL debug logging through an injectable logger (#2416) - -`BaseClickhouseClient` dumped raw SQL to the console on every ClickHouse query, -unconditionally and outside the pino logger, flooding API logs with query spam. - -Query logging now goes through an optional per-client `customLogger` on -`ClickhouseClientOptions`, logged at `debug`, and is silent when no logger is -passed. The API injects a pino-backed logger, so query logging follows the -existing `HYPERDX_LOG_LEVEL` setting instead of writing to `console.debug`. The -browser client defaults to a console logger that pretty-prints the SQL as a -single multi-line block, so query SQL stays visible and readable in devtools in -all builds instead of wrapping into one long line. - -The API's log level now defaults to `info` (was `debug`), so SQL logging is -silent in production unless `HYPERDX_LOG_LEVEL=debug` is set. Dev and CI env -files already pin their levels explicitly and are unaffected. The default also -now applies when `HYPERDX_LOG_LEVEL` is set but empty — which is what Compose -passes when the variable is unset in the environment, and which previously made -pino throw at startup. diff --git a/.changeset/histogram-chart-categorical-color.md b/.changeset/histogram-chart-categorical-color.md deleted file mode 100644 index 344f2d4c2f..0000000000 --- a/.changeset/histogram-chart-categorical-color.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/app': patch ---- - -Use the categorical chart palette and shared tooltip on histogram charts (including Request Latency on the Services dashboard) instead of a hardcoded neon green fill and a one-off tooltip. diff --git a/.changeset/mcp-tool-error-status-message.md b/.changeset/mcp-tool-error-status-message.md deleted file mode 100644 index 81b32e945b..0000000000 --- a/.changeset/mcp-tool-error-status-message.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/api': patch ---- - -fix: populate the span StatusMessage on failed MCP tool calls so the error text is visible in the trace diff --git a/.changeset/metric-formula-editor.md b/.changeset/metric-formula-editor.md deleted file mode 100644 index 598a0fa7f3..0000000000 --- a/.changeset/metric-formula-editor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/app': minor ---- - -Add metric formula editing to the chart editor. Metric-source charts (time series, table, number) gain an "Add Formula" row: a letter-ref arithmetic expression over the chart's series (`A` = series 1, `B` = series 2, ...) such as `A / (A + B) * 100`, with inline structured validation (malformed expressions, unknown series references), per-formula alias and number format, and a "Show input series" toggle to render only the formula column(s) or the formula alongside its operand series. Series rows now carry their reference letter as a badge. Formulas and the "As Ratio" toggle are mutually exclusive, and formulas persist on dashboard tiles and standalone charts. diff --git a/.changeset/metric-formula-rendering.md b/.changeset/metric-formula-rendering.md deleted file mode 100644 index 93a4538953..0000000000 --- a/.changeset/metric-formula-rendering.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/common-utils': minor ---- - -Render metric formulas (`formulas` on builder chart configs) in the composed multi-series metric query. Letter-ref expressions like `A / (A + B + C) * 100` compile into the final SELECT projection over the pivoted per-series columns, with ratio-consistent missing-data semantics: a missing operand counts as 0 while a zero or missing division denominator yields NULL (a rendered gap). `showOperandSeries: false` emits only the formula column(s). Works for grouped and ungrouped line, table, and number charts, and single-series charts with a formula now route through the composed query path. diff --git a/.changeset/multi-series-convert-to-sql.md b/.changeset/multi-series-convert-to-sql.md deleted file mode 100644 index 42260c8ef3..0000000000 --- a/.changeset/multi-series-convert-to-sql.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/common-utils': minor ---- - -"Convert to SQL" now supports multi-series, ratio, and formula metric charts. The composed UNION ALL + pivot query is emitted as a macro-based raw-SQL template with a `$__sourceTable()` macro per series branch, instead of returning a "cannot be auto-converted" error. Non-time-series metric charts remain unsupported, matching the existing single-series restriction. diff --git a/.changeset/number-formula-operands.md b/.changeset/number-formula-operands.md deleted file mode 100644 index 1619da5c34..0000000000 --- a/.changeset/number-formula-operands.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/common-utils': patch ---- - -Number charts on metric formula configs always hide their operand series: `convertToNumberChartConfig` forces `showOperandSeries: false` when formulas are present, so the number tile renders the formula column rather than the first raw operand — regardless of the tile's "Show input series" setting on other display types or when a formula chart is switched to the Number display type. diff --git a/.changeset/per-signal-table-ttl.md b/.changeset/per-signal-table-ttl.md deleted file mode 100644 index 0ddc4e7519..0000000000 --- a/.changeset/per-signal-table-ttl.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@hyperdx/otel-collector': minor ---- - -feat: support per-signal ClickHouse table TTLs and reconcile TTL on existing tables - -Adds `HYPERDX_OTEL_EXPORTER_LOGS_TTL`, `HYPERDX_OTEL_EXPORTER_TRACES_TTL`, `HYPERDX_OTEL_EXPORTER_METRICS_TTL` and `HYPERDX_OTEL_EXPORTER_SESSIONS_TTL`, each falling back to the existing `HYPERDX_OTEL_EXPORTER_TABLES_TTL`, so retention can be configured independently per signal (e.g. keep logs and traces for 6 months while metrics stay at 30 days). - -When `HYPERDX_OTEL_EXPORTER_RECONCILE_TABLE_TTL=true`, the migrate tool also applies the configured TTL to tables that already exist (`ALTER TABLE ... MODIFY TTL`), diff-guarded so only tables whose retention actually differs are changed. Previously a changed TTL only affected newly-created tables. Extending a retention uses `materialize_ttl_after_modify=1` so data already on disk is kept for the new (longer) period; shrinking uses `=0` so a startup reconcile never triggers a bulk delete (existing parts age out under their old TTL). Only a plain ` + ` retention is rewritten: compound policies (`TO VOLUME`/`TO DISK` tiering, `RECOMPRESS`, `GROUP BY` rollups, several rules) and calendar-unit retentions (month/quarter/year) are reported and left untouched. Off by default. Implements hyperdxio/hyperdx#1311. diff --git a/.changeset/rotatable-personal-access-key.md b/.changeset/rotatable-personal-access-key.md deleted file mode 100644 index b02d20c71a..0000000000 --- a/.changeset/rotatable-personal-access-key.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@hyperdx/api': patch -'@hyperdx/app': patch -'@hyperdx/common-utils': patch ---- - -Add a Rotate action for the personal API access key in Team Settings → API & Agents. Previously the personal access key — the bearer token for the external API v2 and the MCP server — was generated once at account creation and could never be changed, so a leaked key could only be remediated by deleting the user. Rotating immediately revokes the previous key, so MCP / AI agent configs, external API v2 clients, Terraform / IaC providers, and CI scripts using the old key must be updated with the new one. Browser sessions are unaffected. diff --git a/.changeset/shared-chart-card.md b/.changeset/shared-chart-card.md deleted file mode 100644 index 096f168e93..0000000000 --- a/.changeset/shared-chart-card.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@hyperdx/app': patch ---- - -Introduce a shared `ChartCard` component that gives standalone charts the same -card treatment as custom dashboard tiles (bordered surface + full-bleed header -divider). The card header stays pinned while the card body scrolls (e.g. cards -wrapping a long list like "Top 20 Most Time Consuming Queries"): in card mode -the header is a fixed row and scrollable list content gets its own internal -scroll region, so the header no longer scrolls away once you pass the first -card-height of content. Migrate the Service -Dashboards (HTTP, Database, Errors, endpoint and DB-query side panels) and the -ClickHouse page from the old `ChartBox` wrapper to `ChartCard` so chart surfaces -look consistent across the app. diff --git a/.changeset/sort-json-viewer-keys.md b/.changeset/sort-json-viewer-keys.md deleted file mode 100644 index 97bc6b32d3..0000000000 --- a/.changeset/sort-json-viewer-keys.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/app': patch ---- - -fix: Sort JSON viewer keys alphabetically so wide Map columns are scannable diff --git a/.changeset/sql-where-kv-direct-read.md b/.changeset/sql-where-kv-direct-read.md deleted file mode 100644 index ef1c2351a6..0000000000 --- a/.changeset/sql-where-kv-direct-read.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@hyperdx/common-utils': patch ---- - -Apply the Map KV text-index rewrite (`Map['k'] = 'v'` → `has(ItemsCol, concat('k', '=', 'v'))`, enabling ClickHouse's direct-read optimization) to SQL predicates in the top-level `where` (search box, saved searches, alerts) and to SQL `aggCondition`s copied into the WHERE clause — previously only `sql`-type `filters[]` entries were rewritten diff --git a/.changeset/stale-agg-params-external-export.md b/.changeset/stale-agg-params-external-export.md deleted file mode 100644 index 7803e882a8..0000000000 --- a/.changeset/stale-agg-params-external-export.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@hyperdx/api": patch ---- - -Stop the external dashboards API returning aggregation parameters the aggregation cannot carry: a `level` left over from a quantile agg, or a `valueExpression` left over on a count. Both are ignored when rendering, but the input schema rejects them, so a GET body could not be PUT back and importing a dashboard into Terraform failed with "Level can only be used with quantile aggregation function". diff --git a/.env b/.env index 16e5e4b25a..cdd88e4a54 100644 --- a/.env +++ b/.env @@ -8,8 +8,8 @@ NEXT_ALL_IN_ONE_IMAGE_NAME_DOCKERHUB=clickhouse/clickstack-all-in-one ALL_IN_ONE_IMAGE_NAME_DOCKERHUB=hyperdx/hyperdx-all-in-one NEXT_OTEL_COLLECTOR_IMAGE_NAME_DOCKERHUB=clickhouse/clickstack-otel-collector OTEL_COLLECTOR_IMAGE_NAME_DOCKERHUB=hyperdx/hyperdx-otel-collector -CODE_VERSION=2.35.0 -IMAGE_VERSION_SUB_TAG=.35.0 +CODE_VERSION=2.36.0 +IMAGE_VERSION_SUB_TAG=.36.0 IMAGE_VERSION=2 IMAGE_NIGHTLY_TAG=2-nightly IMAGE_LATEST_TAG=latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 9592c8ea38..488b4c04a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,220 @@ PR — keep the `hyperdx-release-notes` comment marker intact when editing so yo edits survive regeneration. Per-package detail lives in each `packages/*/CHANGELOG.md`. +## v2.36.0 — 2026-08-21 + + + +Formulas are the headline of this release: any metric, log or trace chart can +now carry a derived series written as letter-ref arithmetic over its own series +(`A / (A + B) * 100`), authored in the chart editor and readable and writable +over the external API, MCP and the CLI. Alerts gained two long-standing +requests — up to ten notification webhooks per alert, and an Edit/Delete action +on the alert details page — and your personal API access key can finally be +rotated instead of being fixed for the life of the account. Operators get +per-signal ClickHouse table TTLs with optional reconciliation of existing +tables, a configurable exporter timeout, and an API that retries a MongoDB it +cannot reach at startup, behind a new `/ready` probe. Note the API logging +default change below before upgrading if you read query SQL out of your API +logs. + +### 💥 Breaking Changes + +- **The API's log level now defaults to `info`, and query SQL is no longer + dumped to the console**: `BaseClickhouseClient` printed raw SQL on every + ClickHouse query, unconditionally and outside the pino logger, flooding API + logs with query spam. Query logging now goes through the pino logger at + `debug`, and the API's default log level moves from `debug` to `info` — so + set `HYPERDX_LOG_LEVEL=debug` if you relied on seeing query SQL or other + debug output in production. Dev and CI env files pin their levels explicitly + and are unaffected. An empty `HYPERDX_LOG_LEVEL` — what Compose passes when + the variable is unset — now falls back to the default instead of making pino + throw at startup. In the browser, query SQL still goes to devtools, + pretty-printed as a readable multi-line block (#2679). + +### ✨ New Features + +- **Formulas on metric, log and trace charts**: time series, table and number + charts gain an "Add Formula" row where you write a letter-ref arithmetic + expression over the chart's series (`A` = series 1, `B` = series 2), with + inline validation of malformed expressions and unknown references, a + per-formula alias and number format, series letter badges, and a "Show input + series" toggle to render the formula on its own or alongside its operands. + Formulas and the "As Ratio" toggle are mutually exclusive, a missing operand + counts as 0 while a zero or missing denominator renders a gap, and number + tiles always show the formula rather than the first raw operand. Event-source + formulas compile inline into the chart's single-scan SELECT, so there's no + per-series query fan-out, and formulas persist on dashboard tiles and + standalone charts (#2909, #2908, #2953). +- **Formulas over the external API, MCP and CLI**: external dashboards API v2 + and the MCP `save_dashboard` / `patch_dashboard` tools accept `formulas` and + `showOperandSeries` on line, stacked bar, table and number builder tiles and + round-trip them through GET/PUT. Expressions are validated on write — unknown + series refs, malformed syntax, formulas combined with `asRatio`, several + formulas on a number tile, and formulas on source kinds that can't carry them + are all rejected with actionable errors. `query_tile` computes formula + columns for metric and event tiles, the query-guide prompt documents the + feature, and CLI-rendered tiles now hide operands exactly as the web does + (#2952). +- **Alerts can notify up to 10 webhooks**: alert forms for saved searches and + dashboard tiles let you add and remove notification channels inline, with + webhooks the alert already uses greyed out in the other pickers since + duplicates are rejected. The new `channels` field is available on the v2 + external API, the internal API and the MCP `clickstack_save_alert` tool, and + the singular `channel` field still works unchanged. One caveat for API + clients: an alert update is a full replace, not a merge, so fetch the alert + and resend the complete `channels` array — an update carrying only `channel` + reduces a multi-channel alert to that one webhook (#2846, #2848, #2845). +- **Edit and delete an alert from its details page**: an "Edit alert" action + opens a modal for the alert's threshold, evaluation interval, schedule, + group-by (saved-search alerts), notification webhook and note, and a Delete + action removes the alert after confirmation and returns you to the alerts + list. Alert API responses now include the notification channel's webhook id + and the alert's name and message template, so edits round-trip those fields + (#2931). +- **Rotate your personal API access key**: Team Settings → API & Agents gains a + Rotate action for the personal access key — the bearer token behind external + API v2 and the MCP server — which until now was generated once at account + creation and could only be changed by deleting the user. Rotating revokes the + previous key immediately, so update your MCP and AI agent configs, API + clients, Terraform providers and CI scripts with the new one. Browser + sessions are unaffected (#2926). +- **Per-signal ClickHouse table TTLs**: `HYPERDX_OTEL_EXPORTER_LOGS_TTL`, + `..._TRACES_TTL`, `..._METRICS_TTL` and `..._SESSIONS_TTL` each fall back to + the existing `HYPERDX_OTEL_EXPORTER_TABLES_TTL`, so you can keep logs and + traces for six months while metrics age out at 30 days. Set + `HYPERDX_OTEL_EXPORTER_RECONCILE_TABLE_TTL=true` and the migrate tool also + applies the configured retention to tables that already exist, where + previously a TTL change only reached newly-created tables. Reconciliation is + off by default and deliberately conservative: extending a retention keeps + data already on disk, shrinking one never triggers a bulk delete at startup, + and compound policies (tiering, `RECOMPRESS`, `GROUP BY` rollups) and + calendar-unit retentions are reported and left untouched (#2709). +- **The API survives a MongoDB that is unreachable at startup, and serves a + readiness probe**: a failed initial connect was never retried, so the process + kept listening while every Mongo-backed request timed out — `/health` still + answered 200, Kubernetes kept the pod Ready indefinitely, and the resulting + OpAMP 500s crash-looped collectors. The initial connection is now retried + with capped exponential backoff until it succeeds, and both the API and OpAMP + servers expose `GET /ready`, which returns 503 unless MongoDB is connected. + Point your Kubernetes readiness probes at it; `/health` remains a pure + liveness check (#2968). +- **Dashboard variables reach chart builder tiles**: variables are now + substituted into builder tiles as well as raw SQL, a variable's value query + can depend on other variables, and variables and macros nested inside macro + arguments are expanded (#2901, #2923, #2937). +- **Dashboard variables over the external API**: dashboard variable properties + are now carried by the external dashboards API, so a dashboard managed as + code keeps its variables (#2944). + +### 🔧 Improvements + +- **"Convert to SQL" handles multi-series, ratio and formula metric charts**: + the composed UNION ALL and pivot query is emitted as a macro-based raw-SQL + template with a `$__sourceTable()` macro per series branch, + instead of answering "cannot be auto-converted". Non-time-series metric + charts remain unsupported, as before (#2908). +- **The ClickHouse exporter timeout is configurable**: set + `HYPERDX_OTEL_EXPORTER_TIMEOUT` in either OpAMP-managed or standalone + collector mode. The default is still 5 seconds (#2899). +- **Map attribute searches use ClickHouse's direct-read path more often**: the + Map KV text-index rewrite now also applies to SQL predicates in the top-level + `where` — the search box, saved searches and alerts — and to SQL + `aggCondition`s copied into the WHERE clause, where previously only + `sql`-type filter entries were rewritten (#2948). +- **Failed MCP tool calls show their error in the trace**: the span's + `StatusMessage` is now populated, so you can read why a tool call failed + without correlating logs (#2934). +- **Interface polish**: standalone charts now use the same bordered card + treatment as dashboard tiles, with a header that stays pinned while a long + list like "Top 20 Most Time Consuming Queries" scrolls underneath (Service + Dashboards and the ClickHouse page are migrated); histogram charts, including + Request Latency on the Services dashboard, use the categorical palette and + shared tooltip instead of a hardcoded neon green fill; and JSON viewer keys + are sorted alphabetically so wide Map columns are scannable (#2829, #2949, + #2943). + +### 🐛 Bug Fixes + +- **Filter sidebar values no longer disappear behind a query proxy**: batched + facet-value queries bound one query parameter per key, and with around 100 + keys that exceeded the ClickHouse web client's URL parameter budget, silently + promoting the request to a multipart body that proxy gateways reject — every + LowCardinality-column and map-attribute filter then vanished with no error. + Keys are now inlined as escaped literals so the query rides the POST body + with a constant parameter count. Also fixes an operator-precedence bug that + applied the KV rollup time filter to only the last OR branch (#2932). +- **Dashboard filter selections survive complex expressions**: the filter + parser shared with the search page now tracks parenthesis depth as well as + quote depth, so a selection stored against an expression-based filter such as + `if(SeverityText IN ('error', 'fatal'), 'Errors', 'Non-errors')` is parsed + correctly instead of being dropped or split on a keyword nested inside the + expression (#2950). +- **Multi-series metric charts can mix float and integer aggregations**: a + chart combining, say, a histogram quantile with a histogram count failed with + "No value columns found in result column metadata". Every series value is now + normalised to Float64 so the merged column type is deterministic, rather than + erroring with NO_COMMON_TYPE or producing a Variant column depending on the + server's `use_variant_as_common_type` setting. All-numeric `Variant(...)` + columns from raw-SQL charts are also classified as numeric now (#2916). +- **HAVING, ORDER BY and LIMIT apply to the whole multi-series chart**: they + were leaking into each per-series branch, so an ORDER BY was applied per + branch and then discarded by the join. They now reference the chart's output + columns — operand aliases, formula names, the ratio column, group-by columns + and the time bucket — so a HAVING like `"err rate" > 0.5` filters the joined + rows and LIMIT/OFFSET paginate one consistent group set across every series + (#2946). +- **MCP tool schemas validate against JSON Schema draft 2020-12**: the + number-tile `colorRules` `between` rule declared its value as a tuple, which + serialises to the draft-07 form, so `clickstack_save_dashboard` and + `clickstack_patch_dashboard` failed validation — and clients that forward + tool schemas straight to an LLM provider rejected the entire tool list, + making the MCP server unusable. The wire format is unchanged, and a new test + validates every tool's schema against the 2020-12 metaschema (#2925). +- **Alert markers line up with the data they were evaluated against**: firing + and recovery markers are drawn at the start of the newest evaluated bucket, + matching the evaluation history table and the plotted point, instead of at + the evaluation time one bucket to the right (#2928). +- **Tile alerts on formula charts evaluate the formula**: the alert task + dropped `formulas` and `showOperandSeries` when rebuilding the tile's chart + config, so the threshold was compared against a raw operand (bytes, say) + rather than the derived value. Grouped ratio tile alerts also honour + `ratioMode` now, where `share_of_total` previously evaluated as `per_group` + (#2909). +- **Surrounding Context filters work on non-OTel schemas**: the "Service" + filter uses the source's `serviceNameExpression` instead of a hardcoded + ResourceAttributes lookup, and quick event attribute filters let you toggle + attributes from the current event to narrow the surrounding results (#2558). +- **The external dashboards API stops returning unusable aggregation + parameters**: a `level` left over from a quantile aggregation, or a + `valueExpression` left on a count, were ignored when rendering but rejected + by the input schema — so a GET body could not be PUT back, and importing a + dashboard into Terraform failed with "Level can only be used with quantile + aggregation function" (#2945). +- **The check-alerts worker no longer hits `MongoExpiredSessionError`**: + mongoose `autoIndex` is disabled in the worker (#2887). + +### 📦 Build / Packaging + +- **Session replay player upgraded to rrweb 2.1.1**: the replayer moves off + `2.0.0-alpha.8` onto the stable release used by current `@hyperdx/browser` + recorders, picking up several years of upstream fixes to style-sheet + handling, the virtual DOM and adopted stylesheets. Replay fidelity was + verified against sessions recorded with both older (`rrweb@1.1.3`) and + current SDKs, so existing recordings keep playing back (#2954). + + + +### 📦 Package changelogs + +- `@hyperdx/api` 2.35.0 → 2.36.0 — [changelog](https://github.com/hyperdxio/hyperdx/blob/main/packages/api/CHANGELOG.md#2360) +- `@hyperdx/app` 2.35.0 → 2.36.0 — [changelog](https://github.com/hyperdxio/hyperdx/blob/main/packages/app/CHANGELOG.md#2360) +- `@hyperdx/cli` 0.6.1 → 0.6.2 — [changelog](https://github.com/hyperdxio/hyperdx/blob/main/packages/cli/CHANGELOG.md#062) +- `@hyperdx/common-utils` 0.26.0 → 0.27.0 — [changelog](https://github.com/hyperdxio/hyperdx/blob/main/packages/common-utils/CHANGELOG.md#0270) +- `@hyperdx/otel-collector` 2.35.0 → 2.36.0 — [changelog](https://github.com/hyperdxio/hyperdx/blob/main/packages/otel-collector/CHANGELOG.md#2360) + + + ## v2.35.0 — 2026-08-14 diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md index fb841d1298..57d5357649 100644 --- a/packages/api/CHANGELOG.md +++ b/packages/api/CHANGELOG.md @@ -1,5 +1,78 @@ # @hyperdx/api +## 2.36.0 + +### Minor Changes + +- 8723d7af: Alerts can be configured with multiple notification channels (up to 10 webhooks) via the new `channels` field on the v2 external API, internal API, and the MCP `clickstack_save_alert` tool. The legacy singular `channel` field is still accepted on input and mirrored in responses, so existing integrations keep working unchanged. + + Note that alert updates are a full replace, not a merge. A client that sends only the legacy `channel` field when updating an alert that has several channels will reduce it to that one channel — fetch the alert and resend the complete `channels` array to preserve them. + +- a4b2ad00: The API now recovers from a MongoDB that is unreachable at startup, and exposes a Mongo-aware readiness endpoint. Previously a failed initial connect was never retried: the process kept listening while every Mongo-backed request timed out, `/health` reported 200, and Kubernetes kept the pod Ready indefinitely — cascading into OpAMP 500s and crash-looping collectors. The initial connection is now retried with capped exponential backoff until it succeeds, and both the API and OpAMP servers expose `GET /ready`, which returns 503 unless MongoDB is connected (point Kubernetes readiness probes at it; `/health` remains a pure liveness check). +- dc29d57f: Chart formulas are now supported across every API surface that persists or accepts chart configs. The external dashboards API v2 and the MCP `save_dashboard` / `patch_dashboard` tools accept `formulas` (letter-ref arithmetic over the tile's select items, e.g. `A / (A + B) * 100`) and `showOperandSeries` on line, stacked bar, table and number builder tiles, round-trip them through GET/PUT, and validate the expressions on write — unknown series refs, malformed syntax, combining formulas with `asRatio`, multiple formulas on a number tile, and formulas on formula-incapable source kinds (anything other than metric, log, or trace) are all rejected with actionable errors. MCP `query_tile` computes formula columns for both metric and log/trace event tiles, the query-guide prompt documents the feature, and the OpenAPI spec includes the new `Formula` schema. The CLI's dashboard tile pipeline now delegates its number/table config transforms to the shared common-utils implementations, so formula tiles render with operand-hiding behavior identical to the web. + +### Patch Changes + +- d205a776: Allow the ClickHouse exporter request timeout to be configured with + `HYPERDX_OTEL_EXPORTER_TIMEOUT` in both OpAMP-managed and standalone collector + modes. The default remains 5 seconds. +- 90da4097: Disable mongoose autoIndex in check-alerts worker to prevent MongoExpiredSessionError +- 43f68566: Allow editing and deleting alerts directly from the alert details page. An + "Edit alert" action opens a modal for changing the alert's threshold, + evaluation interval, schedule, group-by (saved-search alerts), notification + webhook, and note, and a Delete action (with confirmation) removes the alert + and returns to the alerts list. Alert API responses now include the + notification channel's webhook id and the alert's name/message template so + edits round-trip these fields. +- 40ec0858: feat: Add dashboard variable properties to external dashboards API +- b0b13806: Align alert firing/recovery chart markers with the evaluated data: markers are now drawn at the start of the newest evaluated bucket (matching the evaluation history table and the plotted data point) instead of at the evaluation time, which sat one bucket to the right. +- c592207b: Fix MCP tool schemas being rejected by strict JSON Schema draft 2020-12 clients. The number-tile `colorRules` `between` rule declared its `value` as a Zod tuple, which `zod-to-json-schema` renders in the draft-07 tuple form (`items: [ ... ]`). Draft 2020-12 requires `items` to be a schema rather than an array, so `clickstack_save_dashboard` and `clickstack_patch_dashboard` failed validation — and clients that forward MCP tool schemas straight to an LLM provider (e.g. the Anthropic API) rejected the entire tool list with `tools.N.custom.input_schema: JSON schema is invalid`, making the MCP server unusable. `value` is now a fixed-length array, which validates identically and serializes to the same `[min, max]` wire format. A new test validates every MCP tool's input schema against the 2020-12 metaschema so this cannot regress. +- e153f46d: Tile alerts on metric charts with formulas now evaluate the formula value instead of the last raw operand series: the alert task previously dropped `formulas`/`showOperandSeries` when rebuilding the tile's chart config, so an alert on a formula tile compared the threshold against a raw operand (e.g. bytes) rather than the derived value. Grouped ratio tile alerts also now honor `ratioMode` (`share_of_total` previously evaluated as `per_group`). +- 7294944a: fix: route per-query SQL debug logging through an injectable logger (#2416) + + `BaseClickhouseClient` dumped raw SQL to the console on every ClickHouse query, + unconditionally and outside the pino logger, flooding API logs with query spam. + + Query logging now goes through an optional per-client `customLogger` on + `ClickhouseClientOptions`, logged at `debug`, and is silent when no logger is + passed. The API injects a pino-backed logger, so query logging follows the + existing `HYPERDX_LOG_LEVEL` setting instead of writing to `console.debug`. The + browser client defaults to a console logger that pretty-prints the SQL as a + single multi-line block, so query SQL stays visible and readable in devtools in + all builds instead of wrapping into one long line. + + The API's log level now defaults to `info` (was `debug`), so SQL logging is + silent in production unless `HYPERDX_LOG_LEVEL=debug` is set. Dev and CI env + files already pin their levels explicitly and are unaffected. The default also + now applies when `HYPERDX_LOG_LEVEL` is set but empty — which is what Compose + passes when the variable is unset in the environment, and which previously made + pino throw at startup. + +- e60a7d30: fix: populate the span StatusMessage on failed MCP tool calls so the error text is visible in the trace +- 9f640a61: Add a Rotate action for the personal API access key in Team Settings → API & Agents. Previously the personal access key — the bearer token for the external API v2 and the MCP server — was generated once at account creation and could never be changed, so a leaked key could only be remediated by deleting the user. Rotating immediately revokes the previous key, so MCP / AI agent configs, external API v2 clients, Terraform / IaC providers, and CI scripts using the old key must be updated with the new one. Browser sessions are unaffected. +- 08e5b62f: Stop the external dashboards API returning aggregation parameters the aggregation cannot carry: a `level` left over from a quantile agg, or a `valueExpression` left over on a count. Both are ignored when rendering, but the input schema rejects them, so a GET body could not be PUT back and importing a dashboard into Terraform failed with "Level can only be used with quantile aggregation function". +- Updated dependencies [be26530f] +- Updated dependencies [c349a5dd] +- Updated dependencies [68d2ed20] +- Updated dependencies [2eedfb26] +- Updated dependencies [1ce61c0c] +- Updated dependencies [43f68566] +- Updated dependencies [b1d8dc14] +- Updated dependencies [40ec0858] +- Updated dependencies [b0b13806] +- Updated dependencies [a94d6da8] +- Updated dependencies [8be68100] +- Updated dependencies [c592207b] +- Updated dependencies [9c7742fa] +- Updated dependencies [dc29d57f] +- Updated dependencies [7294944a] +- Updated dependencies [3ecf73c2] +- Updated dependencies [3ecf73c2] +- Updated dependencies [e153f46d] +- Updated dependencies [9f640a61] +- Updated dependencies [ea127077] + - @hyperdx/common-utils@0.27.0 + ## 2.35.0 ### Minor Changes diff --git a/packages/api/package.json b/packages/api/package.json index aff2bd9615..1ec6f1e1db 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@hyperdx/api", - "version": "2.35.0", + "version": "2.36.0", "license": "MIT", "private": true, "engines": { @@ -21,7 +21,7 @@ "@braintree/sanitize-url": "^7.1.1", "@clickhouse/client-common": "1.23.0-head.fae5998.1", "@esm2cjs/p-queue": "^7.3.0", - "@hyperdx/common-utils": "^0.26.0", + "@hyperdx/common-utils": "^0.27.0", "@hyperdx/node-opentelemetry": "^0.9.0", "@hyperdx/passport-local-mongoose": "^9.0.1", "@modelcontextprotocol/sdk": "^1.27.1", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index cdadf8adac..2b9e80263f 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,107 @@ # @hyperdx/app +## 2.36.0 + +### Minor Changes + +- fb284465: Alert forms for saved searches and dashboard tiles can now send to several webhooks. Add or remove notification channels inline (up to 10); webhooks already chosen by the alert are greyed out in the other pickers, since duplicates are rejected. +- b1d8dc14: Formulas now work on log and trace sources, not just metrics. Time series, table and number charts on event sources can define derived series via letter-ref arithmetic expressions (e.g. `A / B * 100`), with the same editor controls (Add Formula, series letter badges, Show input series) previously offered only on metric sources. Event formulas compile inline into the chart's single-scan SELECT — no per-series query fan-out — with the same missing-data semantics as the existing events ratio toggle. +- e153f46d: Add metric formula editing to the chart editor. Metric-source charts (time series, table, number) gain an "Add Formula" row: a letter-ref arithmetic expression over the chart's series (`A` = series 1, `B` = series 2, ...) such as `A / (A + B) * 100`, with inline structured validation (malformed expressions, unknown series references), per-formula alias and number format, and a "Show input series" toggle to render only the formula column(s) or the formula alongside its operand series. Series rows now carry their reference letter as a badge. Formulas and the "As Ratio" toggle are mutually exclusive, and formulas persist on dashboard tiles and standalone charts. + +### Patch Changes + +- 59b96e99: Upgrade the session replay player from `rrweb@2.0.0-alpha.8` to stable `rrweb@2.1.1`, aligning the replayer with the rrweb version used by current `@hyperdx/browser` recorders and picking up several years of upstream replayer fixes (style-sheet handling, virtual DOM, adopted stylesheets). Replay fidelity was verified for sessions recorded with both `rrweb@1.1.3` (older browser SDKs) and `rrweb@2.1.1` (current SDKs). +- f31a1458: Make the `CopySnippet` heading optional (omit `label` to hide it) and add + `IconAiNotebook`, a Tabler-compatible custom icon for AI notebooks. +- 68d2ed20: feat: Support dependent variable value queries +- 2eedfb26: feat: Substitute dashboard variables in chart builder tiles +- 1ce61c0c: feat: Expand dashboard variables and macros nested in macro arguments +- 43f68566: Allow editing and deleting alerts directly from the alert details page. An + "Edit alert" action opens a modal for changing the alert's threshold, + evaluation interval, schedule, group-by (saved-search alerts), notification + webhook, and note, and a Delete action (with confirmation) removes the alert + and returns to the alerts list. Alert API responses now include the + notification channel's webhook id and the alert's name/message template so + edits round-trip these fields. +- 905d1941: Adopt React 19 context and ref APIs across the app and enforce them via ESLint. + Render `` directly instead of ``, use the `use` hook + instead of `useContext`, and pass `ref` as a regular prop instead of wrapping + components in `forwardRef`. The corresponding `@eslint-react/no-context-provider`, + `no-use-context`, and `no-forward-ref` rules are promoted to `error` and the + app's `--max-warnings` ceiling is lowered. Behavior is unchanged. +- b0b13806: Align alert firing/recovery chart markers with the evaluated data: markers are now drawn at the start of the newest evaluated bucket (matching the evaluation history table and the plotted data point) instead of at the evaluation time, which sat one bucket to the right. +- 8be68100: Fix dashboard filter selection state breaking on complex expressions. The + filter parser (shared with the search page) now tracks parenthesis depth in + addition to quote depth, so selections stored for expression-based filters such + as `if(SeverityText = 'error' OR SeverityText = 'fatal', 'Errors', 'Non-errors')` + or `if(SeverityText IN ('error', 'fatal'), 'Errors', 'Non-errors')` are parsed + correctly instead of being dropped or split on operators/keywords nested inside + the expression. +- 9c7742fa: Fix multi-series metric charts mixing float and integer aggregations (e.g. histogram quantile + histogram count) failing with "No value columns found in result column metadata". The composed UNION ALL query now normalizes every series value to Float64, so the merged column type is deterministic instead of erroring with NO_COMMON_TYPE or producing a Variant(Float64, Int64) column depending on the ClickHouse server's `use_variant_as_common_type` setting. As a defensive layer, all-numeric `Variant(...)` result columns (e.g. from raw-SQL charts) are now also classified as numeric. +- 75909ace: Fix Surrounding Context filters for non-OTEL schemas by using the source's serviceNameExpression for the "Service" filter instead of hardcoded ResourceAttributes lookup. Also adds quick event attribute filters that let users toggle attributes from the current event to narrow surrounding context results. +- 7294944a: fix: route per-query SQL debug logging through an injectable logger (#2416) + + `BaseClickhouseClient` dumped raw SQL to the console on every ClickHouse query, + unconditionally and outside the pino logger, flooding API logs with query spam. + + Query logging now goes through an optional per-client `customLogger` on + `ClickhouseClientOptions`, logged at `debug`, and is silent when no logger is + passed. The API injects a pino-backed logger, so query logging follows the + existing `HYPERDX_LOG_LEVEL` setting instead of writing to `console.debug`. The + browser client defaults to a console logger that pretty-prints the SQL as a + single multi-line block, so query SQL stays visible and readable in devtools in + all builds instead of wrapping into one long line. + + The API's log level now defaults to `info` (was `debug`), so SQL logging is + silent in production unless `HYPERDX_LOG_LEVEL=debug` is set. Dev and CI env + files already pin their levels explicitly and are unaffected. The default also + now applies when `HYPERDX_LOG_LEVEL` is set but empty — which is what Compose + passes when the variable is unset in the environment, and which previously made + pino throw at startup. + +- 47fe0cd9: Use the categorical chart palette and shared tooltip on histogram charts (including Request Latency on the Services dashboard) instead of a hardcoded neon green fill and a one-off tooltip. +- 9f640a61: Add a Rotate action for the personal API access key in Team Settings → API & Agents. Previously the personal access key — the bearer token for the external API v2 and the MCP server — was generated once at account creation and could never be changed, so a leaked key could only be remediated by deleting the user. Rotating immediately revokes the previous key, so MCP / AI agent configs, external API v2 clients, Terraform / IaC providers, and CI scripts using the old key must be updated with the new one. Browser sessions are unaffected. +- c4dcab95: Introduce a shared `ChartCard` component that gives standalone charts the same + card treatment as custom dashboard tiles (bordered surface + full-bleed header + divider). The card header stays pinned while the card body scrolls (e.g. cards + wrapping a long list like "Top 20 Most Time Consuming Queries"): in card mode + the header is a fixed row and scrollable list content gets its own internal + scroll region, so the header no longer scrolls away once you pass the first + card-height of content. Migrate the Service + Dashboards (HTTP, Database, Errors, endpoint and DB-query side panels) and the + ClickHouse page from the old `ChartBox` wrapper to `ChartCard` so chart surfaces + look consistent across the app. +- adba65ab: fix: Sort JSON viewer keys alphabetically so wide Map columns are scannable +- Updated dependencies [8723d7af] +- Updated dependencies [be26530f] +- Updated dependencies [a4b2ad00] +- Updated dependencies [c349a5dd] +- Updated dependencies [d205a776] +- Updated dependencies [68d2ed20] +- Updated dependencies [2eedfb26] +- Updated dependencies [1ce61c0c] +- Updated dependencies [90da4097] +- Updated dependencies [43f68566] +- Updated dependencies [b1d8dc14] +- Updated dependencies [40ec0858] +- Updated dependencies [b0b13806] +- Updated dependencies [a94d6da8] +- Updated dependencies [8be68100] +- Updated dependencies [c592207b] +- Updated dependencies [9c7742fa] +- Updated dependencies [dc29d57f] +- Updated dependencies [e153f46d] +- Updated dependencies [7294944a] +- Updated dependencies [e60a7d30] +- Updated dependencies [3ecf73c2] +- Updated dependencies [3ecf73c2] +- Updated dependencies [e153f46d] +- Updated dependencies [9f640a61] +- Updated dependencies [ea127077] +- Updated dependencies [08e5b62f] + - @hyperdx/api@2.36.0 + - @hyperdx/common-utils@0.27.0 + ## 2.35.0 ### Minor Changes diff --git a/packages/app/package.json b/packages/app/package.json index 74e0962d05..5a0c996dfd 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@hyperdx/app", - "version": "2.35.0", + "version": "2.36.0", "private": true, "license": "MIT", "engines": { @@ -38,7 +38,7 @@ "@hookform/resolvers": "^3.9.0", "@hyperdx/api": "workspace:*", "@hyperdx/browser": "^0.22.1", - "@hyperdx/common-utils": "^0.26.0", + "@hyperdx/common-utils": "^0.27.0", "@hyperdx/node-opentelemetry": "^0.9.0", "@mantine/core": "^9.0.0", "@mantine/dates": "^9.0.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index d91822777c..ea2c5a2d75 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,11 @@ # @hyperdx/cli +## 0.6.2 + +### Patch Changes + +- dc29d57f: Chart formulas are now supported across every API surface that persists or accepts chart configs. The external dashboards API v2 and the MCP `save_dashboard` / `patch_dashboard` tools accept `formulas` (letter-ref arithmetic over the tile's select items, e.g. `A / (A + B) * 100`) and `showOperandSeries` on line, stacked bar, table and number builder tiles, round-trip them through GET/PUT, and validate the expressions on write — unknown series refs, malformed syntax, combining formulas with `asRatio`, multiple formulas on a number tile, and formulas on formula-incapable source kinds (anything other than metric, log, or trace) are all rejected with actionable errors. MCP `query_tile` computes formula columns for both metric and log/trace event tiles, the query-guide prompt documents the feature, and the OpenAPI spec includes the new `Formula` schema. The CLI's dashboard tile pipeline now delegates its number/table config transforms to the shared common-utils implementations, so formula tiles render with operand-hiding behavior identical to the web. + ## 0.6.1 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index b4940a040a..c2e16dcf9f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@hyperdx/cli", - "version": "0.6.1", + "version": "0.6.2", "license": "MIT", "type": "module", "repository": { @@ -41,7 +41,7 @@ }, "devDependencies": { "@clickhouse/client": "1.23.0-head.fae5998.1", - "@hyperdx/common-utils": "^0.26.0", + "@hyperdx/common-utils": "^0.27.0", "@jest/globals": "^30.2.0", "@types/crypto-js": "^4.2.2", "@types/jest": "^29.5.14", diff --git a/packages/common-utils/CHANGELOG.md b/packages/common-utils/CHANGELOG.md index 665df4ee8c..be43917526 100644 --- a/packages/common-utils/CHANGELOG.md +++ b/packages/common-utils/CHANGELOG.md @@ -1,5 +1,72 @@ # @hyperdx/common-utils +## 0.27.0 + +### Minor Changes + +- be26530f: Add plural alert notification channel schemas: `zAlertChannels` (1–10 entries), `MAX_ALERT_CHANNELS`, and a shared `channel`/`channels` cross-field validator, ahead of multi-channel alert support in the API. +- b1d8dc14: Formulas now work on log and trace sources, not just metrics. Time series, table and number charts on event sources can define derived series via letter-ref arithmetic expressions (e.g. `A / B * 100`), with the same editor controls (Add Formula, series letter badges, Show input series) previously offered only on metric sources. Event formulas compile inline into the chart's single-scan SELECT — no per-series query fan-out — with the same missing-data semantics as the existing events ratio toggle. +- dc29d57f: Chart formulas are now supported across every API surface that persists or accepts chart configs. The external dashboards API v2 and the MCP `save_dashboard` / `patch_dashboard` tools accept `formulas` (letter-ref arithmetic over the tile's select items, e.g. `A / (A + B) * 100`) and `showOperandSeries` on line, stacked bar, table and number builder tiles, round-trip them through GET/PUT, and validate the expressions on write — unknown series refs, malformed syntax, combining formulas with `asRatio`, multiple formulas on a number tile, and formulas on formula-incapable source kinds (anything other than metric, log, or trace) are all rejected with actionable errors. MCP `query_tile` computes formula columns for both metric and log/trace event tiles, the query-guide prompt documents the feature, and the OpenAPI spec includes the new `Formula` schema. The CLI's dashboard tile pipeline now delegates its number/table config transforms to the shared common-utils implementations, so formula tiles render with operand-hiding behavior identical to the web. +- 3ecf73c2: Render metric formulas (`formulas` on builder chart configs) in the composed multi-series metric query. Letter-ref expressions like `A / (A + B + C) * 100` compile into the final SELECT projection over the pivoted per-series columns, with ratio-consistent missing-data semantics: a missing operand counts as 0 while a zero or missing division denominator yields NULL (a rendered gap). `showOperandSeries: false` emits only the formula column(s). Works for grouped and ungrouped line, table, and number charts, and single-series charts with a formula now route through the composed query path. +- 3ecf73c2: "Convert to SQL" now supports multi-series, ratio, and formula metric charts. The composed UNION ALL + pivot query is emitted as a macro-based raw-SQL template with a `$__sourceTable()` macro per series branch, instead of returning a "cannot be auto-converted" error. Non-time-series metric charts remain unsupported, matching the existing single-series restriction. + +### Patch Changes + +- c349a5dd: HAVING, ORDER BY and LIMIT on multi-series metric charts now apply to the final joined result instead of leaking into each per-series branch. They reference the chart's output columns — operand aliases, formula names/aliases, the ratio column, group-by columns and the time bucket — so a HAVING like `"err rate" > 0.5` filters the joined rows, ORDER BY actually orders the result (previously it was applied per branch and then discarded by the join), and LIMIT/OFFSET paginate one consistent group set across all series. +- 68d2ed20: feat: Support dependent variable value queries +- 2eedfb26: feat: Substitute dashboard variables in chart builder tiles +- 1ce61c0c: feat: Expand dashboard variables and macros nested in macro arguments +- 43f68566: Allow editing and deleting alerts directly from the alert details page. An + "Edit alert" action opens a modal for changing the alert's threshold, + evaluation interval, schedule, group-by (saved-search alerts), notification + webhook, and note, and a Delete action (with confirmation) removes the alert + and returns to the alerts list. Alert API responses now include the + notification channel's webhook id and the alert's name/message template so + edits round-trip these fields. +- 40ec0858: feat: Add dashboard variable properties to external dashboards API +- b0b13806: Align alert firing/recovery chart markers with the evaluated data: markers are now drawn at the start of the newest evaluated bucket (matching the evaluation history table and the plotted data point) instead of at the evaluation time, which sat one bucket to the right. +- a94d6da8: Fix filter sidebar values disappearing behind query proxies. Batched facet-value + queries (KV rollup and map text-index lookups) previously bound one query + parameter per key; with ~100 keys this exceeded the ClickHouse web client's URL + parameter budget, silently promoting the request to a multipart/form-data body + that proxy gateways can reject — every LowCardinality-column and map-attribute + filter then vanished without an error. Keys are now inlined as SQL-escaped + literals so the query rides the POST body with a constant parameter count. Also + fixes an operator-precedence bug that applied the KV rollup time filter (and + notEmpty guard) to only the last OR branch. +- 8be68100: Fix dashboard filter selection state breaking on complex expressions. The + filter parser (shared with the search page) now tracks parenthesis depth in + addition to quote depth, so selections stored for expression-based filters such + as `if(SeverityText = 'error' OR SeverityText = 'fatal', 'Errors', 'Non-errors')` + or `if(SeverityText IN ('error', 'fatal'), 'Errors', 'Non-errors')` are parsed + correctly instead of being dropped or split on operators/keywords nested inside + the expression. +- c592207b: Fix MCP tool schemas being rejected by strict JSON Schema draft 2020-12 clients. The number-tile `colorRules` `between` rule declared its `value` as a Zod tuple, which `zod-to-json-schema` renders in the draft-07 tuple form (`items: [ ... ]`). Draft 2020-12 requires `items` to be a schema rather than an array, so `clickstack_save_dashboard` and `clickstack_patch_dashboard` failed validation — and clients that forward MCP tool schemas straight to an LLM provider (e.g. the Anthropic API) rejected the entire tool list with `tools.N.custom.input_schema: JSON schema is invalid`, making the MCP server unusable. `value` is now a fixed-length array, which validates identically and serializes to the same `[min, max]` wire format. A new test validates every MCP tool's input schema against the 2020-12 metaschema so this cannot regress. +- 9c7742fa: Fix multi-series metric charts mixing float and integer aggregations (e.g. histogram quantile + histogram count) failing with "No value columns found in result column metadata". The composed UNION ALL query now normalizes every series value to Float64, so the merged column type is deterministic instead of erroring with NO_COMMON_TYPE or producing a Variant(Float64, Int64) column depending on the ClickHouse server's `use_variant_as_common_type` setting. As a defensive layer, all-numeric `Variant(...)` result columns (e.g. from raw-SQL charts) are now also classified as numeric. +- 7294944a: fix: route per-query SQL debug logging through an injectable logger (#2416) + + `BaseClickhouseClient` dumped raw SQL to the console on every ClickHouse query, + unconditionally and outside the pino logger, flooding API logs with query spam. + + Query logging now goes through an optional per-client `customLogger` on + `ClickhouseClientOptions`, logged at `debug`, and is silent when no logger is + passed. The API injects a pino-backed logger, so query logging follows the + existing `HYPERDX_LOG_LEVEL` setting instead of writing to `console.debug`. The + browser client defaults to a console logger that pretty-prints the SQL as a + single multi-line block, so query SQL stays visible and readable in devtools in + all builds instead of wrapping into one long line. + + The API's log level now defaults to `info` (was `debug`), so SQL logging is + silent in production unless `HYPERDX_LOG_LEVEL=debug` is set. Dev and CI env + files already pin their levels explicitly and are unaffected. The default also + now applies when `HYPERDX_LOG_LEVEL` is set but empty — which is what Compose + passes when the variable is unset in the environment, and which previously made + pino throw at startup. + +- e153f46d: Number charts on metric formula configs always hide their operand series: `convertToNumberChartConfig` forces `showOperandSeries: false` when formulas are present, so the number tile renders the formula column rather than the first raw operand — regardless of the tile's "Show input series" setting on other display types or when a formula chart is switched to the Number display type. +- 9f640a61: Add a Rotate action for the personal API access key in Team Settings → API & Agents. Previously the personal access key — the bearer token for the external API v2 and the MCP server — was generated once at account creation and could never be changed, so a leaked key could only be remediated by deleting the user. Rotating immediately revokes the previous key, so MCP / AI agent configs, external API v2 clients, Terraform / IaC providers, and CI scripts using the old key must be updated with the new one. Browser sessions are unaffected. +- ea127077: Apply the Map KV text-index rewrite (`Map['k'] = 'v'` → `has(ItemsCol, concat('k', '=', 'v'))`, enabling ClickHouse's direct-read optimization) to SQL predicates in the top-level `where` (search box, saved searches, alerts) and to SQL `aggCondition`s copied into the WHERE clause — previously only `sql`-type `filters[]` entries were rewritten + ## 0.26.0 ### Minor Changes diff --git a/packages/common-utils/package.json b/packages/common-utils/package.json index e1fa73f399..ef8f573e98 100644 --- a/packages/common-utils/package.json +++ b/packages/common-utils/package.json @@ -1,7 +1,7 @@ { "name": "@hyperdx/common-utils", "description": "Common utilities for HyperDX application", - "version": "0.26.0", + "version": "0.27.0", "license": "MIT", "private": true, "files": [ diff --git a/packages/otel-collector/CHANGELOG.md b/packages/otel-collector/CHANGELOG.md index e4f7fb472e..17cbaf30d0 100644 --- a/packages/otel-collector/CHANGELOG.md +++ b/packages/otel-collector/CHANGELOG.md @@ -1,5 +1,21 @@ # @hyperdx/otel-collector +## 2.36.0 + +### Minor Changes + +- 395ae8d6: feat: support per-signal ClickHouse table TTLs and reconcile TTL on existing tables + + Adds `HYPERDX_OTEL_EXPORTER_LOGS_TTL`, `HYPERDX_OTEL_EXPORTER_TRACES_TTL`, `HYPERDX_OTEL_EXPORTER_METRICS_TTL` and `HYPERDX_OTEL_EXPORTER_SESSIONS_TTL`, each falling back to the existing `HYPERDX_OTEL_EXPORTER_TABLES_TTL`, so retention can be configured independently per signal (e.g. keep logs and traces for 6 months while metrics stay at 30 days). + + When `HYPERDX_OTEL_EXPORTER_RECONCILE_TABLE_TTL=true`, the migrate tool also applies the configured TTL to tables that already exist (`ALTER TABLE ... MODIFY TTL`), diff-guarded so only tables whose retention actually differs are changed. Previously a changed TTL only affected newly-created tables. Extending a retention uses `materialize_ttl_after_modify=1` so data already on disk is kept for the new (longer) period; shrinking uses `=0` so a startup reconcile never triggers a bulk delete (existing parts age out under their old TTL). Only a plain ` + ` retention is rewritten: compound policies (`TO VOLUME`/`TO DISK` tiering, `RECOMPRESS`, `GROUP BY` rollups, several rules) and calendar-unit retentions (month/quarter/year) are reported and left untouched. Off by default. Implements hyperdxio/hyperdx#1311. + +### Patch Changes + +- d205a776: Allow the ClickHouse exporter request timeout to be configured with + `HYPERDX_OTEL_EXPORTER_TIMEOUT` in both OpAMP-managed and standalone collector + modes. The default remains 5 seconds. + ## 2.35.0 ### Minor Changes diff --git a/packages/otel-collector/package.json b/packages/otel-collector/package.json index 6e0f905d65..fda9885322 100644 --- a/packages/otel-collector/package.json +++ b/packages/otel-collector/package.json @@ -1,7 +1,7 @@ { "name": "@hyperdx/otel-collector", "description": "HyperDX OpenTelemetry Collector configuration and Docker image", - "version": "2.35.0", + "version": "2.36.0", "license": "MIT", "private": true } diff --git a/yarn.lock b/yarn.lock index d423f1bbb6..bc64ac7dc8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4616,7 +4616,7 @@ __metadata: "@braintree/sanitize-url": "npm:^7.1.1" "@clickhouse/client-common": "npm:1.23.0-head.fae5998.1" "@esm2cjs/p-queue": "npm:^7.3.0" - "@hyperdx/common-utils": "npm:^0.26.0" + "@hyperdx/common-utils": "npm:^0.27.0" "@hyperdx/node-opentelemetry": "npm:^0.9.0" "@hyperdx/passport-local-mongoose": "npm:^9.0.1" "@modelcontextprotocol/sdk": "npm:^1.27.1" @@ -4708,7 +4708,7 @@ __metadata: "@hookform/resolvers": "npm:^3.9.0" "@hyperdx/api": "workspace:*" "@hyperdx/browser": "npm:^0.22.1" - "@hyperdx/common-utils": "npm:^0.26.0" + "@hyperdx/common-utils": "npm:^0.27.0" "@hyperdx/node-opentelemetry": "npm:^0.9.0" "@mantine/core": "npm:^9.0.0" "@mantine/dates": "npm:^9.0.0" @@ -4835,7 +4835,7 @@ __metadata: resolution: "@hyperdx/cli@workspace:packages/cli" dependencies: "@clickhouse/client": "npm:1.23.0-head.fae5998.1" - "@hyperdx/common-utils": "npm:^0.26.0" + "@hyperdx/common-utils": "npm:^0.27.0" "@jest/globals": "npm:^30.2.0" "@types/crypto-js": "npm:^4.2.2" "@types/jest": "npm:^29.5.14" @@ -4862,7 +4862,7 @@ __metadata: languageName: unknown linkType: soft -"@hyperdx/common-utils@npm:^0.26.0, @hyperdx/common-utils@workspace:packages/common-utils": +"@hyperdx/common-utils@npm:^0.27.0, @hyperdx/common-utils@workspace:packages/common-utils": version: 0.0.0-use.local resolution: "@hyperdx/common-utils@workspace:packages/common-utils" dependencies: