Log4j 日志框架
2025/9/17大约 6 分钟
Log4j 日志框架完整教程
前置知识
在开始本教程之前,建议您具备以下基础知识:
- Java 基础语法
- Maven 或 Gradle 构建工具
- 基本的日志概念
- Spring Boot 基础(可选)
什么是 Log4j?
Log4j 是 Apache 软件基金会的一个开源项目,是一个基于 Java 的日志记录工具。它提供了:
- 📝 灵活的配置:支持多种配置方式(XML、JSON、YAML、Properties)
- 🎯 多种输出目标:控制台、文件、数据库、网络等
- 📊 日志级别:TRACE、DEBUG、INFO、WARN、ERROR、FATAL
- ⚡ 高性能:异步日志记录,高性能输出
- 🔧 插件化架构:支持自定义 Appender 和 Layout
Log4j 版本对比
特性 | Log4j 1.x | Log4j 2.x |
---|---|---|
性能 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
配置灵活性 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
异步支持 | ⭐⭐ | ⭐⭐⭐⭐⭐ |
安全性 | ⭐⭐ | ⭐⭐⭐⭐⭐ |
环境准备
1. 添加依赖
在您的 pom.xml
中添加 Log4j 依赖:
<dependencies>
<!-- Log4j 核心依赖 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
<!-- Log4j 实现 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<!-- Log4j 异步支持 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies>
2. 基础配置
创建 log4j2.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<!-- 定义属性 -->
<Properties>
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Property>
<Property name="LOG_FILE_PATH">logs</Property>
</Properties>
<!-- 定义 Appender -->
<Appenders>
<!-- 控制台输出 -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
<!-- 文件输出 -->
<RollingFile name="FileAppender" fileName="${LOG_FILE_PATH}/app.log"
filePattern="${LOG_FILE_PATH}/app-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<!-- 定义 Logger -->
<Loggers>
<!-- 根 Logger -->
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="FileAppender"/>
</Root>
<!-- 自定义 Logger -->
<Logger name="com.example" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="FileAppender"/>
</Logger>
</Loggers>
</Configuration>
核心使用
1. 基础日志记录
package com.example;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class LogExample {
// 获取 Logger 实例
private static final Logger logger = LogManager.getLogger(LogExample.class);
public void basicLogging() {
// 不同级别的日志
logger.trace("这是 TRACE 级别的日志");
logger.debug("这是 DEBUG 级别的日志");
logger.info("这是 INFO 级别的日志");
logger.warn("这是 WARN 级别的日志");
logger.error("这是 ERROR 级别的日志");
logger.fatal("这是 FATAL 级别的日志");
// 带参数的日志
String user = "张三";
int age = 25;
logger.info("用户 {} 的年龄是 {}", user, age);
// 异常日志
try {
// 模拟异常
throw new RuntimeException("测试异常");
} catch (Exception e) {
logger.error("发生异常", e);
}
}
}
2. 性能优化配置
异步日志配置
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Property>
</Properties>
<Appenders>
<!-- 异步控制台输出 -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
<!-- 异步文件输出 -->
<RollingFile name="AsyncFile" fileName="logs/async-app.log"
filePattern="logs/async-app-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="AsyncFile"/>
</Root>
</Loggers>
</Configuration>
3. 自定义 Appender
自定义 Appender 实现
package com.example.custom;
import org.apache.logging.log4j.core.*;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.PatternLayout;
import java.io.Serializable;
@Plugin(name = "CustomAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE)
public class CustomAppender extends AbstractAppender {
protected CustomAppender(String name, Filter filter, Layout<? extends Serializable> layout) {
super(name, filter, layout);
}
@PluginFactory
public static CustomAppender createAppender(
@PluginAttribute("name") String name,
@PluginElement("Filter") Filter filter,
@PluginElement("Layout") Layout<? extends Serializable> layout) {
if (name == null) {
LOGGER.error("No name provided for CustomAppender");
return null;
}
if (layout == null) {
layout = PatternLayout.createDefaultLayout();
}
return new CustomAppender(name, filter, layout);
}
@Override
public void append(LogEvent event) {
// 自定义日志处理逻辑
System.out.println("自定义 Appender: " + getLayout().toSerializable(event));
}
}
高级功能
1. 日志级别控制
package com.example;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Level;
public class LogLevelExample {
private static final Logger logger = LogManager.getLogger(LogLevelExample.class);
public void logLevelControl() {
// 动态设置日志级别
org.apache.logging.log4j.core.config.LoggerConfig loggerConfig =
(org.apache.logging.log4j.core.config.LoggerConfig) LogManager.getRootLogger();
// 设置为 DEBUG 级别
loggerConfig.setLevel(Level.DEBUG);
// 输出日志
logger.debug("现在可以看到 DEBUG 日志了");
logger.info("INFO 日志正常显示");
// 设置为 WARN 级别
loggerConfig.setLevel(Level.WARN);
// 只有 WARN 及以上级别的日志会显示
logger.debug("这条 DEBUG 日志不会显示");
logger.warn("这条 WARN 日志会显示");
}
}
2. 结构化日志
package com.example;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
public class StructuredLogExample {
private static final Logger logger = LogManager.getLogger(StructuredLogExample.class);
public void structuredLogging() {
// 添加上下文信息
ThreadContext.put("userId", "12345");
ThreadContext.put("sessionId", "session-abc");
// 记录业务日志
logger.info("用户登录成功");
// 记录操作日志
ThreadContext.put("operation", "create_order");
logger.info("创建订单");
// 清理上下文
ThreadContext.clearAll();
}
}
最佳实践
安全注意事项
- 敏感信息:不要在日志中记录密码、token等敏感信息
- 日志轮转:配置合理的日志轮转策略,避免磁盘空间不足
- 日志级别:生产环境使用合适的日志级别(通常 INFO 或 WARN)
性能优化
- 异步日志:使用异步 Appender 提高性能
- 日志格式:使用简单的日志格式,避免复杂的字符串拼接
- 日志级别:合理使用日志级别,避免过多 DEBUG 日志
1. 生产环境配置
生产环境 log4j2.yml 配置
# log4j2.yml 生产环境配置
Configuration:
status: warn
Properties:
LOG_PATTERN: "%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"
LOG_FILE_PATH: "/var/logs/app"
Appenders:
Console:
name: Console
target: SYSTEM_OUT
PatternLayout:
Pattern: "${LOG_PATTERN}"
RollingFile:
name: FileAppender
fileName: "${LOG_FILE_PATH}/app.log"
filePattern: "${LOG_FILE_PATH}/app-%d{yyyy-MM-dd}-%i.log.gz"
PatternLayout:
Pattern: "${LOG_PATTERN}"
Policies:
TimeBasedTriggeringPolicy: {}
SizeBasedTriggeringPolicy:
size: 100MB
DefaultRolloverStrategy:
max: 30
Loggers:
Root:
level: warn
AppenderRef:
- ref: Console
- ref: FileAppender
2. 开发环境配置
# log4j2.yml 开发环境配置
Configuration:
status: info
Properties:
LOG_PATTERN: "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
Appenders:
Console:
name: Console
target: SYSTEM_OUT
PatternLayout:
Pattern: "${LOG_PATTERN}"
File:
name: FileAppender
fileName: "logs/dev.log"
PatternLayout:
Pattern: "${LOG_PATTERN}"
Loggers:
Root:
level: debug
AppenderRef:
- ref: Console
- ref: FileAppender
常见问题
1. 如何配置日志输出到数据库?
可以使用 JDBC Appender 将日志输出到数据库:
<Appenders>
<JDBC name="DatabaseAppender" tableName="app_logs">
<ConnectionFactory class="com.example.DatabaseConnectionFactory" method="getConnection"/>
<Column name="timestamp" isEventTimestamp="true"/>
<Column name="level" pattern="%level"/>
<Column name="logger" pattern="%logger"/>
<Column name="message" pattern="%message"/>
</JDBC>
</Appenders>
2. 如何实现日志脱敏?
可以通过自定义 Layout 实现日志脱敏:
public class SensitiveDataLayout extends PatternLayout {
@Override
public String toSerializable(LogEvent event) {
String message = super.toSerializable(event);
// 脱敏处理
return message.replaceAll("password=\\w+", "password=***")
.replaceAll("token=\\w+", "token=***");
}
}
3. 如何配置日志发送到远程服务器?
可以使用 Socket Appender 或 HTTP Appender:
<Appenders>
<!-- Socket Appender -->
<Socket name="SocketAppender" host="localhost" port="8080">
<JsonLayout compact="true" eventEol="true"/>
</Socket>
<!-- HTTP Appender -->
<Http name="HttpAppender" url="http://localhost:8080/logs">
<JsonLayout compact="true" eventEol="true"/>
</Http>
</Appenders>
总结
本教程详细介绍了 Log4j 的完整使用流程,包括:
- ✅ 环境准备:添加必要的依赖和基础配置
- ✅ 核心使用:基础日志记录和性能优化
- ✅ 高级功能:日志级别控制、结构化日志
- ✅ 最佳实践:安全注意事项和性能优化
- ✅ 常见问题:数据库输出、日志脱敏、远程发送
下一步学习
- 学习 Log4j 与 Spring Boot 集成
- 了解分布式系统中的日志收集
- 探索 ELK 日志分析栈的使用
希望这个教程对您有所帮助!如果您有任何问题,欢迎在评论区讨论。