journald和syslog调整
1核1G开发版 /var/log 目录每天12点写满问题排查与解决
一、问题现象
- 服务器配置:1核1G 开发版
- 问题:每天中午12点,
/var/log目录被写满 - 检查发现:
systemd-journald是主要占用来源
二、初步排查
2.1 检查系统定时任务
cat /etc/crontab发现系统有标准的 cron 任务,包括每小时、每天、每周、每月的任务调度。
2.2 检查 cron.d 目录
ls -la /etc/cron.d/发现两个关键脚本被禁用:
pbsbc01h3-truncate-logs.disabledpbsbc01h3-ram-logging.disabled
2.3 检查清理脚本逻辑
cat /usr/lib/pbsbc01h3/pbsbc01h3-truncate-logs脚本功能:
- 当
/var/log使用率超过 75% 时触发 - 执行:写入SD卡 → logrotate轮转 → truncate清空 → 删除旧文件
- 但依赖 ramlog 且已被禁用
三、问题根源定位
3.1 真正元凶:systemd-journald
# 查看日志占用
du -sh /var/log/
journalctl --disk-usage根本原因:systemd-journald 默认配置不主动限制日志大小,在1核1G开发版上容易写满磁盘。
3.2 进一步排查:rsyslogd 也在写入
lsof /var/log/* 2>/dev/null发现 rsyslogd 正在写入多个日志文件:
/var/log/syslog/var/log/daemon.log/var/log/messages/var/log/kern.log/var/log/auth.log/var/log/user.log
结论:问题来自两个组件共同作用:
systemd-journald写 journal 日志rsyslogd将日志转发写入磁盘文件
四、解决方案
4.1 方案一:journald 放弃持久化(适合开发板)
修改 /etc/systemd/journald.conf:
[Journal]
# 核心:只存内存
Storage=volatile
# 内存大小限制
RuntimeMaxUse=40M
RuntimeMaxFileSize=10M
# 性能优化
Compress=no
SyncIntervalSec=0
# 防刷屏
RateLimitIntervalSec=10s
RateLimitBurst=200
# 日志转发(建议关闭)
ForwardToSyslog=no
ForwardToWall=no应用配置:
sudo systemctl restart systemd-journald
sudo journalctl --rotate
sudo journalctl --vacuum-size=1M
sudo rm -rf /var/log/journal/*4.2 方案二:处理 rsyslogd
选项A:完全禁用 rsyslog(最推荐)
sudo systemctl stop rsyslog
sudo systemctl disable rsyslog
# 清理现有日志
sudo find /var/log -name "*.log" -exec truncate -s 0 {} \; 2>/dev/null
sudo find /var/log -name "*.log.*" -delete 2>/dev/null选项B:最小化 rsyslog 配置
备份原配置后,创建最小配置只保留关键日志(auth、kern.crit):
sudo tee /etc/rsyslog.conf > /dev/null << 'EOF'
module(load="imuxsock")
module(load="imklog")
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
$WorkDirectory /var/spool/rsyslog
$IncludeConfig /etc/rsyslog.d/*.conf
# 只记录关键日志
auth,authpriv.* /var/log/auth.log
kern.crit;kern.emerg /var/log/kern.crit
*.emerg :omusrmsg:*
# 丢弃其他所有日志
*.* stop
EOF
sudo systemctl restart rsyslog选项C:激进 logrotate 策略
创建 /etc/logrotate.d/rsyslog-aggressive:
/var/log/syslog
/var/log/messages
/var/log/kern.log
/var/log/daemon.log
/var/log/auth.log
{
rotate 1
size 10M
hourly
missingok
notifempty
compress
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}4.3 方案对比
| 方案 | 磁盘写入 | 日志保留 | 适用场景 |
|---|---|---|---|
| journald volatile + 禁用rsyslog | 零写入 | 仅内存,重启丢失 | 开发板最优 |
| journald volatile + 最小化rsyslog | 极低 | 仅关键日志 | 需保留安全日志 |
| 激进 logrotate | 仍有写入 | 所有日志但限制大小 | 临时方案 |
五、放弃持久化的影响分析
5.1 优点
| 方面 | 效果 |
|---|---|
| 磁盘IO | 显著减小,不再持续写入 |
| SD卡寿命 | 延长数倍(日志写入是主要磨损源) |
| CPU占用 | 减少(关闭压缩) |
| 磁盘空间 | /var/log 不再被journal撑爆 |
| 启动速度 | 减少1-2秒(无需加载历史日志) |
5.2 缺点及对策
| 缺点 | 解决方案 |
|---|---|
| 重启后日志丢失 | 定期导出重要日志:journalctl -p err -b > /var/log/error-$(date).log |
| 无法追溯历史 | 使用 ForwardToSyslog=yes 配合 rsyslog 只存ERROR级别 |
| 内存占用增加 | 设置 RuntimeMaxUse=30M(1G内存占约3%) |
六、验证方法
6.1 确认配置生效
# 检查 journald 配置
journalctl --show-config | grep -E "Storage|Runtime|ForwardToSyslog"
# 检查 rsyslog 状态
ps aux | grep rsyslog
systemctl status rsyslog6.2 监控磁盘占用
# 实时监控
watch -n 5 'du -sh /var/log/ && ls -lh /var/log/*.log 2>/dev/null'
# 查看具体占用
du -sh /var/log/*
df -h /var/log/6.3 测试日志写入
# 写入测试日志
logger "test message"
# 查看日志位置
journalctl -n 1 | grep "test message"
# 检查磁盘文件是否增长
ls -lh /var/log/syslog 2>/dev/null七、最佳实践总结
对于 1核1G 开发板,推荐配置:
最终配置
1. journald 配置 (/etc/systemd/journald.conf):
[Journal]
Storage=volatile
RuntimeMaxUse=40M
Compress=no
ForwardToSyslog=no
RateLimitIntervalSec=10s
RateLimitBurst=2002. 禁用 rsyslog:
sudo systemctl stop rsyslog
sudo systemctl disable rsyslog3. 清理现有日志:
sudo journalctl --rotate
sudo journalctl --vacuum-size=1M
sudo find /var/log -name "*.log" -exec truncate -s 0 {} \;预期效果
- ✅
/var/log不再增长 - ✅ 磁盘IO显著降低
- ✅ SD卡寿命延长
- ✅ 每天12点不再爆盘
- ⚠️ 重启后日志丢失(可接受,开发板场景)
八、附录:相关命令速查
| 命令 | 用途 |
|---|---|
journalctl --disk-usage | 查看 journal 日志占用 |
journalctl --rotate | 强制轮转日志 |
journalctl --vacuum-size=100M | 清理到指定大小 |
journalctl --show-config | 显示当前配置 |
journalctl -f | 实时查看日志 |
journalctl -p err -b | 查看本次启动的错误日志 |
systemctl restart systemd-journald | 重启 journald 服务 |
lsof /var/log/* | 查看谁在写日志文件 |
du -sh /var/log/ | 查看日志目录总大小 |
最终调整结果
/etc/systemd/journald.conf
root@pbsbc01h3:~# grep -E -v "^\s*(#|$)" /etc/systemd/journald.conf
[Journal]
Storage=volatile
Compress=no
SyncIntervalSec=0
RuntimeMaxUse=40M
RuntimeMaxFileSize=10M
ForwardToSyslog=no
ForwardToWall=no/etc/rsyslog.conf
root@pbsbc01h3:~# grep -E -v "^\s*(#|$)" /etc/rsyslog.conf
module(load="imuxsock") # provides support for local system logging
module(load="imklog") # provides kernel logging support
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
$FileOwner root
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
$WorkDirectory /var/spool/rsyslog
$IncludeConfig /etc/rsyslog.d/*.conf
auth,authpriv.* /var/log/auth.log
kern.crit;kern.emerg /var/log/kern.crit
*.emerg :omusrmsg:*
*.* stop