← 返回文章列表
产品动态 4 分钟阅读 炬鲸团队

用 SQL 语法查日志:生产排障从翻页到秒级定位

日志量越大,检索越慢。本文介绍炬鲸 OBSERVE 的类 SQL 日志检索能力,用字段过滤、聚合与上下文关联,把生产排障从逐页翻日志变成一条语句秒级定位。

用 SQL 语法查日志:生产排障从翻页到秒级定位

生产环境的日志量增长,往往比业务还快。一个中等规模微服务集群,高峰期每秒产生数万条日志,一天就是几十亿条。传统的关键词搜索加翻页,在这种量级下基本失效:搜「error」返回几十万条,翻到下一页要等十几秒,翻到真正有用的那条时,故障可能已经扩大了。

炬鲸 OBSERVE 把日志检索做成了类 SQL 的查询语言,核心思路是:先过滤、再聚合、最后看明细。

从关键词到结构化查询

日志被采集进来后,我们会自动解析常见格式(JSON、Nginx access log、Java 堆栈、K8s 容器日志),把时间戳、级别、服务名、traceId、状态码等拆成独立字段。这样你就没必要在整段文本里盲搜关键词。

一条典型查询长这样:

service = "order-svc" AND level = "ERROR"
  AND status_code >= 500
  AND ts >= now() - 15m
ORDER BY ts DESC
LIMIT 200

它和 SQL 的阅读方式一致,运维和开发都能上手。支持的算子包括:=、!=、>、<、>=、<=、IN、LIKE、正则 ~、AND/OR/NOT,以及 COUNT、GROUP BY、histogram 等聚合函数。

用聚合先看全局

翻页之前,先聚合。一条 GROUP BY 就能回答「最近 15 分钟哪个服务报错最多」:

SELECT service, COUNT(*) AS err_cnt
FROM logs
WHERE level = "ERROR" AND ts >= now() - 15m
GROUP BY service
ORDER BY err_cnt DESC

再叠加 histogram(ts, interval=1m),能看到错误的时间分布,判断是突刺还是持续劣化。这种「先聚合定位、再下钻明细」的顺序,能把排查范围从几十万条收窄到几十条。

上下文关联:从一条日志看到整条链路

单条日志只能说明一个点。炬鲸会把日志里的 traceId 和 spanId 与链路追踪打通:在日志详情页点一下 traceId,就能看到这次请求经过的完整调用链、每个节点的耗时和上下游日志。反过来,在追踪视图里点某个 span,也能直接下钻到对应日志。排障时不用在日志系统和追踪系统之间来回切换。

实践建议

  1. 上线前约定统一字段:service、traceId、businessId 尽量落成结构化字段,别只塞进 message。
  2. 把高频排障查询保存为「保存的查询」,配成告警或仪表盘,团队复用。
  3. 敏感字段(手机号、身份证)在采集端做脱敏,检索结果里自然不可见。
  4. 冷热分层:热数据走内存索引秒级返回,冷数据自动落到对象存储,控制成本。

日志检索的价值不在「能搜到」,而在「搜得快、搜得准」。把查询从翻页变成语句,排查效率的提升是数量级的。