10 Logging Best Practices Every Java Backend Engineer Should Follow

This article presents ten practical rules for producing clean, searchable, and performance‑friendly logs in Java applications, covering unified formatting, stack traces, log levels, complete parameters, data masking, asynchronous writing, traceability, dynamic log levels, structured storage, and intelligent monitoring with concrete code snippets and configuration examples.

IT Services Circle
IT Services Circle
IT Services Circle
10 Logging Best Practices Every Java Backend Engineer Should Follow

Introduction

This guide presents ten practical rules for producing clean, consistent, and maintainable logs in Java applications using Logback. The rules cover log format, exception handling, level usage, parameter completeness, data masking, performance, traceability, dynamic configuration, structured storage, and monitoring.

Rule 1 – Unified Log Format

Define a single pattern in logback.xml so every log entry contains the same fields. A typical pattern includes timestamp, trace identifier, thread name, log level, logger name and the message:

<!-- logback.xml core configuration -->
<pattern>%d{yy-MM-dd HH:mm:ss.SSS} |%X{traceId:-NO_ID}| %thread |%-5level |%logger{36} |%msg%n</pattern>

This makes troubleshooting easier because all contextual information is present.

Rule 2 – Always Log Stack Traces

When catching an exception, pass the throwable to the logging call so the full stack trace is recorded.

try {
    processOrder();
} catch (Exception e) {
    log.error("Order processing failed, orderId={}", orderId, e); // e is mandatory
}

Without the throwable the root cause is lost.

Rule 3 – Reasonable Log Levels

Use log levels according to the severity of the event:

FATAL : System is about to crash (e.g., OOM, disk full)

ERROR : Core business failure (payment error, order creation exception)

WARN : Recoverable problem (retry succeeded, degradation triggered)

INFO : Important business milestones (order status change)

DEBUG : Development‑time details (parameter values, intermediate results)

Misusing levels (e.g., logging a normal timeout as ERROR) obscures real issues.

Rule 4 – Complete Parameters

Log enough context to identify the who, what, where and why. Example of a detective‑style log:

log.warn("User login failed username={}, clientIP={}, failReason={}",
    username, clientIP, "password attempts exceeded");

The timestamp is supplied by the pattern defined in Rule 1.

Rule 5 – Data Masking

Mask sensitive fields before writing them to the log. A simple utility for mobile numbers:

public class LogMasker {
    public static String maskMobile(String mobile) {
        return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }
}

log.info("User registration mobile={}", LogMasker.maskMobile("13812345678"));

Rule 6 – Asynchronous Logging for Performance

Synchronous writes can become a bottleneck under high concurrency (e.g., flash‑sale spikes). Use Logback’s AsyncAppender to off‑load I/O to a background thread.

Step 1 – AsyncAppender configuration

<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
    <discardingThreshold>0</discardingThreshold>   <!-- never discard -->
    <queueSize>4096</queueSize>                     <!-- depth = maxThreads × 2 -->
    <appender-ref ref="FILE"/>
</appender>

Step 2 – Logging code

// Good: let the framework handle queuing
log.debug("Received MQ message: {}", msg.toSimpleString());

// Bad: expensive computation before logging (still runs in the caller thread)
log.debug("Detailed content: {}", computeExpensiveLog());

Step 3 – Sizing the queue

// Approximate memory usage
maxMemory ≈ queueSize × avgLogSize;
// Recommended depth = peakTPS × toleratedDelaySec
// Example: 10 000 TPS with 0.5 s tolerance → queueSize ≈ 5 000

Monitor queue usage (alert at 80 %) and avoid large toString() calls that could cause OOM.

Rule 7 – End‑to‑End Traceability

Inject a unique traceId into the MDC at the entry point of each request and include it in the log pattern:

// Interceptor (or filter)
MDC.put("traceId", UUID.randomUUID().toString().substring(0,8));

// Pattern snippet
<pattern>%d{HH:mm:ss} |%X{traceId}| %msg%n</pattern>

All logs across services then share the same identifier, enabling full‑chain correlation.

Rule 8 – Dynamic Log Level Adjustment

Expose a lightweight endpoint to change a logger’s level at runtime without restarting the JVM:

@GetMapping("/logLevel")
public String changeLogLevel(@RequestParam String loggerName,
                             @RequestParam String level) {
    ch.qos.logback.classic.Logger logger =
        (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(loggerName);
    logger.setLevel(ch.qos.logback.classic.Level.valueOf(level));
    return "OK";
}

This is useful for temporarily enabling DEBUG on a problematic component.

Rule 9 – Structured Storage

Store logs as JSON so downstream systems (e.g., Elasticsearch, Splunk) can index fields directly.

{
  "event": "ORDER_CREATE",
  "orderId": 1001,
  "amount": 8999,
  "products": [{"name": "iPhone", "sku": "A123"}]
}

Structured logs eliminate parsing ambiguities and support powerful queries.

Rule 10 – Intelligent Monitoring

Integrate logs with the ELK stack (Elasticsearch, Logstash, Kibana) to aggregate, visualize and alert on patterns. Example alert thresholds:

ERROR logs > 100 entries within 5 min → phone alert
WARN logs sustained for 1 h → email notification

Automated alerts prevent critical issues from remaining unnoticed for days.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

best practiceslogginglogbackstructured loggingasynchronous logging
IT Services Circle
Written by

IT Services Circle

Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.