feat(alloy-syslog): label UniFi plain syslog on udp-5514 separately from CEF #1530

Merged
k.renner merged 1 commits from worktree-alloy-unifi-syslog-label into main 2026-10-30 13:23:48 +00:00
Member

UniFi activity logging sends everything to one target (udp-5514): the UDM SIEM events (CEF), the UDM system log (log_all_contents) and the AP/switch device logs (debug). Today all of it lands as source="udm-siem", and the plain syslog lines carry no host/app labels.

This splits the stream in loki.process.udm_cef:

  • CEF lines: source="udm-siem", unchanged CEF labels (vendor, product, signature_id, event_name, category).
  • All other lines: source="unifi-syslog", plus host and app parsed from the header.
    • UDM: <ts> <host> <host> <app>[pid]: …
    • APs/switches: <ts> <host> <mac>,<model>-<fw>: [: ]<app>[pid]: …

The listener no longer sets source statically; each stage.match sets it.

Example queries after merge:

{source="unifi-syslog", host="APBro", app="hostapd"}
{source="unifi-syslog", host="UDM-Sudstrasse-28", app="radiusd"}

Checks:

  • Regex run against 10 min of live udp-5514 traffic: every non-CEF line matches. Resulting cardinality is about 12 hosts and 30 apps.
  • alloy validate --stability.level=experimental passes on the extracted config with grafana/alloy v1.21.3 (the deployed version).

🤖 Generated with Claude Code

UniFi activity logging sends everything to one target (udp-5514): the UDM SIEM events (CEF), the UDM system log (`log_all_contents`) and the AP/switch device logs (`debug`). Today all of it lands as `source="udm-siem"`, and the plain syslog lines carry no host/app labels. This splits the stream in `loki.process.udm_cef`: - **CEF lines**: `source="udm-siem"`, unchanged CEF labels (`vendor`, `product`, `signature_id`, `event_name`, `category`). - **All other lines**: `source="unifi-syslog"`, plus `host` and `app` parsed from the header. - UDM: `<ts> <host> <host> <app>[pid]: …` - APs/switches: `<ts> <host> <mac>,<model>-<fw>: [: ]<app>[pid]: …` The listener no longer sets `source` statically; each `stage.match` sets it. Example queries after merge: ``` {source="unifi-syslog", host="APBro", app="hostapd"} {source="unifi-syslog", host="UDM-Sudstrasse-28", app="radiusd"} ``` Checks: - Regex run against 10 min of live udp-5514 traffic: every non-CEF line matches. Resulting cardinality is about 12 hosts and 30 apps. - `alloy validate --stability.level=experimental` passes on the extracted config with grafana/alloy v1.21.3 (the deployed version). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude-bot added 1 commit 2026-10-30 13:22:43 +00:00
feat(alloy-syslog): label UniFi plain syslog on udp-5514 separately from CEF
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
229e0cf5d8
UniFi activity logging has a single target, so the UDM SIEM CEF events,
the UDM system log (log_all_contents) and the AP/switch device logs
(debug) all arrive on udp-5514. Split them in loki.process.udm_cef:

- CEF lines keep source="udm-siem" and the existing CEF labels.
- Everything else gets source="unifi-syslog" plus host and app parsed
  from the line header (UDM: "<host> <host> <app>[pid]:", devices:
  "<host> <mac>,<model>-<fw>: [: ]<app>[pid]:").

The listener no longer sets source statically; each stage.match sets it,
so no label is overwritten. Regex checked against 10 min of live lines
(all non-CEF lines match); config validated with alloy v1.21.3
`validate --stability.level=experimental`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
k.renner merged commit a7543cb78b into main 2026-10-30 13:23:48 +00:00
Sign in to join this conversation.