介绍炬鲸 OBSERVE 日志检索引擎的类 SQL 查询语法、倒排索引与冷热分层设计,给出常用查询模板与性能调优建议,帮助运维把海量日志变成可快速回答的问题。
日志系统的价值不在于能存多少,而在于出问题时你能多快找到答案。传统做法是 grep 加 awk 在几台机器上翻文件,日志一多就抓瞎;上了集中式平台后,很多人仍然只会一个关键词搜索,最后还是在几十万条结果里翻页。炬鲸 OBSERVE 的检索引擎解决的就是这个问题:把日志当成一张可以随时查询的表。
检索的前提是结构化。采集端(Filebeat / Fluent Bit / 自研 agent)在写入时会对日志做解析,把 time、level、host、service、trace_id 以及业务字段拆出来。对于非结构化日志,OBSERVE 内置了 Grok 和正则解析规则,可以在接入时配置,也可以事后对历史数据重建索引。
字段化之后,查询就从“搜文本”变成了“过滤字段”。例如查某台机器上过去 5 分钟内的 ERROR:
level=ERROR AND host="pay-svc-03" AND @timestamp > now()-5m
这比在文本里搜 "ERROR" 准确得多——它不会命中用户昵称里恰好叫 ERROR 的字段,也不会漏掉被打包成 JSON 的日志。
OBSERVE 的查询语言刻意做得像 SQL,降低上手成本。支持 AND / OR / NOT、括号分组、比较运算、IN / LIKE 模糊匹配,以及聚合。
按服务统计错误数:
SELECT service, count(*) AS err_count
FROM logs
WHERE level="ERROR" AND @timestamp > now()-1h
GROUP BY service
ORDER BY err_count DESC
找出响应最慢的接口(需要日志里带 duration 字段):
SELECT api, p99(duration) AS p99_ms
FROM logs
WHERE kind="access" AND @timestamp > now()-1h
GROUP BY api
ORDER BY p99_ms DESC
常用的还有数值字段的直方图聚合(histogram)、按时间桶的时序统计(date_histogram),以及针对 trace_id 的关联查询。配合 trace_id,可以直接从一条错误日志下钻到整条调用链。
底层是倒排索引,对分词后的 term 建索引,命中后再按时间范围过滤,所以查“近一小时”不会扫描全量数据。时间列使用列式存储,聚合和排序在毫秒到秒级返回。
存储按冷热分层:近 7 天的数据落在 SSD 热层,查询延迟最低;7 到 90 天的数据自动下沉到机械盘冷层,仍可查询但延迟略高;超过 90 天按策略归档到对象存储,需要时再恢复。这样在成本可控的前提下,查询体验不会随数据量线性恶化。
排查接口超时,先看慢接口再下钻:
SELECT api, p99(duration), count(*) FROM logs
WHERE kind="access" AND @timestamp > now()-30m
GROUP BY api ORDER BY p99(duration) DESC LIMIT 20
统计错误突增的节点:
SELECT host, count() FROM logs
WHERE level IN ("ERROR","FATAL") AND @timestamp > now()-15m
GROUP BY host ORDER BY count() DESC
按错误关键词聚类,看问题是否集中:
SELECT error_keyword, count() FROM logs
WHERE level="ERROR" AND @timestamp > now()-1h
GROUP BY error_keyword ORDER BY count() DESC
建议把高频查询存成“保存的检索”,配合告警直接复用;团队内沉淀一套字段命名规范,检索才能发挥最大价值。检索不是目的,快速定位根因才是。