Unravel โบ Java concepts โบ Errors and logging
Logging with SLF4J
A logger writes diagnostic messages at a level (trace, debug, info, warn, error).
At a glance
A ship's log with severity tags: the captain chooses whether only emergencies or every detail get written down today.
- 1private static final Logger log = LoggerFactory.getLogger(MyClass.class); (or Lombok's @Slf4j) gives each class its own named logger
- 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.
- 3To log an exception pass it as the last argument: log.error("Payment failed for {}", id, e) prints the message and the stack trace
- Never log secrets, tokens or personal data
- SLF4J is only an API; a backend such as Logback or Log4j2 does the writing
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; }}- line 1 uses Logger, the core of Logging with SLF4J
- line 4 uses info, the core of Logging with SLF4J
- 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:
- Annotations:
@Slf4j - Types:
LoggerLoggerFactoryLogMDC - Method calls:
log.info()log.warn()log.error()log.debug()log.trace()logger.info()logger.warn()logger.error()logger.debug()
Part of a learning path
- Reliable code ยท previous: try-with-resources ยท next: Retry and circuit breaker
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.