github hyperdxio/hyperdx @hyperdx/app@2.28.0

5 hours ago

Minor Changes

  • 3123db5: feat: experimental promql support

  • 1df7583: feat: emit Lucene conditions from sidebar/dashboard filters to enable KV items direct_read optimization on Map columns

    Legacy type: 'sql' filters in URLs are automatically migrated to Lucene
    on page load. The persisted DashboardFilter.expression in MongoDB is unchanged.

  • cb6a74c: fix(otel-collector): allow CUSTOM_OTELCOL_CONFIG_FILE to override the
    default memory_limiter, batch (and other pipeline processors)

    Pipeline processors: lists used to be defined in the OpAMP remote config
    sent by the API (packages/api/src/opamp/controllers/opampController.ts).
    That meant the remote config overwrote any pipeline processors: list a
    user supplied via CUSTOM_OTELCOL_CONFIG_FILE, making it impossible to
    substitute the default memory_limiter with one configured for
    limit_percentage/spike_limit_percentage mode (#2145).

    The pipeline processors: lists now live in the bootstrap config
    (docker/otel-collector/config.yaml for supervisor mode, and
    docker/otel-collector/config.standalone.yaml for standalone mode). The
    OpAMP remote config no longer sets processors: on these pipelines, so the
    bootstrap+custom merge wins. Receivers and exporters are still configured
    dynamically by the OpAMP controller.

    To override memory_limiter, define a new processor with a different name
    in CUSTOM_OTELCOL_CONFIG_FILE and swap the pipeline processors: lists:

    processors:
      memory_limiter/custom:
        check_interval: 5s
        limit_percentage: 75
        spike_limit_percentage: 25
    
    service:
      pipelines:
        traces:
          processors: [memory_limiter/custom, batch]
        metrics:
          processors: [memory_limiter/custom, batch]
        logs/out-default:
          processors: [memory_limiter/custom, transform, batch]
        logs/out-rrweb:
          processors: [memory_limiter/custom, batch]

    The default memory_limiter block defined in the base config is left in
    the merged config but is no longer referenced by any pipeline; the
    collector only instantiates memory_limiter/custom at runtime.

    The same swap pattern works for the batch processor (and any other base
    processor). For example, to lower the export timeout on a specific
    pipeline:

    processors:
      batch/lowlatency:
        send_batch_size: 1000
        send_batch_max_size: 2000
        timeout: 500ms
    
    service:
      pipelines:
        traces:
          processors: [memory_limiter, batch/lowlatency]
        logs/out-default:
          processors: [memory_limiter, transform, batch/lowlatency]

    Lighter-weight env-var tuning is also available for the default batch
    processor without writing a custom config file:
    HYPERDX_OTEL_BATCH_SEND_BATCH_SIZE,
    HYPERDX_OTEL_BATCH_SEND_BATCH_MAX_SIZE, and HYPERDX_OTEL_BATCH_TIMEOUT.
    See the README for details.

  • b8f51ed: feat: upgrade to clickhouse-server 26.5

Patch Changes

  • 55926e5: fix: "Add to Filters" on a JSON-typed ClickHouse column no longer produces an
    unparseable Lucene query

    Previously, clicking "Add to Filters" on a field under a JSON column wrapped
    the field path with toString(...) before handing it off as a Lucene filter
    key. Lucene's grammar forbids parentheses inside field names, so the resulting
    condition like toString(JSONColumn.\foo`):"…"failed to parse withExpected … but ":" found.`

    The handler now passes the clean dot-notation path (e.g. JSONColumn.foo)
    to the filter setter.

  • 1648c22: feat(dashboard): add Table of Contents right rail with bulk collapse/expand

    Adds a toggleable right-rail Table of Contents to the dashboard page, plus
    "Collapse all sections" and "Expand all sections" actions. All three live
    under a new "View" section in the dashboard's existing menu. TOC visibility
    is persisted per-user via localStorage; bulk collapse uses the same
    per-viewer URL state as single-section toggling, so it's shareable via link
    and does not change the dashboard's stored defaults. Clicking a TOC entry
    scrolls the section into view, auto-expanding it first if collapsed.

  • 937e043: fix: collapse duplicate map sub-key entries in the search filter sidebar (HDX-4340)

    A map sub-field stored in filterState under dot notation (e.g. LogAttributes.time,
    from a Lucene URL round-trip) and the same key returned by the facet query under
    bracket notation (e.g. LogAttributes['time']) no longer render as two separate
    accordion items. The merged entry keeps the bracket form so "Load more" stays
    valid, and the user's selection still resolves via a tolerant filterState lookup.

  • dcab1cb: feat: default the direct_read map column optimization on supported ClickHouse versions

    The full-text-search logs schema (00002_otel_logs.sql) now ships with
    ResourceAttributeItems, ScopeAttributeItems, and LogAttributeItems
    ALIAS columns plus their text(tokenizer='array') skip indexes. The
    traces schema (00005_otel_traces.sql) similarly gains
    ResourceAttributeItems and SpanAttributeItems ALIAS columns with
    matching items indexes. New installs and freshly migrated tables get
    the optimization automatically — no manual ALTER TABLE required.

    Note: the traces table previously used only bloom_filter skip indexes
    and worked on any ClickHouse version. The added text(tokenizer='array')
    items indexes raise the minimum ClickHouse version required to create
    the traces table to >= 26.2. Existing tables on older clusters are
    unaffected (CREATE TABLE IF NOT EXISTS is a no-op).

    At query time, the app gates the Map['key'] = 'value'
    has(<MapItems>, concat('key', '=', 'value')) rewrite on the connected
    ClickHouse server version (SELECT version(), cached per connection).
    The gate only applies to ALIAS items columns, which are computed at
    query time and therefore depend on the server being able to perform a
    direct_read against the underlying Map's tuple storage. The direct_read
    feature was backported into multiple stable 26.x release lines, so the
    gate uses a per-branch minimum:

    • 26.2 line: >= 26.2.19.43
    • 26.3 line: >= 26.3.12.3
    • 26.4 line: >= 26.4.3.37
    • 26.5+ : always supported

    ALIAS items columns on servers below their branch's threshold continue
    to compile filters into the original Map-subscript form.

    MATERIALIZED items columns are always used when available, regardless
    of ClickHouse version. MATERIALIZED columns are physically stored on
    disk, so has(items, ...) reads them directly and works on any
    ClickHouse version that supports the text index itself. Operators who
    want the optimization on servers below the backport cutoffs can
    ALTER TABLE to materialize the items columns.

  • 923b544: feat: preserve compatible filters when switching sources

  • b94b8ef: fix: persist column widths in search results table

  • 996a113: fix(row-panel): hide empty attribute sections and stop showing "[Empty]"
    when the source's body column isn't configured

    The row-expand side panel always rendered Log/Span Attributes and
    Resource Attributes accordion sections, even when both were empty. The
    body header fell back to a literal [Empty] paper in two visually
    identical cases that meant different things: the body column was
    configured but the value was empty, or the body column wasn't configured
    on the source at all.

    The two attribute accordions now mirror the existing topLevelAttributes
    pattern and only render when their content is non-empty. The body header
    takes a new bodyConfigured prop: when false (source has neither body
    nor implicit column expression configured), the body paper is suppressed
    entirely. When true and the content is empty, the placeholder reads
    "No body for this event." instead of [Empty].

    DBRowOverviewPanel derives bodyConfigured from
    getEventBody(source) !== undefined, which already returns undefined
    when neither expression is set.

    Fixes HDX-4373.

  • e1c4381: fix: bare-text Lucene search now falls back from Implicit Column Expression to
    Body Expression on log sources

    Previously, a log source configured with bodyExpression set but
    implicitColumnExpression unset threw Can not search bare text without an implicit column set. on every bare-token search, even though the row panel
    rendered correctly using the body column.

    Search now reuses the same one-way fallback that getEventBody already
    implements: when no Implicit Column Expression is set, bare-text search runs
    against the configured Body Expression. Trace sources are unchanged
    (spanNameExpression is not a body equivalent for trace search).

  • 19cd7c9: fix: only use pk and row uniqueness to look up a row

  • a44fa21: Number tile: pick a static color from the palette in Display Settings. The color picker stores a palette token (not a hex value) so the choice reflows correctly across light, dark, and IDE themes.

  • b5148c8: Dashboard table tiles configured with a row-click action now show a hover hint describing where the click will go (for example, Search HyperDX Logs or Open dashboard "API Latency Drilldown"). The cell wrapper is now a real link, so cmd-click and middle-click open the destination in a new tab, right-click shows the browser context menu with "Open in New Tab" and "Copy Link Address", and the destination URL appears in the browser status bar on hover. Keyboard users can Tab to a cell and press Enter to navigate, with a visible focus ring.

  • 0e8a5b3: chore: use PageHeader title prop on Alerts, Dashboards, and Saved Searches list pages for consistency with the shared header API.

  • 800081c: chore: migrate the ClickHouse dashboard to shared PageLayout with breadcrumbs and a sticky header (connection selector, time range, refresh) instead of a duplicate page title.

  • 41d6760: chore: migrate the Kubernetes dashboard to shared PageLayout with breadcrumbs and a sticky header (log + metric sources, time range, refresh) instead of a duplicate page title.

  • 4d248bf: chore: migrate Service Map to shared PageLayout with a sticky toolbar (source, sampling, time range) and no duplicate page title.

  • 633eda6: refactor: Use new VirtualMultiSelect for dashboard filter inputs

  • 8938b05: fix: let "Load more" surface unselected values in exact filter mode

  • 04a5a92: feat: Add source scoping to dashboard filters

  • b24cb88: fix(app): copy correct session URL on first Share Session click

    The Share Session button captured window.location.href at render time, which ran before nuqs flushed sid/sfrom/sto into the URL. The button now reads the URL at click time via the shared copyTextToClipboard util, so the first copy always contains the session params (no reload needed).

  • 8810ff0: feat: Add option for force-enabling/disabling text index support

  • a8eb27d: feat: filters reflect all values, not search aware; filters use metadata MVs if available

  • Updated dependencies [3123db5]

  • Updated dependencies [d134212]

  • Updated dependencies [dcab1cb]

  • Updated dependencies [a945fa0]

  • Updated dependencies [1df7583]

  • Updated dependencies [cb6a74c]

  • Updated dependencies [6a5ac3e]

  • Updated dependencies [e1c4381]

  • Updated dependencies [b30dfe0]

  • Updated dependencies [dcb8582]

  • Updated dependencies [c3a8aa5]

  • Updated dependencies [a4b9fa8]

  • Updated dependencies [07911fd]

  • Updated dependencies [b5148c8]

  • Updated dependencies [04a5a92]

  • Updated dependencies [8810ff0]

  • Updated dependencies [a8eb27d]

    • @hyperdx/common-utils@0.20.0
    • @hyperdx/api@2.28.0

Don't miss a new hyperdx release

NewReleases is sending notifications on new releases.