# Prometheus 知识学习手册 · 第 2 篇:PromQL 与查询 > 基于 [prometheus.io 官方文档](https://prometheus.io/docs/prometheus/latest/querying/basics/) 整理 > 文档版本:Prometheus v3.15.0(最新稳定版,2026-10 发布)| 抓取日期:2026-10-08 > 数据来源:prometheus/prometheus@v3.15.0、prometheus/alertmanager、prometheus/docs 官方仓库源文件(与官网 latest 内容一致) > > **全册结构(共 4 篇)** > - 第 1 篇:入门与架构 > - **第 2 篇:PromQL 与查询** ← 本篇 > - 第 3 篇:配置与运维 > - 第 4 篇:Alertmanager 与生态(告警、插桩、可视化、规范) --- ## 目录 - [第 1 章 PromQL 基础](#第-1-章-promql-基础) - [1.1 查询语言总览](#11-查询语言总览) - [1.2 样本与 flavor](#12-样本与-flavor) - [1.3 表达式语言数据类型](#13-表达式语言数据类型) - [1.4 字面量与时间表达式](#14-字面量与时间表达式) - [1.5 时间序列选择器](#15-时间序列选择器) - [1.6 时间修饰:offset、@ modifier 与子查询](#16-时间修饰offset-modifier-与子查询) - [1.7 Lookback 与 staleness](#17-lookback-与-staleness) - [1.8 正则表达式](#18-正则表达式) - [1.9 UTF-8 引用语法提点](#19-utf-8-引用语法提点) - [1.10 注释与慢查询规避](#110-注释与慢查询规避) - [第 2 章 运算符](#第-2-章-运算符) - [2.1 一元运算符](#21-一元运算符) - [2.2 算术运算符](#22-算术运算符) - [2.3 三角函数运算符](#23-三角函数运算符) - [2.4 直方图裁剪运算符](#24-直方图裁剪运算符) - [2.5 比较运算符](#25-比较运算符) - [2.6 逻辑/集合运算符](#26-逻辑集合运算符) - [2.7 向量匹配](#27-向量匹配) - [2.8 聚合运算符](#28-聚合运算符) - [2.9 二元运算符优先级](#29-二元运算符优先级) - [2.10 实验特性:fill modifiers](#210-实验特性fill-modifiers) - [第 3 章 函数全表](#第-3-章-函数全表) - [3.1 通用约定](#31-通用约定) - [3.2 缺失检测类](#32-缺失检测类) - [3.3 取整与数值钳制类](#33-取整与数值钳制类) - [3.4 数学函数](#34-数学函数) - [3.5 时间与日期类](#35-时间与日期类) - [3.6 范围向量(趋势/变化/速率)类](#36-范围向量趋势变化速率类) - [3.7 直方图专用函数](#37-直方图专用函数) - [3.8 标签操作类](#38-标签操作类) - [3.9 排序与向量构造类](#39-排序与向量构造类) - [3.10 over_time 聚合系列](#310-over_time-聚合系列) - [3.11 三角函数](#311-三角函数) - [3.12 函数速查总表](#312-函数速查总表) - [第 4 章 查询示例集](#第-4-章-查询示例集) - [4.1 简单时序选择](#41-简单时序选择) - [4.2 子查询示例](#42-子查询示例) - [4.3 函数与运算符实战](#43-函数与运算符实战) - [第 5 章 HTTP API](#第-5-章-http-api) - [5.1 通用格式与响应信封](#51-通用格式与响应信封) - [5.2 表达式查询端点](#52-表达式查询端点) - [5.3 元数据查询端点](#53-元数据查询端点) - [5.4 目标与抓取池端点](#54-目标与抓取池端点) - [5.5 规则与告警端点](#55-规则与告警端点) - [5.6 指标元数据端点](#56-指标元数据端点) - [5.7 Alertmanager 与状态端点](#57-alertmanager-与状态端点) - [5.8 TSDB 管理 API](#58-tsdb-管理-api) - [5.9 写入/读取接收端](#59-写入读取接收端) - [5.10 通知与特性端点](#510-通知与特性端点) - [5.11 Remote Read API](#511-remote-read-api) - [第 6 章 查询调试](#第-6-章-查询调试) - [第 7 章 直方图与分位数](#第-7-章-直方图与分位数) - [第 8 章 UTF-8 指标名](#第-8-章-utf-8-指标名) - [附录 本篇覆盖清单](#附录-本篇覆盖清单) --- ## 第 1 章 PromQL 基础 ### 1.1 查询语言总览 Prometheus 提供函数式查询语言 **PromQL**(Prometheus Query Language),用于实时选择与聚合时间序列数据。 查询请求分为两类: | 类型 | 含义 | UI 对应 | |:-----|:-----|:--------| | **instant query**(瞬时查询) | 在单一时点上对表达式求值 | expression browser 的 "Table" 标签页 | | **range query**(范围查询) | 在 `start` 与 `end` 之间以等间隔 `step` 上求值 | expression browser 的 "Graph" 标签页 | PromQL 在两种情况下行为完全一致——range query 相当于在多个不同时间戳上重复执行 instant query。其他程序可通过 **HTTP API** 获取 PromQL 表达式结果(见第 5 章)。 > 引自:[Querying basics](https://prometheus.io/docs/prometheus/latest/querying/basics/) ### 1.2 样本与 flavor #### 1.2.1 样本值类型 - **float sample**:简单的浮点数值。 - **native histogram sample**:包含完整直方图,即 count、sum 与 buckets。 术语说明(重要,避免混淆): - 术语 "histogram sample" **始终**指 native histogram。 - **classic histogram** 指由带 `_bucket`、`_count`、`_sum` 后缀的 float 样本序列共同描述的直方图。从 PromQL 视角看它们只是 float samples,**不存在 "classic histogram samples"**。 #### 1.2.2 counter/gauge flavor float sample 与 histogram sample 都具有 counter 或 gauge 的 **flavor**: | 类型 | 命名 | 是否存储 flavor | |:-----|:-----|:----------------| | counter float sample | "counters" | 否(float samples 不存储 flavor) | | gauge float sample | "gauges" | 否 | | counter histogram | "counter histograms" | 是(histogram sample "知道" 自己的 flavor) | | gauge histogram | "gauge histograms" | 是 | 因为 float samples 不存储 flavor,需用户自行在写 PromQL 时考虑(约定:float counter 的时间序列名以 `_total` 结尾以便区分)。而 histogram samples 知道自己属于 counter 还是 gauge,因此可对不匹配的操作给出**可靠警告**: - 对 gauge floats 应用 `rate` 函数很可能产生荒谬结果,但查询会被**无抱怨地**处理。 - 若应用于 gauge histograms,查询结果会被标注 **warning**。 > 引自:[Querying basics](https://prometheus.io/docs/prometheus/latest/querying/basics/) ### 1.3 表达式语言数据类型 表达式或子表达式可求值为以下四种类型之一: | 类型 | 英文 | 说明 | |:-----|:-----|:-----| | **瞬时向量** | Instant vector | 一组时间序列,每条序列含单个样本,全部共享同一时间戳 | | **区间向量** | Range vector | 一组时间序列,每条序列含一段时间范围内的多个数据点 | | **标量** | Scalar | 简单数值浮点值 | | **字符串** | String | 简单字符串值;**目前未使用** | **哪些类型可作表达式根?** - 对 **instant queries**:以上任意类型均可作为表达式根。 - 对 **range queries**:**仅支持 scalar 类型与 instant-vector 类型**的表达式。 向量与时间序列均可混合包含 float samples 与 histogram samples。 #### 1.3.1 Native histogram bucket layout 的 reconciliation - Native histograms 可有不同 bucket layouts,但通常可转换为兼容版本以施加二元与聚合运算。作用于 range vectors 且适用于 native histograms 的函数也执行此类 reconciliation。 - 二元运算中 reconciliation **成对(pairwise)**执行;聚合运算与函数中所有 histogram samples 被统一 reconcile 到一种兼容 bucket layout。 - 并非所有 bucket layout 都可 reconcile;若运算遇到不兼容直方图,对应**输出向量元素会从结果中移除**,并标记 warn-level annotation。详见 native histogram specification。 > 引自:[Querying basics](https://prometheus.io/docs/prometheus/latest/querying/basics/) ### 1.4 字面量与时间表达式 #### 1.4.1 String literals(字符串字面量) **不存在 "histogram literal"。** String literals 由单引号、双引号或反引号界定,遵循与 Go 相同的 escaping rules: - 单/双引号内反斜杠开始转义序列,后可跟 `a`、`b`、`f`、`n`、`r`、`t`、`v` 或 `\`;特定字符可用八进制(`\nnn`)或十六进制(`\xnn`、`\unnnn`、`\Unnnnnnnn`)表示。 - 反引号界定的字符串中**不解析转义字符**;且与 Go 不同,Prometheus **不丢弃**反引号内的换行。 ```promql "this is a string" 'these are unescaped: \n \\ \t' `these are not unescaped: \n ' " \t` ``` #### 1.4.2 Float literals 标量浮点值可写为整数或浮点字面量,格式(空白仅为可读性): ```text [-+]?( [0-9]*\.?[0-9]+([eE][-+]?[0-9]+)? | 0[xX][0-9a-fA-F]+ | [nN][aA][nN] | [iI][nN][fF] ) ``` 示例:`23`、`-2.43`、`3.4e-9`、`0x8f`、`-Inf`、`NaN`。可在十进制或十六进制数字之间使用下划线 `_` 提升可读性,如 `1_000_000`、`.123_456_789`、`0x_53_AB_F3_82`。 #### 1.4.3 时间持续(duration) Float literals 也用于以**秒**为单位指定时长。十进制整数可组合以下时间单位: | 单位 | 含义 | 等价关系 | |:-----|:-----|:---------| | `ms` | milliseconds | — | | `s` | seconds | 1s equals 1000ms | | `m` | minutes | 1m equals 60s(忽略 leap seconds) | | `h` | hours | 1h equals 60m | | `d` | days | 1d equals 24h(忽略 daylight saving time) | | `w` | weeks | 1w equals 7d | | `y` | years | 1y equals 365d(忽略 leap days) | 给十进制整数加上述单位后缀,等价于以裸 float literal 表示的相同秒数: | 写法 | 等价裸值 | |:-----|:---------| | `1s` | `1.` | | `2m` | `120.` | | `1ms` | `0.001.` | | `-2h` | `-7200.` | 以下示例**不**工作: - `0xABm`(十六进制数不可加后缀) - `1.5h`(时间单位不能与浮点数组合) - `+Infd`(±Inf 或 NaN 不可加后缀) 多个单位可通过拼接带后缀整数组合,**单位必须从最长到最短排序,且每个单位在一个 float literal 中只能出现一次**: | 写法 | 等价 | |:-----|:-----| | `1h30m` | 5400s 即 `5400.` | | `12h34m56s` | 45296s 即 `45296.` | | `54s321ms` | `54.321` | #### 1.4.4 Duration expressions(时长表达式) 凡期望时间持续之处均可使用算术表达式,即 **range vector selectors** 与 **offset durations** 中: ```promql rate(http_requests_total[5m * 2]) # 10 minute range rate(http_requests_total[(5+2) * 1m]) # 7 minute range http_requests_total offset (1h / 2) # 30 minute offset http_requests_total offset ((2 ^ 3) * 1m) # 8 minute offset ``` 使用 `offset` 配合 duration expression 时**必须用括号包裹表达式**;无括号时 offset 计算只采用第一个 duration 值。支持的运算符(按通常优先级):`+` 加法、`-` 减法、`*` 乘法、`/` 除法、`%` 取模、`^` 幂。 duration expressions 内可用函数: | 函数 | 解析结果 | instant query 下 | |:-----|:---------|:-----------------| | `step()` | range query 的 step width | `0s` | | `range()` | range query 的完整范围(end time − start time) | `0s` | | `min_of(, )` | 两者中较小者(用于把时长封顶到最大值) | — | | `max_of(, )` | 两者中较大者(用于强制最小值) | — | `range()` 特别适合配合 `@ end()` 回顾整个查询范围,如 `max_over_time(metric[range()] @ end())`。 例如 `max_of(step(), 5s)` 保证时长不短于 `5s`,`min_of(range(), 1h)` 把时长封顶为 `1h`。**注意**:`@` modifier 中**不支持** duration expressions。 等价时长示例: | 表达式 | 等价于 | |:-------|:-------| | `5m * 2` | `10m` 或 `600s` | | `10m - 1m` | `9m` 或 `540s` | | `(5+2) * 1m` | `7m` 或 `420s` | | `1h / 2` | `30m` 或 `1800s` | | `4h % 3h` | `1h` 或 `3600s` | | `(2 ^ 3) * 1m` | `8m` 或 `480s` | | `step() + 1` | 查询 step width 增加 `1s` | | `max_of(step(), 5s)` | 查询 step 与 `5s` 中较大者 | | `min_of(2 * step() + 5s, 5m)` | 两倍 step 加 `5s` 与 `5m` 中较小者 | > 引自:[Querying basics](https://prometheus.io/docs/prometheus/latest/querying/basics/) ### 1.5 时间序列选择器 #### 1.5.1 Instant vector selectors(瞬时向量选择器) 允许选择一组时间序列及其在给定时点的单个样本值。最简形式只指定 metric name,返回包含所有该名字时间序列的 instant vector。 返回值是**查询评估时间戳(instant query)或查询中当前 step(range query)之前或等于该时刻的最新样本**。`@` modifier 可覆盖选择所依据的时间戳。仅当其最新样本在 lookback period 之内时序列才被返回(见 1.7)。 ```promql http_requests_total http_requests_total{job="prometheus",group="canary"} http_requests_total{environment=~"staging|testing|development",method!="GET"} ``` #### 1.5.2 标签匹配运算符 | 运算符 | 含义 | |:-------|:-----| | `=` | 选择标签值**精确等于**所给字符串 | | `!=` | 选择标签值**不等于**所给字符串 | | `=~` | 选择标签值**正则匹配**所给字符串 | | `!~` | 选择标签值**不正则匹配**所给字符串 | 关键规则: - Regex 匹配**完全锚定**:`env=~"foo"` 视为 `env=~"^foo$"`。 - 匹配空标签值的 matcher 也会选中**所有根本没有设置该标签**的时间序列。 - 同一标签名可有多个 matcher,**所有 matcher 都通过**才返回。 **空标签匹配示例**:给定数据集 `http_requests_total`、`http_requests_total{replica="rep-a"}`、`http_requests_total{replica="rep-b"}`、`http_requests_total{environment="development"}`: - 查询 `http_requests_total{environment=""}` 返回前三条,排除 `environment="development"` 那条。 - 查询 `http_requests_total{replica!="rep-a",replica=~"rep.*"}` 匹配 `http_requests_total{replica="rep-b"}`。 **合法性要求**:Vector selectors **必须指定 name 或至少一个不匹配空字符串的 label matcher**: | 写法 | 是否合法 | |:-----|:---------| | `{job=~".*"} # Bad!` | ❌ 非法(正则匹配空串) | | `{job=~".+"} # Good!` | ✅ 合法 | | `{job=~".*",method="get"} # Good!` | ✅ 合法(有一个不匹配空串) | #### 1.5.3 通过 `__name__` 匹配指标名 Label matchers 也可通过匹配内部 `__name__` 标签施加于 metric name: - `http_requests_total` 等价于 `{__name__="http_requests_total"}`。 - 除 `=` 外还可用 `!=`、`=~`、`!~`。 - `{__name__=~"job:.*"}` 选择所有名字以 `job:` 开头的指标。 metric name 不得为关键字 `bool`、`on`、`ignoring`、`group_left`、`group_right`,例如 `on{} # Bad!` 非法;变通方法是使用 `__name__` 标签:`{__name__="on"} # Good!`。 #### 1.5.4 Range Vector Selectors(区间向量选择器) 行为类似 instant vector literals,但选择从当前时刻回溯的一段样本范围。语法上在 vector selector 末尾用方括号 `[]` 追加一个 float literal,指定每条 range vector 元素向前回溯多少秒取值,常用带时间单位的写法如 `[5m]`。 - **区间为左开右闭**:时间戳与左边界重合的样本被**排除**,与右边界重合的被**包含**。 ```promql http_requests_total{job="prometheus"}[5m] ``` > 引自:[Querying basics](https://prometheus.io/docs/prometheus/latest/querying/basics/) ### 1.6 时间修饰:offset、@ modifier 与子查询 #### 1.6.1 Offset modifier 允许为查询中单个 instant 与 range vector 改变时间偏移。**`offset` 必须紧跟 selector**。 ```promql http_requests_total offset 5m sum(http_requests_total{method="GET"} offset 5m) // GOOD. sum(http_requests_total{method="GET"}) offset 5m // INVALID. rate(http_requests_total[5m] offset 1w) rate(http_requests_total[5m] offset -1w) ``` - 查询过去的样本用**正** offset。 - **负 offset** 可实现向未来方向的时间比较,允许查询前瞻其评估时间。 #### 1.6.2 @ modifier 允许为查询中单个 instant 与 range vector 改变**求值时间**。`@` 接受 Unix timestamp,用 float literal 描述。**`@` 必须紧跟 selector**。 ```promql http_requests_total @ 1609746000 sum(http_requests_total{method="GET"} @ 1609746000) // GOOD. sum(http_requests_total{method="GET"}) @ 1609746000 // INVALID. rate(http_requests_total[5m] @ 1609746000) ``` - 它支持上述所有数值字面量表示形式。 - 可与 `offset` 共用,offset 相对于 `@` 时间施加,**结果与两者顺序无关**: ```promql http_requests_total @ 1609746000 offset 5m http_requests_total offset 5m @ 1609746000 ``` - `start()` 与 `end()` 可作为 `@` 的特殊值:对 range query 分别解析为 range query 的起点与终点,且对所有 step 保持不变;对 instant query 两者都解析为求值时间。 ```promql http_requests_total @ start() rate(http_requests_total[5m] @ end()) ``` **注意**:`@` modifier 允许查询前瞻其评估时间。 #### 1.6.3 Subquery(子查询) Subquery 允许对给定 range 与 resolution 运行 instant query,结果是一个 **range vector**。 语法: ```text '[' ':' [] ']' [ @ ] [ offset ] ``` - `` 可选,**默认为全局 evaluation interval**。 > 引自:[Querying basics](https://prometheus.io/docs/prometheus/latest/querying/basics/) ### 1.7 Lookback 与 staleness #### 1.7.1 为什么需要 lookback 查询期间采样数据的时间戳独立于实际现存的时间序列数据而选择,主要为支持 `sum`、`avg` 等聚合场景(多条被聚合序列在时间上并不精确对齐)。因此 Prometheus 需为每个相关时间序列在这些时间戳赋值,方式是取**不超过 lookback period 之前的最新样本**。 #### 1.7.2 lookback period | 项 | 值 | |:---|:---| | 默认值 | **5 分钟** | | 全局配置 | `--query.lookback-delta` flag | | 单次查询覆盖 | `lookback_delta` 参数(HTTP API,见第 5 章) | #### 1.7.3 Staleness(陈旧标记) - 若 target scrape 或 rule evaluation 不再返回某条先前存在的时间序列的样本,该序列被标记为 **stale**。 - 若 target 被移除,先前抓取的序列会在移除后不久被标记 stale。 - 若查询在某序列被标记 stale **之后**的采样时间戳求值,则该序列**不返回值**;若后续有新样本摄入,则按预期返回。 - 序列在其不再被导出或 target 不存在时变 stale,会**消失在图中**(在最后一次采集样本处),并在标记 stale 后不再被查询返回。 - 某些自行给样本打时间戳的 exporters 行为不同:停止导出的序列会在(默认)5 分钟内保留最后一个值再消失;`track_timestamps_staleness` 设置可改变该行为。 > 引自:[Querying basics](https://prometheus.io/docs/prometheus/latest/querying/basics/) ### 1.8 正则表达式 Prometheus 中所有正则表达式使用 **RE2 syntax**。Regex 匹配**始终完全锚定**。 > 引自:[Querying basics](https://prometheus.io/docs/prometheus/latest/querying/basics/) ### 1.9 UTF-8 引用语法提点 从 Prometheus 3.0 起,任意 UTF-8 字符串都是合法的 metric/label 名(详见第 8 章)。在 PromQL 中查询这类名称需要**略不同的语法**: - classic 查询语法对 legacy-compatible 名称仍有效:`my_metric{}`。 - UTF-8 名称**必须加引号并移入花括号内**:`{"my.metric"}`。 - label 名若含 legacy-incompatible 字符也必须加引号:`{"metric.name", "my.label.name"="bar"}`。 - metric 名可出现在花括号内任意位置,但风格上偏好放在首个位置。 > 引自:[UTF-8 in Prometheus](https://prometheus.io/docs/guides/utf8/) ### 1.10 注释与慢查询规避 #### 1.10.1 注释 PromQL 支持以 `#` 开头的行注释,例如 `# This is a comment`。 #### 1.10.2 Avoiding slow queries and overloads 若查询需处理大量数据,绘图可能超时或拖垮服务器/浏览器。因此: - 在未知数据上构建查询时,应**始终先在 expression browser 的表格视图中构建**,直到结果集合理(**最多数百条**而非数千条时间序列)。 - 只有充分过滤或聚合后才切到 graph 模式。 - 若临时绘图仍太慢,通过 **recording rule** 预先记录。 此点对 PromQL 尤其相关: - 裸 metric name selector 如 `api_http_requests_total` 可能展开为**数千条**不同标签的时间序列; - 即便输出仅少量序列,对众多序列聚合的表达式也会给服务器带来负载,类似关系数据库中求整列之和即便输出单值也会很慢。 > 引自:[Querying basics](https://prometheus.io/docs/prometheus/latest/querying/basics/) > 💡 补充:本手册第 6 章「查询调试」给出了 query log 的开启方式与性能排查思路,可与本节配合使用。 --- ## 第 2 章 运算符 PromQL 支持 **unary(一元)**、**binary(二元)** 与 **aggregation(聚合)** 三类运算符。 > 引自:[Operators](https://prometheus.io/docs/prometheus/latest/querying/operators/) ### 2.1 一元运算符 PromQL 中唯一的 unary 运算符是 `-`(unary minus),可作用于 scalar 或 instant vector: - 作用于 scalar 时返回符号取反的 scalar; - 作用于 instant vector 时返回每个元素符号取反的 instant vector; - histogram sample 的符号通过反转所有 bucket populations 及观测的 count 与 sum 的符号来反转,**结果 histogram sample 总被视为 gauge histogram**。 > **NOTE**:含任何**负 bucket population** 或**负观测 count** 的 histogram 只应作为**中间结果**使用。若这种负直方图是 recording rule 的最终结果,rule evaluation 会**失败**。负直方图无法被任何交换格式(exposition、remote-write、OTLP)表示,因此无法以任何方式摄入 Prometheus,只能由 PromQL 表达式创建。 > 引自:[Operators](https://prometheus.io/docs/prometheus/latest/querying/operators/) ### 2.2 算术运算符 #### 2.2.1 运算符清单 | 运算符 | 含义 | |:-------|:-----| | `+` | addition(加法) | | `-` | subtraction(减法) | | `*` | multiplication(乘法) | | `/` | division(除法) | | `%` | modulo(取模) | | `^` | power / exponentiation(幂) | 定义为 scalar/scalar、vector/scalar、vector/vector 值对之间的运算,遵循通常的 **IEEE 754 浮点算术**,包括对 `NaN`、`+Inf`、`-Inf` 等特殊值的处理。 #### 2.2.2 scalar 之间 直接求值为对两个操作数施加运算符后的另一个 scalar。 #### 2.2.3 instant vector 与 scalar 之间 运算符施加于 vector 中每个数据样本的值。 - 若样本是 **float**,则在该 float 与 scalar 间执行运算(例如 float samples 的 instant vector 乘 2,结果是每个样本值都乘以 2 的 float samples 向量)。 - 对 **histogram sample** 的向量元素: - `*`:将所有 bucket populations 及观测 count 与 sum 乘以 scalar(scalar 为负则结果视为 gauge histogram,否则保留输入的 counter vs. gauge flavor)。 - `/`:要求 histogram sample 在**左侧(LHS)**、scalar 在**右侧(RHS)**,将 bucket populations 及 count 与 sum 除以 scalar。**除以零**结果为无 regular buckets 的直方图,zero bucket population 与 count、sum 依输入值(正、负、零/NaN)分别设为 `+Inf`、`-Inf` 或 `NaN`(scalar 为负则结果为 gauge histogram,否则保留输入 flavor)。 - scalar 在 LHS、histogram 在 RHS 的 `/`,以及所有其他 scalar 与 histogram 组合的算术二元运算符,**无结果且对应元素从结果向量中移除**,并以 **info-level annotation** 标记。 #### 2.2.4 两个 instant vectors 之间 运算符施加于 LHS 向量每个条目及其在 RHS 中的 matching element,结果传播到结果向量且 grouping labels 成为输出标签集。默认情况下,在对面向量找不到匹配条目的序列**不进入结果**,该行为可用 fill modifiers 调整(见 2.10)。 样本类型匹配规则: | LHS / RHS | 行为 | |:----------|:-----| | float / float | 对两个输入值施加算术运算符 | | float / histogram | 遵循 scalar 与 histogram 间的同一逻辑(`*` 与 `/` 后者要求 histogram 在 LHS 有效,其余导致元素移除) | | histogram / histogram | **只有 `+` 与 `-` 有效**,各将匹配的 bucket populations 及 count 与 sum 相加或相减;其余运算导致元素移出输出向量并标记 info-level annotation | 关于 histogram 的加减: - `+` 与 `-` 一般只应作用于 **gauge histograms**,但 PromQL 也允许用于 **counter histograms** 以覆盖特定用例,此时需特别留意 **counter resets 不对齐**问题(PromQL 能检测某些 counter reset 不兼容并标记 warn-level annotation)。 - 两个 counter histograms 相加结果为 **counter histogram**;**所有其他操作数组合及所有减法结果为 gauge histogram**。 - **任何涉及向量的算术二元运算都会丢弃 metric name**,即便在 `on` 中显式提到 `__name__` 也如此(参见 issue 16631)。 - 对任何可能产生负直方图的算术二元运算,须注意 2.1 节 unary operator 的相关 note。 > 引自:[Operators](https://prometheus.io/docs/prometheus/latest/querying/operators/) ### 2.3 三角函数运算符 存在以下三角函数**二元**运算符,以**弧度**工作: | 运算符 | 含义 | |:-------|:-----| | `atan2` | 基于 | 三角函数运算符允许借助 vector matching 对两个向量执行三角函数,这是普通函数所不具备的。其行为方式与算术运算符相同,**仅作用于 float samples**;涉及 histogram samples 的运算导致对应向量元素移出输出向量并标记 **info-level annotation**。 > 引自:[Operators](https://prometheus.io/docs/prometheus/latest/querying/operators/) ### 2.4 直方图裁剪运算符 存在以下二元 **histogram trim** 运算符: | 运算符 | 含义 | |:-------|:-----| | `/` | trim lower:移除所有低于阈值的观测 | 定义为 vector/scalar 与 vector/vector 值对之间的运算,**左侧为 native histogram(exponential 或 NHCB),右侧为 float 阈值**。 - 若阈值未与直方图某 bucket 边界对齐,则采用**线性插值**(对 NHCB 与 exponential histogram 的 zero buckets)或**指数插值**(对 exponential histogram 的非零 bucket)计算阈值所在 bucket 中剩余观测的估计数量。 - 当有观测被 trim 时,新的观测值之和基于剩余观测(近似)重新计算。 > 引自:[Operators](https://prometheus.io/docs/prometheus/latest/querying/operators/) ### 2.5 比较运算符 #### 2.5.1 运算符清单 | 运算符 | 含义 | |:-------|:-----| | `==` | equal(等于) | | `!=` | not-equal(不等于) | | `>` | greater-than(大于) | | `<` | less-than(小于) | | `>=` | greater-or-equal(大于等于) | | `<=` | less-or-equal(小于等于) | 定义为 scalar/scalar、vector/scalar、vector/vector 值对之间。**默认过滤(filter)**,行为可通过在运算符后提供 **`bool`** 修改,`bool` 会返回值 `0` 或 `1` 而非过滤。 #### 2.5.2 各类组合的详细行为 | 组合 | 行为 | |:-----|:-----| | **两个 scalars** | **必须提供 `bool` modifier**,结果为另一个 scalar,依比较结果为 `0`(`false`)或 `1`(`true`) | | **instant vector 与 scalar** | 施加于 vector 中每个数据样本值,比较结果为 false 的向量元素从结果向量中丢弃。**仅适用于 float samples**;对 histogram samples,对应元素从结果向量移除并标记 info-level annotation | | **两个 instant vectors** | 默认作为 filter 施加于匹配条目。表达式不为真或在另一侧找不到匹配的向量元素从结果中丢弃,其余传播到结果向量且 grouping labels 成为输出标签集 | 向量间样本类型: - 两个 float samples 匹配照常工作; - float sample 与 histogram sample 匹配**非法**,对应元素移除并标记 info-level annotation; - 两个 histogram samples 之间 **`==` 与 `!=` 照常工作**,**其余比较二元运算均非法**。 #### 2.5.3 `bool` modifier 与 metric name - **涉及向量的比较二元运算中提供 `bool` modifier** 会改变行为:在另一侧找到匹配但表达式为假的向量元素值为 `0`,找到匹配且表达式为真的值为 `1`(注意无匹配或涉及 histogram samples 的非法运算**仍返回无结果**而非 `0`);且 **metric name 被丢弃**。 - 若**未提供 `bool` modifier**,则**保留左侧的 metric name**,但有例外: - 使用 `on` 时 metric name 被丢弃; - 使用 `group_right` 时保留右侧 metric name 以避免冲突。 > 引自:[Operators](https://prometheus.io/docs/prometheus/latest/querying/operators/) ### 2.6 逻辑/集合运算符 以下 logical/set 二元运算符**仅在 instant vectors 之间定义**: | 运算符 | 含义 | |:-------|:-----| | `and` | intersection(交集) | | `or` | union(并集) | | `unless` | complement(补集) | 语义: - `vector1 and vector2`:结果为 `vector1` 中那些在 `vector2` 存在标签集完全匹配元素的元素,其他元素丢弃;metric name 与值从**左侧**向量带过来。 - `vector1 or vector2`:结果为包含 `vector1` 全部原始元素(标签集 + 值),外加 `vector2` 中在 `vector1` **无匹配标签集**的全部元素。 - `vector1 unless vector2`:结果为 `vector1` 中那些在 `vector2` **不存在**标签集完全匹配元素的元素;两向量中所有匹配元素都被丢弃。 由于这些 logical/set 运算符**不与样本值交互**,**对 float samples 与 histogram samples 行为相同**。 > 引自:[Operators](https://prometheus.io/docs/prometheus/latest/querying/operators/) ### 2.7 向量匹配 向量间运算为 LHS 每个条目尝试在 RHS 向量中找到匹配元素。有两种基本匹配行为:**One-to-one** 与 **many-to-one / one-to-many**。 #### 2.7.1 匹配关键字 **Vector matching keywords**(允许在不同标签集的序列间匹配): | 关键字 | 含义 | |:-------|:-----| | `on(