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

SQL 式日志检索:像查数据库一样查日志

日志排查不该靠关键字和正则。本文介绍炬鲸 OBSERVE 的 SQL 式日志检索:结构化字段、聚合函数与三个典型排查场景,让你像查数据库一样秒级定位线上问题。

传统日志检索要么靠模糊关键字,要么靠正则。关键字命中后你分不清这是哪个服务、哪个用户报的错;正则写起来费劲,换个人维护还得重新猜。排查线上问题时,你真正想要的往往是"把最近 5 分钟里、支付服务内、状态码 500 的请求全捞出来,按耗时倒序排"。这本质上是查询,不是搜索。

结构化字段与 SQL 语法

炬鲸 OBSERVE 在日志接入阶段就把 JSON 日志和 Nginx、Java 等常见格式解析成结构化字段,比如 level、service、trace_id、status_code、cost_ms、user_id。检索框里可以直接写 SQL 风格语句:

SELECT * FROM logs
WHERE service = 'payment'
  AND level = 'ERROR'
  AND status_code >= 500
  AND ts BETWEEN now() - 5m AND now()
ORDER BY cost_ms DESC
LIMIT 100

支持 WHERE、GROUP BY、ORDER BY、LIMIT,聚合函数包括 count、avg、p95、sum。p95 对定位"慢请求"比平均值有用得多——平均值会被个别超大耗时拉偏,p95 反映的才是大多数请求的真实体验。如果你的监控写着"平均耗时 40ms"而 p95 已经 900ms,说明有一小撮流量体验极差,光看均值根本发现不了。

三个排查场景示例

慢接口定位:找出过去一小时订单服务里最慢的接口:

SELECT uri, count(*) AS cnt, p95(cost_ms) AS p95
FROM logs
WHERE service = 'order' AND ts > now() - 1h
GROUP BY uri
ORDER BY p95 DESC

错误关联链路:日志里带 trace_id 时,一条错误日志能一键跳转到对应链路,看清上下游调用顺序和每一跳的耗时,不用再靠"猜测 + 翻代码"。这一步省掉的,正是故障里最耗时的"到底哪个服务才是源头"。

用户维度定位:按 user_id 聚合,几秒钟就能判断故障只影响个别用户,还是全量爆炸,这决定了你要不要立刻回滚。

实践建议

  • 应用日志尽量带 trace_id 和 userId,检索维度会翻倍。
  • 字段命名跨服务保持一致(一处叫 cost_ms、一处叫 latency 就没法聚合),用一份共享 schema 管住。
  • 高频查询保存成告警或看板,别每次手敲。
  • 大时间范围先 GROUP BY 缩小范围再拉明细,比直接 LIMIT 快一个量级。
  • 给日志设合理的保留期和冷热分层,历史查询走对象存储,成本可控。