介绍炬鲸 OBSERVE 的 SQL 风格日志检索能力,给出错误聚合、慢请求定位等常用查询示例与三个提速技巧,并说明查询到告警的闭环设计。
SQL 风格日志检索是炬鲸 OBSERVE 用户用得最多的能力。大多数日志平台只提供关键词匹配,一旦遇到"近一小时各服务的 5xx 错误占比""哪个服务错误最多"这类聚合需求,只能一页页翻、手动拼表。OBSERVE 把日志当成一张可查询的表,字段就是列,原生支持 SELECT、WHERE、GROUP BY、ORDER BY、HAVING,运维和开发不用再学一套专属查询语法。
关键词搜索只能回答"这个字符串是否存在",而真实的排障问题几乎都是聚合问题:哪个服务错误最多、状态码分布如何、哪些请求超时。这些问题天然映射到 SQL,而 SQL 是团队已经掌握的技能——没有新的 DSL 要学,没有特殊操作符要记。从 Lucene/KQL 类工具转过来心智负担也小:status:500 AND service:orders 不过是写成 WHERE status = 500 AND service = 'orders'。真正的差别在聚合和排序——SQL 一个语句就能 GROUP BY、ORDER BY、HAVING,Lucene 那套往往得导出后到外部处理。
统计各服务近一小时错误数:
SELECT service, count(*) AS err_cnt
FROM logs
WHERE level = 'ERROR' AND time >= now() - 1h
GROUP BY service
ORDER BY err_cnt DESC
定位慢请求:
SELECT request_id, latency_ms, status, service
FROM logs
WHERE latency_ms > 3000
ORDER BY latency_ms DESC
LIMIT 50
按状态码统计分布:
SELECT status, count(*) AS cnt
FROM logs
WHERE time >= now() - 1d
GROUP BY status
ORDER BY cnt DESC
字段不需要预定义索引或 mapping,系统从数据里自动推断类型并建索引。time、level、service 是内置字段,业务自定义字段直接从 JSON 日志平铺出来,user_id、trace_id 这类字段一出现即可查询。日志带了 trace_id 的话,会自动关联到对应链路,慢请求查询结果能一键跳到完整请求时间线。
message =~ /timeout|refused/ 走倒排索引,比 message LIKE '%timeout%' 快一个数量级。排查时先用正则圈定范围,再用 LIKE 做精确匹配。GROUP BY service HAVING count(*) > 100 直接筛出异常多的服务,省掉导出后二次过滤的步骤。任何 SQL 结果都能一键"转存为告警"。以第一条示例为例设阈值:某服务 5 分钟 ERROR 数超过 50 就通知值班人。查询、可视化、告警共用一套 SQL,排查时看到的和告警触发时用的口径完全一致,减少"告警响了但查不到"的断层。性能上我们做了时间分区裁剪和列式存储:带时间范围的查询只扫对应分区,SELECT service 这类单列查询只读单列,聚合在引擎侧完成而非浏览器端,TB 级日志下仍能秒级返回。