Skip to content

[9.3] [Discover][Logs profile] Fix missing search highlights (#260056)#260397

Merged
kibanamachine merged 1 commit intoelastic:9.3from
kibanamachine:backport/9.3/pr-260056
Mar 31, 2026
Merged

[9.3] [Discover][Logs profile] Fix missing search highlights (#260056)#260397
kibanamachine merged 1 commit intoelastic:9.3from
kibanamachine:backport/9.3/pr-260056

Conversation

@kibanamachine
Copy link
Copy Markdown
Contributor

Backport

This will backport the following commits from main to 9.3:

Questions ?

Please refer to the Backport tool documentation

## Summary

Fixes search result highlighting not working in the Logs profile summary
column and content breakdown.

> [!IMPORTANT]
> This should be seen as a temporary fix, while the team works on
React-based field formatters

Closes elastic#259407

### Root cause

The message value was read from `row.flattened`, which doesn't contain
ES highlights. The highlight snippets can be found in
`row.raw.highlight[field]` with `@kibana-highlighted-field@` tags, but
were never passed to the rendering pipeline, after recent changes to the
implementation.

### Approaches considered

We explored different ways to get the highlighted value into the message
rendering.

First approach was to reuse `getLogDocumentOverview`, which had been
removed to solve an issue with OTel documents, but it called
`formatFieldValue` internally. That receives the full ES hit, the field
formatter would convert the ES tags to `<mark>` HTML tags automatically,
so that we could then keep our current logic working. The idea was to
get the field name from `getMessageFieldWithFallbacks(row.flattened)`
(which handles OTel fallback) and the already highlighted value from
`getMessageFieldWithFallbacks(documentOverview)`.

However, this approach didn't work for two reasons:
- There's a field resolution priority mismatch, where
`getMessageFieldWithFallbacks` checks OTel fields first (`body.text`
before `message`), while `getFieldValueWithFallback` inside
`getLogDocumentOverview` checks ECS first (`message` before
`body.text`). If a doc has both, the field name and value could come
from different sources.

- `formatFieldValue` passes the ECS field name to
`dataView.fields.getByName()`, which can return `undefined` for OTel
docs without aliases. When that happens, the field formatter can't look
up `hit.highlight[field.name]` and silently skips highlighting entirely.
In testing, highlights didn't appear.

The final approach reads `row.raw.highlight[field]` directly using the
correctly-resolved field name from
`getMessageFieldWithFallbacks(row.flattened)`, bypassing the field
formatter altogether. A new `getHighlightedFieldValue` utility
replicates the logic of `getHighlightHtml` from
`@kbn/field-formats-plugin` (which packages can't import directly),
merging all ES highlight snippets into the escaped field value —
handling multi-valued fields and multiple highlight regions within a
single value. `escapeAndPreserveHighlightTags` was simplified back to
only handle HTML `<mark>` tags (used by resource badges that receive
pre-formatted values from `formatFieldValue`). Also, we fixed a
pre-existing undetected bug where multiple highlight regions were
silently dropped due to a `markTags.length === 2` condition that only
allowed single keyword highlighting.

### Changes

- **`content.tsx` / `summary_column.tsx` / `content_breakdown.tsx`**
- Read the full ES highlight array from `row.raw.highlight[field]` (not
just `[0]`) and pass it with the plain field value to
`getHighlightedFieldValue`, which merges all snippets and produces
XSS-safe HTML.

- **`highlight_utils.ts`** (renamed from
`escape_preserve_highlight_tags.ts`)
- Added `getHighlightedFieldValue(fieldValue, highlights)`, directly
replicating `getHighlightHtml` from `@kbn/field-formats-plugin`,
iterating over all ES highlight snippets, stripping ES tags to find
matching text, and replacing occurrences in the escaped field value with
`<mark>` elements. Handles multi-valued fields and multiple highlight
regions.
- Simplified `escapeAndPreserveHighlightTags` to only handle HTML
`<mark>` tags (its sole remaining use case in `cell_actions_popover.tsx`
for resource badges).

### Demo

https://github.com/user-attachments/assets/7aa67eb4-f2ff-4874-bd3b-f8734f2c2e00
(cherry picked from commit 7346059)
@kibanamachine kibanamachine added the backport This PR is a backport of another PR label Mar 31, 2026
@kibanamachine kibanamachine enabled auto-merge (squash) March 31, 2026 08:46
@kibanamachine kibanamachine merged commit 081aa83 into elastic:9.3 Mar 31, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport This PR is a backport of another PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants