Add a consolidated log search dashboard

The per-application dashboards answer "how is this component behaving". This
one answers "where did that string come from", across every source at once, and
is kept separate so neither has to compromise for the other.

Scope is a curated preset rather than a free namespace picker: the cluster
carries 48 log sources and most are infrastructure noise. The presets are job
regexes over the <namespace>/<container> label Alloy sets — except kong-audit,
which Fluent Bit ships with no namespace at all. That mismatch between the two
collection paths is the reason a single naive selector cannot span both, and
why the presets spell the sources out.

The search term is injected inside LogQL backticks, a raw string, so a quote
typed in the box cannot break the query; an empty box yields `(?i)`, a valid
regex matching every line, which makes "no search" the default rather than a
special case. The four stat panels carry `or vector(0)` so an empty result
reads as 0 rather than "No data" — on a search box, finding nothing is an
answer, not a failure.

Two deliberate omissions. No per-format parsing: the Message column holds the
line as emitted, because the five formats agree on nothing and that is what the
per-application dashboards are for. And the level filter is partial by nature —
roughly 40% of lines are `unknown`, since access lines and Kong records carry
no severity for Loki to infer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Stéphane Tailland
2026-08-25 18:23:48 +02:00
parent 7a8a476ef0
commit 40ffac4acf
3 changed files with 813 additions and 0 deletions
+26
View File
@@ -206,6 +206,32 @@ Each application dashboard carries the same four sections: an overview of RED
indicators, HTTP traffic, a runtime section specific to the stack in use, and a
**Logs** row, followed by container resources.
### Consolidated log search
`obs-log-search` searches every source at once, and is deliberately separate
from the per-application dashboards: those answer "how is this component
behaving", this one answers "where did that string come from".
Four controls: a **scope** preset, a **source** picker chained to it, a
**level** filter, and a free-text **search** box. The search term is injected as
a case-insensitive line filter inside LogQL backticks — a raw string, so a quote
typed in the box cannot break the query, and an empty box yields `(?i)`, a valid
regex matching every line. That is what makes "no search" the natural default
rather than a special case.
Scope is a curated preset list rather than a free namespace picker, because the
cluster carries 48 log sources and most are infrastructure noise. The presets
are job regexes matched against the `<namespace>/<container>` label Alloy sets —
except `kong-audit`, which Fluent Bit ships with no namespace at all, and which
is why a single naive selector cannot span both collection paths.
Two things this dashboard deliberately does not do. It does not parse per
format: its Message column holds the line as emitted, since the five sources
agree on nothing and that is what the per-application dashboards are for. And
its level filter is honest about being partial — around 40% of lines are
`unknown` because access lines and Kong records carry no severity for Loki to
infer, so for those the text is the only thing worth searching.
### Parsed log tables
Every dashboard shows its logs twice: a **table** with one column per parsed