BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ Errors and logging

Errors and logging

Logging with SLF4J

A logger writes diagnostic messages at a level (trace, debug, info, warn, error).

๐Ÿ”Ž Unravel this example

At a glance

Mental model

A ship's log with severity tags: the captain chooses whether only emergencies or every detail get written down today.

What happens, in order
  1. 1private static final Logger log = LoggerFactory.getLogger(MyClass.class); (or Lombok's @Slf4j) gives each class its own named logger
  2. 2Use placeholders: log.info("Order {} paid by {}", id, user)The text is built only if the level is enabled, unlike "..." + id + ..., which always builds the string.
  3. 3To log an exception pass it as the last argument: log.error("Payment failed for {}", id, e) prints the message and the stack trace
Remember
Watch out
String concatenation in log callsLogging the exception message but not the exceptionLogging sensitive dataLogging in tight loops at info level
Example (highlighted lines explain it)
private static final Logger log = LoggerFactory.getLogger(PaymentService.class);public void pay(long orderId) {    log.info("Paying order {}", orderId);    try {        gateway.charge(orderId);    } catch (GatewayException e) {        log.error("Payment failed for order {}", orderId, e);        throw e;    }}
  1. line 1 uses Logger, the core of Logging with SLF4J
  2. line 4 uses info, the core of Logging with SLF4J
  3. line 8 uses error, the core of Logging with SLF4J
Read the full explanation (about 1 min)

A logger writes diagnostic messages at a level (trace, debug, info, warn, error). The level setting decides in production which ones are kept.

A mental model

A ship's log with severity tags: the captain chooses whether only emergencies or every detail get written down today.

How it works

private static final Logger log = LoggerFactory.getLogger(MyClass.class); (or Lombok's @Slf4j) gives each class its own named logger.

Use placeholders: log.info("Order {} paid by {}", id, user). The text is built only if the level is enabled, unlike "..." + id + ..., which always builds the string.

To log an exception pass it as the last argument: log.error("Payment failed for {}", id, e) prints the message and the stack trace.

Going deeper

Never log secrets, tokens or personal data. Log at the right level: error for failures needing action, warn for recoverable surprises, info for business milestones, debug for diagnosis. MDC (a map bound to the thread) lets you add a request id to every line.

Under the hood

SLF4J is only an API; a backend such as Logback or Log4j2 does the writing. Placeholders avoid string concatenation, and the backend checks the level before formatting.

Common mistakes

  • String concatenation in log calls.
  • Logging the exception message but not the exception.
  • Logging sensitive data.
  • Logging in tight loops at info level.

How Unravel recognises it

When you paste code, Unravel looks for these signs of logging with slf4j. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Builds on this

Frequently asked questions

What is Logging with SLF4J?

A logger writes diagnostic messages at a level (trace, debug, info, warn, error). The level setting decides in production which ones are kept.

What are the most common mistakes with Logging with SLF4J?

String concatenation in log calls. Logging the exception message but not the exception. Logging sensitive data. Logging in tight loops at info level.

How can I see Logging with SLF4J in real code?

Paste your own Java into Unravel and it will point out where logging with slf4j appears, explain how it works at the detail level you choose, and draw the flow of the code around it.