Spring Exception Logging: Find Errors Fast
The Problem: Logs Exist, But Root Cause Is Missing
You have error logs in production, but still can’t answer:
“Where did this error actually happen?”
Typical logs look like this:
log.error("Error occurred");
or:
log.error(e.getMessage());
These logs are almost useless for debugging.
Why This Happens
In Spring, global exception handling is usually implemented with:
@RestControllerAdvice
However, this layer is not where the error originates.
The real issue is:
You're not using the Exception object correctly.
Key Insight: Exception Already Contains Everything
An Exception in Java is not just a message.
It contains:
- Full call stack
- Exact class and method
- Line number of failure
This is captured at the moment the error occurs.
Solution: Proper Exception Logging
1. Always log with the Exception object
log.error("stacktrace ↓↓↓", e);
This prints:
- Full stack trace
- Root cause
- Execution flow
2. Extract the exact failure point
private String getRootStack(Exception e) {
StackTraceElement ste = e.getStackTrace()[0];
return ste.getClassName() + "." +
ste.getMethodName() +
"(" + ste.getFileName() + ":" + ste.getLineNumber() + ")";
}
3. Production-ready log format
log.error("""
[GLOBAL_EXCEPTION]
traceId = {}
uri = {}
method = {}
errorType = {}
errorAt = {}
message = {}
""",
traceId,
request.getRequestURI(),
request.getMethod(),
e.getClass().getSimpleName(),
getRootStack(e),
e.getMessage(),
e
);
4. Add traceId for request tracking
MDC.put("traceId", UUID.randomUUID().toString());
This allows you to:
Track all logs within a single request
Real Impact
Instead of vague logs:
Error occurred
You get:
traceId=ab12cd34
errorAt=OrderService.createOrder(OrderService.java:42)
→ Jump directly to the failing line
→ Debug in minutes instead of hours
Takeaway
Good logging is not about logging more.
It’s about logging in a way that makes root cause immediately visible.