journalctl 查不到日志主因是默认仅存内存日志且未启用持久化,需配置 storage=persistent 并重启 systemd-journald;grep 失效因输出含干扰字段,应改用 -o json + jq 过滤;服务无日志常因 stdout/stderr 未重定向至 journal。

journalctl 查不到最近的日志?先确认日志存储模式
默认情况下,journalctl 只读内存日志(RuntimeMaxUse= 未配置时可能只保留最近几小时),重启后就丢。这不是 bug,是 systemd-journald 的默认行为。
- 检查当前日志存储位置:
journalctl --disk-usage—— 如果显示0B,说明没启用持久化 - 启用持久化:创建
/etc/systemd/journald.conf.d/persistent.conf,写入:[Journal] Storage=persistent RuntimeMaxUse=512M MaxRetentionSec=3month
- 重启服务:
sudo systemctl restart systemd-journald;注意旧日志不会自动补回,只从重启后开始落盘 - 常见误操作:只改了
/etc/systemd/journald.conf主文件但没 reload,或改完忘记重启服务,journalctl --system仍查不到历史
grep 日志时匹配不到关键词?注意时间、单位和字段隔离
journalctl 默认输出带时间戳和优先级前缀,直接 grep "error" 很容易漏掉真正含 error 的业务日志,因为匹配被时间戳或 INFO 字段干扰。
- 用
-o json输出结构化数据再过滤更可靠:journalctl -u nginx.service -o json | jq 'select(.MESSAGE | contains("timeout"))' - 时间范围必须明确:
journalctl --since "2024-05-20 14:00:00"比--since "2 hours ago"更准,后者受系统时钟跳变影响 - 避免模糊匹配:
journalctl | grep -i "fail"可能命中failed to start(系统级)和user_login_failed(应用级),建议加-u或_PID限定上下文 - 注意单位大小写:
--since "2h"有效,--since "2H"会报错Failed to parse relative time
服务崩溃后 journalctl 显示 no logs?检查 SyslogIdentifier 和 stdout 重定向
很多 Go/Python 服务默认不刷 stdout/stderr 到 journald,或者用了自定义日志库(如 logrus 设为 json 格式但没配 journalhook),导致 journalctl -u myapp 空空如也。
- 验证是否真的没日志:先用
journalctl _COMM=myapp(按进程名查),比-u更底层,能捕获非 systemd 启动的实例 - 检查服务 unit 文件中是否有
StandardOutput=journal和StandardError=journal—— 缺一不可,否则输出直接进/dev/null - Go 程序若用
log.Printf但没调log.SetOutput(os.Stderr),日志可能静默丢失;Python 若用logging.basicConfig()但没设handlers=[logging.StreamHandler(sys.stderr)],同样不进 journal - 临时调试:启动服务时加
ExecStart=/usr/bin/myapp 2>&1 | logger -t myapp,强制走 syslog 兜底
日志量突增导致磁盘打满?别只删 /var/log/journal
rm -rf /var/log/journal/* 是最危险的“快速解法”——它可能破坏 journal 索引,后续 journalctl 报 Invalid argument 或直接卡死。
- 安全清理命令:
journalctl --vacuum-size=500M或journalctl --vacuum-time=2weeks,journald 自动重建索引 - 限制单服务日志量:在 service unit 文件里加
SystemMaxUse=100M(全局)或RuntimeMaxUse=50M(运行时),需配合Storage=volatile或persistent - 高频日志源头常是健康检查失败循环打印,比如 etcd 成员连不上时每秒打一条
context deadline exceeded—— 这类要先停服务再查网络,不是靠删日志解决 - 监控建议:用
journalctl --disk-usage做 Prometheus exporter 的采集指标,而不是等磁盘 100% 才发现
日志排查真正的难点不在命令怎么敲,而在于分清「是日志没产生」「产生了但没存下来」「存下来了但查法不对」——这三个环节任何一个断掉,journalctl 都会显得很沉默。










