Java Log Levels — TRACE, DEBUG, INFO, WARN, ERROR
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
Java logging has five standard levels, and the order matters: from least to most severe they're TRACE, DEBUG, INFO, WARN, and ERROR.
The thing most freshers get wrong is thinking the level you set is an exact filter. It isn't — it's a threshold. If I set my logger to INFO, I see INFO and everything more severe, so INFO, WARN, and ERROR all show up, but DEBUG and TRACE get filtered out.
Let me walk through what each one is for. TRACE is the finest detail, like method entry and exit — you almost never turn it on, even in development. DEBUG is for developer diagnostics, like the SQL that just ran or the value of a variable; it's on locally and off in production.
INFO is the business narrative — an order was placed, a user registered, a job finished. That's what you keep on in production. WARN is for something unexpected that you handled gracefully, like falling back to a default config or a retry that eventually succeeded — worth noticing, but the app kept working.
ERROR is a real failure, like the database being down or an unhandled exception — that's the kind of thing that should page someone. A detail that makes you sound experienced: in production you usually set framework loggers like Spring or Hibernate to WARN so they stay quiet, and keep your own application code at INFO so you can actually follow what it's doing.
Java Log Levels — TRACE, DEBUG, INFO, WARN, ERROR
Direct Answer
SLF4J commonly exposes TRACE, DEBUG, INFO, WARN, and ERROR. A configured level acts as a threshold for that logger, so INFO normally allows INFO, WARN, and ERROR while suppressing DEBUG and TRACE. These are event categories, not guarantees about alerts or program flow; providers and teams may add levels or map them differently.
Code Example
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrderService {
// One logger per class, named after the class
private static final Logger log = LoggerFactory.getLogger(OrderService.class);
public void processOrder(long orderId) {
log.trace("Entering processOrder, orderId={}", orderId); // finest detail
log.debug("Loading order from DB, orderId={}", orderId); // dev diagnostics
Order order = findOrder(orderId);
log.info("Processing order {} for customer {}", orderId, order.customerId()); // business event
if (order.total() > 10_000) {
log.warn("Large order {} exceeds threshold: {}", orderId, order.total()); // handled surprise
}
try {
charge(order);
} catch (PaymentException e) {
log.error("Payment failed for order {}", orderId, e); // real failure + stack trace
throw e;
}
}
}
With the logger set to INFO, the trace and debug lines never print — but the same code shows them the moment you lower the threshold to DEBUG.
Common Mistakes & Pitfalls
- Treating levels as independent: thinking INFO shows only INFO. It's a threshold — INFO also shows WARN and ERROR.
- Reversing the order: assuming ERROR is verbose. ERROR is the least verbose; it shows the fewest messages.
- Logging everything at one level: putting framework loggers and your app at the same level, so either you drown in Spring/Hibernate noise or miss your own business events.
Check your understanding
Answer these without looking back at the article.
- What is the FATAL log level and does SLF4J support it?
- How do you configure different log levels for different packages?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.