linux日志需区分journald与rsyslog职责:journald管启动及unit日志,默认不落盘;rsyslog管应用输出与转发,需启用imjournal模块、正确配置模板和权限,并禁用logrotate对journald目录的操作。

Linux 系统日志不是“存着就行”,默认配置下 rsyslog 和 journald 会互相干扰、日志轮转失效、关键字段被截断,甚至导致磁盘爆满。
为什么 journald 日志查不到 syslog 记录
因为 systemd 默认启用 ForwardToSyslog=yes,但多数发行版(如 Ubuntu 22.04+、RHEL 9)实际禁用了 rsyslog 服务,导致日志只进 journald 内存/二进制日志,不落地到 /var/log/syslog 或 /var/log/messages。
- 检查是否双写:运行
systemctl is-active rsyslog;若返回inactive,说明rsyslog没在跑,journalctl是唯一入口 - 想恢复传统文本日志:启用
rsyslog并设为开机启动,再在/etc/rsyslog.conf中取消注释$ModLoad imjournal,否则它连journald的数据都读不到 - 注意权限:若用
rsyslog读journald,必须保证rsyslog进程属于systemd-journal用户组,否则报错Failed to get journal cursor: Permission denied
logrotate 对 journald 日志完全无效
logrotate 只处理文件,而 journald 默认把日志存在二进制的 /run/log/journal/(易丢失)和 /var/log/journal/(持久化需手动创建目录)。它有自己的轮转逻辑,跟 logrotate 不搭界。
- 控制
journald大小:改/etc/systemd/journald.conf中的SystemMaxUse=512M(非logrotate配置) - 启用持久化前先执行:
mkdir -p /var/log/journal && systemd-tmpfiles --create --prefix /var/log/journal,否则所有设置都白配 - 不要给
/var/log/journal加logrotate规则——它不是普通日志文件,强行 rotate 会导致journalctl报错Invalid argument
rsyslog 转发时字段丢失或时间错乱
从 rsyslog 发送到远程服务器(如 ELK、Graylog)时,常见 timestamp 变成接收时间、hostname 变成转发机名、programname 为空——本质是默认模板没保留原始结构化字段。
- 用
RSYSLOG_ForwardFormat模板会丢字段;改用json-template,并在/etc/rsyslog.conf中定义:template(name="json" type="list") { property(name="timegenerated" format="json") property(name="hostname" format="json") property(name="syslogtag" format="json") property(name="msg" format="json") } - 确保发送端开启
imjournal模块并设置StateFile=/var/lib/rsyslog/journal.state,否则重启后会重复发送旧日志 - 远程接收端若用
rsyslog,需加载mmjsonparse模块,否则收到的是纯文本,解析不出字段
真正难的不是配参数,是分清哪段日志归谁管:journald 管启动过程和 unit 生命周期,rsyslog 管应用级输出和转发,两者边界模糊时,journalctl -o json | jq '.SYSLOG_IDENTIFIER' 是唯一能快速定位源头的方式。










