在 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_total5m)) 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

相关推荐
杰佛史彦明115 小时前
ElasticSearch中的分词器详解
大数据·elasticsearch·c#
头茬韭菜15 小时前
3.9 成本预警 — 退出钩子、$5 阈值对话框与多通道成本通知
java·大数据·jvm·ai
studyrunner15 小时前
GPT-5.5 对比 GPT-5.6 Sol、Terra、Luna:官方性能数据与选型分析
大数据·人工智能·gpt
广州浮点FLOATLIC15 小时前
装备制造企业怎么做许可证高峰冲突分析:设计、仿真与工艺评审为何总在关键节点同时挤占资源
大数据·制造·许可证管理
AllData公司负责人15 小时前
数据同步平台|AIIData数据中台实现MySQL、Hive、Kafka 一键接入Doris
大数据·数据库·hive·mysql·kafka·实时同步
wuhanzhanhui15 小时前
从芯片到精密制造:2026武汉电子元器件、材料及生产设备展会见证微观世界的跃迁
大数据·人工智能
百胜软件@百胜软件15 小时前
百胜软件推出RT业务:零售技术服务全链路飞轮如何助力品牌商“降本+增收”?
大数据·人工智能·零售
数据小玩子16 小时前
会员留存率低?告别粗放式触达,用数据标签+BI构建“留量“护城河
大数据·数据运营·助睿数智·会员留存
Elasticsearch16 小时前
如何在 Elasticsearch 中使用 BBQ 将 Jina v5 嵌入缩小 29 倍而不损失召回率
elasticsearch
DolphinScheduler社区16 小时前
Apache DolphinScheduler 6 月治理优化,补齐调度运维全链路细节
大数据·运维·云原生·apache·海豚调度