15 Essential Logging Practices to Debug Faster and Avoid Blame
This article presents 15 practical logging best‑practice recommendations for Java developers, covering log level selection, formatting, conditional logging, performance‑friendly placeholders, asynchronous output, proper exception handling, and log file organization to improve debugging efficiency and maintainable production systems.
Preface
Logs are essential for quickly locating problems and can also be used for blame‑shifting; good logging is therefore crucial.
1. Choose the appropriate log level
Common levels are error, warn, info, debug, trace. Select the proper level for each situation.
error: serious errors affecting normal business, needs ops monitoring.
warn: warnings, minor impact, needs developer attention.
info: key information for troubleshooting such as timestamps, input/output.
debug: runtime data in critical logic.
trace: most detailed, usually logged to files only.
2. Log method input and output parameters
Print only effective logs that help locate issues quickly, such as method entry parameters (e.g., userId) and return values.
public String testLogMethod(Document doc, Mode mode) {
log.debug("method enter param:{}",userId);
String id = "666";
log.debug("method exit param:{}",id);
return id;
}3. Choose a suitable log format
An ideal format includes timestamp (millisecond precision), log level, thread name, etc. Example Logback configuration:
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level [%thread][%logger{0}] %m%n</pattern>
</encoder>
</appender>Without a timestamp you cannot know when a request occurred.
4. Log at the beginning of each conditional branch
Print a log at the first line of each if/else or switch branch to identify which path was taken.
Example:
if(user.isVip()){
log.info("User is VIP, Id:{}, start VIP logic",user,getUserId());
// VIP logic
}else{
log.info("User is non‑VIP, Id:{}, start non‑VIP logic",user,getUserId());
// non‑VIP logic
}5. Guard low‑level logs with a log‑level check
For trace/debug logs, check if the level is enabled before constructing the message.
User user = new User(666L, "公众号", "捡田螺的小男孩");
if (log.isDebugEnabled()) {
log.debug("userId is: {}", user.getId());
}If the configured level is warn, the debug message will not be printed but the string concatenation still occurs, wasting resources.
6. Use SLF4J API instead of direct Log4j/Logback calls
SLF4J provides a façade that makes it easy to switch underlying logging frameworks without code changes.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(TianLuoBoy.class);7. Prefer parameter placeholders {} over string concatenation
Using placeholders avoids the performance cost of concatenation.
logger.info("Processing trade with id: {} and symbol: {}", id, symbol);8. Output logs asynchronously
Asynchronous logging improves I/O performance.
Use Logback's AsyncAppender for simple configuration.
<appender name="FILE_ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="ASYNC"/>
</appender>9. Avoid e.printStackTrace()
Instead log the exception with the logger to keep stack traces together and prevent memory issues.
try{
// business logic
}catch(Exception e){
log.error("Your program has an exception", e);
}10. Log full exception information
Include the exception object, not just its message, to capture the complete stack trace.
try{
// business logic
}catch(Exception e){
LOG.error("Your program has an exception", e);
}11. Never enable debug in production
Debug logs can quickly fill disk space and affect system stability.
12. Do not log and then re‑throw the same exception
Logging the exception and then wrapping and throwing it results in duplicate stack traces.
log.error("IO exception", e);
throw new MyException(e);13. Avoid duplicate log statements
Do not log the same information multiple times; set additivity=false in log4j.xml to prevent duplication.
<logger name="com.taobao.dubbo.config" additivity="false">14. Separate log files by type
Write different log categories (e.g., access.log, error.log) to separate files for easier analysis.
15. Add detailed logs for core or complex modules
For critical or complex code, include comprehensive comments and logs to aid troubleshooting.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
