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

用 SQL 检索日志:炬鲸 OBSERVE 检索引擎详解

炬鲸 OBSERVE 的日志检索引擎直接复用 SQL 语法,支持字段自动提取、聚合统计与全文检索。本文介绍字段提取方式、常用查询写法、索引性能三原则与落地建议。

用 SQL 检索日志:炬鲸 OBSERVE 检索引擎详解

日志检索是排障的第一站。多数日志平台要么只支持关键词模糊匹配,要么逼你学一套自创的查询 DSL。炬鲸 OBSERVE 的检索引擎直接复用 SQL 语法——运维和开发不用再记一套新语法,上手成本接近零。本文把字段提取、查询写法和性能要点一次讲清楚。

为什么用 SQL 而不是自创 DSL

SQL 是工程师的通用语言:DBA 会写,后端会写,运维也多少会写。自创 DSL 的问题在于语法不通用、资料少、换人接手要重新学;而 SQL 有几十年积累的教材、示例和社区问答,搜 GROUP BY 语法立刻能找到答案。

更重要的是,SQL 天然贴合日志的两类操作:过滤(WHERE)和聚合(GROUP BY)。日志排查九成场景就是"先过滤出相关记录,再按维度统计分布",SQL 一条语句就能表达清楚,不必拆分多个操作步骤。还有一个隐藏好处:查出来的结果可以直接接进 BI 或报表工具,不用再导一遍数据。

字段怎么来的:三种自动提取方式

能写 SQL 的前提是日志被拆成了字段。炬鲸 OBSERVE 在采集阶段自动做三件事:

  1. JSON 解析:日志是 JSON 时直接按层级展开成字段,嵌套对象用点号访问,如 span.attributes.http.status_code
  2. 键值对解析key=valuekey: value 格式自动拆成字段,常见于 Nginx、HAProxy 这类访问日志;
  3. 正则分组:在采集配置里写一条正则,命名分组直接变成字段名,适合解析格式固定的自定义日志。

三种方式可以叠加:同一条日志里,JSON 部分走 JSON 解析,前缀部分走正则,互不冲突。例如给 2026-08-31 10:00:01 order-service ERROR [trace=abc123] payment timeout 配置正则 \[trace=(?P<trace_id>\w+)\],就能直接用 WHERE trace_id = 'abc123' 检索。字段提取在写入时完成,检索阶段不用重复解析,这也是查询能快到秒级的原因之一。

常用查询:从字段过滤到聚合

有了字段,就可以写查询。比如一条 Nginx 日志:

{"time":"2026-08-31T10:00:00Z","status":502,"upstream":"10.0.3.21:8080","latency_ms":1200}

你可以直接写:

SELECT count(*), upstream
FROM nginx_access
WHERE status = 502
  AND time > now() - interval '1 hour'
GROUP BY upstream
ORDER BY count(*) DESC
LIMIT 20

这条查询回答了一个具体问题:"过去一小时,哪些上游实例返回了 502,各多少次。"statusupstream 都是自动提取的字段,无需预先定义 schema,也不用写字段映射。

全文检索同样保留:WHERE message LIKE '%timeout%'WHERE message CONTAINS 'connection reset'。聚合函数覆盖 countavgmaxminpercentile,可以直接算 P95、P99 延迟:

SELECT upstream, percentile(latency_ms, 99) AS p99
FROM nginx_access
WHERE time > now() - interval '15 minute'
GROUP BY upstream

索引与性能:别把全表扫当常态

SQL 检索最容易踩的坑是性能,写查询时注意三点:

  1. 始终带上时间范围。日志按时间分片,WHERE time > ... 让引擎只扫相关分片。不带时间范围的查询会被引擎默认限制在最近 24 小时,并给出提示。
  2. 高基数字段慎用 GROUP BY。按 request_idtrace_id 这种每个值只出现一次的字段分组,会产生海量分组,慢且无意义。先想清楚这个维度有没有聚合价值。
  3. 正则和全文检索放在等值过滤之后。引擎会先执行 status = 502 这类等值过滤缩小候选集,再做昂贵的正则匹配,查询优化器会自动处理顺序,但把正则写进 WHERE 仍比写在外层便宜。

落地建议

把常用排查语句存成"查询模板"团队共享。比如"过去 15 分钟错误率 Top 上游""某 trace 关联的所有日志""某服务慢请求分布",存成模板后值班同学点开即用,不必每次现写 SQL。模板建议配上清晰的命名和一句"何时用"的说明,新人翻模板列表就知道该点哪个。

检索只是第一步。查出的日志可以直接"下钻到 trace",也可以"基于结果创建告警"——把检索结果固化成告警条件,是从被动排障转向主动发现的关键一步。例如把 SELECT count(*) WHERE status >= 500 设成每 5 分钟跑一次、超过阈值就通知,等于给错误率装了一个持续的探针。