用 jq 安全地解析与处理 JSON 日志

举报
yd_240997615 发表于 2026/10/30 15:21:54 2026/10/30
【摘要】 现在很多服务都把日志打成 JSON 格式,一行一条,字段齐全,看着规整。可真到了排查问题的时候,用眼睛一行行扫、拿 grep 硬搜字符串,既容易漏又容易误伤:搜 error 会把 "error_count": 0 也翻出来,搜状态码又分不清是请求还是响应里的。jq 就是为这种场景准备的工具:它把 JSON 当结构化数据来查,字段、类型、嵌套层级都清清楚楚。 一、先把日志「摆整齐」看拿到一个 ...

现在很多服务都把日志打成 JSON 格式,一行一条,字段齐全,看着规整。可真到了排查问题的时候,用眼睛一行行扫、拿 grep 硬搜字符串,既容易漏又容易误伤:搜 error 会把 "error_count": 0 也翻出来,搜状态码又分不清是请求还是响应里的。jq 就是为这种场景准备的工具:它把 JSON 当结构化数据来查,字段、类型、嵌套层级都清清楚楚。

一、先把日志「摆整齐」看

拿到一个 JSON 日志文件,先别急着过滤,用 jq 把它格式化输出,确认结构:

cat app.log | jq '.'

如果某一行不是合法 JSON,jq 会直接报出行号,这本身就是一种体检——很多「日志丢了」的假象,其实是写日志时混进了半行普通文本。只想看某几个字段也很简单:

cat app.log | jq '{time: .timestamp, level: .level, msg: .message}'

二、按字段过滤,比 grep 靠谱

排查故障时最常见的需求是「只看错误级别以上的日志」。用字段比较,一条命令搞定,而且不会被无关字段里的字符串误导:

cat app.log | jq 'select(.level == "error" or .level == "fatal")'

再比如只看耗时超过 1 秒的慢请求:

cat app.log | jq 'select(.duration_ms > 1000)'

因为比较的是字段的真实类型和值,duration_ms 是字符串还是数字一眼就能验证,不像 grep 那样只能对文本猜。

三、统计与汇总,顺手就做

定位问题往往还要回答「哪类错误最多」「每个接口平均耗时多少」。jq 内置了分组和聚合能力,不必再把数据导去别处:

# 按错误码统计出现次数
cat app.log | jq -s 'group_by(.status) | map({status: .[0].status, count: length})'

# 统计各级别日志条数
cat app.log | jq -s 'group_by(.level) | map({level: .[0].level, count: length})'

-s(slurp)会把多行 JSON 读成一个数组,再配合 group_by、map、length 就能做简单的报表。应急排查时,这种「一条命令出结论」的效率非常关键。

四、输出成表格,方便贴给同事

jq 的 @tsv 和 @csv 可以把查询结果转成制表符或逗号分隔文本,方便粘到表格或文档里沟通:

cat app.log | jq -r 'select(.level == "error") | [.timestamp, .service, .message] | @tsv'

-r 表示输出原始字符串、不带引号,配合 @tsv 复制出来就是整齐的三列。

五、两个安全习惯

第一,处理不可信的日志文件时,先小样验证再全量跑:head -n 100 app.log | jq ... 确认表达式没问题,再对整份文件执行,避免写错过滤条件还浑然不觉。第二,把复杂表达式写进脚本文件用 jq -f 调用,而不是在命令行里越拼越长,既能复用,也便于同事接手时看懂。

日志从「文本」变成「数据」之后,排查的思路也会跟着变:先按字段收窄范围,再做统计定位热点,最后抽取明细确认根因。jq 学起来不难,常用的就 select、group_by、map 这几个,值得放进每个运维的工具箱。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。