Correct Way to Log Exceptions in Java
Fast recall
Quick revision
Core answer
log.error("Could not load order {}", orderId, e), so the stack trace is retained. Choose the level from operational meaning, and avoid logging here if the same exception will be handled and logged at a higher boundary.Practical logging knowledge — how to write debuggable code that helps troubleshoot production issues
Using log.error(e.getMessage()) which loses the stack trace in production logs, making debugging impossible
Mention log levels (error vs warn vs info) and when to use each, plus the SLF4J parameterized logging syntax for performance
Interview-ready guide
Interview answer
When a failure should be logged, I pass the exception object to the logging API so the type, stack trace, causes, and suppressed exceptions are preserved. With SLF4J I might write log.error("Could not load order {}", orderId, e), using a placeholder rather than string concatenation.
I choose the level from operational meaning, include safe correlation context, and avoid secrets or raw sensitive data. I also check ownership: if this method only rethrows and a higher boundary will log the same failure, I do not create a duplicate entry here.
Correct Way to Log Exceptions in Java
Direct Answer
When a failure should be logged, pass the exception object to the logging API, for example log.error("Could not load order {}", orderId, e), so the stack trace is retained. Choose the level from operational meaning, and avoid logging here if the same exception will be handled and logged at a higher boundary.
Common Mistakes & Pitfalls
- Logging Only getMessage: Using
log.error(e.getMessage())orlog.error("Error: " + e.getMessage())— this loses the stack trace completely, showing only the error text without any location information. When you see "Connection timeout" in production logs without knowing which service or method timed out, debugging becomes guesswork. - String Concatenation in Logs: Writing
log.error("Failed for user " + userId, e)— this builds the string even if error logging is disabled, wasting CPU. Use parameterized logging:log.error("Failed for user {}", userId, e)— the framework only formats the string if error level is enabled. - Wrong Parameter Order: Putting the exception first like
log.error(e, "message")— SLF4J expects the exception as the last parameter after message and placeholders, otherwise it might get interpreted as a placeholder value instead of being formatted with stack trace.
Check your understanding
Answer these without looking back at the article.
- What is the difference between log.error(msg) and log.error(msg, e)?
- What is SLF4J and why is it preferred over System.out.println?
- How do you configure log levels in Spring Boot?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.