CentOS 7及以上版本使用systemd管理服务,日志由journalctl统一收集和管理,默认日志存储在/var/log/journal目录下。如果不做任何配置,日志会持续增长直到占满磁盘空间。解决这个问题的核心方法是修改journald的配置文件/etc/systemd/journald.conf,通过设置SystemMaxUse、SystemMaxFileSize、SystemMaxFiles等参数来控制日志总量、单个文件大小和文件数量,从而实现日志轮转和保留策略。下面我会把每一个参数、每一种场景、每一步操作全部讲透。
一、journald日志机制的基本原理
systemd-journald是CentOS 7/8/9的日志守护进程,它以二进制格式(journal文件)存储日志,而不是传统的纯文本文件。这种设计让查询更高效,但也带来一个问题:你不能像处理/var/log/messages那样直接用rm删除单个日志文件来释放空间,因为journal文件是一个整体数据库结构。journald有两种存储模式:持久化存储(/var/log/journal/)和易失性存储(/run/log/journal/,重启丢失)。大多数生产环境都使用持久化模式。
journald本身内置了简单的轮转逻辑,但默认策略非常宽松——只要磁盘空间够,日志就会一直写。所以运维人员必须主动配置限制参数,否则在高并发、高日志量的服务器上,/var/log/journal可能在几天内就膨胀到几十GB甚至上百GB。
二、核心配置文件与关键参数详解
配置文件路径是/etc/systemd/journald.conf。CentOS默认没有这个文件,你需要手动创建。所有参数都写在[Journal]段下面。以下是控制日志保留策略最关键的几个参数:
SystemMaxUse=:设置持久化日志的最大占用空间。例如设置为500M,意味着/var/log/journal下所有文件加起来不能超过500MB。超过后journald会自动删除最旧的日志。默认值是系统可用空间的10%,这在生产环境中远远不够。
SystemMaxFileSize=:设置单个journal文件的最大大小。默认是系统可用空间的10%或8G取较小值。设置为100M意味着每个文件最大100MB,写满后会创建新文件。这个参数决定了轮转的触发条件。
SystemMaxFiles=:设置持久化日志文件的最大数量。例如设为10,那么最多保留10个文件,超出后删除最旧的。这个参数和SystemMaxUse配合使用,双重限制更安全。
RuntimeMaxUse=:控制/run/log/journal(易失性日志)的最大空间,一般生产环境不太关注这个,设个合理值如100M即可。
MaxRetentionSec=:按时间保留日志,例如设为30day,则只保留30天内的日志,超过30天的自动删除。这个参数在CentOS 8及以上版本可用,非常实用。
下面是一个典型的生产环境配置示例:
[Journal] Storage=persistent SystemMaxUse=500M SystemMaxFileSize=100M SystemMaxFiles=10 RuntimeMaxUse=200M MaxRetentionSec=30day Compress=yes Seal=yes
Compress=yes表示对旧日志进行压缩,能节省约60%-70%的空间。Seal=yes表示对日志文件进行签名防篡改,安全场景建议开启。
三、配置生效的完整操作步骤
第一步:创建或编辑配置文件。
vi /etc/systemd/journald.conf
把上面的参数按需写入[Journal]段,保存退出。
第二步:重启journald服务使配置生效。
systemctl restart systemd-journald
注意:重启journald不会影响正在运行的业务,但正在写入的日志可能会有极短暂的中断,生产环境建议在业务低峰期操作。
第三步:验证配置是否生效。
journalctl --disk-usage
这个命令会显示当前日志占用的磁盘空间、可用空间等信息。你也可以用以下命令查看当前配置参数:
systemctl show systemd-journald | grep -i max
第四步:手动清理已有的过往日志(如果磁盘已经满了)。
journalctl --vacuum-size=500M
或者按时间清理:
journalctl --vacuum-time=7d
或者按文件数量清理:
journalctl --vacuum-files=10
这三种清理方式可以单独使用也可以组合使用,journald会取最严格的那个限制。比如同时设了500M和7天,那么哪个条件先触发就按哪个清理。
四、不同场景下的推荐配置方案
场景一:低日志量的开发测试机。日志量不大,磁盘空间有限,建议SystemMaxUse=200M,SystemMaxFileSize=50M,SystemMaxFiles=5,MaxRetentionSec=7day。够用且不浪费。
场景二:中等日志量的应用服务器。建议SystemMaxUse=1G,SystemMaxFileSize=200M,SystemMaxFiles=10,MaxRetentionSec=14day。配合Compress=yes压缩,实际占用会更少。
场景三:高日志量的数据库或中间件服务器。这类机器日志产生快,建议SystemMaxUse=2G,SystemMaxFileSize=500M,SystemMaxFiles=15,MaxRetentionSec=30day。同时建议把/var/log/journal挂载到独立的大容量磁盘或LVM卷上,避免日志占满根分区导致系统崩溃。
场景四:有合规审计要求的服务器。需要保留较长时间且防篡改,建议SystemMaxUse=5G,SystemMaxFileSize=1G,SystemMaxFiles=30,MaxRetentionSec=180day,Seal=yes,同时配合外部日志归档方案(如rsyslog转发到远程日志服务器)。
五、journald与传统rsyslog的配合使用
很多运维人员习惯用rsyslog来管理日志,journald和rsyslog并不冲突,它们可以共存。journald负责收集,rsyslog负责转发和归档。如果你需要把日志转发到远程日志服务器或者按服务名分割到不同文件,可以在/etc/rsyslog.conf或/etc/rsyslog.d/下配置转发规则。
但要注意:如果你同时开启了rsyslog转发和journald的轮转,可能会出现日志重复存储的问题。建议二选一:要么用journald自带的轮转(推荐,简单高效),要么关闭journald的持久化存储(Storage=volatile),完全交给rsyslog管理。关闭持久化的配置如下:
[Journal] Storage=volatile
这样日志只存在内存中,重启就没了,全部依赖rsyslog写到文件。这种方案适合有完善日志收集平台(如ELK、Splunk)的环境。
六、常见问题与排错技巧
问题1:修改配置后重启journald报错。通常是配置文件格式错误,比如参数名拼写错误、等号两边有空格等。用systemctl status systemd-journald查看具体报错信息,journald对配置文件格式要求严格,不能有多余的空格或注释放错位置。
问题2:磁盘已经100%满,无法重启服务。先用journalctl --vacuum-size=100M紧急清理一部分空间,然后再重启服务。也可以用find命令手动删除/var/log/journal下的旧文件,但不推荐,因为可能破坏journal数据库结构。
问题3:想查看某个服务的日志但journalctl输出太多。用-u参数指定服务名:journalctl -u nginx.service --since "2024-01-01" --until "2024-01-02"。用-f实时跟踪:journalctl -f -u mysqld.service。用-n限制行数:journalctl -n 100。
问题4:日志压缩后查看慢。这是正常现象,压缩的日志需要解压才能读取。如果频繁查询旧日志,可以适当调大SystemMaxFileSize减少压缩频率,或者把常查的日志用rsyslog单独导出到文本文件。
七、进阶:结合logrotate做二次轮转
虽然journald自带轮转,但有些场景需要更精细的控制,比如按周轮转、保留不同周期的日志。这时候可以在/etc/logrotate.d/下创建专门针对journal的轮转脚本,配合journalctl --vacuum命令定期执行。不过说实话,journald自身的参数已经能覆盖绝大多数需求,logrotate更适合传统文本日志的轮转。如果你的环境同时有journal日志和/var/log下的文本日志,建议分开配置,互不干扰。
总结一下:CentOS运维中journalctl日志保留策略的核心就是改好/etc/systemd/journald.conf这一个文件,设好SystemMaxUse、SystemMaxFileSize、SystemMaxFiles、MaxRetentionSec这几个关键参数,重启服务,定期用journalctl --vacuum做清理。根据服务器角色和磁盘情况选择合适的数值,别用默认值,默认值在生产环境就是定时炸弹。把这套配置做好,日志管理就稳了。
