Start Learning
Javaneer
Back to stage
Stage 6·Professional Java

Logging & Observability

SLF4J and Logback, log levels, structured logging, and basic metrics.

12 min readIntermediate
On this page

When an app runs in production, you can't attach a debugger - you need it to tell you what it's doing. Logging and observability are how you understand a live system: what happened, when, and why. Skimp on this and production problems become guessing games.

Logging: leave a trail

A log is a timestamped record of events. Good logs are your eyes into a running system.

Logs are like a flight recorder

An aircraft's black box continuously records what's happening so investigators can reconstruct events after the fact. Logs are your application's black box: when something goes wrong at 3 a.m., they're often the only record of what led up to it. Log thoughtfully, and future-you can piece the story together.

Use SLF4J + Logback, not println

System.out.println has no timestamps, levels, or control. Real apps use a logging framework: SLF4J (the standard API) with Logback (the implementation).

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class OrderService {
    private static final Logger log = LoggerFactory.getLogger(OrderService.class);

    void process(Order order) {
        log.info("Processing order {}", order.id());   // {} is a safe placeholder
        try {
            // ...
        } catch (Exception e) {
            log.error("Failed to process order {}", order.id(), e);  // logs stack trace
        }
    }
}

Use placeholders, not string concatenation

Write log.info("Order {}", id) rather than log.info("Order " + id). The placeholder version skips building the string entirely if that log level is disabled - cheaper and cleaner. And always pass the exception as the last argument so the stack trace is logged.

Log levels

Levels let you control verbosity - chatty in development, quiet in production:

LevelUse for
ERRORSomething failed and needs attention
WARNSomething odd, but the app continues
INFONotable business events (order placed)
DEBUGDetailed diagnostic info for developers
TRACEVery fine-grained, rarely enabled

You configure which levels to actually output per environment - no code changes needed.

Never log secrets

Passwords, tokens, credit-card numbers, and personal data must never appear in logs - logs are widely accessible and long-lived. Redact or omit sensitive fields. A leaked log file has caused many real breaches.

Structured logging

Instead of plain text, structured logs (often JSON) attach machine-readable fields, so tools can search and filter them:

{"time":"...","level":"INFO","orderId":42,"msg":"Order placed","userId":7}

This makes logs searchable at scale - "show every ERROR for user 7 today" becomes a simple query.

The three pillars of observability

Logging is one of three complementary tools:

  • Logs - discrete events ("order 42 failed").
  • Metrics - numbers over time (requests/sec, error rate, memory use).
  • Traces - the path of a single request across services (where did the time go?).

Metrics and health checks

Spring Boot Actuator exposes metrics and a /health endpoint out of the box. Tools like Micrometer, Prometheus, and Grafana collect and visualize metrics so you can watch trends and get alerted before users notice a problem.

Quick check

Which log level should you use for an event that failed and needs attention?

Key takeaways

  • Logs are a timestamped record - your window into a running system.
  • Use SLF4J + Logback with parameterized messages (log.info("{}", x)), not System.out.println.
  • Log levels (ERROR, WARN, INFO, DEBUG, TRACE) control verbosity per environment.
  • Never log secrets or personal data; redact sensitive fields.
  • Structured (JSON) logs are searchable at scale.
  • Observability has three pillars: logs (events), metrics (numbers over time), and traces (request paths).

Finally, let's get your app out the door: packaging and deployment.