一、journald 简介

在传统的 Linux 系统中,日志分散存储在 /var/log/ 目录下的各种文本文件中(如 syslogmessagessecure 等)。systemd 带来的 systemd-journald 服务彻底改变了这一局面——它将日志以二进制格式集中存储,提供了更高效的查询和管理能力。

1.1 核心特点

特性 说明
二进制存储 日志以二进制格式保存在 /var/log/journal//run/log/journal/
索引化 自动建立时间戳、服务名、优先级等索引,查询极快
元数据丰富 每条日志附带 PID、UID、GID、主机名、服务单元等上下文信息
持久化可选 默认系统重启后日志清空,可配置持久化存储
安全可靠 支持日志签名和配额限制,防止日志填满磁盘

1.2 配置文件

主配置文件:/etc/systemd/journald.conf

[Journal]
# 存储方式: volatile(内存), persistent(磁盘), auto(自动)
Storage=auto

# 日志最大磁盘使用量
SystemMaxUse=4G

# 单个日志文件最大大小
SystemMaxFileSize=100M

# 日志保留时间
MaxRetentionSec=1month

# 转发到传统 syslog
ForwardToSyslog=yes

二、journalctl 基础命令

2.1 基本查看

# 查看所有日志(从旧到新)
journalctl

# 查看所有日志(从新到旧)
journalctl -r

# 查看最新 N 条日志
journalctl -n 50

# 实时跟踪新日志(类似 tail -f)
journalctl -f

# 只显示内核日志(dmesg 替代)
journalctl -k

2.2 按时间过滤

# 查看今天的日志
journalctl --since today

# 查看昨天的日志
journalctl --since yesterday

# 查看最近1小时的日志
journalctl --since "1 hour ago"

# 指定时间范围
journalctl --since "2024-01-15 10:00:00" --until "2024-01-15 12:00:00"

# 相对时间
journalctl --since "10:30:00"
journalctl --since "2024-01-15" --until "2024-01-16"

2.3 按服务/单元过滤

# 查看特定 systemd 单元的日志
journalctl -u nginx.service
journalctl -u sshd

# 查看多个单元
journalctl -u nginx -u php-fpm

# 查看所有用户单元
journalctl --user -u myapp.service

2.4 按优先级过滤

优先级级别(数字越小越严重):

级别 代码 说明
emerg 0 系统不可用
alert 1 需要立即处理
crit 2 临界条件
err 3 错误条件
warning 4 警告条件
notice 5 正常但重要的条件
info 6 信息性消息
debug 7 调试消息
# 查看错误及以上级别(err, crit, alert, emerg)
journalctl -p err

# 查看警告及以上级别
journalctl -p warning

# 优先级别名也支持
journalctl -p 3        # 等同于 -p err
journalctl -p crit..debug   # 范围过滤

2.5 按进程/用户过滤

# 按 PID 过滤
journalctl _PID=1234

# 按可执行文件路径
journalctl /usr/bin/nginx

# 按用户 ID
journalctl _UID=1000

# 按命令名
journalctl _COMM=sshd

# 按内核设备
journalctl _KERNEL_DEVICE=+usb:1-2

2.6 高级过滤(多条件组合)

# 组合条件:nginx 服务 + 错误级别 + 最近1小时
journalctl -u nginx -p err --since "1 hour ago"

# 多个 PID
journalctl _PID=1234 _PID=5678

# 排除特定条件(使用 + 作为 OR 运算符)
journalctl -u nginx _PID=1234 + _PID=5678

# 按系统引导 ID
journalctl --list-boots          # 列出所有引导
journalctl -b -1                 # 上一次引导的日志
journalctl -b 2                  # 倒数第2次引导(0为当前)

三、日志输出格式控制

3.1 输出格式选项

# 短格式(默认)
journalctl -o short

# 带详细时间戳
journalctl -o short-iso

# 完整格式(显示所有字段)
journalctl -o verbose

# JSON 格式(便于程序解析)
journalctl -o json
journalctl -o json-pretty   # 格式化JSON

# 只显示消息内容
journalctl -o cat

# 显示导出格式(可备份恢复)
journalctl -o export

# 无格式(只显示消息)
journalctl -o cat

3.2 查看字段信息

# 显示所有可用字段
journalctl -F _SYSTEMD_UNIT

# 显示所有服务单元名称
journalctl -F _SYSTEMD_UNIT | sort

# 显示所有优先级值
journalctl -F PRIORITY

# 显示所有用户 ID
journalctl -F _UID

3.3 常用查看技巧

# 显示本引导的日志概要
journalctl --verify

# 显示磁盘使用情况
journalctl --disk-usage

# 只显示日志条数统计
journalctl --since today | wc -l

# 获取特定服务的启动失败原因
journalctl -u nginx --since "5 minutes ago" --no-pager

