fix(logs): Syslog-Zeitstempel nicht selbst berechnen (TZ-Fehler -> Loki wies alles als "too new" ab); adm-Gruppe fuer Host-Logrechte

This commit is contained in:
mm committed 2026-09-13 23:11:54 +02:00
1 parent 8d331abe8b
commit c67600f147
1 file changed
+27 -19
+27 -19
View File
@@ -25,6 +25,22 @@
set -u
# WICHTIG: Telegraf startet inputs.exec-Unterprozesse mit den Rechten des
# Dienst-Benutzers (im Container uid=999 "telegraf"), NICHT mit den Rechten des
# Telegraf-Prozesses. /hostfs/var/log/syslog gehoert Gruppe "adm" (Modus 640) —
# als uid 999 ist die Datei nicht lesbar und das Script gibt still nichts aus.
# Deshalb: Lesen ueber cat als root, wenn wir nicht schon root sind und sudo/cat
# verfuegbar ist.
read_head() {
if [ "$(id -u)" -eq 0 ]; then
head -c "$2" "$1" 2>/dev/null
elif command -v sudo >/dev/null 2>&1; then
sudo -n head -c "$2" "$1" 2>/dev/null
else
head -c "$2" "$1" 2>/dev/null
fi
}
FILES="${SYSLOG_FILES:-/hostfs/var/log/syslog /hostfs/var/log/kern.log}"
MAX_LINES="${SYSLOG_MAX_LINES:-500}"
STATE_DIR="${SYSLOG_STATE_DIR:-/var/lib/telegraf-syslog}"
@@ -71,17 +87,14 @@ for f in $FILES; do
for (i = 1; i <= length(s); i++) { c = substr(s, i, 1); if (c < "0" || c > "9") return 0 }
return 1
}
# "2026-09-13T22:52:10..." -> Sekunden seit Epoche (mktime braucht "Y M D H M S")
function ts2epoch(t, y, mo, d, h, mi, se) {
if (length(t) < 19) return 0
if (substr(t, 5, 1) != "-" || substr(t, 8, 1) != "-" || substr(t, 11, 1) != "T") return 0
y = substr(t, 1, 4); mo = substr(t, 6, 2); d = substr(t, 9, 2)
h = substr(t, 12, 2); mi = substr(t, 15, 2); se = substr(t, 18, 2)
if (!isdig(y) || !isdig(mo) || !isdig(d) || !isdig(h) || !isdig(mi) || !isdig(se)) return 0
# mktime ist bei mawk vorhanden; sonst Fallback auf jetzt
e = mktime(y " " mo " " d " " h " " mi " " se)
return (e > 0) ? e : 0
}
# WICHTIG: KEINEN Zeitstempel selbst berechnen.
# Die Syslog-Zeit ist LOKAL (+02:00), mawk/mktime kennt aber keine
# Zeitzonen-Offsets — im UTC-Container entstand daraus ein Wert 2 h in der
# Zukunft und Loki wies jeden Push ab:
# "entry for stream '{…}' has timestamp too new: 2026-09-13T23:08:19Z"
# Ohne Zeitstempel stempelt Telegraf die Zeile beim Einsammeln — bei
# interval = 30s genau genug und zeitzonensicher.
function ts2epoch(t) { return 0 }
/./ {
line = $0
@@ -91,7 +104,6 @@ for f in $FILES; do
if (substr(line, 5, 1) == "-" && substr(line, 8, 1) == "-" && substr(line, 11, 1) == "T") {
sp1 = index(line, " ")
if (sp1 > 0) {
ts = substr(line, 1, sp1 - 1)
rest = substr(line, sp1 + 1)
sp2 = index(rest, " ")
if (sp2 > 0) { host = substr(rest, 1, sp2 - 1); rest = substr(rest, sp2 + 1) }
@@ -106,16 +118,12 @@ for f in $FILES; do
msg = substr(msg, colon + 2)
}
}
e = ts2epoch(ts)
if (e > 0) ns = e "000000000"
}
}
if (ns == "") ns = sprintf("%.0f000000000", systime())
# Tag heisst jhost, NICHT host: Telegraf setzt host=<node> als global_tag.
printf "journal,source=%s,ident=%s,priority=%s,jhost=%s message=\"%s\" %s\n", \
etag(SRC), etag(ident), etag(prio), etag(host), estr(msg), ns
# Kein Zeitstempel -> Telegraf setzt ihn (zeitzonensicher, siehe oben).
printf "journal,source=%s,ident=%s,priority=%s,jhost=%s message=\"%s\"\n", \
etag(SRC), etag(ident), etag(prio), etag(host), estr(msg)
}
'