Backend Development 22 min read

The Importance of Logging, Log Levels, and Common Java Logging Frameworks (Log4j, Logback, SLF4J)

This article explains why logging is crucial in software development, introduces the standard log levels, reviews popular Java logging libraries such as Log4j, Logback and SLF4J, demonstrates their configuration and usage, compares their features, and highlights the Facade design pattern that underlies SLF4J.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
The Importance of Logging, Log Levels, and Common Java Logging Frameworks (Log4j, Logback, SLF4J)

Logging is essential for diagnosing problems, monitoring performance, and maintaining code, especially for junior developers who often neglect log statements; the article begins with a real‑world incident where insufficient logs caused costly delays in bug resolution.

The classic Syslog hierarchy—TRACE, DEBUG, INFO, WARN, and ERROR—is described, along with the occasional CRITICAL/FATAL levels found in some frameworks.

Common Java logging libraries are introduced: Log4j (the original Java logger), SLF4J (a façade that abstracts underlying implementations), Logback (the successor to Log4j 1), and Log4j 2 (the modern, high‑performance version).

The Facade (外观) pattern is explained with everyday analogies, showing how SLF4J provides a simple, unified API while hiding the complexity of the concrete logging framework.

Usage of SLF4J is demonstrated with Maven dependencies and Java code snippets:

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.32</version>
</dependency>

private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
logger.info("This is an info message.");

When Lombok is available, the @Slf4j annotation can replace the manual logger declaration.

Logback configuration (logback.xml) is shown, covering property definitions, console and file appenders, rolling policies, async appenders, and logger hierarchy with additivity="false" to prevent duplicate logging.

<configuration>
  <property name="LOG_PATH" value="logs"/>
  <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder><pattern>%-5relative [%thread] %-5level %logger{35} - %msg%n</pattern></encoder>
  </appender>
  <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_PATH}/app.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <maxFileSize>50MB</maxFileSize>
      <fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/app-%i.log.gz</fileNamePattern>
      <maxHistory>30</maxHistory>
    </rollingPolicy>
    <encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern></encoder>
  </appender>
  <logger name="com.zhanfu" level="INFO">
    <appender-ref ref="console"/>
    <appender-ref ref="file"/>
  </logger>
  <logger name="com.zhanfu.child" level="DEBUG" additivity="false">
    <appender-ref ref="console"/>
    <appender-ref ref="file"/>
  </logger>
  <root level="WARN">
    <appender-ref ref="console"/>
  </root>
</configuration>

Log4j 2 configuration (log4j2.xml) is also presented, illustrating properties, console and rolling file appenders, and logger definitions that mirror the Logback setup.

<Configuration status="INFO" monitorInterval="30">
  <Properties>
    <Property name="logPath">logs</Property>
  </Properties>
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{ISO8601} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <RollingFile name="File" fileName="${logPath}/example.log" filePattern="${logPath}/example-%d{yyyy-MM-dd}-%i.log">
      <PatternLayout pattern="%d{ISO8601} [%t] %-5level %logger{36} - %msg%n"/>
      <Policies>
        <SizeBasedTriggeringPolicy size="10 MB"/>
      </Policies>
      <DefaultRolloverStrategy max="4"/>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Logger name="com.zhanfu.child" level="DEBUG">
      <AppenderRef ref="File"/>
      <AppenderRef ref="Console"/>
    </Logger>
    <Logger name="com.zhanfu" level="INFO">
      <AppenderRef ref="File"/>
      <AppenderRef ref="Console"/>
    </Logger>
    <Root level="WARN">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

A comparative analysis shows Log4j 2 offers greater configurability, advanced features (asynchronous logging, Disruptor, Kafka integration) and higher throughput, while Logback is simpler, well‑integrated with Spring Boot, and sufficient for most applications.

The article concludes by emphasizing the habit of writing comprehensive logs, being aware of logger hierarchy and additivity, and handling potential conflicts when multiple logging frameworks coexist.

JavaLoggingLogbackSlf4jlog4j2FacadePattern
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

login 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.