四、日志维护与管理

4.1 手动清理日志

# 查看磁盘占用
journalctl --disk-usage

# 清理日志,保留 500MB
journalctl --vacuum-size=500M

# 清理日志,保留最近 7 天
journalctl --vacuum-time=7d

# 清理日志,只保留 5 个日志文件
journalctl --vacuum-files=5

# 清空所有归档日志(保留活动日志)
sudo journalctl --rotate
sudo journalctl --vacuum-time=1s

4.2 持久化配置

默认情况下,systemd-journald 将日志存储在 /run/log/journal/(内存文件系统),重启后丢失。要启用持久化:

# 创建持久化目录
sudo mkdir -p /var/log/journal

# 修改配置
sudo systemctl edit systemd-journald

添加:

[Journal]
Storage=persistent
# 重启服务
sudo systemctl restart systemd-journald

4.3 日志轮转

journald 自带日志轮转机制,不需要 logrotate。配置项:

# /etc/systemd/journald.conf
SystemMaxUse=4G          # 最大使用空间
SystemKeepFree=1G        # 保留空闲空间
SystemMaxFileSize=100M   # 单文件最大大小
MaxFileSec=1month        # 单文件最大时间

五、高级用法与实战

5.1 故障排查实战

# 1. 查找系统启动缓慢的原因
journalctl -b -1 --grep="slow|timeout|failed"

# 2. 追踪数据库启动问题
journalctl -u postgresql --since "10 minutes ago" -f

# 3. 查看 SSH 登录失败的 IP
journalctl -u sshd --since today | grep "Failed password"

# 4. 监控特定内核模块
journalctl -k --grep="usb"

# 5. 导出日志供离线分析
journalctl -b -o export > system_logs.export

# 6. 导入备份的日志
journalctl --file=/path/to/backup.export

# 7. 监控服务异常退出
journalctl -u nginx -p err --since "1 day ago" --no-pager

5.2 脚本集成

#!/bin/bash
# 获取最近1小时错误日志计数

ERROR_COUNT=$(journalctl --since "1 hour ago" -p err -o cat | wc -l)
echo "Last hour errors: $ERROR_COUNT"

# 获取服务最后5分钟日志
journalctl -u myapp --since "5 minutes ago" --no-pager

# 检查是否有特定错误
if journalctl -u nginx --since "1 hour ago" | grep -q "segmentation fault"; then
    echo "Nginx crashed!"
fi

5.3 与其他工具集成

# 发送到 syslog 服务器
journalctl -f -o json | nc syslog-server 514

# 生成 Prometheus 指标
journalctl --since "1 hour ago" -p err --output=json | jq '.PRIORITY' | sort | uniq -c

# 与 Logstash/Fluentd 集成(使用 json 格式)
journalctl -f -o json | fluent-cat

六、常见问题与解决方案

6.1 日志丢失或未记录

# 检查 journald 状态
systemctl status systemd-journald

# 查看是否有错误
journalctl -u systemd-journald -p err

# 检查磁盘空间
journalctl --disk-usage
df -h /var/log

# 检查配置
systemd-analyze cat-config systemd/journald.conf

6.2 查询速度慢

# 重建索引(通常不需要,但如果性能下降明显)
sudo systemctl restart systemd-journald

# 检查是否有大量日志
journalctl -u some-service --since "1 month ago" --no-pager | wc -l

# 考虑清理旧日志
sudo journalctl --vacuum-time=30d

6.3 权限问题

普通用户只能查看自己的日志,要查看系统日志需要:

# 将自己加入 systemd-journal 组
sudo usermod -a -G systemd-journal $USER

# 或者使用 sudo
sudo journalctl

七、与传统 syslog 的对比

特性 journald rsyslog/syslog-ng
存储格式 二进制 文本
查询速度 极快(索引化) 慢(grep遍历)
元数据 丰富(自动记录) 有限
磁盘占用 较高 较低
可读性 需专用工具 直接 cat/less
集中化 需转发 原生支持
日志签名 支持 不支持

八、最佳实践总结

  1. 启用持久化存储:生产环境务必启用 /var/log/journal
  2. 设置合理配额:根据磁盘大小设置 SystemMaxUse
  3. 定期清理:使用 journalctl --vacuum-time=30d 清理旧日志
  4. 监控磁盘使用:设置告警防止日志占满磁盘
  5. 保留原始日志:故障排查时需要完整上下文
  6. 结合 rsyslog:需要集中式日志服务器时可同时启用

journalctl 是现代 Linux 系统日志管理的核心工具,熟练掌握它将极大提升系统管理和故障排查效率。无论是快速定位问题、监控服务状态,还是进行安全审计,journalctl 都能提供强大而灵活的支持。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