Logback 介绍 Logback 是 Log4j 的替代品,也是 Spring Boot 框架中的默认日志实现。性能优异、配置丰富且灵活,使其被广泛使用在 Java 项目中。
环境搭建 创建一个简单的 maven 项目。
引入依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-core</artifactId > <version > 1.6.5</version > <scope > compile</scope > </dependency > <dependency > <groupId > ch.qos.logback</groupId > <artifactId > logback-classic</artifactId > <version > 1.6.5</version > <scope > compile</scope > </dependency > <dependency > <groupId > org.slf4j</groupId > <artifactId > slf4j-api</artifactId > <version > 2.0.20</version > <scope > compile</scope > </dependency >
简单使用 在 resources 目录下创建 logback.xml 配置 logback,如果是 spring 项目,也可以使用 logback-spring.xml。
Logback 配置由三部分组成:Logger、Appender、Layout。三者的关系非常清晰:Logger 负责生成日志事件,Appender 决定日志往哪写,Layout 则控制日志长什么样。
最简单的使用方式就是将日志自定义格式化然后输出到控制台中,下面是 logback.xml 配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?xml version="1.0" encoding="UTF-8" ?> <configuration > <property name ="LOG_HOME" value ="logs/app" /> <appender name ="CONSOLE" class ="ch.qos.logback.core.ConsoleAppender" > <encoder > <pattern > %d{yyyy-MM-dd} [%thread] %-5level %logger{36} - %msg%n</pattern > </encoder > </appender > <root level ="DEBUG" > <appender-ref ref ="CONSOLE" /> </root > </configuration >
代码中增加日志打印:
1 2 3 4 5 6 7 8 9 10 11 12 package day.happy365.logbackdemo;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class Main { private static final Logger logger = LoggerFactory.getLogger(Main.class); public static void main (String[] args) { logger.info("Example log info" ); } }
输出的日志样式 2026-10-12 19:48:37 [main] INFO day.happy365.logbackdemo.Main - Example log info
Layout 格式化 1 2 3 <encoder > <pattern > %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern > </encoder >
占位变量说明:
%d{HH:mm:ss.SSS} 时间戳(精确到毫秒)
[%thread] 线程名
%-5level 日志级别,左对齐占 5 字符
%logger{36} Logger 名,最多 36 字符
%msg 日志内容
%n 换行符
指定特定包的日志输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="UTF-8" ?> <configuration debug ="true" > <property name ="LOG_HOME" value ="C://Users/Roborock/Documents/projects/logback-demo/logs/aftersales" /> <appender name ="CONSOLE" class ="ch.qos.logback.core.ConsoleAppender" > <encoder > <pattern > %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern > </encoder > </appender > <logger name ="com.example" level ="INFO" /> <root level ="INFO" > <appender-ref ref ="CONSOLE" /> </root > </configuration >
测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package day.happy365.logbackdemo;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class Main { private static final Logger logger1 = LoggerFactory.getLogger("com.example" ); private static final Logger logger2 = LoggerFactory.getLogger("com.example.xx" ); public static void main (String[] args) { logger1.debug("Example log debug of {}" , "logger1" ); logger1.info("Example log info of {}" , "logger1" ); logger2.debug("Example log debug of {}" , "logger2" ); logger2.info("Example log info of {}" , "logger2" ); } }
输出:
1 2 2026-10-12 20:30:10 [main] INFO com.example - Example log info of logger1 2026-10-12 20:30:10 [main] INFO com.example.xx - Example log info of logger2
日志样式的继承关系 Logger 会自动继承其父级日志配置,通过类的全限定名决定类的继承关系。例如 com.example 是 com.example.xx 的父级。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package day.happy365.logbackdemo;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class Main { private static final Logger logger1 = LoggerFactory.getLogger("com.example" ); private static final Logger logger2 = LoggerFactory.getLogger("com.example.xx" ); public static void main (String[] args) { logger1.debug("Example log debug of {}" , "logger1" ); logger1.info("Example log info of {}" , "logger1" ); logger2.debug("Example log debug of {}" , "logger2" ); logger2.info("Example log info of {}" , "logger2" ); } }
输出:
1 2 3 4 2026-10-12 20:18:46 [main] DEBUG com.example - Example log debug of logger1 2026-10-12 20:18:46 [main] INFO com.example - Example log info of logger1 2026-10-12 20:18:46 [main] DEBUG com.example.xx - Example log debug of logger2 2026-10-12 20:18:46 [main] INFO com.example.xx - Example log info of logger2
参数化日志 避免字符串拼接的性能损耗:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 log.debug("Current count is " + count); log.debug("Current count is {}" , count); ```` 支持多个参数,最后一个参数为异常时自动打印堆栈: ```java String message = "This is a String" ;Integer zero = 0 ;try { logger.debug("Logging message: {}" , message); logger.debug("Going to divide {} by {}" , 42 , zero); int result = 42 / zero; } catch (Exception e) { logger.error("Error dividing {} by {} " , 42 , zero, e); }
输出:
1 2 3 4 5 6 21:32:10.311 [main] DEBUG com.baeldung.logback.LogbackTests - Logging message: This is a String 21:32:10.316 [main] DEBUG com.baeldung.logback.LogbackTests - Going to divide 42 by 0 21:32:10.316 [main] ERROR com.baeldung.logback.LogbackTests - Error dividing 42 by 0 java.lang.ArithmeticException: / by zero at com.baeldung.logback.LogbackTests.givenParameters_ValuesLogged(LogbackTests.java:64) ...
Appender 基本配置 1 2 3 4 5 6 7 8 9 10 11 <configuration > <appender name ="CONSOLE" class ="ch.qos.logback.core.ConsoleAppender" > <encoder > <pattern > %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern > </encoder > </appender > <root level ="debug" > <appender-ref ref ="CONSOLE" /> </root > </configuration >
appender 定义输出行为
encoder 内的 pattern 控制格式
root 设置根 Logger 级别并绑定 Appender
对 Spring 的支持:
test、prod 环境的输出行为控制:
1 2 3 4 5 6 7 8 <configuration > ... <springProfile name ="test,prod" > <root level ="INFO" > <appender-ref ref ="CONSOLE" /> </root > </springProfile > </configuration >
变量替换 通过 <property name="VAR_NAME" value="VAR_VAL"/> 定义变量,通过 ${VAR_NAME} 引用。
1 2 3 4 5 6 7 8 9 10 11 <configuration > <property name ="LOG_DIR" value ="/var/log/application" /> <appender name ="FILE" class ="ch.qos.logback.core.FileAppender" > <file > ${LOG_DIR}/tests.log</file > <append > true</append > <encoder > <pattern > %-4relative [%thread] %-5level %logger{35} - %msg%n</pattern > </encoder > </appender > </configuration >
Appender ConsoleAppender 输出到控制台(System.out 或 System.err),使用缓冲 I/O,性能较好。
1 2 3 4 5 6 <appender name ="STDOUT" class ="ch.qos.logback.core.ConsoleAppender" > <target > System.out</target > <encoder > <pattern > %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern > </encoder > </appender >
FileAppender 输出到指定文件:
1 2 3 4 5 6 7 <appender name ="FILE" class ="ch.qos.logback.core.FileAppender" > <file > tests.log</file > <append > true</append > <encoder > <pattern > %-4relative [%thread] %-5level %logger{35} - %msg%n</pattern > </encoder > </appender >
RollingFileAppender 按时间或大小滚动日志文件,生产环境必备。
按天滚动 + 压缩归档
1 2 3 4 5 6 7 8 9 10 11 12 <property name ="LOG_FILE" value ="LogFile" /> <appender name ="FILE" class ="ch.qos.logback.core.rolling.RollingFileAppender" > <file > ${LOG_FILE}.log</file > <rollingPolicy class ="ch.qos.logback.core.rolling.TimeBasedRollingPolicy" > <fileNamePattern > ${LOG_FILE}.%d{yyyy-MM-dd}.gz</fileNamePattern > <maxHistory > 30</maxHistory > <totalSizeCap > 3GB</totalSizeCap > </rollingPolicy > <encoder > <pattern > %-4relative [%thread] %-5level %logger{35} - %msg%n</pattern > </encoder > </appender >
按月归档 + 自定义路径
1 2 3 4 5 6 7 8 <property name ="LOG_DIR" value ="/var/logs/application" /> <appender name ="FILE" class ="ch.qos.logback.core.rolling.RollingFileAppender" > <file > ${LOG_DIR}/${LOG_FILE}.log</file > <rollingPolicy class ="ch.qos.logback.core.rolling.TimeBasedRollingPolicy" > <fileNamePattern > ${LOG_DIR}/%d{yyyy/MM}/${LOG_FILE}.gz</fileNamePattern > <totalSizeCap > 3GB</totalSizeCap > </rollingPolicy > </appender >
关键点:
%d{} 控制滚动周期(支持 yyyy-MM-dd, HH, mm 等)
.gz 后缀自动启用压缩
maxHistory 和 totalSizeCap 防止磁盘被占满
自定义 Appender 可通过继承 AppenderBase 实现自定义输出,如写入数据库、发送 MQ 消息等。
1 2 3 4 5 6 7 public class CustomAppender extends AppenderBase <ILoggingEvent> { @Override protected void append (ILoggingEvent event) { System.out.println("Custom: " + event.getFormattedMessage()); } }
配置中引用:
1 <appender name ="CUSTOM" class ="com.example.CustomAppender" />
参考文献 Logback 使用指南
示例配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <configuration > <property name ="LOG_HOME" value ="logs" > </property > <appender name ="CONSOLE" class ="ch.qos.logback.core.ConsoleAppender" > <encoder > <pattern > %d{yyyy-MM-dd HH:mm:ss [%thread] %-5level %logger{36} - %msg%n</pattern > </encoder > </appender > <appender name ="FILE" class ="ch.qos.logback.core.rolling.RollingFileAppender" > <file > ${LOG_HOME}/app.log</file > <rollingPolicy class ="ch.qos.logback.core.rolling.TimeBasedRollingPolicy" > <fileNamePattern > ${LOG_HOME}/app.%d{yyyy-MM-dd}.gz</fileNamePattern > <maxHistory > 30</maxHistory > </rollingPolicy > <encoder > <pattern > %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg%n</pattern > </encoder > </appender > <springProfile name ="dev" > <root level ="DEBUG" > <appender-ref ref ="CONSOLE" /> </root > </springProfile > <springProfile name ="prod" > <root level ="INFO" > <appender-ref ref ="FILE" /> </root > </springProfile > <root level ="INFO" > <appender-ref ref ="CONSOLE" /> <appender-ref ref ="FILE" /> </root > <configuration >