在 Elasticsearch 中使用原生 PromQL 支持查询 Prometheus 指标

作者:来自 Elastic Sergey SidorovFelix BarnsteinerKostas KrikellasCostin Leau

Elasticsearch 现在在 ES|QL 中原生支持 PromQL,作为一等 source 命令。你可以直接在 Kibana 中对时间序列数据运行熟悉的 Prometheus 查询。

许多团队在日常工作中已经依赖 PromQL。我们正在让 PromQL 成为 Elasticsearch 中一等公民的体验。

ES|QL 中的新 PROMQL 命令让你可以用 PromQL 查询 Elasticsearch 中的时间序列数据,无论这些数据来自 Prometheus Remote Write、OpenTelemetry,还是其他来源。

指标、日志和追踪数据------全部统一在一个地方,并可在 Kibana 中直接进行探索。

PROMQL 源命令

PROMQL 是 ES|QL 中的一个 source 命令,类似于 FROMTS。它接受标准的 PromQL 参数和一个 PromQL 表达式,执行查询,并将结果作为普通的 ES|QL 列返回,之后你可以继续使用其他命令对其进行处理。

其通用语法如下:

复制代码
PROMQL [index=<pattern>] [step=<duration>] [start=<timestamp>] [end=<timestamp>]
  [<value_column_name>=](<PromQL expression>)

这些参数与 Prometheus HTTP API 的查询参数(step、start、end)一致,因此如果你之前使用过 Prometheus 查询 API,会感觉非常熟悉。

基础范围查询

该查询计算在滑动 5 分钟窗口内 HTTP 请求的每秒速率,并按 instance 分组:

复制代码
PROMQL index=metrics-*
  step=1m
  start="2026-04-01T00:00:00Z"
  end="2026-04-01T01:00:00Z"
  sum by (instance) (rate(http_requests_total[5m]))

结果包含三列:

列名 类型 描述
sum by (instance) (rate(http_requests_total[5m])) double 计算得到的指标值
step date 每个评估步的时间戳
instance keyword 来自 by (instance) 的分组标签

当 PromQL 表达式包含跨时间序列聚合(例如 sum by (instance))时,每个分组标签都会成为一个独立的输出列。

当不存在跨时间序列聚合时,所有标签会作为一个 _timeseries 列返回,并以 JSON 字符串形式表示。

命名 value 列

默认情况下,value 列的名称就是 PromQL 表达式本身。你可以指定一个自定义名称,以便在后续命令中更方便地引用:

复制代码
PROMQL index=metrics-*
  step=1m
  start="2026-04-01T00:00:00Z"
  end="2026-04-01T01:00:00Z"
  http_rate=(sum by (instance) (rate(http_requests_total[5m])))
| SORT http_rate DESC

这与在 STATS 中命名聚合的方式相同,例如:STATS avg_cpu = avg(system.cpu.usage)

索引模式

index 参数支持与 FROMTS 相同的模式,包括通配符和逗号分隔的列表。如果未指定,则默认使用 *,即查询所有配置了 index.mode: time_series 的索引。在生产环境中,建议显式指定索引模式,以避免扫描无关数据。

底层是如何工作的

PROMQL 命令并不会运行一个独立的查询引擎。相反,PROMQL 命令是在 ES|QL 计算引擎内部执行的,并且复用了通过 TS source 命令实现的时间序列聚合逻辑。

考虑下面这个 PromQL 查询:

复制代码
PROMQL index=metrics-*
  step=1m
  start="2026-04-01T00:00:00Z"
  end="2026-04-01T01:00:00Z"
  sum by (host.name) (rate(http_requests_total[5m]))

在内部,PROMQL 命令会将该查询转换为一个等价的 ES|QL 查询,并使用 TS source 来执行:

复制代码
TS metrics-*
| WHERE TRANGE("2026-04-01T00:00:00Z", "2026-04-01T01:00:00Z")
| STATS SUM(RATE(http_requests_total, 5m)) BY TBUCKET(1m), host.name

两个查询会产生相同的结果。

PROMQL 命令会解析 PromQL 语法,将函数映射为 ES|QL 中的等价实现(例如 rate 转换为 RATEsum 转换为 SUMavg_over_time 转换为 AVG_OVER_TIME 等),并构建一个逻辑执行计划,由 ES|QL 引擎执行。

这种转换方式的一个实际好处是:PromQL 查询可以自动受益于 ES|QL 引擎的所有优化能力,包括 segment 级并行处理以及时间序列感知的数据访问模式。

目前已有 19 个时间序列函数可用,覆盖速率(rates)、差值(deltas)、导数(derivatives)以及多种 *_over_time 聚合函数。

简化查询的智能默认值

在 Prometheus 中,PromQL 查询需要显式指定 startendstep 参数。在 Kibana 中,这些参数通常由时间选择器和面板大小决定。PROMQL 命令提供了三个特性,使查询能够自动适配这些上下文。

自动 step

如果你省略 step 参数,系统会根据时间范围和目标桶数量自动推导 step(默认:100 个桶)。你也可以通过设置 buckets=<n> 来显式指定目标桶数量。

复制代码
PROMQL index=metrics-*
  start="2026-04-01T00:00:00Z"
  end="2026-04-01T01:00:00Z"
  sum by (instance) (rate(http_requests_total[5m]))

在 1 小时时间范围内,如果使用默认的 100 个桶目标,step 将为 1m,从而生成 60 个桶。这使用的是与 ES|QL BUCKET 函数相同的日期取整逻辑。

