强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

systemd 教程 / 日志系统(journalctl)

日志系统(journalctl)

一、systemd-journald 简介

systemd-journald 是 systemd 的日志服务,使用二进制格式存储日志,提供结构化查询、完整性校验等能力。

1.1 journald vs syslog 对比

特性journaldsyslog (rsyslog)
存储格式二进制纯文本
结构化数据✅ 支持❌ 需解析
查询能力字段过滤grep 文本
日志完整性Forward Secure Sealing
日志大小压缩存储无压缩
启动日志✅ 从最早开始网络服务启动后
内核日志✅ 原生集成需配置

二、journalctl 基础用法

# 查看所有日志(分页显示)
journalctl

# 从最新日志开始查看
journalctl -r

# 只显示最新 N 条
journalctl -n 50

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

# 查看特定服务的日志
journalctl -u nginx.service

# 跟踪特定服务的实时日志
journalctl -u nginx.service -f

# 查看多个服务的日志
journalctl -u nginx.service -u php-fpm.service

# 指定 PID
journalctl _PID=12345

💡 提示-u 选项可以多次使用来同时查看多个服务的日志,无需使用管道组合。

2.1 按时间过滤

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

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

# 查看指定时间范围
journalctl --since "2026-05-11 08:00" --until "2026-05-11 12:00"

# 查看本次启动的日志
journalctl -b

# 查看上一次启动的日志
journalctl -b -1

# 列出所有启动记录
journalctl --list-boots
时间格式示例
绝对时间"2026-05-11 10:30:00"
相对时间"1 hour ago""5 min ago"
关键字todayyesterdaynow
ISO 8601"2026-05-11T10:30:00+08:00"

三、高级过滤

3.1 按优先级过滤

等级名称说明
0emerg系统不可用
1alert需要立即处理
2crit严重条件
3err错误
4warning警告
5notice正常但重要
6info信息
7debug调试
# 只显示错误及以上级别
journalctl -p err

# 指定范围(3=err 到 6=info)
journalctl -p 3..6

# 组合使用
journalctl -u nginx.service -p err --since today

3.2 按标识符与字段过滤

# 按 syslog 标识符过滤
journalctl -t nginx

# 查看日志条目的所有字段
journalctl -o verbose -n 1

# 按字段过滤
journalctl _COMM=sshd
journalctl _UID=0
journalctl _HOSTNAME=server1

3.3 组合过滤示例

# nginx 今天的错误日志,最新 20 条
journalctl -u nginx.service -p err --since today -n 20

# SSH 登录失败
journalctl -u sshd.service -p err | grep "Failed"

# 内核从上次启动以来的错误
journalctl -k -b -p err

四、输出格式

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

# ISO 时间格式
journalctl -o short-iso

# 详细格式(显示所有字段)
journalctl -o verbose

# JSON 格式(便于程序处理)
journalctl -o json

# 美化 JSON
journalctl -o json-pretty

# 仅消息内容(无元数据)
journalctl -o cat
# 导出 JSON 格式日志到文件
journalctl -u nginx.service --since today -o json > /tmp/nginx-logs.json

五、持久化存储

5.1 启用持久存储

journald 默认使用易失存储/run/log/journal/,重启后丢失)。创建持久目录即可启用:

# 创建持久存储目录
sudo mkdir -p /var/log/journal/
sudo systemd-tmpfiles --create --prefix /var/log/journal/
sudo systemctl restart systemd-journald

# 检查当前存储模式
ls -la /var/log/journal/ 2>/dev/null && echo "持久存储" || echo "易失存储"

5.2 日志大小限制

编辑 /etc/systemd/journald.conf

[Journal]
SystemMaxUse=500M        # 最大磁盘使用
SystemMaxFileSize=50M    # 单文件最大大小
SystemKeepFree=1G        # 保留最小可用空间
MaxRetentionSec=3month   # 最大保留时间
Storage=persistent       # 持久存储
# 重载配置
sudo systemctl restart systemd-journald

# 查看当前日志占用空间
journalctl --disk-usage

5.3 日志清理

# 按大小清理(保留最近 100M)
sudo journalctl --vacuum-size=100M

# 按时间清理(保留最近 7 天)
sudo journalctl --vacuum-time=7d

# 按文件数清理(最多 5 个日志文件)
sudo journalctl --vacuum-files=5

六、日志签名与完整性

Forward Secure Sealing (FSS) 用于验证日志完整性,防止篡改:

# 创建密封密钥
sudo journalctl --setup-keys

# 验证日志完整性
sudo journalctl --verify

⚠️ 注意:FSS 密钥有有效期(默认 24 小时),建议配合 cron 定期验证。


七、日志转发

# 转发到传统 syslog
cat > /etc/systemd/journald.conf.d/forward.conf << 'EOF'
[Journal]
ForwardToSyslog=yes
EOF
sudo systemctl restart systemd-journald

配合 rsyslog 转发到远程服务器(/etc/rsyslog.d/remote.conf):

# 转发所有日志到远程 syslog
*.* @@192.168.1.100:514

使用 systemd-remote-journal 集中收集日志:

# 日志服务器上
systemctl enable --now systemd-journal-remote.socket

# 客户端配置
cat > /etc/systemd/journal-upload.conf << 'EOF'
[Upload]
URL=https://logserver.example.com:19532
EOF
systemctl enable --now systemd-journal-upload.service

八、journalctl 命令速查表

查看与过滤

操作命令
查看所有日志journalctl
查看最新 N 条journalctl -n N
实时跟踪journalctl -f
反向查看journalctl -r
按 Unit 过滤journalctl -u <unit>
按优先级journalctl -p <level>
按时间journalctl --since "..." --until "..."
本次启动journalctl -b
上次启动journalctl -b -1
内核日志journalctl -k

输出格式

选项说明
-o short默认短格式
-o short-isoISO 时间格式
-o verbose详细字段
-o jsonJSON 格式
-o cat仅消息内容

存储管理

操作命令
查看磁盘占用journalctl --disk-usage
按大小清理journalctl --vacuum-size=100M
按时间清理journalctl --vacuum-time=7d
验证完整性journalctl --verify
列出启动记录journalctl --list-boots

九、生产场景

场景 1:排查服务崩溃

# 查看崩溃前后日志
journalctl -u myapp.service --since "2026-05-11 14:29" --until "2026-05-11 14:31"

# 只看错误
journalctl -u myapp.service -p err --since today

场景 2:安全审计

# 查看 sudo 使用记录
journalctl _COMM=sudo

# SSH 登录尝试
journalctl -u sshd.service | grep -E "(Accepted|Failed)"

# 导出安全日志
journalctl -u sshd.service --since "2026-05-01" -o json > audit-log.json

场景 3:磁盘空间不足

# 查看日志占用
journalctl --disk-usage

# 紧急清理
sudo journalctl --vacuum-time=1d

# 永久配置 /etc/systemd/journald.conf
# SystemMaxUse=500M
# MaxRetentionSec=1month

场景 4:日志分析

# 找出最活跃的服务(日志量前 10)
journalctl --since today -o json | \
  jq -r '._SYSTEMD_UNIT // empty' | \
  sort | uniq -c | sort -rn | head -10

# 查找 OOM 事件
journalctl -k | grep -i "out of memory"

十、扩展阅读