Java Maven Log4j 项目日志打印
- [1 依赖](#1 依赖)
- [2 配置](#2 配置)
- [3 测试](#3 测试)
-
- [1 Log4j](#1 Log4j)
- [2 Lombok](#2 Lombok)
- [3 结果](#3 结果)
SLF4J 是日志接口,代码中只依赖它,后续可切换 Log4j2 等实现(无需改代码)。
Logback 是 SLF4J 的默认实现,性能优于 Log4j,且内置 RollingFileAppender(滚动日志)。
1 依赖
| 依赖 | 解释 |
|---|---|
SLF4J-1.7.36 |
最后一个官方明确支持 JDK 1.8 的 1.7.x 版本,稳定无兼容问题。 |
Logback-1.2.11 |
与 SLF4J 1.7.x 完全兼容,且原生支持 JDK 1.8 的所有特性,滚动日志功能不受影响。 |
Java 日志设计遵循 "面向接口编程" 思想,这两个依赖分别承担"日志标准"和"标准实现"的角色,解耦日志 API 与具体功能逻辑:
| 依赖名称 | 角色 | 核心职责 | 类比(便于理解) |
|---|---|---|---|
slf4j-api(SLF4J) |
日志门面(接口层) | 定义统一的日志操作接口(如 Logger、LoggerFactory),屏蔽底层实现差异 |
相当于"日志界的 JDBC 规范" |
logback-classic |
日志实现(功能层) | 实现 SLF4J 接口,提供日志打印、滚动、彩色输出等具体功能 | 相当于"日志界的 MySQL 驱动" |
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gohope</groupId>
<artifactId>TaskMission</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Java 通用工具 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.41</version>
</dependency>
<!-- 1. SLF4J 日志门面(JDK 1.8 兼容版本) -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version> <!-- 1.7.x 系列是 JDK 1.8 长期支持版本 -->
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<!-- 2. Logback 日志实现(与 SLF4J 1.7.x 兼容,支持 JDK 1.8) -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version> <!-- 1.2.x 系列适配 JDK 1.8,无语法兼容问题 -->
</dependency>
</dependencies>
</project>
2 配置
| 项目 | Value |
|---|---|
| 滚动策略 | TimeBasedRollingPolicy 是按时间滚动的核心,fileNamePattern 定义归档文件名(必须包含 %d 日期占位符)。 |
| 日志路径 | logs/app.log 是当前日志文件(始终写入最新日志),归档文件会自动生成 app-2025-11-12.log 格式。 |
| 日志保留 | maxHistory=30 表示保留 30 天历史日志,totalSizeCap=1GB 限制总日志大小(可选,防止磁盘溢出)。 |
| 文件编码 | 显式指定 UTF-8 避免中文乱码。 |
| 编译验证 | 使用 JDK 1.8 编译项目,不会出现 UnsupportedClassVersionError(Logback 1.2.11 和 SLF4J 1.7.36 的编译目标是 JDK 1.6+)。 |
| 功能验证 | 启动项目后,logs 文件夹会正常生成 app.log(当前日志)和 app-2025-11-12.log(归档日志),滚动策略完全生效。 |
| 冲突处理 | 如果项目中引入了其他日志框架(如 commons-logging、log4j),需通过 exclusion 排除,避免冲突: |
需要在 src/main/resources 下创建 Logback 的配置文件 logback.xml(Logback 会自动识别该文件名),核心配置 按日期滚动日志。
完整配置文件(logback.xml)
xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds"> <!-- 自动扫描配置文件变更(每60秒) -->
<!-- 1. 定义日志输出格式 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 控制台输出格式:时间 [线程名] 日志级别 类名 - 日志信息 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} [%file:%line] - %msg%n </pattern>
<charset>UTF-8</charset> <!-- 解决中文乱码 -->
</encoder>
</appender>
<!-- 2. 按日期滚动的文件日志(核心配置) -->
<appender name="FILE_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 2.1 日志文件保存路径(相对路径/绝对路径均可) -->
<file>logs/app.log</file>
<!-- 2.2 滚动策略:按日期滚动(一天一个文件) -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 归档日志文件名格式:app-2025-11-12.log(日期后缀) -->
<fileNamePattern>logs/app-%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志保留天数:保留30天的历史日志,自动删除过期文件 -->
<maxHistory>60</maxHistory>
<!-- 可选:限制所有日志文件总大小(例如 1GB),防止磁盘占满 -->
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
<!-- 2.3 日志输出格式(文件中包含的字段) -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} [%file:%line] - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 3. 全局日志级别(DEBUG/INFO/WARN/ERROR) -->
<!-- 级别说明:DEBUG < INFO < WARN < ERROR,只输出 >= 该级别的日志 -->
<root level="INFO">
<appender-ref ref="CONSOLE"/> <!-- 同时输出到控制台 -->
<appender-ref ref="FILE_ROLLING"/> <!-- 输出到滚动日志文件 -->
</root>
<!-- 可选:单独配置某个包的日志级别(例如降低 Spring 框架的日志级别) -->
<logger name="org.springframework" level="WARN" additivity="false">
<appender-ref ref="FILE_ROLLING"/>
</logger>
</configuration>
3 测试
1 Log4j
java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogTest1 {
private static final Logger log = LoggerFactory.getLogger(LogTest1.class);
public static void main(String[] args) {
log.error("测试日志1 Log4j");
}
}
2 Lombok
java
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class LogTest2 {
public static void main(String[] args) {
log.error("测试日志2 Lombok");
}
}
3 结果
java
2025-11-12 17:39:17.348 [main] ERROR LogTest1 [LogTest1.java:10] - 测试日志1 Log4j
2025-11-12 17:39:21.675 [main] ERROR LogTest2 [LogTest2.java:6] - 测试日志2 Lombok
