在档案管理软件的实际运行中,日志不完整通常由三个核心问题导致:应用重启时缓冲区未刷新、磁盘空间不足导致写入失败、单文件过大被系统截断。要彻底解决此问题,必须从应用层日志组件配置和系统层日志轮转策略两端同时入手。本方案采用Logback作为日志框架,配合Linux系统的Logrotate工具,实现日志的完整记录与自动管理。
我们需要在档案管理软件的依赖中引入Logback相关组件。请确保项目的pom.xml中包含以下依赖(版本号建议使用1.2.x稳定版):
ch.qos.logback
logback-classic
1.2.12
ch.qos.logback
logback-core
1.2.12
接下来,在项目的src/main/resources目录下创建或修改logback-spring.xml文件。这个配置是解决日志丢失的核心,它采用了基于时间和大小的滚动策略,并开启了异步日志以防止阻塞业务逻辑,同时配置了永不阻塞策略确保极端情况下日志不丢。
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${LOG_HOME}/${APP_NAME}.log
true
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
UTF-8
${LOG_HOME}/${APP_NAME}-%d{yyyy-MM-dd}.%i.log
100MB
30
10GB
512
false
20
配置细节解读:上述配置中,SizeAndTimeBasedRollingPolicy确保了单文件不会无限增大,neverBlock虽然设置为false以在极端情况下阻塞,但配合discardingThreshold,优先保证错误日志(WARN/ERROR)不丢失,这是档案系统合规性的关键。
虽然应用层做了滚动,但为了进一步压缩旧日志并释放磁盘空间,必须配置Linux系统的Logrotate。请以root用户执行以下命令创建配置文件:
vim /etc/logrotate.d/archivesystem
在文件中输入以下完整配置内容:
/var/log/archivesystem/.log
{
每天检查一次
daily
保留最近30个备份文件
rotate 30
如果日志文件为空,则不轮转
notifempty
如果日志文件丢失,不报错继续执行下一个
missingok
轮转后压缩旧日志(节省空间)
compress
延迟压缩(防止当前正在写入的文件出现问题)
delaycompress
轮转时创建新文件,权限644,用户root,组root
create 0644 root root
重要:由于Java进程持有文件句柄,使用copytruncate先复制再清空原文件
避免Java进程仍然向旧文件写入数据
copytruncate
轮转后的日志文件名添加日期后缀(可选,Logback已处理,这里主要配合系统)
dateext
}
配置完成后,手动执行一次以验证配置是否有语法错误:
logrotate -f /etc/logrotate.d/archivesystem
执行后,使用ls -lh /var/log/archivesystem/查看是否生成了压缩包(.gz或类似后缀)且原文件被清空。如果一切正常,系统会自动通过Cron每天执行此任务。
为了防止突发流量导致日志在应用轮转前打满磁盘,我们需要部署一个兜底清理脚本。创建脚本文件clean_log.sh:

vim /usr/local/bin/clean_log.sh
写入以下内容:
!/bin/bash
设定日志目录
LOG_DIR="/var/log/archivesystem"
设定磁盘使用率告警阈值,超过80%开始清理
DISK_THRESHOLD=80
获取当前磁盘使用率(去除%号)
CURRENT_USAGE=$(df /var | awk 'NR==2 {gsub("%",""); print $5}')
echo "检查时间: $(date '+%Y-%m-%d %H:%M:%S'), 当前磁盘使用率: ${CURRENT_USAGE}%"
if [ $CURRENT_USAGE -gt $DISK_THRESHOLD ]; then
echo "警告:磁盘使用率超过 ${DISK_THRESHOLD}%,开始清理7天前的压缩日志..."
查找并删除7天前的 .log.gz 文件
注意:这里只删除压缩后的归档日志,不删除当前正在写入的.log文件
DELETED_FILES=$(find $LOG_DIR -name ".gz" -mtime +7 -type f -print -delete)
if [ -z "$DELETED_FILES" ]; then
echo "未找到需要清理的旧日志文件。"
else
echo "已清理以下文件:"
echo "$DELETED_FILES"
fi
else
echo "磁盘空间充足,无需清理。"
fi
赋予脚本执行权限并设置定时任务:
chmod +x /usr/local/bin/clean_log.sh
编辑crontab:
crontab -e
添加一行,每天凌晨2点执行检查:
0 2 /usr/local/bin/clean_log.sh >> /var/log/clean_log.log 2>&1
完成上述配置后,必须进行验证以确保方案生效。
1. 验证应用日志生成:启动档案管理软件,在系统中进行一次档案上传或查询操作。检查/var/log/archivesystem/archive-app.log是否实时输出了对应的INFO或DEBUG日志。
2. 验证日志滚动:为了快速测试,可以临时将logback-spring.xml中的maxFileSize改为1KB。重启应用,重复触发操作,观察目录下是否生成了archive-app-2023-xx-xx.0.log、archive-app-2023-xx-xx.1.log等文件。测试完毕后记得改回100MB。
3. 验证日志完整性:对比操作步骤和应用日志,检查是否有时间断档。重点关注应用重启瞬间,上一条日志的下一条日志时间差是否合理,确认重启未导致日志截断。
4. 验证清理脚本:手动执行/usr/local/bin/clean_log.sh,观察输出日志。如果磁盘未达标,可以手动修改脚本中的DISK_THRESHOLD为一个较小的值(如10)再次执行,查看find命令是否正确匹配了旧文件。