DQL 函数参考¶
DQL 提供了丰富的函数用于数据聚合、转换和匹配。本文档详细介绍每个函数的语义、参数和使用方法。
聚合函数¶
聚合函数用于将多行数据聚合为单个值,通常与时间窗口(time-expr)和分组(BY 子句)一起使用。
基础聚合¶
sum¶
计算字段值的总和。
语法:
参数:
field: 数值字段
示例:
// 计算总请求数
M::http_requests:(sum(request_count)) [1h]
// 按服务分组计算总请求数
M::http_requests:(sum(request_count)) [1h] BY service
avg¶
计算字段值的平均值。
语法:
参数:
field: 数值字段
示例:
// 计算平均响应时间
M::response_time:(avg(duration)) [1h] BY endpoint
// 计算平均 CPU 使用率
M::cpu:(avg(usage)) [1h] BY host
count¶
计算数据行数。
语法:
参数:
field: 任意字段,计算非空值的数量*: 计算所有行数
示例:
// 计算日志条数
L::nginx:(count(*)) [1h]
// 计算有响应时间的请求数
M::response_time:(count(duration)) [1h] BY service
min / max¶
计算字段的最小值或最大值。
语法:
参数:
field: 数值字段
示例:
// 找出最大响应时间
M::response_time:(max(duration)) [1h] BY endpoint
// 找出 CPU 使用率的范围
M::cpu:(min(usage), max(usage)) [1h] BY host
first / last¶
获取第一个或最后一个值(按时间顺序)。
语法:
参数:
field: 任意字段
说明:
first: 返回时间最早的值last: 返回时间最晚的值,如果字段是数组类型会展开last_row: 返回时间最晚的值,数组类型不展开
示例:
// 获取最新的状态值
M::system:(last(status)) [1h] BY host
// 获取初始值和最终值
M::counter:(first(value), last(value)) [1h] BY metric
any¶
返回任意一个非空值。适用于获取样本数据或不需要特定聚合顺序的场景。
语法:
参数:
field: 任意字段
示例:
// 获取任意一个消息样本
L::logs:(any(message)) [1h] BY service
// 获取任意一个错误堆栈
L::error_logs:(any(stack_trace)) [1h] BY error_type
spread¶
计算极差(最大值与最小值的差)。
语法:
参数:
field: 数值字段
示例:
stddev¶
计算标准差。
语法:
参数:
field: 数值字段
示例:
mode¶
计算众数(出现次数最多的值)。
语法:
参数:
field: 任意字段
示例:
count_series¶
计算时间序列(分组)的数量。返回当前查询范围内有多少个独立的时间序列。
语法:
参数:
field: 任意字段(通常使用*或任意存在字段)
示例:
// 计算有多少个主机在报告 CPU 指标
M::cpu:(count_series(*)) [1h]
// 计算每个服务有多少个实例
M::http_requests:(count_series(*)) [1h] BY service
统计聚合(估算函数)¶
以下函数使用概率数据结构进行估算,适用于大数据量的场景,可以在精度和性能之间取得平衡。
count_distinct¶
计算字段的不同值数量(估算值)。
语法:
参数:
field: 任意字段
算法说明:
使用 HyperLogLog 算法进行基数估算:
- 寄存器数量:2¹⁶ = 65536
- 使用 LogLog-Beta 估计方法
- 标准误差:约 0.4%
适用场景:
- 统计独立用户数(UV)
- 计算不同 IP 地址数量
- 分析唯一请求 ID 数量
示例:
// 统计独立用户数
L::access_logs:(count_distinct(user_id)) [1d] BY service
// 统计访问的不同 IP 数量
L::nginx:(count_distinct(client_ip)) [1h] BY endpoint
percentile¶
计算字段的百分位数(估算值)。
语法:
参数:
field: 数值字段n: 百分位数,范围 0-100
简写形式:
p50(field)等价于percentile(field, 50)p95(field)等价于percentile(field, 95)p99(field)等价于percentile(field, 99)
算法说明:
使用对数线性插值直方图进行估算: - 桶范围:10⁻⁹ 到 10¹⁸,覆盖绝大多数数值场景 - 每个数量级划分为 128 个桶 - 使用对数空间的线性插值提高精度
适用场景:
- 计算响应时间的 P99、P95
- 分析性能指标的尾部延迟
- 评估服务等级协议(SLA)达成情况
示例:
// 计算响应时间的 P99
M::response_time:(percentile(duration, 99)) [1h] BY service
// 使用简写形式
M::response_time:(p99(duration)) [1h] BY service
// 同时计算多个百分位数
M::response_time:(p50(duration), p95(duration), p99(duration)) [1h] BY service
median¶
计算中位数,等价于 percentile(field, 50)。
语法:
示例:
直方图函数¶
DQL 提供三种直方图相关的函数,适用于不同的数据源和场景:
| 函数 | 适用场景 | 数据源类型 | 推荐度 |
|---|---|---|---|
histogram_auto |
日志、Trace 等明细数据的数值分布统计 | 明细模型(日志/Trace) | ⭐⭐⭐ 推荐 |
histogram |
需要固定桶边界的直方图 | 明细模型(日志/Trace) | ⭐⭐ Deprecated |
histogram_quantile |
从 Prometheus 直方图指标计算分位数 | Prometheus 指标 | ⭐⭐⭐ 推荐 |
histogram_auto(推荐)¶
自动生成分布直方图,专为日志、Trace 等明细数据的数值分布统计设计。
特点:
- 无需指定桶边界,自动适应数据分布
- 使用对数线性插值直方图算法,覆盖 10⁻⁹ 到 10¹⁸ 的数值范围
- 同时返回分位数统计和桶分布信息
语法:
参数:
field: 数值字段
返回值:
| 列名 | 说明 |
|---|---|
lower_bounds |
各桶的下边界数组 |
upper_bounds |
各桶的上边界数组 |
counts |
各桶的计数数组 |
min |
最小值 |
p50 |
中位数 |
p75 |
75分位数 |
p90 |
90分位数 |
p95 |
95分位数 |
p99 |
99分位数 |
max |
最大值 |
算法说明:
使用估算直方图(对数线性插值),每个数量级划分为 128 个桶,适合大数据量的分布统计。
适用场景:
- 分析日志中的响应时间分布
- 统计 Trace 中的耗时分布
- 探索性数据分析,无需预设桶边界
示例:
// 分析 Nginx 访问日志的响应时间分布
L::nginx:(histogram_auto(response_time)) [1h]
// 按服务统计请求耗时分布
L::app_logs:(histogram_auto(duration)) [1h] BY service
// 统计 Trace 调用的耗时分布
T::http_client:(histogram_auto(elapsed)) [1h] BY operation
结果示例:
| lower_bounds | upper_bounds | counts | min | p50 | p75 | p90 | p95 | p99 | max |
|---|---|---|---|---|---|---|---|---|---|
| [0, 10, 100] | [10, 100, 1000] | [1000, 500, 100] | 0.5 | 45 | 120 | 280 | 450 | 850 | 1200 |
注意
lower_bounds、upper_bounds、counts 为数组类型,表示各桶的边界和计数。
histogram(Deprecated)¶
生成指定桶边界的直方图。此函数 Deprecated,推荐使用 histogram_auto 替代。
说明:
histogram 需要手动指定桶的边界参数,使用起来不够灵活。histogram_auto 可以自动适应数据分布,覆盖更广泛的数值范围,且返回更丰富的统计信息。
语法:
参数:
field: 数值字段left_bound: 左边界right_bound: 右边界bucket_size: 桶大小threshold(可选): 单桶最小计数,低于此值的桶不返回
返回值:
返回两列:bucket_le(桶的右边界)和 count(计数)
示例:
// 生成 0-1000ms 范围内、每 100ms 一个桶的直方图
M::response_time:(histogram(duration, 0, 1000, 100)) [1h]
// 推荐使用 histogram_auto 替代
M::response_time:(histogram_auto(duration)) [1h]
结果示例:
| bucket_le | count |
|---|---|
| 100 | 1500 |
| 200 | 2800 |
| 300 | 3500 |
| ... | ... |
| 1000 | 5000 |
histogram_quantile¶
从 Prometheus 直方图指标计算分位数。
特点:
- 专门用于处理 Prometheus 上报的直方图类型指标
- 依赖
le标签(或 VictoriaMetrics 的vmrange标签)识别 bucket 边界 - 输入数据应为累积计数(cumulative)
语法:
参数:
field: 直方图计数字段(如http_request_duration_bucket)q: 分位数,范围 0-1(如 0.99 表示 P99)
使用场景对比:
| 场景 | 推荐函数 | 说明 |
|---|---|---|
| 分析日志中的响应时间分布 | histogram_auto |
日志是明细数据,无预聚合直方图 |
| 分析 Prometheus 直方图指标的 P99 | histogram_quantile |
指标已按 le 标签预聚合 |
| 统计 Trace 调用的耗时分布 | histogram_auto |
Trace 是明细数据 |
le 标签处理机制:
histogram_quantile 依赖 le 标签(less than or equal)来识别直方图 bucket 的边界:
-
Prometheus 格式(默认):使用
le标签直接表示 bucket 上边界le值为数值(如 "0.1", "1", "10")或 "+Inf"(无穷大)- 数据应为累积计数(cumulative)
-
VictoriaMetrics 格式:使用
vmrange标签表示范围- 格式为
"下限...上限"(如"0.1...0.2") - 数据为范围计数(非累积)
- 函数会自动将范围计数转换为累积计数
- 格式为
计算过程:
- 按
le值排序所有 bucket - 如果是
vmrange格式,累加计数转换为累积分布 - 确保 bucket 计数单调递增(修复可能的异常数据)
- 使用线性插值计算目标分位数
与 PromQL 的差异:
| 特性 | DQL | PromQL |
|---|---|---|
| 函数类型 | 聚合函数 | 转换函数 |
| 输入数据 | 直接读取带 le 标签的指标 |
需要配合 sum(rate(...)) by (le) |
| 使用方式 | histogram_quantile(field, 0.99) |
histogram_quantile(0.99, sum(rate(...)) by (le)) |
| 数据格式 | 支持 le 和 vmrange 两种标签 |
仅支持 le 标签 |
| 分组方式 | 通过 DQL 的 BY 子句 | 通过 by (le) 显式分组 |
等价示例:
假设有直方图指标 http_request_duration_bucket,包含 le 标签(如 0.1, 0.5, 1, 5, +Inf)和 service 标签。
场景 1:计算 P99 延迟
DQL:
PromQL 等价:
场景 2:计算各服务的 P95 延迟(多分组)
DQL:
PromQL 等价:
场景 3:计算 P50(中位数)和 P99
DQL:
M::http_request_duration:(
histogram_quantile(duration_bucket, 0.50) as p50,
histogram_quantile(duration_bucket, 0.99) as p99
) [1h] BY service
PromQL 等价:
label_join(
histogram_quantile(0.50, sum(rate(http_request_duration_bucket[1h])) by (le, service)), "quantile", "", "0.50"
)
or
label_join(
histogram_quantile(0.99, sum(rate(http_request_duration_bucket[1h])) by (le, service)), "quantile", "", "0.99"
)
注意
PromQL 需要 label_join 或 label_replace 来区分不同分位数的结果。
注意事项:
- 输入数据必须包含
le或vmrange标签,否则无法计算 - 如果没有
+Infbucket,最后一个 bucket 的上边界将作为最大值 - 计数为 0 或 NaN 的 bucket 会被跳过
- 当分位数 < 0 时返回 -Inf,> 1 时返回 +Inf
TopN 函数¶
top¶
获取前 N 个最大的值。
语法:
参数:
field: 数值字段n: 返回值的数量
示例:
// 获取响应时间最长的 5 个请求
M::response_time:(top(duration, 5)) [1h] BY service
// 获取流量最大的 10 个主机
M::network:(top(bytes, 10)) [1h]
结果示例:
| service | top(duration, 5) |
|---|---|
| api | 1250 |
| api | 1180 |
| api | 1050 |
| api | 980 |
| api | 920 |
注意
返回多行,每行包含一个 TopN 值。
bottom¶
获取前 N 个最小的值。
语法:
参数:
field: 数值字段n: 返回值的数量
示例:
结果示例:
| service | bottom(duration, 5) |
|---|---|
| api | 12 |
| api | 18 |
| api | 25 |
| api | 32 |
| api | 45 |
注意
返回多行,每行包含一个 BottomN 值。
值收集函数¶
distinct¶
返回字段的所有不同值。
语法:
示例:
结果示例:
| endpoint | distinct(status) |
|---|---|
| /api/v1 | 200 |
| /api/v1 | 404 |
| /api/v1 | 500 |
| /health | 200 |
注意
返回多行,每行包含一个不同的值。
distinct_by_collapse¶
按折叠策略获取字段的不同值,并在去重时保留其他字段的最后一个值。
语法:
参数:
field: 去重依据的字段last_fields(可选): 需要保留最后一个值的字段列表
说明:
与 distinct 不同,distinct_by_collapse 在去重时会保留其他相关字段的信息(取最后一个值),适用于需要保留上下文信息的场景。
示例:
// 获取不同的用户 ID,并保留每个用户最后访问的时间
L::access_logs:(distinct_by_collapse(user_id, [timestamp])) [1h]
// 获取不同的主机,并保留最后的状态和消息
O::HOST:(distinct_by_collapse(host, [status, message])) [1h]
结果示例:
| user_id | last(timestamp) | last(path) |
|---|---|---|
| user001 | 1704067200000 | /checkout |
| user002 | 1704067100000 | /product |
| user003 | 1704067000000 | /home |
注意
返回去重后的主字段值,以及 last_fields 指定的其他字段的最后一个值。
collect¶
收集所有值(包含重复)。
语法:
参数:
field: 任意字段limit(可选): 最多收集的数量
示例:
// 收集所有响应时间
M::response_time:(collect(duration)) [1h] BY service
// 最多收集 100 个值
M::response_time:(collect(duration, 100)) [1h] BY service
结果示例:
| service | collect(duration) |
|---|---|
| api | [120, 135, 98, 142, ...] |
| web | [45, 52, 48, 61, ...] |
注意
返回数组类型,包含收集到的所有值(可能包含重复值)。
collect_distinct¶
收集所有不同的值。
语法:
参数:
field: 任意字段limit(可选): 最多收集的数量
示例:
结果示例:
| service | collect_distinct(error_type) |
|---|---|
| api | ["timeout", "connection refused", "404"] |
| web | ["200", "301", "404"] |
注意
返回数组类型,包含去重后的所有值。
field_values¶
获取字段的所有值,返回数组类型。
语法:
示例:
结果示例:
| metric_name | field_values(tags) |
|---|---|
| cpu_usage | ["host:A", "env:prod", "team:backend"] |
| memory_used | ["host:B", "env:staging", "team:frontend"] |
注意
返回数组类型,包含字段的所有值。
筛选聚合¶
count_filter¶
统计字段值在指定列表中的数量。
语法:
参数:
field: 任意字段values: 值列表
示例:
// 统计特定状态码的请求数
M::http:(count_filter(status, [200, 201, 204])) [1h] BY endpoint
// 统计错误级别日志
L::logs:(count_filter(level, ["error", "critical"])) [1h] BY service
辅助函数¶
default¶
为字段设置默认值,当字段为空时返回默认值。
语法:
参数:
field: 任意字段default_value: 默认值(可以是数值、字符串、布尔值或 null)
示例:
时间序列函数¶
时间序列函数用于处理随时间变化的数据,特别是 Counter 类型的指标。
Rollup 函数¶
Rollup 函数用于在时间窗口中对原始时间序列数据进行预处理,详细说明请参考 本文中的 Rollup 函数。
写法说明:
- Rollup 写在时间子句中,例如
[rate]、[1h::5m:rate]。 - 写在查询外层(如
rate(DQL))属于外层函数,不是 Rollup。
支持的 Rollup 函数:
| 函数 | 说明 |
|---|---|
rate |
计算增长率(每秒) |
irate |
计算瞬时增长率 |
increase |
计算增长量 |
deriv |
计算导数(变化率) |
difference |
计算差值 |
non_negative_derivative |
计算非负导数 |
non_negative_difference |
计算非负差值 |
rate_over_sum |
计算每秒平均值 |
rate_over_count |
计算每秒计数 |
sum |
求和 |
avg |
平均值 |
min |
最小值 |
max |
最大值 |
count |
计数 |
first |
第一个值 |
last |
最后一个值 |
stddev |
标准差 |
mode |
众数 |
spread |
极差 |
any |
任意一个值 |
示例:
// 计算请求 QPS
M::http_requests:(sum(request_count)) [1h::5m:rate] BY service
// 简写形式
M::cpu:(max(usage)) [rate]
增长率计算¶
rate¶
计算指标的增长率(每秒)。
语法:
说明:
rate 计算的是 Counter 指标在时间窗口内的平均增长率。对于单调递增的 Counter 类型指标,直接使用原始值进行聚合没有意义,需要先计算增长率。
适用场景:
- 计算请求 QPS
- 计算数据写入速率
- 分析流量增长趋势
示例:
// 计算请求 QPS
M::http_requests:(sum(request_count)) [rate] BY service
// 计算数据写入速率
M::data_ingestion:(sum(bytes)) [rate] BY source
irate¶
计算指标的瞬时增长率。
语法:
说明:
与 rate 不同,irate 只使用最后两个数据点计算增长率,反映的是瞬时变化率,更适合用于告警场景。
示例:
increase¶
计算指标的增长量。
语法:
说明:
increase 返回的是时间窗口内的总增长量,而不是增长率。
示例:
rate_over_sum¶
计算每秒的平均值(sum / 时间窗口秒数)。
语法:
说明:
等效于 sum(field) / 时间窗口(秒),用于计算每秒的平均值。常用于 Rollup 阶段将累计值转换为每秒速率。
与 rate 的区别:
rate:计算 Counter 的增长率(处理重置)rate_over_sum:简单地将 sum 除以时间窗口秒数
示例:
rate_over_count¶
计算每秒的计数(count / 时间窗口秒数)。
语法:
说明:
等效于 count(field) / 时间窗口(秒),用于计算每秒的发生次数。
示例:
差值计算¶
本节描述的是函数语义。相同函数既可作为 Rollup 使用(如 [rate]、[increase]),也可写在查询内表达式中(如 rate(field)、increase(field));两者执行阶段不同,优先按业务需求选择位置。
rate / deriv¶
计算变化率(导数)。rate 用于 Counter 类型指标(忽略负值),deriv 用于 Gauge 类型指标(保留负值)。
别名: rate 的别名是 non_negative_derivative;deriv 的别名是 derivative(PromQL 风格)。
语法:
函数选择:
| 函数 | 说明 | 适用场景 |
|---|---|---|
rate |
只计算非负变化率 | Counter 类型指标(单调递增) |
deriv |
计算完整变化率(包括负值) | Gauge 类型指标(可增可减) |
示例:
// Counter 指标:计算请求 QPS
M::requests:(rate(count)) [1h::5m] BY service
// Gauge 指标:计算内存使用变化率
M::memory:(deriv(used)) [1h::5m] BY host
increase / difference¶
计算相邻值的差值。increase 用于 Counter 类型指标(忽略负值),difference 用于 Gauge 类型指标(保留负值)。
说明: increase 和 difference 是两个独立的函数,行为不同,不是别名关系。
语法:
函数选择:
| 函数 | 说明 | 适用场景 |
|---|---|---|
increase |
只计算非负差值 | Counter 类型指标(单调递增) |
difference |
计算完整差值(包括负值) | Gauge 类型指标(可增可减) |
示例:
// Counter 指标:计算请求增长量
M::requests:(increase(count)) [1h::5m] BY service
// Gauge 指标:计算请求数变化(可能增加或减少)
M::requests:(difference(count)) [1h::5m] BY service
移动计算¶
moving_average¶
计算移动平均值。
语法:
参数:
field: 数值字段n: 窗口大小(数据点数量)
示例:
cumsum¶
计算累积和。
语法:
示例:
转换函数¶
转换函数用于对字段值进行数学运算、类型转换或字符串处理。
数学函数¶
abs¶
计算绝对值。
语法:
示例:
round / ceil / floor¶
取整函数。
语法:
示例:
log / log2 / log10¶
对数函数。
语法:
示例:
类型转换¶
int / uint / float / string / bool¶
类型转换函数。
语法:
int(field) // 转为有符号整型
uint(field) // 转为无符号整型
float(field) // 转为浮点型
string(field) // 转为字符串
bool(field) // 转为布尔型
示例:
// 将字符串转为数值
L::logs:(int(response_time)) [1h] BY service
// 将数值转为字符串进行拼接
M::metrics:(string(value)) [1h] BY metric_name
字符串函数¶
substr¶
截取子字符串。
语法:
参数:
field: 字符串字段start: 起始位置(从 0 开始,支持负数表示从末尾开始)length(可选): 子字符串长度
返回值:
返回截取后的子字符串。
示例:
// 截取消息前 100 个字符
L::logs:(substr(message, 0, 100)) [1h]
// 截取最后 10 个字符
L::logs:(substr(message, -10)) [1h]
结果示例:
| message | substr(message, 0, 10) | substr(message, -5) |
|---|---|---|
| "Error: connection timeout" | "Error: con" | "eout" |
regexp_extract¶
正则表达式提取。
语法:
参数:
field: 字符串字段pattern: 正则表达式n(可选): 提取第 n 个捕获组,默认为 0(整个匹配)
返回值:
返回单个字符串,提取第 n 个捕获组的内容。如果没有匹配返回 null。
示例:
// 提取错误码
L::logs:(regexp_extract(message, 'error_code: (\d+)', 1)) [1h] BY service
// 提取 IP 地址
L::nginx:(regexp_extract(message, '(\d+\.\d+\.\d+\.\d+)', 1)) [1h]
结果示例:
| service | regexp_extract(message, 'error_code: (\d+)', 1) |
|---|---|
| api | "404" |
| api | "500" |
| web | null |
regexp_extract_all¶
提取所有匹配的结果。
语法:
返回值:
返回字符串数组,包含所有匹配的子串。
示例:
// 提取所有数字
L::logs:(regexp_extract_all(message, '\d+', 0)) [1h]
// 提取所有 IP 地址
L::logs:(regexp_extract_all(message, '\d+\.\d+\.\d+\.\d+', 0)) [1h]
结果示例:
| message | regexp_extract_all(message, '\d+.\d+.\d+.\d+', 0) |
|---|---|
| Request from 192.168.1.1 to 10.0.0.1 | ["192.168.1.1", "10.0.0.1"] |
md5¶
计算 MD5 哈希值。
语法:
返回值:
返回 32 位十六进制字符串(小写)。
示例:
结果示例:
| service | md5(message) |
|---|---|
| api | 5d41402abc4b2a76b9719d911017c592 |
| web | 098f6bcd4621d373cade4e832627b4f6 |
concat¶
字符串连接。
语法:
返回值:
返回连接后的单个字符串。
示例:
结果示例:
| service | level | concat(service, ":", level) |
|---|---|---|
| api | error | "api:error" |
| web | info | "web:info" |
set¶
对数组字段去重并排序。
语法:
返回值:
返回去重并排序后的数组。
示例:
// 获取所有不同的标签
M::metrics:(set(tags)) [1h] BY metric_name
// 对 collect 的结果去重
M::http:(set(collect(status))) [1h] BY endpoint
结果示例:
| metric_name | set(tags) |
|---|---|
| cpu_usage | ["env:prod", "host:A", "team:backend"] |
| memory_used | ["env:staging", "host:B", "team:frontend"] |
日志聚类¶
drain¶
使用 Drain 算法对日志进行聚类,生成日志模板。
语法:
参数:
field: 字符串字段(通常是 message)similarity_threshold: 相似度阈值,范围 (0, 1],值越大聚类越严格max_clusters: 最大聚类数量,范围 [1, 10000]
算法说明:
Drain 是一种基于解析树的日志聚类算法,能够自动识别日志中的常量和变量部分,生成日志模板。
适用场景:
- 日志模式识别
- 异常日志聚类分析
- 日志降噪
示例:
// 对日志进行聚类,相似度 0.7,最多 1000 个聚类
L::logs:(drain(message, 0.7, 1000)) [1h] BY service
// 更严格的聚类
L::logs:(drain(message, 0.9, 500)) [1h] BY service
结果示例:
| service | drain(message, 0.7, 1000) |
|---|---|
| api | "Request from |
| db | "Query |
注意
返回字符串类型的日志模板,其中 <...> 表示变量部分。
匹配函数¶
匹配函数用于在 WHERE 子句中进行文本匹配,也可以作为返回布尔值的表达式使用。
子串匹配¶
match¶
检查字段是否包含指定子串。
语法:
参数:
pattern: 要匹配的子串field: 字段名(可选,在 WHERE 子句中可省略)
示例:
// 在 WHERE 中使用
L::logs:(message) {match(message, "error")} [1h]
// 简写形式
L::logs:(message) {match("error")} [1h]
// 作为表达式
L::logs:(match(message, "timeout")) [1h] BY match_result
短语匹配¶
phrase / search¶
分词短语匹配,支持中英文混合。
语法:
参数:
query: 查询短语field: 字段名(可选)
匹配规则:
- 中文:按字符分词匹配
- 英文:按词边界匹配(空格、标点分隔)
- 大小写不敏感
示例:
// 匹配包含 "connection timeout" 的日志
L::logs:(message) {phrase("connection timeout")} [1h]
// 中文匹配
L::logs:(message) {phrase("连接超时")} [1h]
// 中英文混合
L::logs:(message) {search("error 错误")} [1h]
正则匹配¶
re / regex / regexp¶
正则表达式匹配。
语法:
re(pattern)
re(field, pattern)
regex(pattern)
regex(field, pattern)
regexp(pattern)
regexp(field, pattern)
参数:
pattern: 正则表达式(支持 PromRegex 语法)field: 字段名(可选)
示例:
// 匹配以 error 开头的日志
L::logs:(message) {re("error.*")} [1h]
// 匹配特定格式的错误码
L::logs:(message) {regexp(message, "ERR-\d{4}")} [1h]
// 在数据源中使用正则
M::re('cpu.*'):(usage) [1h]
通配符匹配¶
wildcard¶
通配符模式匹配。
语法:
参数:
-
pattern: 通配符模式*: 匹配任意多个字符?: 匹配单个字符
-
field: 字段名(可选)
示例:
// 匹配以 error 开头的消息
L::logs:(message) {wildcard("error*")} [1h]
// 匹配特定格式
L::logs:(message) {wildcard(message, "ERR-????")} [1h]
CIDR 匹配¶
cidr¶
IP 地址网段匹配。
语法:
参数:
cidr: CIDR 表示的网段,如192.168.1.0/24field: IP 地址字段(可选)
示例:
// 匹配内网 IP
L::nginx:(*) {cidr(client_ip, "10.0.0.0/8")} [1h]
// 匹配特定网段
L::nginx:(*) {cidr(client_ip, "192.168.1.0/24")} [1h]
字段存在检查¶
exists¶
检查字段是否存在。
语法:
示例:
查询字符串语法¶
query_string¶
使用查询字符串语法进行复杂匹配。
语法:
参数:
query: 查询字符串field: 字段名(可选,默认匹配全文)
查询字符串语法:
1. 词项匹配¶
2. 通配符¶
3. 正则表达式¶
4. 布尔操作符¶
foo AND bar # 逻辑与,两者都必须包含
foo OR bar # 逻辑或,至少包含一个
NOT foo # 逻辑非,不包含 foo
# 简写形式
foo && bar # 等价于 foo AND bar
foo || bar # 等价于 foo OR bar
!foo # 等价于 NOT foo
5. 分组¶
6. 默认操作符¶
当空格分隔多个词项时,默认使用 OR 连接(可配置为 AND):
示例:
// 简单词项匹配
L::logs:(message) {query_string("error timeout")} [1h]
// 布尔组合
L::logs:(message) {query_string("error AND NOT timeout")} [1h]
// 正则表达式
L::logs:(message) {query_string("/ERR-\d{4}/")} [1h]
// 复杂查询
L::logs:(message) {query_string("(error OR warn) AND service")} [1h]
// 指定字段
L::logs:(*) {query_string(message, "error AND timeout")} [1h]
// 中文查询
L::logs:(message) {query_string("错误 AND 超时")} [1h]
外层函数¶
使用建议
外层函数是遗留设计。能用 Rollup + 聚合函数(如 [rate]、[last]、[increase] 等)解决的场景,优先使用 Rollup 方式。外层函数仅在不适用 Rollup 的场景下使用(如需要对聚合结果进行二次计算)。
外层函数作用于整个 DQL 查询结果之上,用于对查询输出的时间序列数据进行二次计算。外层函数包裹整个 DQL 表达式,而不是写在 Select 子句内部。
查询内函数与外层函数¶
- 查询内函数:在 DQL 表达式内部使用,如
sum、avg、max等 - 外层函数:包裹整个 DQL 查询结果,对输出的时间序列进行后处理
写法对比:
// Rollup(时间子句):先对每条时间线做增长率,再聚合
M::http_requests:(sum(request_count)) [rate] BY service
// 外层函数:先得到查询结果,再做二次计算
rate(M::http_requests:(sum(request_count)) [1h::1m] BY service)
语法:
示例:
// 查询内函数:对原始数据求平均
M::cpu:(avg(usage)) [1h::5m] BY host
// 外层函数:对查询结果计算移动平均
moving_average(M::cpu:(avg(usage)) [1h::5m] BY host, 5)
累积计算¶
cumsum¶
计算累积和,对时间序列的每个点计算前面所有点的累加值。
语法:
示例:
差值与导数¶
推荐使用
这些函数优先作为 Rollup 函数使用(如 [rate]、[deriv]),外层函数形式仅用于对聚合结果进行二次计算。
以下函数可作为外层函数使用:
| 函数 | 说明 |
|---|---|
derivative(DQL) |
计算导数(变化率) |
difference(DQL) |
计算与前一个值的差 |
non_negative_derivative(DQL) |
计算非负导数 |
non_negative_difference(DQL) |
计算非负差值 |
rate(DQL) |
计算增长率(每秒) |
irate(DQL) |
计算瞬时增长率 |
示例:
// 外层函数:对查询结果计算导数
derivative(M::cpu:(avg(usage)) [1h::5m] BY host)
// 推荐:使用 Rollup 方式
M::cpu:(deriv(usage)) [1h::5m:last] BY host
移动计算¶
moving_average¶
对查询结果计算移动平均。
推荐使用
优先使用 Rollup 方式 moving_average(field, n),外层函数形式仅用于对聚合结果进行二次平滑。
语法:
参数:
DQL_expression: DQL 查询表达式n: 窗口大小(数据点数量)
示例:
// 外层函数:对查询结果计算移动平均
moving_average(M::cpu:(avg(usage)) [1h::1m] BY host, 5)
// 推荐:使用 Rollup 方式
M::cpu:(moving_average(usage, 5)) [1h::1m] BY host
TopN¶
top / bottom¶
推荐使用
优先使用 Rollup 方式 top(field, n) 或 bottom(field, n),外层函数形式仅用于对聚合结果进行二次筛选。
对查询结果获取 TopN 或 BottomN。
语法:
示例:
// 外层函数:对查询结果获取 TopN
top(M::response_time:(max(duration)) [1h::5m] BY service, 5)
// 推荐:使用 Rollup 方式
M::response_time:(top(duration, 5)) [1h::5m] BY service
空值填充¶
fill¶
对查询结果中的空值进行填充。
详细说明请参考 fill 函数。
示例:
// 用 0 填充空值
fill(M::cpu:(avg(usage)) [1h::5m] BY host, 0)
// 线性插值填充
fill(M::cpu:(avg(usage)) [1h::5m] BY host, LINEAR)
其他外层函数¶
以下函数同样可作为外层函数使用:
| 函数 | 说明 |
|---|---|
abs(DQL) |
取绝对值 |
round(DQL) |
四舍五入 |
ceil(DQL) |
向上取整 |
floor(DQL) |
向下取整 |
log(DQL) / log2(DQL) / log10(DQL) |
对数变换 |
set(DQL) |
去重并排序 |
concat(DQL, ...) |
字符串连接 |
组合使用¶
外层函数可以组合使用:
// 计算移动平均后四舍五入
round(moving_average(M::cpu:(avg(usage)) [1h::1m] BY host, 5))
// 计算增长率的移动平均
moving_average(rate(M::requests:(sum(count)) [1h::5m] BY service), 3)
eval 表达式计算¶
eval 是一个特殊的函数,允许在查询外部进行表达式计算,可以引用多个子查询的结果进行组合运算。
语法¶
参数:
expression: 数学表达式,使用name.field引用子查询结果name=query: 命名的子查询alias: 结果别名(可选)
工作原理¶
- 执行所有命名的子查询
- 按时间对齐各个子查询的结果
- 对每个时间点计算表达式
- 返回计算结果
适用场景¶
- 计算多个指标的比率(如错误率、利用率)
- 对比不同时间段的指标
- 组合多个数据源的计算结果
示例¶
计算错误率¶
// 计算错误率 = 错误数 / 总请求数 * 100
eval(a / b * 100,
a=M::http:(sum(error_count)) [1h] BY service,
b=M::http:(sum(request_count)) [1h] BY service,
alias="error_rate")
计算 CPU 使用率¶
// 使用率 = used / total * 100
eval(used / total * 100,
used=M::memory:(sum(used_bytes)) [1h] BY host,
total=M::memory:(sum(total_bytes)) [1h] BY host,
alias="memory_usage_percent")
计算同比增长¶
// 计算本周与上周的对比
eval(this_week / last_week - 1,
this_week=M::sales:(sum(amount)) [7d],
last_week=M::sales:(sum(amount)) [7d offset 7d],
alias="week_over_week_growth")
引用子查询的字段¶
// 引用子查询的特定字段
eval(a.usage / b.total * 100,
a=M::cpu:(avg(usage)) [1h] BY host,
b=M::cpu:(avg(total)) [1h] BY host,
alias="cpu_percent")
注意事项¶
- 所有子查询的时间窗口必须兼容
- 子查询的分组维度应当一致
- 表达式中引用的字段名使用
name.field格式 - 如果只有一个子查询,可以直接使用字段名
其他函数¶
fill¶
为查询结果中的空值填充指定值。
推荐使用
fill 建议作为外层函数使用,作用于整个查询结果之上:
虽然在 Select 子句中也支持 fill(avg(usage), 0) 的写法,但 fill 实际是在聚合完成后对结果进行填充,因此外层函数形式更符合其工作机制。
语法(外层函数):
参数:
DQL_expression: DQL 查询表达式value: 填充值,支持多种模式:- 具体值:数值、字符串、null
LINEAR:线性插值PREVIOUS:填充前一个非空值
示例:
// 推荐:作为外层函数使用
fill(M::cpu:(avg(usage)) [1h::5m] BY host, 0)
// 线性插值填充
fill(M::cpu:(avg(usage)) [1h::5m] BY host, LINEAR)
// 用前一个值填充
fill(M::cpu:(avg(usage)) [1h::5m] BY host, PREVIOUS)
now¶
返回当前时间戳(毫秒)。
语法:
示例:
unwrap¶
展开聚合结果的包装。
语法:
示例:
Show 函数¶
Show 函数用于查看元数据(如 measurement、tag、field、基数与系列计数),常用于建模排查与查询前探查。
通用语法¶
-
where、time_window、LIMIT、OFFSET都是可选项; -
LIMIT/OFFSET不能为负数。
M 命名空间内置 Show 函数¶
| 函数 | 参数 | 返回列 | 说明 |
|---|---|---|---|
show_measurement |
可选 re('pattern') |
name |
列出 measurement |
show_tag_key |
可选 from=['measurement'] |
tagKey |
列出 tag key |
show_field_key |
可选 from=['measurement'] |
fieldKey, fieldType |
列出 field key(当前 fieldType 为 float) |
show_tag_value |
keyin=['tagKey'](必填),可选 from |
key, value |
列出 tag value |
show_measurement_cardinality |
无强制参数 | count |
measurement 数量 |
show_series_cardinality |
无强制参数 | count |
series 基数(估算) |
show_tag_key_cardinality |
无强制参数 | count |
tag key 基数(估算) |
show_tag_value_cardinality |
keyin=['tagKey'](必填) |
count |
指定 tag key 的 value 基数(估算) |
show_field_key_cardinality |
无强制参数 | count |
field key 基数(估算) |
show_series_count_by_field_key |
from=['measurement'](建议) |
name, count |
按 field key 统计 series 数 |
show_series_count_by_tag_key |
from=['measurement'](建议) |
name, count, value_count |
按 tag key 统计 series 数与 value 数 |
show_series_count_by_tag_value |
keyin=['tagKey'](必填),from=['measurement'](建议) |
name, count |
按指定 tag key 的 value 统计 series 数 |
基数(cardinality)相关函数底层使用 HyperLogLog 合并,返回值为估算值。
非 M 命名空间 Show 函数(后缀模式)¶
对于非 M 命名空间,支持以下后缀模式:
show_<namespace>_sourceshow_<namespace>_classshow_<namespace>_typeshow_<namespace>_fieldshow_<namespace>_label
其中 <namespace> 由函数名中间段自动映射得到,例如:
show_logging_source->Lshow_tracing_field->Tshow_object_source->O
常见示例:
show_logging_source()
show_tracing_field('mysql')
show_logging_field('*')
show_logging_label(name='env')
show_logging_label(names=['env', 'team'])
参数与行为说明¶
from:measurement 列表,支持字符串或字符串数组;keyin:tag key 列表,支持字符串或字符串数组;field:field 列表,支持字符串或字符串数组(用于 metric show 的 field 过滤);-
对于
show_*_field:- 无名参数(如
'mysql')通常作为 source 过滤 '*'等价于不指定 source- 命名参数会被转成 where 过滤条件
- 无名参数(如
-
对于
show_*_label:- 需要命名参数;
names会被视作name的别名处理。
- 需要命名参数;
约束与注意事项¶
show_tag_value与show_tag_value_cardinality必须提供keyin;show_series_count_by_tag_value必须提供keyin;show_series_count_by_*必须提供from,或在 where 中提供等价的 source 约束(例如@__source__条件);show_<namespace>_source、show_<namespace>_class、show_<namespace>_type当前共享同一条执行路径,返回 source 去重列表;- 目前 parser 不支持
show_<namespace>_index语法(即使执行层存在对应分支); - 在 Query API 未提供 show 时间范围时,部分日志 show 查询会回落到最近 30 分钟窗口执行。
返回示例¶
以下示例仅展示典型列结构与示例行,实际结果会受租户数据、过滤条件、时间范围和 LIMIT/OFFSET 影响。
| 查询 | 典型列 | 示例行(示意) |
|---|---|---|
show_measurement() |
name |
cpu、disk、memory |
show_tag_value(from=['cpu'], keyin=['host']) |
key, value |
host, web-01;host, web-02 |
show_series_count_by_tag_key(from=['cpu']) |
name, count, value_count |
host, 3200, 120;service, 2800, 35 |
show_tag_value_cardinality(keyin=['host']) |
count |
120 |
show_logging_field('*') |
fieldKey, fieldType, fieldIndices |
service, keyword, ["idx_service"] |
show_logging_source() |
source |
nginx、mysql、redis |
函数分类速查表¶
基础聚合¶
| 函数 | 说明 | 精确/估算 |
|---|---|---|
| sum | 求和 | 精确 |
| avg | 平均值 | 精确 |
| count | 计数 | 精确 |
| count_distinct | 去重计数 | 估算 (HyperLogLog, 误差≈0.4%) |
| min / max | 最小/最大值 | 精确 |
| first / last | 首个/最后一个值 | 精确 |
| any | 任意一个值 | 精确 |
统计聚合¶
| 函数 | 说明 | 精确/估算 |
|---|---|---|
| percentile / pXX | 百分位数 | 估算 (对数直方图) |
| median | 中位数 | 估算 |
| stddev | 标准差 | 精确 |
| mode | 众数 | 精确 |
| spread | 极差 | 精确 |
| count_series | 时间序列数 | 精确 |
筛选聚合¶
| 函数 | 说明 | 精确/估算 |
|---|---|---|
| top / bottom | TopN / BottomN | 精确 |
| count_filter | 条件计数 | 精确 |
直方图函数¶
| 函数 | 说明 | 适用数据源 | 精确/估算 |
|---|---|---|---|
| histogram_auto | 自动直方图(推荐) | 日志、Trace 明细数据 | 估算 |
| histogram | 固定桶边界直方图(已过时) | 日志、Trace 明细数据 | 精确 |
| histogram_quantile | 从 Prometheus 直方图计算分位数 | Prometheus 指标 | 估算 |
集合函数¶
| 函数 | 说明 | 精确/估算 |
|---|---|---|
| distinct | 去重值列表 | 精确 |
| distinct_by_collapse | 折叠去重(保留其他字段) | 精确 |
| collect | 收集所有值 | 精确 |
| collect_distinct | 收集去重值 | 精确 |
辅助函数¶
| 函数 | 说明 | 精确/估算 |
|---|---|---|
| default | 设置默认值 | 精确 |
时间序列函数¶
| 函数 | 说明 |
|---|---|
| rate | 增长率(每秒) |
| irate | 瞬时增长率 |
| increase | 增长量 |
| derivative | 导数 |
| difference | 差值 |
| non_negative_derivative | 非负导数 |
| non_negative_difference | 非负差值 |
| moving_average | 移动平均 |
| cumsum | 累积和 |
Rollup 函数¶
| 函数 | 说明 |
|---|---|
rate |
计算增长率(每秒) |
irate |
计算瞬时增长率 |
increase |
计算增长量 |
rate_over_sum |
计算每秒平均值 |
rate_over_count |
计算每秒计数 |
deriv |
计算导数(derivative) |
difference |
计算差值(difference) |
sum |
求和 |
avg |
平均值 |
min |
最小值 |
max |
最大值 |
count |
计数 |
first |
第一个值 |
last |
最后一个值 |
stddev |
标准差 |
mode |
众数 |
spread |
极差 |
any |
任意一个值 |
转换函数¶
| 函数 | 说明 |
|---|---|
| abs | 绝对值 |
| round / ceil / floor | 取整 |
| log / log2 / log10 | 对数 |
| int / uint / float / string / bool | 类型转换 |
| substr | 子字符串 |
| regexp_extract | 正则提取 |
| regexp_extract_all | 正则提取全部 |
| md5 | MD5 哈希 |
| concat | 字符串连接 |
| set | 数组去重排序 |
| drain | 日志聚类 |
匹配函数¶
| 函数 | 说明 |
|---|---|
| match | 子串匹配 |
| phrase / search | 分词短语匹配 |
| re / regex / regexp | 正则匹配 |
| wildcard | 通配符匹配 |
| cidr | CIDR 网段匹配 |
| query_string | 查询字符串语法 |
| exists | 字段存在检查 |
外层函数(优先使用 Rollup)¶
| 函数 | 说明 |
|---|---|
| cumsum | 累积和 |
| rate / irate | 增长率(非负) |
| deriv | 导数(允许负值) |
| increase | 增长量(非负) |
| difference | 差值(允许负值) |
| moving_average | 移动平均 |
| top / bottom | TopN |
| fill | 空值填充(推荐外层使用) |
| abs / round / ceil / floor | 数学运算 |
| set | 去重排序 |
| concat | 字符串连接 |
表达式计算¶
| 函数 | 说明 |
|---|---|
| eval | 多查询表达式计算 |