Loslegen
Javaneer
Zurück zur Stufe
Modul 8·Produktion & modernes Spring

Strukturiertes Logging

Logs, die Maschinen lesen können: JSON-Logging, Korrelation über Trace-IDs und Log-Level, die sich zur Laufzeit ändern lassen.

12 Min. LesezeitFortgeschritten

Deutsche Übersetzung in Arbeit

Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.

Auf dieser Seite

When one app runs on one machine, System.out.println and a scroll of console text get you a long way. In production - many instances, many services, logs shipped to a central store - humans stop reading logs line by line. Machines do. Structured logging makes your logs something a machine can parse, index, and search.

From text lines to structured events

A traditional log line is a string: readable to you, opaque to tooling. A log aggregator (Elasticsearch/Kibana, Loki, Datadog) can only grep it. A structured log is a record with named fields - typically JSON:

{"timestamp":"2026-07-21T09:14:22Z","level":"ERROR","logger":"c.b.lending.LendingService",
 "message":"Borrow failed: no copies","traceId":"a1b2c3","memberId":42,"isbn":"978-0134685991"}

Now the aggregator can do what strings can't: 'show me every ERROR with isbn=978-0134685991 in the last hour', or 'group failures by memberId'. Spring Boot 3.4+ makes this a one-line config change - no custom appender:

logging:
  structured:
    format:
      console: ecs        # Elastic Common Schema JSON (or 'logstash', 'gelf')

Human-readable locally, structured in production

You don't want JSON scrolling past while developing. Enable structured output only in the profiles that ship (e.g. application-prod.yml), and keep the friendly, colored console format for local runs. Same code, different config - the twelve-factor way.

Correlation: tying lines to a request

A single request produces many log lines, scattered among lines from other concurrent requests. What ties its lines together is a value in the MDC (Mapped Diagnostic Context) - a per-thread (or per-request) bag of key/values automatically added to every line. The most important key is the trace ID:

[traceId=a1b2c3 spanId=d4e5]  Borrowing book 978-0134685991 for member 42
[traceId=a1b2c3 spanId=d4e5]  Loan created, 3 copies remaining

When Micrometer Tracing is present (the tracing lesson), Spring populates traceId/spanId in the MDC for you, so filtering logs by one trace ID reconstructs a request's whole story - even across services. You can add your own MDC keys (MDC.put("memberId", ...)) for domain context.

A library's catalog vs. a pile of books

A pile of books is 'searchable' only by picking each up and reading the spine. A catalog records each book as fields - title, author, subject, shelf - so you can query 'every book by this author on this subject' instantly. Plain text logs are the pile; structured logs are the catalog. Same books, but now findable.

Levels you can turn without redeploying

Logging frameworks have levels - ERROR, WARN, INFO, DEBUG, TRACE - and you set a threshold so noise stays out of production. The catch: when you need DEBUG to diagnose a live incident, redeploying to change it is slow. Actuator's loggers endpoint changes a level at runtime:

# turn on DEBUG for one package on a running instance - no restart
curl -X POST localhost:8080/actuator/loggers/com.bookvault.lending \
  -H 'Content-Type: application/json' -d '{"configuredLevel":"DEBUG"}'
Find one failing request in the noise

Production is serving 500 requests a second across three instances, all logging to one central store. One user reports their borrow failed. Explain how structured logging plus a trace ID lets you isolate exactly that request's log lines, when a plain-text grep for 'failed' would drown you.

Why is structured (JSON) logging with a trace ID valuable in production?

Key takeaways

  • In production, logs are read by machines (aggregators), so they must be machine-parseable - structured JSON, not free text.
  • Spring Boot enables structured logging (ECS/Logstash/GELF) via one property; keep human-readable format for local dev.
  • The MDC adds per-request context (especially traceId/spanId) to every line, so filtering by trace ID reconstructs a request's story - even across services.
  • Log levels (ERROR..TRACE) control noise; Actuator's loggers endpoint changes them at runtime without a redeploy.
  • Logs are the 'what happened' pillar of observability, complementing metrics and traces.
War diese Lektion hilfreich?
Diese Seite auf GitHub bearbeiten