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.disabled
  • pbsbc01h3-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

结论:问题来自两个组件共同作用:

  1. systemd-journald 写 journal 日志
  2. 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 rsyslog

6.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=200

2. 禁用 rsyslog

sudo systemctl stop rsyslog
sudo systemctl disable rsyslog

3. 清理现有日志

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

标签: none

添加新评论