vector.yaml aktualisiert

This commit is contained in:
2026-07-12 16:57:12 +00:00
parent eb0577360e
commit 397922b636
+99 -8
View File
@@ -1,47 +1,138 @@
# =============================================================================
# VECTOR CONFIGURATION
# Zweck: Docker-Container-Logs einsammeln, aufbereiten und an Loki (-> Grafana)
# senden. Zusätzlich Debug-Ausgabe in der Konsole.
# =============================================================================
# -----------------------------------------------------------------------------
# GLOBAL / API (optional, aber praktisch für Monitoring von Vector selbst)
# -----------------------------------------------------------------------------
api:
enabled: true
address: "127.0.0.1:8686" # Vector-eigenes Dashboard/API, nur lokal erreichbar
# =============================================================================
# SOURCES: Woher kommen die Daten?
# =============================================================================
sources:
docker_logs:
type: docker_logs
# Nur laufende + gestoppte Container-Logs seit Vector-Start (Default: true)
include_containers: [] # leer = alle Container
exclude_containers:
- "vector" # verhindert, dass Vector seine eigenen Logs einsammelt (Log-Loop!)
auto_partial_merge: true # zusammengehörige, von Docker aufgeteilte Zeilen mergen
# =============================================================================
# TRANSFORMS: Verarbeitung der Daten
# =============================================================================
transforms:
# ---------------------------------------------------------------------------
# 1. Grundbereinigung + feste Metadaten
# ---------------------------------------------------------------------------
parse_logs:
type: remap
inputs: [docker_logs]
source: |
# FIX: Prüfung, ob .message existiert und ein String ist (verhindert Error E103)
# --- Message bereinigen (Newlines raus, damit Loki/Grafana sauber anzeigen) ---
if is_string(.message) {
.message = replace(.message, "\n", " ")
.message = replace!(.message, "\n", " ")
.message = strip_whitespace(.message)
}
# Das Feld 'service' setzen.
# --- Statisches Service-/Cluster-Label ---
.service = "my-cluster"
# Optional: Zusätzliche Metadaten bereinigen
# .container_name = .container_name || "unknown"
# --- Docker-Metadaten absichern (falls mal Felder fehlen) ---
.container_name = .container_name || "unknown"
.host = .host || "unknown"
# --- Container-Image ohne Tag/Hash extrahieren (weniger Kardinalität) ---
if exists(.image) {
image_parts, err = split(string!(.image), ":")
if err == null {
.image_name = image_parts[0]
}
}
# --- Log-Level heuristisch erkennen (falls die App das nicht strukturiert liefert) ---
.level = "info"
msg_lower = downcase(to_string(.message) ?? "")
if contains(msg_lower, "error") || contains(msg_lower, "err ") || contains(msg_lower, "exception") {
.level = "error"
} else if contains(msg_lower, "warn") {
.level = "warn"
} else if contains(msg_lower, "debug") {
.level = "debug"
}
# ---------------------------------------------------------------------------
# 2. Versuch, JSON-Logs (strukturierte Logs von Apps) zu parsen
# Falls die Message JSON ist, wird sie geflattet -> mehr Kontext in Grafana.
# Falls nicht, bleibt .message unverändert (kein Fehler, kein Absturz).
# ---------------------------------------------------------------------------
parse_json_if_possible:
type: remap
inputs: [parse_logs]
source: |
parsed, err = parse_json(.message)
if err == null {
# nur mergen, wenn wirklich ein Objekt rauskam (kein Array/String/Zahl)
if is_object(parsed) {
. = merge(., object!(parsed), deep: true)
}
}
# =============================================================================
# SINKS: Wohin sollen die Daten?
# =============================================================================
sinks:
# Debug-Ausgabe in der Konsole
# ---------------------------------------------------------------------------
# Debug-Ausgabe in der Konsole (praktisch zum Testen, kann später raus)
# ---------------------------------------------------------------------------
stdout_debug:
type: console
inputs: [parse_logs]
inputs: [parse_json_if_possible]
encoding:
codec: json
# ---------------------------------------------------------------------------
# Loki-Sink -> Grafana
# ---------------------------------------------------------------------------
loki_sink:
type: loki
inputs: [parse_logs]
inputs: [parse_json_if_possible]
endpoint: "http://docker1.lan:3100"
# Falls dein Loki Multi-Tenancy nutzt (Standard bei vielen Setups, auch Single-User).
# Falls "no org id"-Fehler auftauchen: diese Zeile aktivieren.
tenant_id: "fake"
encoding:
codec: json
# Diese Felder werden bereits als Loki-Labels genutzt -> nicht doppelt im JSON-Body
except_fields: ["host", "service", "container_name"]
# WICHTIG: Nur Felder mit niedriger Kardinalität als Labels verwenden!
# container_id, message, timestamp etc. NIEMALS als Label -> "too many streams" in Loki.
labels:
host: "{{ host }}"
service: "{{ service }}"
container_name: "{{ container_name }}"
level: "{{ level }}"
# Reihenfolge der Log-Zeilen pro Stream sicherstellen
out_of_order_action: rewrite_timestamp
batch:
max_bytes: 1048576 # 1 MB pro Batch
timeout_secs: 5
request:
retry_attempts: 10
retry_max_duration_secs: 30
healthcheck:
enabled: true