结构化日志为什么更好用
journalctl -o json 把每条日志输出成结构化对象:字段可筛选、可统计、可导出给分析脚本,比逐行 grep 强大得多。常用字段包括 MESSAGE、_PRIORITY、_SYSTEMD_UNIT、SYSLOG_IDENTIFIER 与 _PID。配合 jq 就能按字段过滤、按优先级计数、按错误文本提取,是做日志统计与取证分析的实用组合。
基本信息
| 适用平台 | Linux(systemd 的 journald) |
|---|---|
| 语法 | journalctl -o json 或 -o json-pretty |
| 常用参数 | --output-fields 限制字段、--since/--until 限定时间窗、-u 限定单元、-n 限制条数 |
| 配套工具 | jq(最小化系统通常不带,需另行安装) |
| 字段名规则 | 固定大小写与下划线,如 _PID、_SYSTEMD_UNIT、_PRIORITY |
典型使用场景
- 统计某服务各优先级的日志条数
- 按字段提取错误文本做聚类分析
- 导出结构化日志交给外部分析脚本
- 精确限定时间窗与单元,避免全量导出
- 把日志证据交给他人时附带字段说明
常用示例
常用示例
journalctl -u nginx -o json --output-fields=_PID,SYSLOG_IDENTIFIER,MESSAGE -n 5 | jq -c .
# 只取需要的字段,输出紧凑 JSON,一条一行
journalctl -u myapp -o json --since today | jq -r '._PRIORITY' | sort | uniq -c
# 统计各优先级条数(3 是 err,4 是 warning)
journalctl -u myapp -o json --since '1 hour ago' | jq -r 'select(.MESSAGE | test("timeout")) | .MESSAGE'
# 按错误文本过滤,提取消息正文
journalctl -u myapp -o json --since '2 hours ago' > /tmp/lg.json
jq -r '[._SYSTEMD_UNIT, ._PRIORITY, .MESSAGE] | @tsv' /tmp/lg.json | head -n 20
# 先落盘再多次分析,避免重复查询 journal
journalctl -o json-pretty -n 1 # 没有 jq 时用人眼可读的展开格式常用字段
| 字段 | 含义 | 用途 |
|---|---|---|
| MESSAGE | 日志正文 | 文本筛选与内容提取 |
| _PRIORITY | 优先级数字(0 到 7) | 统计与过滤错误级别 |
| _SYSTEMD_UNIT | 产生日志的单元 | 多服务混合时区分来源 |
| SYSLOG_IDENTIFIER | 日志标识(程序名) | 区分同一单元内的不同组件 |
| _PID | 进程号 | 关联同一进程的多条日志 |
| _HOSTNAME 与时间戳字段 | 主机名与实时时间戳 | 多机日志集中分析 |
jq 不在最小化系统里时,先用 json-pretty 人眼确认结构,或把 JSON 落盘后拿到别的机器分析,不必在故障机器上临时装包。
JSON 输出体量远大于短格式:只在需要的窗口与字段上抓取,避免全量导出写满磁盘;字段名大小写与下划线是固定的,写错时 jq 返回空结果且不报错,很容易误判为“没有相关日志”。
做统计时先把字段投影出来再算:jq -r 取 _PRIORITY 后接 sort 与 uniq -c 就是一份优先级分布,换成 _SYSTEMD_UNIT 就能按服务拆分;同一套思路也可用于自定义字段,无需额外搭建日志系统。