日志量越大,检索越慢。本文介绍炬鲸 OBSERVE 的类 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,也能直接下钻到对应日志。排障时不用在日志系统和追踪系统之间来回切换。
service、traceId、businessId 尽量落成结构化字段,别只塞进 message。日志检索的价值不在「能搜到」,而在「搜得快、搜得准」。把查询从翻页变成语句,排查效率的提升是数量级的。