grafana: move logLevelRules implementation notes to docs

The 41-line comment on logLevelRules tripped the comment-block lint
(30-line max). Move the detailed walkthrough (why each rule shape is
what it is, the three silent-failure modes, the query a level button
emits) into docs/scheduler/observability.md's existing 'Log severity'
section, which already covered the mapping at a higher level. The nix
comment now carries the short why/contract and points at the doc for
the full detail — no information dropped, just relocated.
This commit is contained in:
atlas 2026-09-20 16:37:30 +02:00 committed by mara
commit da1f80c2ef
2 changed files with 49 additions and 46 deletions

View file

@ -41,46 +41,19 @@ let
logsDatasourceUid = "swarm-victorialogs";
# Which field carries the log level, told to the READER because the writer
# cannot be told. Grafana's log-level buttons filter on a field called
# `level`, and no row in this store has one: VictoriaLogs' OTLP ingester
# names the stored field `severity_text` unconditionally (v1.52.0,
# `app/vlinsert/opentelemetry/pb.go`) and its ingest parameters have no
# `_level_field` sibling to rename it with. So the mapping is made here.
# cannot be told: VictoriaLogs' OTLP ingester names the stored field
# `severity_text` unconditionally, with no option to rename it, but
# Grafana's log-level buttons filter on a field called `level`. So the
# mapping is made here, one `logLevelRules` entry per level below.
#
# `logLevelRules` is the datasource plugin's own jsonData key and the only
# level-related one it has — there is no "the level lives in field X"
# string to set. A rule names its own field, so saying it takes one rule
# per level.
#
# 🔑 Each enabled rule appends an `OR <field>:<op>"<value>"` term to the
# query a level button emits, beside the `level:…` term that matches
# nothing here. Clicking "info" goes from
#
# level:contains_common_case("info","information","informational","notice")
#
# to that OR `severity_text:="INFO"`, which our rows do match.
#
# ⚠️ Three ways to get a rule wrong, all of them SILENT — Grafana accepts
# any jsonData it does not recognise, so a bad rule provisions cleanly and
# the buttons go on returning zero:
#
# - `enabled` must be literally `true`, not merely not-false. The query
# builder keeps rules on `rule.enabled` being truthy while the row
# colouring path keeps them on `!== false`, so an omitted flag colours
# rows correctly and leaves the buttons broken — working in the half
# nobody is looking at.
# - `level` must be a CANONICAL Grafana `LogLevel` value. The builder
# groups rules by it and only ever looks up `critical`, `error`,
# `warning`, `info`, `debug`, `trace`; `warn` and `fatal` are enum
# aliases that resolve to other spellings and match no group.
# - `value` is compared with `===`, so it is the severity text exactly as
# STORED: the uppercase OpenTelemetry short names `overwrite_text`
# writes in ../journald-severity.nix, not that table's lowercase keys.
#
# `Unspecified` is deliberately unmapped. It is VictoriaLogs' own rendering
# of an absent severity, and it is what the logs dashboard's "no severity"
# panel counts — giving it a level would dress the missing data up as a
# colour and retire the instrument that measures it.
# 🔑 A rule wrong in any of three ways provisions cleanly and its level
# button silently returns zero rows — `enabled` must be literally `true`,
# `level` must be a canonical Grafana `LogLevel` (not an alias like `warn`
# or `fatal`), and `value` must match ../journald-severity.nix's uppercase
# STORED text, not its lowercase keys. `Unspecified` is deliberately left
# unmapped so the "no severity" panel keeps counting it. Full walkthrough
# (why each rule shape is what it is, the query a level button actually
# emits): docs/scheduler/observability.md#why-explores-level-buttons-need-the-datasource-told
logLevelRules =
let
fromSeverityText = value: level: {