VictoriaLogs 日志检索

简介

Nightingale 集成了 VictoriaLogs 的日志检索能力。在日志检索页面选择 VictoriaLogs 类型的数据源和时间范围后,可以在查询输入框中输入 LogsQL,查看日志原文或切换到统计图表模式做聚合分析。

LogsQL 查询由过滤条件和管道组成:

过滤条件 | 管道

其中:

  • | 左侧是过滤条件,用来筛选日志。只需要查看原始日志时,可以只写这一部分。
  • | 右侧是可选管道,可以做字段选择、排序、限制条数、统计聚合等。
  • 页面时间范围由 Nightingale 的时间选择器控制,通常不需要在 LogsQL 中额外写 _time 条件。
  • VictoriaLogs 支持 {app="nginx"} 这种日志流过滤。如果字段已作为 stream field 写入,优先使用日志流过滤,查询效率更高。

本文后续样例使用以下常见日志字段。实际查询时,请替换成你自己的 VictoriaLogs 字段名。

字段 示例值 常见用途
app nginx 按应用过滤或分组
namespace prod 按命名空间过滤或分组
pod nginx-7d9f 按 Pod 过滤或分组
method GET 按请求方法过滤或分组
uri /api/v1/login 按请求路径过滤或分组
status 200 按状态码过滤或分组
remote_addr 10.0.0.8 按客户端 IP 过滤或分组
request_time 0.123 统计请求耗时

如果字段名中包含点号、冒号、空格等特殊字符,建议用双引号包裹字段名,例如 "log.level":"error"

基本查询语句

以下示例可直接放在查询输入框中,用于查看日志原文。

场景 示例
全量查询 *
按关键字查询 error
按短语查询 "internal server error"
按日志流过滤 {app="nginx"}
按多个日志流字段过滤 {namespace="prod", app="nginx"}
按字段查询 status:"500"
精确匹配字段完整值 method:="GET"
按字段正则查询 uri:~"/api/v1/.*"
查询 5xx 状态码 status:~"5.."
数值比较 request_time:>0.5
数值范围 status:>=500 status:<=599
排除健康检查 NOT uri:"/health"
多条件与关系 app:"nginx" AND status:"500"
多条件或关系 status:"500" OR status:"502"
只展示部分字段 `error fields _time, app, status, uri, _msg`
按时间倒序取 20 条 `error sort by (_time desc) limit 20`

常见写法:

{app="nginx"} error
{namespace="prod", app="nginx"} status:~"5.."
request_time:>0.5 NOT uri:"/health"

VictoriaLogs 中多个过滤条件可以用 AND 连接,也可以直接用空格连接。为了便于阅读,复杂条件建议显式写 ANDORNOT 并加括号。

统计图表查询

统计图表模式可以使用 statsmathsortlimit 等 LogsQL 管道。以下示例中的 _time:1m 表示按 1 分钟做时间桶;如果查询时间范围较大,可以把它改成 _time:5m_time:1h 等更大的粒度。

统计日志总量

统计当前时间范围内的日志总数:

* | stats count() log_count

统计错误日志总数:

error | stats count() error_count

按状态码统计数量

* | stats by (status) count() log_count
  | sort by (log_count desc)
  | limit 20

适用于查看 HTTP 状态码分布,例如 2xx、4xx、5xx 哪类日志最多。

查看 Top URI

* | stats by (uri) count() pv
  | sort by (pv desc)
  | limit 20

如果只关注 5xx 请求,可以先过滤状态码:

status:~"5.." | stats by (uri) count() error_count
  | sort by (error_count desc)
  | limit 20

最近 1 小时日志量趋势

先在页面时间范围中选择最近 1 小时,再输入:

* | stats by (_time:1m) count() log_count
  | sort by (_time)

这个查询会把当前时间范围内的日志按 1 分钟聚合。

最近 1 小时 5xx 趋势

status:~"5.." | stats by (_time:1m) count() error_count
  | sort by (_time)

按时间统计不同状态码数量

* | stats by (_time:1m, status) count() log_count
  | sort by (_time, status)

适用于观察某个时间点 5xx 是否突然升高,或 4xx 是否集中出现。

计算错误率

* | stats by (_time:1m)
    count() total,
    count() if (status:~"5..") errors
  | math (errors / total * 100) as error_rate
  | sort by (_time)

返回的 error_rate 单位是百分比。例如结果为 3.5,表示该时间桶内 5xx 日志占比约为 3.5%。

统计接口平均耗时

* | stats by (uri)
    count() log_count,
    avg(request_time) avg_request_time
  | sort by (avg_request_time desc)
  | limit 20

适用于定位平均耗时最高的接口。这里的 request_time 需要是可解析为数值的字段。

按客户端 IP 统计访问量

* | stats by (remote_addr) count() pv
  | sort by (pv desc)
  | limit 20

统计不同客户端 IP 数量趋势

* | stats by (_time:1m) count_uniq(remote_addr) unique_ip_count
  | sort by (_time)

适用于观察当前时间范围内,不同客户端 IP 数量是否有异常变化。

使用建议

  1. 如果日志已配置 stream field,优先使用 {app="..."}{namespace="..."} 这类日志流过滤。
  2. 只看原始日志时,使用关键字、字段过滤、fieldssortlimit 即可。
  3. 做趋势、TopN、错误率等分析时,使用统计图表模式,并用 stats by (...) 聚合。
  4. 大范围查询时先缩小字段过滤或日志流过滤,再扩大时间范围,避免一次扫描过多日志。
快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云