Properly configured logging is the difference between an hour of debugging and a five-minute diagnosis. Bad logging is either too much (thousands of lines per second that nobody reads) or too little (ERROR — nothing more).
SLF4J as a facade¶
SLF4J (Simple Logging Facade for Java) decouples your code from the concrete logging implementation. In production you use Log4j, in tests Logback — the code doesn’t change. Always log through SLF4J, never directly through the Log4j API.
Log levels — the rules¶
ERROR: something failed and requires action (database unavailable, external service not responding). WARN: something is suspicious but the application continues (deprecated API, approaching a limit). INFO: significant business events (user logged in, order created). DEBUG: details for developers (SQL queries, HTTP headers). In production: INFO and above; in dev: DEBUG.
MDC — Mapped Diagnostic Context¶
Every log line should contain: timestamp, thread, level, logger, message — and also username, session ID, request ID. MDC handles this: at the start of a request you put userId into MDC and every log line automatically includes it. Invaluable when diagnosing a specific user’s problem.
Rotation and retention¶
DailyRollingFileAppender: new file every day. 30-day retention. Maximum size of 100 MB per file (RollingFileAppender). Compression of old logs (gzip). In production NEVER log to stdout — use FileAppender.
Centralized collection¶
With 20 servers, reading logs on each server individually is impractical. Rsyslog/syslog-ng for centralized collection on a log server. We’re looking for a solution for full-text search in logs — for now grep, but it doesn’t scale.
Rules¶
- SLF4J facade. 2. Correct log levels. 3. MDC for context. 4. Rotation and retention. 5. Log what, not how (the result of an operation, not every line of code).
Need help with implementation?
Our experts can help with design, implementation, and operations. From architecture to production.
Contact us