systemd-journald 是 Linux 系统中 systemd 初始化系统的一个核心组件,专门负责日志的收集、存储和管理。它改变了传统的 Linux 日志管理方式(如纯文本的 syslog),采用二进制格式存储日志,提供了更高效的查询功能和丰富的元数据。
核心功能与特点
- 集中式收集:它能从多个来源收集日志,包括:
- 内核日志 (kmsg)
- 系统启动日志 (initrd)
- 标准输出/错误输出 (stdout/stderr) 的服务日志
- Syslog 协议日志
- 审计记录 (Audit records)
- 二进制存储:日志不以纯文本存储,而是以二进制格式存储在
.journal 文件中。这使得日志体积更小,且支持快速索引和检索。
- 结构化数据:每条日志不仅仅是一行文本,还包含大量元数据(字段),例如:
_PID (进程 ID)
_UID (用户 ID)
_SYSTEMD_UNIT (服务单元名称)
_COMM (命令名称)
- 时间戳(精确到微秒)
- 自动轮替与清理:自动管理磁盘空间,根据配置的大小或时间自动删除旧日志,防止日志填满磁盘。
- 访问控制:支持基于 ACL 的访问控制,普通用户只能查看自己的日志,管理员可查看系统日志。
日志存储位置
systemd-journald 的存储行为取决于配置和目录是否存在:
-
易失性存储 (Volatile Storage) - 默认情况
- 路径:
/run/log/journal/
- 特点:日志存储在内存中(tmpfs)。系统重启后,日志会丢失。
- 适用:未手动配置持久化,或
/var/log/journal 目录不存在时。
-
持久化存储 (Persistent Storage)
- 路径:
/var/log/journal/
- 特点:日志写入磁盘。重启后日志依然存在。
- 如何开启:通常只需创建该目录并赋予正确权限,journald 会自动切换模式:
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
配置文件解析
主配置文件位于 /etc/systemd/journald.conf。常见配置项如下:
[Journal]
# Storage: auto (默认, 有目录则存盘), volatile (只存内存), persistent (强制存盘), none (不记录)
# Storage=auto
# 限制日志占用的最大磁盘空间 (例如 500M)
# SystemMaxUse=500M
# 限制日志保留的最长时间 (例如 1个月)
# MaxRetentionSec=1month
# 是否将日志转发给传统的 syslog 守护进程 (如 rsyslog)
# ForwardToSyslog=yes
# 单个日志文件的最大体积
# SystemMaxFileSize=
修改配置后,需要重启服务生效:
sudo systemctl restart systemd-journald
如何查看日志:journalctl
由于日志是二进制格式,不能用 cat 或 less 直接查看,必须使用 journalctl 命令。
常用命令速查:
journalctl -n
journalctl -n 20 # 显示最后20行
$ sudo journalctl -b -1
journalctl -u nginx.service
journalctl -u sshd
journalctl --since "2023-10-01 12:00:00" --until "2023-10-01 13:00:00"
journalctl --since "1 hour ago"
journalctl --since "10 min ago"
journalctl --since yesterday
journalctl -p err # 显示 error 及更严重级别的日志
journalctl -u nginx -o json-pretty
# 查看指定服务的日志
$ sudo journalctl /usr/lib/systemd/systemd
# 查看指定进程的日志
$ sudo journalctl _PID=1
# 查看某个路径的脚本的日志
$ sudo journalctl /usr/bin/bash
# 查看指定用户的日志
$ sudo journalctl _UID=88 --since today
# 查看某个 Unit 的日志
$ sudo journalctl -u tengine.service
$ sudo journalctl -u tengine.service --since today
# 实时滚动显示某个 Unit 的最新日志
$ sudo journalctl -u tengine.service -f
# 合并显示多个 Unit 的日志
$ journalctl -u tengine.service -u chrony.service --since today
# 查看磁盘使用情况
$ journalctl --disk-usage
# 按日期或容量清理
$ journalctl --vacuum-time=7d
$ journalctl --vacuum-size=500M
# 检查日志文件是否正常
$ journalctl --verify
与 Rsyslog 的关系
在很多现代 Linux 发行版(如 CentOS 7/8/9, Ubuntu 16.04+)中,systemd-journald 和 rsyslog 通常是共存的。
- Systemd-journald 是第一道防线,它捕获所有日志。
- 它可以将日志转发给 Rsyslog。
- Rsyslog 负责将日志写入传统的文本文件(如
/var/log/messages, /var/log/secure, /var/log/auth.log)或发送到远程日志服务器。
为什么有了 journald 还需要 rsyslog?
- 兼容性:很多老旧的监控工具或脚本依赖纯文本日志文件。
- 远程传输:虽然 journald 也支持远程传输,但 rsyslog 在日志路由、过滤和传输协议方面更强大、更成熟。
维护与清理
如果发现日志占用了太多磁盘空间,可以手动清理:
- 查看当前磁盘占用:
- 清理日志,只保留最近 1GB:
journalctl --vacuum-size=1G
- 清理日志,只保留最近 2 天:
journalctl --vacuum-time=2d
F&Q
日志 Suppressed 问题
Nov 16 10:21:14 cn-xiexianbin journal: Suppressed 1422 messages from /system.slice/tengine.service
解决方法:
- 修改
/etc/systemd/journald.conf
[Journal]
RateLimitInterval=30s # default is 30s
RateLimitBurst=5000 # 1000
systemctl restart systemd-journald.service
总结
systemd-journald 是现代 Linux 系统不可或缺的日志守护进程。它通过二进制存储和结构化索引解决了传统日志查询慢、格式乱的问题。对于系统管理员来说,熟练掌握 journalctl 命令是排查服务器故障的基本技能。