Skip to content

Release v1.2.0#30

Merged
fxthiry merged 9 commits intomainfrom
release/1.2.0
Apr 15, 2026
Merged

Release v1.2.0#30
fxthiry merged 9 commits intomainfrom
release/1.2.0

Conversation

@fxthiry
Copy link
Copy Markdown
Owner

@fxthiry fxthiry commented Apr 15, 2026

Promotes release/1.2.0 to main after green validation from the original reporter (@congto, #25 and #26).

Bundled

Validation

Release flow

After this merge, v1.2.0 gets tagged on the merge commit and the release build produces the final binaries and debs.

François-Xavier THIRY and others added 9 commits April 15, 2026 11:15
VictoriaLogs emits fields like `nginx.http.request_id` as literal flat keys,
but minijinja interprets `a.b.c` as nested attribute access. Both `--validate`
and runtime rendering would therefore fail on user-written templates referencing
these fields.

Two complementary fixes:

- At render time, deflate the event additively in `TemplateEngine` before
  handing it to minijinja: flat dotted keys stay accessible, and a nested
  structure is added on top so `{{ nginx.http.request_id }}` resolves.
  Deep-merges with existing nested values; on collision with an existing
  top-level scalar, the scalar wins and a `warn!` is emitted.

- Swap the `validate_template_render` sentinel from `json!({})` to a
  `TruthyChainable` Object that returns itself on any attribute access,
  is always truthy, iterates as an empty sequence, and stringifies as empty.
  Keeps `{% if x.y %}` bodies walked so unknown-filter detection doesn't
  regress, while allowing chained undefined access and `{% for %}` / length
  against undefined to validate cleanly.
fix(templates): accept dotted VictoriaLogs fields in templates (#25)
…#26)

VictoriaLogs events don't carry `title` / `body` fields. When a user copies
the example config verbatim, `{{ title }}` and `{{ body }}` at the outer
template layer resolve to empty strings. Telegram's `parse_mode: HTML`
default then receives `"<b></b>\n"` after `DEFAULT_BODY_TEMPLATE` renders,
and responds 400 Bad Request. The alert is lost.

Two coupled fixes:

- `TelegramNotifier::prepare_text` now runs a `fallback_if_empty` guard:
  if the rendered text is empty, whitespace-only, or contains no text after
  stripping HTML tags, substitute with a priority-ordered fallback
  (`<b>{title}</b>` if title non-empty, else `Alert: {rule_name}`, else
  `"(valerter alert, empty render)"`) and emit a structured `warn!` with
  `rule_name`, `notifier_name`, and the matching reason. Title and
  rule_name are HTML-escaped and the title is capped to stay under
  Telegram's 4096 codepoint limit once wrapped.

- `config/config.example.yaml` now separates "variables available inside
  the template (VL fields + rule_name + log_timestamp)" from "template
  output keys (title, body, body_html, accent_color)". The default_alert
  example switches to `title: "{{ rule_name }}"` and `body: "{{ _msg }}"`
  so it renders non-empty content out of the box on any VL event.
fix(telegram): guard against empty renders and fix misleading example (#26)
The previous wording ("HTML version for email (optional, falls back to
body)") was ambiguous enough to let users infer that body_html would be
picked up by any notifier whose parse_mode was HTML. Issue #26 was
triggered exactly by that inference: a Telegram user put meaningful
content in body_html, left body as "{{ body }}" (which rendered to empty
because the VictoriaLogs event has no `body` field), and got a 400 from
Telegram.

Reinforce in both the example config header and the docs/notifiers.md
sections for Telegram, Mattermost, and Webhook that:

- body_html is read only by the email notifier.
- All other notifiers (Telegram, Mattermost, webhook) read `body`.
- For rich formatting in Telegram, write markup inline in `body` using
  Telegram's supported HTML subset.

No code changes - the runtime guard landed in the previous commit still
catches the empty-body case as a safety net.
Only the email notifier consumes this field. Telegram, Mattermost, and
webhook have always ignored it. The old name suggested a generic HTML
output slot, which directly misled at least one user into putting
Telegram content in body_html and leaving body empty (issue #26).

Breaking change: configs using `body_html:` are rejected at load with
serde's "unknown field" error, which lists `email_body_html` among the
expected fields. Migration is a one-liner per template and applies
equally to inline templates and split `templates.d/` files.

No behavior change elsewhere. Email fallback preserved exactly:
`email_body_html.or(body)`. The runtime semantics are identical after
the rename — only the field identifier changed, at every call site.

CHANGELOG entry added for v1.2.0 bundling this breaking change with the
previously merged fixes for #25 (dotted fields) and #26 (empty telegram
guard + honest example).
…y-html

refactor!: rename template field body_html to email_body_html (v1.2.0 breaking)
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 15, 2026

Codecov Report

❌ Patch coverage is 93.90244% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/parser.rs 89.65% 3 Missing ⚠️
src/config/validation.rs 87.50% 1 Missing ⚠️
src/main.rs 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@fxthiry fxthiry merged commit ae05983 into main Apr 15, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant