在生产环境中,Java应用程序通常以java -jar方式运行,而日志管理是运维的重要部分。如果日志文件过大,不仅影响性能,还会增加排查问题的难度。因此,按日分包日志成为常见的需求。本文将介绍4种实现方式,并提供详细配置和代码示例。
方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
Logback | Spring Boot项目 | 原生支持,配置简单 | 需依赖Logback |
Log4j2 | 高性能日志需求 | 异步日志,性能好 | 配置稍复杂 |
logrotate | Linux服务器 | 不依赖应用代码 | 需额外安装 |
Shell+Cron | 简单应用 | 无需修改代码 | 不够可靠 |
Logback是Log4j的改进版,Spring Boot默认使用它。它支持基于时间的滚动策略,非常适合日志分包。
logback.xml在src/main/resources/logback.xml中添加:
<configuration>
<!-- 定义日志存储目录 -->
<property name="LOG_DIR" value="logs" />
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当前日志文件 -->
<file>${LOG_DIR}/app.log</file>
<!-- 滚动策略:按天分割 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 文件名格式 -->
<fileNamePattern>${LOG_DIR}/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 保留30天日志 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 日志格式 -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 设置日志级别 -->
<root level="INFO">
<appender-ref ref="ROLLING_FILE" />
</root>
</configuration>直接运行:
java -jar your-app.jar日志会自动按天存储:
logs/
├── app.log # 当前日志
├── app.2023-10-01.log # 前一天的日志
└── app.2023-10-02.log # 更早的日志Log4j2是Log4j的升级版,支持异步日志,性能优于Logback。
log4j2.xml在src/main/resources/log4j2.xml中配置:
<Configuration>
<Appenders>
<!-- 按天滚动日志 -->
<RollingFile name="RollingFile"
fileName="logs/app.log"
filePattern="logs/app.%d{yyyy-MM-dd}.log">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Pattern>
</PatternLayout>
<Policies>
<!-- 每天滚动一次 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
<!-- 最多保留30天 -->
<DefaultRolloverStrategy max="30"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>java -jar your-app.jar日志存储结构:
logs/
├── app.log # 当前日志
├── app.2023-10-01.log # 历史日志
└── app.2023-10-02.loglogrotate是Linux自带的日志管理工具,可定时压缩、删除旧日志。
在/etc/logrotate.d/myapp中添加:
/path/to/logs/app.log {
daily # 按天分割
missingok # 如果日志不存在,不报错
rotate 30 # 保留30天
compress # 压缩旧日志
delaycompress # 延迟一天压缩
notifempty # 空日志不处理
copytruncate # 复制后清空原日志(避免重启应用)
}java -jar your-app.jar > /path/to/logs/app.log 2>&1 &logrotate会每天自动分割日志:
/path/to/logs/
├── app.log # 当前日志
├── app.log.1.gz # 昨天的日志(压缩)
└── app.log.2.gz # 前天的日志#!/bin/bash
LOG_DIR="/path/to/logs"
TODAY=$(date +%Y-%m-%d)
# 如果日志文件存在,则重命名
if [ -f "$LOG_DIR/app.log" ]; then
mv "$LOG_DIR/app.log" "$LOG_DIR/app-$TODAY.log"
fi
# 重新启动应用(可选)
# kill现有进程并重启
pkill -f "java -jar your-app.jar"
nohup java -jar your-app.jar > "$LOG_DIR/app.log" 2>&1 &# 每天0点执行
0 0 * * * /path/to/rotate_logs.sh方案 | 适用场景 | 推荐指数 |
|---|---|---|
Logback | Spring Boot项目 | ⭐⭐⭐⭐⭐ |
Log4j2 | 高性能需求 | ⭐⭐⭐⭐ |
logrotate | Linux服务器管理 | ⭐⭐⭐ |
Shell+Cron | 简单临时方案 | ⭐⭐ |
推荐选择:
本文介绍了4种java -jar启动的日志分包方案:
最佳选择取决于项目架构,但Logback/Log4j2是最可靠的方式。
你的项目用哪种方案?欢迎在评论区讨论! 🚀