Files

4.4 KiB

Logging — Dateieingang Service

Stack

Entwicklung (Dev Services)

Quarkus startet den gesamten Observability-Stack automatisch über Dev Services.

Maven-Profil (pom.xml):

<profile>
    <id>grafana</id>
    <dependencies>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-observability-devservices-lgtm</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</profile>

Mit ./mvnw quarkus:dev -Pgrafana startet automatisch:

  • Loki — Log-Aggregation
  • Grafana — Visualisierung / Dashboards (http://localhost:3000, admin/admin)
  • Tempo — Distributed Tracing (optional nutzbar)
  • Mimir — Metriken (optional nutzbar)

Laufzeit-Dependency (immer aktiv):

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-opentelemetry</artifactId>
</dependency>

Quarkus schickt Logs via OTLP direkt an den LGTM-Stack — kein Promtail, kein Log-File-Scraping.

Produktion

Einen OTLP-fähigen Collector vor dem produktiven Loki/Grafana-Stack betreiben:

  • Grafana Alloy (Nachfolger von Promtail, OTLP-nativ)
  • OpenTelemetry Collector

Quarkus-Konfiguration bleibt identisch — nur der OTLP-Endpoint-URL ändert sich.


Log-Hierarchie (MDC-Felder)

Ein ZIP-Verarbeitungslauf erzeugt Logs auf zwei Ebenen:

runId      → ein ZIP-Verarbeitungslauf     (gesetzt am Anfang jeder ZIP)
  step     → aktueller Pipeline-Step       (gesetzt zu Beginn jedes Steps)

zipFilename wird zusätzlich als menschenlesbarer Kontext geloggt, ist aber kein MDC-Feld (kein Filter-Kriterium, da runId eindeutiger ist).

MDC-Felder im Detail

Feld Typ Beispielwert Gesetzt in Gelöscht in
runId UUID a1b2c3d4-... Beginn ZIP-Verarbeitung finally nach ZIP
step String oci-upload Beginn jedes Pipeline-Steps Ende jedes Steps

MDC.clear() wird immer im finally-Block nach jeder ZIP aufgerufen — kein Kontext sickert in die nächste ZIP.

Filtermöglichkeiten in Grafana (LogQL)

# Alle Logs eines Verarbeitungslaufs
{service="dateieingang"} | json | runId="a1b2c3d4"

# Alle Logs eines Pipeline-Steps über alle Läufe
{service="dateieingang"} | json | step="oci-upload"

# Nur Fehler
{service="dateieingang"} | json | level="ERROR"

# Fehler in einem bestimmten Lauf
{service="dateieingang"} | json | runId="a1b2c3d4" | level="ERROR"

Loki-Labels (wenige, statische Werte — keine hohe Kardinalität):

  • service = dateieingang
  • level = INFO / WARN / ERROR
  • environment = dev / prod

Alle anderen Felder (runId, step) werden per | json im Query-Body gefiltert, nicht als Label.


Log-Events pro Step

Step Level Event / Inhalt
api-trigger INFO "Processing triggered by APEX, starting async pipeline"
api-trigger WARN "Pipeline already running, rejecting trigger (409)"
sftp-list INFO "N new ZIP files found on SFTP"
sftp-list INFO "No new ZIP files found on SFTP"
sftp-download INFO "ZIP <filename> downloaded (X bytes)"
zip-extract INFO "ZIP <filename> extracted: N files, M directories"
zip-extract ERROR "ZIP <filename> is corrupt or unreadable"
oci-upload INFO "Uploaded N files + marker to OCI in Xms"
oci-upload WARN "OCI upload attempt N/3 failed (503), retrying..."
oci-upload ERROR "OCI upload permanently failed (403) — check credentials"
sftp-rename INFO "SFTP rename: <file><file>.processed"
sftp-rename INFO "SFTP rename: <file><file>.error"
ords-notify INFO "ORDS endpoint called, HTTP 200"
ords-notify WARN "ORDS call failed (attempt N/3), retrying..."
ords-notify WARN "ORDS notification failed — marker is present, APEX will pick up next run"
cleanup DEBUG "Local files deleted: <path>"
Alle ERROR Fehler mit vollem MDC-Kontext, Exception-Message (nie Passwörter/Keys loggen)

Fehlerverhalten (Logging-Perspektive)

  • Fehler werden immer vor dem Rename zu .error geloggt — damit der Log-Eintrag auch dann vorhanden ist, wenn das Rename selbst fehlschlägt
  • Der runId-Kontext bleibt für den gesamten ZIP-Verarbeitungslauf erhalten — alle Logs einer ZIP sind in Grafana über runId filterbar
  • Retry-Verhalten: siehe Architecture.md — Abschnitt Fehlerbehandlung