fix(logs): journald via exec+Cursor statt inputs.journal (existiert nicht) bzw. syslog (fehlt auf PVE)
This commit is contained in:
1 parent
49b5811d94
commit
258157c943
3 files changed
+107
-32
No files matched your search
+7
-3
@@ -270,14 +270,18 @@ esac
|
||||
|
||||
# --- System-Logs (journald) → Loki — nur auf systemd-Systemen ---
|
||||
if command -v journalctl >/dev/null 2>&1 && [ -d /run/systemd/system ]; then
|
||||
fetch scripts/journal-tail.sh /etc/telegraf/journal-tail.sh
|
||||
chmod 0755 /etc/telegraf/journal-tail.sh
|
||||
fetch_conf telegraf/journal.conf /etc/telegraf/telegraf.d/journal.conf
|
||||
log "journald-Logs aktiv (Warnungen+ ab jetzt; PVE-Units inklusive)."
|
||||
# Journal-Zugriff fuer den Dienst-Benutzer
|
||||
# Zustandsverzeichnis fuer den Journal-Cursor
|
||||
mkdir -p /var/lib/telegraf-journal
|
||||
if [ "$ROLE" = "proxmox" ]; then
|
||||
: # laeuft als root (Drop-in) — voller Zugriff
|
||||
: # laeuft als root (Drop-in) — voller Journal-Zugriff
|
||||
else
|
||||
chown telegraf:telegraf /var/lib/telegraf-journal 2>/dev/null || true
|
||||
usermod -aG systemd-journal telegraf 2>/dev/null || true
|
||||
fi
|
||||
log "Journald-Logs aktiv (Warnungen+, inkrementell ueber Cursor)."
|
||||
fi
|
||||
|
||||
# --- Node-Info (LAN-IP, NetBird-IP/FQDN, PVE-URL) — auf jeder Node ---
|
||||
|
||||
Executable
+82
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
# journal-tail.sh — journald-Logs inkrementell als Influx Line Protocol liefern.
|
||||
#
|
||||
# Warum dieses Script:
|
||||
# * inputs.journal existiert in den offiziellen Telegraf-Builds NICHT
|
||||
# (Docker-Image + InfluxData-Debian-Paket 1.40 geprüft).
|
||||
# * Auf PVE gibt es KEIN rsyslog — /var/log/syslog existiert dort nicht.
|
||||
# * Der JSON-Parser von inputs.exec liest nur EIN Objekt, keine NDJSON-Zeilen.
|
||||
# * Das fertige Line Protocol ist dasselbe Muster wie gpu-rocm.sh (bewährt).
|
||||
#
|
||||
# Zustand: der Cursor steckt in jeder journalctl-JSON-Zeile ("__CURSOR").
|
||||
# Er wird in $STATE_DIR/cursor gemerkt -> keine Duplikate, kein Verlust.
|
||||
#
|
||||
# Telegraf:
|
||||
# [[inputs.exec]]
|
||||
# interval = "30s"
|
||||
# timeout = "25s"
|
||||
# data_format = "influx"
|
||||
# commands = ["/etc/telegraf/journal-tail.sh"]
|
||||
|
||||
set -u
|
||||
|
||||
PRIORITY="${JOURNAL_PRIORITY:-warning}" # warning|err|info|debug
|
||||
SINCE="${JOURNAL_SINCE:-}" # optional, nur beim Erstanlauf
|
||||
MAX_LINES="${JOURNAL_MAX_LINES:-500}" # Schutz vor Flut pro Lauf
|
||||
STATE_DIR="${JOURNAL_STATE_DIR:-/var/lib/telegraf-journal}"
|
||||
CURSOR_FILE="$STATE_DIR/cursor"
|
||||
|
||||
mkdir -p "$STATE_DIR" 2>/dev/null || true
|
||||
|
||||
args=(-o json --no-pager --no-hostname -p "$PRIORITY" -n "$MAX_LINES")
|
||||
if [ -s "$CURSOR_FILE" ]; then
|
||||
args+=(--after-cursor "$(cat "$CURSOR_FILE" 2>/dev/null)")
|
||||
elif [ -n "$SINCE" ]; then
|
||||
args+=(--since "$SINCE")
|
||||
else
|
||||
args+=(--since "-5min")
|
||||
fi
|
||||
|
||||
last_cursor=""
|
||||
|
||||
journalctl "${args[@]}" 2>/dev/null | while IFS= read -r line; do
|
||||
case "$line" in \{*) ;; *) continue ;; esac
|
||||
|
||||
# Felder aus dem JSON ziehen (jq-frei, damit kein Extra-Paket nötig ist)
|
||||
get() { printf '%s' "$line" | sed -n "s/.*\"$1\":\"\([^\"]*\)\".*/\1/p" | head -1; }
|
||||
getnum() { printf '%s' "$line" | sed -n "s/.*\"$1\":\([0-9]*\).*/\1/p" | head -1; }
|
||||
|
||||
cur="$(get '__CURSOR')"
|
||||
[ -n "$cur" ] && last_cursor="$cur"
|
||||
|
||||
msg="$(get 'MESSAGE')"
|
||||
[ -n "$msg" ] || continue
|
||||
|
||||
unit="$(get '_SYSTEMD_UNIT')"; [ -n "$unit" ] || unit="$(get 'SYSLOG_IDENTIFIER')"
|
||||
ident="$(get 'SYSLOG_IDENTIFIER')"
|
||||
prio="$(get 'PRIORITY')"
|
||||
ts_us="$(getnum '__REALTIME_TIMESTAMP')"
|
||||
host="$(get '_HOSTNAME')"
|
||||
|
||||
# Line Protocol: Escaping für Tag-Werte und String-Felder
|
||||
esc_tag() { printf '%s' "$1" | sed 's/[ ,=]/\\&/g'; }
|
||||
esc_str() { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'; }
|
||||
|
||||
# Nanosekunden: __REALTIME_TIMESTAMP ist in Mikrosekunden
|
||||
if [ -n "$ts_us" ]; then
|
||||
ns="${ts_us}000"
|
||||
else
|
||||
ns="$(date +%s)000000000"
|
||||
fi
|
||||
|
||||
printf 'journal,unit=%s,ident=%s,priority=%s,host=%s message="%s" %s\n' \
|
||||
"$(esc_tag "${unit:-unknown}")" \
|
||||
"$(esc_tag "${ident:-unknown}")" \
|
||||
"$(esc_tag "${prio:-0}")" \
|
||||
"$(esc_tag "${host:-unknown}")" \
|
||||
"$(esc_str "$msg")" \
|
||||
"$ns"
|
||||
|
||||
# Zustand nach jedem Datensatz sichern
|
||||
[ -n "$cur" ] && { printf '%s' "$cur" > "$CURSOR_FILE.tmp" && mv -f "$CURSOR_FILE.tmp" "$CURSOR_FILE"; }
|
||||
done
|
||||
+18
-29
@@ -1,33 +1,22 @@
|
||||
# System-Logs (Syslog) → Loki
|
||||
# System-Logs (journald) -> Loki
|
||||
#
|
||||
# Warum: inputs.docker_log deckt nur Container ab. PVE-Knoten und alle
|
||||
# Nicht-Docker-Hosts lieferten damit gar keine Logs — genau dort stehen aber
|
||||
# die relevanten Meldungen (pvedaemon, pveproxy, qemu, Kernel, Storage).
|
||||
# Warum dieses Script statt eines Plugins:
|
||||
# * inputs.journal existiert in den offiziellen Telegraf-Builds NICHT
|
||||
# (Docker-Image UND InfluxData-Debian-Paket 1.40 geprueft, Web-Recherche
|
||||
# bestaetigt: Plugin braucht einen Build mit systemd-Headern).
|
||||
# * Auf PVE gibt es KEIN rsyslog -> /var/log/syslog existiert dort nicht.
|
||||
# * Der JSON-Parser von inputs.exec liest nur ein Objekt, keine NDJSON-Zeilen.
|
||||
# * Line Protocol direkt ist dasselbe bewaehrte Muster wie gpu-rocm.sh.
|
||||
#
|
||||
# Umsetzung: inputs.tail auf die Syslog-Dateien.
|
||||
# HINWEIS: inputs.journal existiert in den offiziellen Telegraf-Builds NICHT
|
||||
# (Docker-Image und InfluxData-Debian-Paket 1.40 wurden beide geprüft) — das
|
||||
# Plugin braucht einen Build mit systemd-Headern. Deshalb der Datei-Weg.
|
||||
# Cursor-Zustand liegt in /var/lib/telegraf-journal/cursor -> keine Duplikate,
|
||||
# kein Verlust bei Neustart oder Journal-Rotation.
|
||||
#
|
||||
# Voraussetzung: rsyslog schreibt eine Datei. Auf PVE ist das /var/log/syslog
|
||||
# (pve-manager hängt an rsyslog). Prüfen mit: ls -la /var/log/syslog
|
||||
# Feintuning per Umgebungsvariable in /etc/default/telegraf:
|
||||
# JOURNAL_PRIORITY=warning (warning|err|info|debug)
|
||||
# JOURNAL_MAX_LINES=500
|
||||
|
||||
[[inputs.tail]]
|
||||
# Fehlende Dateien sind unkritisch (Debian hat kein /var/log/messages).
|
||||
files = ["/var/log/syslog", "/var/log/messages", "/var/log/kern.log", "/var/log/daemon.log"]
|
||||
name_override = "journal"
|
||||
# Default "saved-or-end": beim ersten Start nichts nachholen, danach merken.
|
||||
initial_read_offset = "saved-or-end"
|
||||
# Zeilen als Text durchreichen (kein Parsing nötig)
|
||||
data_format = "value"
|
||||
data_type = "string"
|
||||
# Pfad als Tag, damit man in Loki nach Datei filtern kann
|
||||
path_tag = "logfile"
|
||||
|
||||
# Feldname vereinheitlichen: tail/value liefert "value", das Logs-Panel
|
||||
# erwartet (wie docker_log) "message". Umbenennen statt Panel-Sonderfall.
|
||||
[[processors.rename]]
|
||||
namepass = ["journal"]
|
||||
[[processors.rename.replace]]
|
||||
field = "value"
|
||||
dest = "message"
|
||||
[[inputs.exec]]
|
||||
interval = "30s"
|
||||
timeout = "25s"
|
||||
data_format = "influx"
|
||||
commands = ["/etc/telegraf/journal-tail.sh"]
|
||||
Reference in new issue
Block a user