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

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

介绍炬鲸的 SQL 式日志检索能力:用类 SQL 语法对日志做过滤、聚合、分组和时间分桶,替代 grep 与正则的反复试错,附常用查询范式与性能建议。

为什么用 SQL 查日志

排查线上问题时,多数人的第一反应是 grep 加管道:先 grep error,再 grep -v 掉噪音,接着 awk 取字段,最后 sort | uniq -c 做统计。这套流程在几十兆日志里还能应付,一旦碰上每小时 TB 级、跨几十个节点的日志,grep 的单机扫描会变得极慢,而且管道越写越长,下一次排查又得重写一遍。

炬鲸把日志检索做成了类 SQL 的查询语言。你会得到三样东西:一套稳定的查询语法(不用记正则转义)、一次能跑完整份数据的聚合能力(不是抽样)、以及可复用的查询(存下来下次直接用)。

基础语法:过滤与投影

最常用的语句是 SELECT + WHERE,字段来自日志解析后提取的结构化字段,比如 levelservicehostmessage 以及自定义字段。

SELECT timestamp, host, message
FROM logs
WHERE level = 'ERROR'
  AND service = 'order-service'
  AND timestamp >= now() - 1h
ORDER BY timestamp DESC
LIMIT 100

字段比较支持 =!=><INLIKE。要模糊匹配,用 LIKE '%timeout%'message CONTAINS 'connection refused'IN 适合一次圈定多个服务:service IN ('order-service', 'pay-service')

一个容易踩的坑:字段名必须用解析后的标准名。如果日志里写的是 loglevel,解析后映射成了 level,查询时用 loglevel 会返回空结果而不是报错。建议先看一条样例日志确认字段。

聚合与分组:把噪音变成趋势

grep 只能告诉你有多少行匹配,聚合才能告诉你问题集中在哪。下面这个查询统计过去一小时各服务的错误数分布:

SELECT service, count(*) AS err_count
FROM logs
WHERE level = 'ERROR'
  AND timestamp >= now() - 1h
GROUP BY service
ORDER BY err_count DESC

再做一层下钻,看某个错误在哪些主机、哪个版本上集中出现:

SELECT host, version, count(*) AS cnt
FROM logs
WHERE service = 'order-service'
  AND level = 'ERROR'
GROUP BY host, version
ORDER BY cnt DESC
LIMIT 20

聚合函数除 count 外,还支持 sumavgminmaxp50p99uniq(近似去重)。p99uniq 在做性能分析时尤其有用:比如 SELECT p99(duration) FROM logs WHERE service = 'api-gateway' 能直接看出尾延迟。

时间桶与趋势图

按时间分桶是把「当前有没有问题」变成「问题什么时候开始的」的关键:

SELECT time_bucket(timestamp, '5m') AS t, count(*) AS cnt
FROM logs
WHERE service = 'order-service' AND level = 'ERROR'
GROUP BY t
ORDER BY t

time_bucket 支持 smhd 单位。把结果画成折线,一眼就能看出错误是从哪个时间点开始飙升的,再结合那段时间的发布记录,基本能锁定诱因。

值得存下来的查询

几个存下来就能直接上手的查询:错误飙升(上面的 GROUP BY 查询,共享给值班同事);慢请求 SELECT p99(duration), count(*) FROM logs WHERE service = 'api-gateway' GROUP BY route ORDER BY p99 DESC;鉴权失败 WHERE message CONTAINS 'invalid credentials' GROUP BY host,通常能揪出某一台节点上出错的凭证轮换。

性能建议

  • 尽量给 WHERE 里的时间字段加范围限定,避免全量扫描。
  • 高频查询里,把选择性最高的条件(如 service =)放在前面。
  • 结果集很大时用 LIMIT 而不是 SELECT 会把整条原始日志拖回来,慢且占内存。
  • 需要长期复用的查询存成「保存的查询」,并给团队共享,避免每个人重复造轮子。

SQL 式检索的价值不在于「又学了一种语法」,而在于把排查流程从临时管道变成可沉淀、可复用、可协作的资产。