Java Logging — Why Logging Matters
Every developer starts with System.out.println() for debugging. It works — until you deploy to production and realize you have no timestamps, no log levels, no way to search through millions of lines, and no way to turn off debug messages without redeploying.
Logging is the professional alternative. In this chapter, you’ll learn why logging matters and get an overview of Java’s logging framework landscape.
System.out.println() is Not Logging
| Feature | System.out.println() |
Proper Logging |
|---|---|---|
| Timestamps | ❌ | ✅ Automatic |
| Log levels (DEBUG, INFO, WARN, ERROR) | ❌ | ✅ |
| Write to files | ❌ | ✅ Configurable |
| Filter by severity | ❌ | ✅ |
| Structured output (JSON) | ❌ | ✅ |
| Thread name / class name | ❌ | ✅ Automatic |
| Performance impact | High (synchronized) | Low (async, buffered) |
| Production-ready | ❌ | ✅ |
The Java Logging Landscape
| Framework | Role | Status |
|---|---|---|
java.util.logging (JUL) |
Built-in Java logging | ⚠️ Rarely used (poor defaults) |
| Log4j 2 | Full logging framework | ✅ Popular, powerful |
| SLF4J | Logging facade (interface) | ✅ Industry standard |
| Logback | SLF4J implementation | ✅ Default in Spring Boot |
The winning combination in 2026: Use SLF4J as your logging API and Logback as the implementation. This is what Spring Boot uses by default.
What’s Next?
In the next chapter, we’ll start with Java’s built-in java.util.logging — not because it’s the best, but because it requires no dependencies and helps you understand logging fundamentals.