推断 start 和 end

Kibana 会通过对 @timestamp 的 Query DSL range filter,在每个 ES|QL 请求中自动添加时间范围过滤条件。PROMQL 命令会提取这些边界,并在查询未显式指定时,将其作为 startend 使用。该命令可以直接从请求上下文中读取 date picker 的范围,无需额外配置。

隐式范围选择器

在标准 PromQL 中,像 rate 这样的函数需要显式的范围选择器,例如:rate(http_requests_total[5m])。而 PROMQL 命令允许省略该范围选择器:

复制代码
PROMQL sum by (instance) (rate(http_requests_total))

当范围选择器缺失时,窗口会自动确定为 max(step, scrape_interval)scrape_interval 默认值为 1m,如果你的数据有不同的采集间隔,可以通过 scrape_interval 参数覆盖,例如:PROMQL scrape_interval=15s sum(rate(http_requests_total))

最终结果

结合这三个默认行为,在 Kibana 中一个完全自适应的查询如下所示:

复制代码
PROMQL sum(rate(http_requests_total))

这个查询会响应 date picker 的时间范围选择,根据所选时间范围自动调整 step 大小,并相应地设置范围选择器窗口大小,无需手动调优。

使用 ES|QL 进行后处理

由于 PROMQL 是一个 ES|QL source 命令,它的输出会继续流入 ES|QL 的其余处理管道。你可以使用任意 ES|QL 命令对 PromQL 的结果进行过滤、排序、增强和转换。

过滤结果

复制代码
PROMQL index=metrics-*
  http_rate=(sum by (instance) (rate(http_requests_total[5m])))
| WHERE http_rate > 100

排序与限制(limit)

复制代码
PROMQL index=metrics-*
  http_rate=(sum by (instance) (rate(http_requests_total[5m])))
| SORT http_rate DESC
| LIMIT 10

使用 lookup 进行数据增强

复制代码
PROMQL index=metrics-*
  http_rate=(sum by (instance) (rate(http_requests_total[5m])))
| LOOKUP JOIN instance_metadata ON instance

这在 Prometheus 中是无法实现的。PromQL 的结果是自包含的,没有办法将其与外部数据进行 join,也无法进行任意的后处理。在 Elasticsearch 中,PromQL 的输出只是查询的第一阶段,之后可以继续使用任何 ES|QL 操作进行处理。

当前覆盖范围与后续计划

在 9.4 中,PROMQL 命令将作为技术预览提供,并且在对主流 Grafana 开源仪表盘进行基准测试时,查询覆盖率超过 80%。

当前技术预览中最主要的缺失包括:

  • 尚不支持 group 修饰符,例如 on(chip) group_left(chip_name)

  • 尚未支持布尔集合运算符(orandunless

  • 部分函数仍未支持,包括 histogram_quantilepredict_linearlabel_join

这些功能都已在后续版本规划中。路线图包括更完整的 PromQL 函数与操作符覆盖、与 Prometheus 对齐的 step 语义,以及对原生 histogram 的支持。

体验方式

PromQL 支持在 Elasticsearch Serverless 中作为技术预览直接使用,无需额外配置。对于自管理集群,从 9.4 版本开始提供支持。

在 Kibana 中体验方式如下:

  • 进入 Dashboards,创建一个新的 panel,并选择 ES|QL 作为查询类型

  • 输入 PromQL 查询,例如:PROMQL index=metrics-* sum by (host.name) (rate(http_requests_total))

该命令会自动从 Kibana 的 date picker 推断时间范围,因此无需额外参数。

你也可以在 Discover 的 ES|QL 模式中运行 PromQL 查询,以表格或 XY 图表形式查看结果。后续将在专门的 Kibana 博客中详细介绍 PromQL 在 Dashboards、Discover 和 Alerting 中的完整使用方式。

完整命令参考(包括所有选项与示例)请查看 PROMQL command 文档

如果你想在自管理集群中体验,可以使用 start-local 快速启动环境。

如果遇到问题或有反馈,可以在 Elasticsearch 仓库中提交 issue。

原文:https://www.elastic.co/observability-labs/blog/elasticsearch-supports-promql

相关推荐
AC赳赳老秦1 小时前
政企内网落地:OpenClaw 离线环境深度适配方案,无外网场景下本地化模型对接与全功能使用
java·大数据·运维·python·自动化·deepseek·openclaw
ITyunwei09872 小时前
团队管理与人才发展:如何打造一支“召之即来,来之能战”的铁军?
大数据·运维·人工智能
喜欢流萤吖~2 小时前
Elasticsearch集群:高可用与水平扩展的基石
大数据·elasticsearch·搜索引擎
我是发哥哈4 小时前
跨AI模型生成视频的五大维度对比:选型避坑指南
大数据·人工智能·学习·机器学习·chatgpt·音视频
Elastic 中国社区官方博客4 小时前
Elastic 9.4:Workflows 正式发布、Agent Builder 更新,以及 Prometheus / PromQL 支持
运维·数据库·人工智能·elasticsearch·搜索引擎·信息可视化·prometheus
逸Y 仙X4 小时前
Elasticsearch时间类型实战
java·大数据·elasticsearch·搜索引擎·全文检索
Dxy12393102166 小时前
Python如何处理树状分类数据
大数据·python·分类
凡人AI录7 小时前
小红书商业变现 100 个关键词:从流量逻辑到长期复利
大数据
zhongerzixunshi7 小时前
筑牢国家安全防线,赋能企业合规发展
大数据·人工智能·安全