跳到主要内容
版本:Nightly

Prometheus Query Language

GreptimeDB 提供基于 Rust 的 PromQL 实现,可通过 Prometheus HTTP API、GreptimeDB HTTP API 和 SQL 接口查询。Grafana 可通过 Prometheus 数据源连接 GreptimeDB。支持范围与已知差异见局限。

Prometheus 的 HTTP API​

GreptimeDB 实现了兼容 Prometheus 的一系列 API,通过 /v1/prometheus 路径对外提 供服务:

  • Instant queries /api/v1/query
  • Range queries /api/v1/query_range
  • Series /api/v1/series
  • Label names /api/v1/labels
  • Label values /api/v1/label/<label_name>/values

这些接口使用 Prometheus HTTP API 的请求和响应格式。在 Grafana 中,将 http://localhost:4000/v1/prometheus/ 设置为 Prometheus 数据源地址。

访问 Prometheus 文档 获得更详细的说明。

你可以通过设置 HTTP 请求的 db 参数来指定 GreptimeDB 中的数据库名。

例如,以下查询将返回 public 数据库中 process_cpu_seconds_total 指标的 CPU 使用率:

curl -X POST \
-H 'Authorization: Basic <base64-encoded-credentials>' \
--data-urlencode 'query=irate(process_cpu_seconds_total[1h])' \
--data-urlencode 'start=2024-11-24T00:00:00Z' \
--data-urlencode 'end=2024-11-25T00:00:00Z' \
--data-urlencode 'step=1h' \
'http://localhost:4000/v1/prometheus/api/v1/query_range?db=public'

如果你使用启用了身份验证的 GreptimeDB,则需要 Authorization header,请参阅鉴权。 该 API 的查询字符串参数与原始 Prometheus API 的查询字符串参数相同。 你需要在 HTTP 的 query param 设置 db 参数,或者通过 --header 'x-greptime-db-name: <database name>' 设置在 HTTP 请求头中。

输出格式与 Prometheus API 完全兼容:

{
"status": "success",
"data": {
"resultType": "matrix",
"result": [
{
"metric": {
"job": "node",
"instance": "node_exporter:9100",
"__name__": "process_cpu_seconds_total"
},
"values": [
[
1732618800,
"0.0022222222222222734"
],
[
1732622400,
"0.0009999999999999788"
],
[
1732626000,
"0.0029999999999997585"
],
[
1732629600,
"0.002222222222222175"
]
]
}
]
}
}

SQL​

GreptimeDB 还扩展了 SQL 语法以支持 PromQL。可以用 TQL(Time-series Query Language)为关键字开始写入参数和进行查询。该语法如下:

TQL [EVAL|EVALUATE] (<START>, <END>, <STEP>) <QUERY>

<START> 指定查询开始时间范围,<END> 指定查询结束时间。 <STEP> 识别查询步幅。它们均可为无引号数字(表示<START>和<END>的 UNIX 时间戳,以及<STEP>的秒数持续时间),或带引号的字符串(表示<START>和<END>的 RFC3339 时间戳,以及<STEP>的字符串格式的持续时间)。

例如:

TQL EVAL (1676738180, 1676738780, '10s') sum(some_metric)

你可以在所有支持 SQL 的地方编写上述命令,包括 GreptimeDB HTTP API、SDK、PostgreSQL 和 MySQL 客户端等。

GreptimeDB 的扩展​

指定数值列​

基于表模型,GreptimeDB 支持在单个表(或在 Prometheus 中称为指标)中查询多个字段。默认情况下,查询将应用于每个值字段 (field)。或者也可以使用特殊的过滤器 __field__ 来查询特定的字段:

metric{__field__="field1"}

反选或正则表达式也都支持

metric{__field__!="field1"}

metric{__field__=~"field_1|field_2"}

metric{__field__!~"field_1|field_2"}

指定数据库​

不同于 Prometheus,GreptimeDB 包含数据库概念。如果要进行跨数据库的 PromQL 查询, 可以使用 __database__ 来指定数据库名称。

metric{__database__="mydatabase"}

注意 __database__ 仅支持 = 匹配。

局限​

PromQL 查询支持浮点样本和原生直方图样本。浮点指标使用时间戳列、字符串标签和 Double 值。原生直方图的支持范围和写入要求见原生直方图。

v1.3.0 兼容性测试结果​

v1.3.0 发布测试使用 promql-compat 1203cd8,以 Prometheus v3.15.0 为参考。这些结果对应 v1.3.0,不代表 Nightly 构建的测试结果。

测试集计入统计的用例排除的用例比较 __name__仅忽略 __name__ 差异
Prometheus 测试用例集852139153.52% (456/852)88.50% (754/852)
Prometheus compliance 查询集539054.17% (292/539)94.81% (511/539)
随机生成的查询(seed 1)1999163.83% (1276/1999)93.35% (1866/1999)

百分比为测试用例通过率,排除项不计入分母;最后一列仅忽略 __name__ 差异。测试方法见 promql-compat README。

v1.3.0 已知差异​

查询行为示例与 Prometheus 的差异
函数和聚合结果中的指标名称rate(x[1m])、abs(x)、sum(rate(x[1m]))、sum(x > 0)函数结果保留 __name__,对其进行不带分组的聚合时也可能保留,影响 Grafana 图例及告警和 recording rule 的标签。v1.3 不带 bool 的过滤比较还可能重新附加已移除的指标名。
带参数的日期函数year(vector(1136239445))使用样本时间戳,而不是样本值。影响 year、month、day_of_month、day_of_week、day_of_year、days_in_month、hour 和 minute。
不带指标名的选择器{job="demo"}返回 Expect a metric matcher, but not found。必须指定指标名或显式的 __name__ 匹配器。
vector(time())vector(time())瞬时查询和范围查询均返回 Invalid function argument for unknown,单独调用也会失败。
absent_over_timeabsent_over_time(nonexistent_metric[5m])部分查询返回的序列与 Prometheus 不同,既可能缺少预期序列,也可能多返回序列。此例不返回序列,Prometheus 会返回值为 1 的序列。
动态 scalar 参数topk(scalar(foo), x)、quantile_over_time(scalar(foo), x[5m])将 scalar() 用作参数时,部分查询无法生成执行计划。
first_over_timefirst_over_time(x[5m])返回 Unsupported expr type,尚未实现。
校验差异scalar_metric > on() dup_metric、clamp(x, 10, 1)重复标签集和重复匹配可能返回结果,而 Prometheus 会报错;clamp 上下界写反时返回错误,而 Prometheus 返回空结果;label_replace 拒绝 Prometheus 3 接受的 UTF-8 目标标签名。

字面量​

支持字符串和浮点数,与 PromQL 的规则相同。

选择器​

Instant 选择器和 Range 选择器均已支持。选择器必须指定指标名或显式的 __name__ 匹配器;只有普通标签的选择器(如 {job="demo"})会报错。指标名称匹配有以下限制:

  • 在 TQL 中只支持等值匹配,例如 {__name__="request_count"}。
  • Prometheus HTTP API 还支持正则匹配和反向匹配,例如 {__name__=~"request_.*"} 或 {__name__!="request_count", host="h1"}。这些匹配只作用于 metric engine 创建的表,例如通过 Prometheus Remote Write 写入的表。

时间区间、时间偏移修饰符和 @ 修饰符(包括 @ start() 和 @ end())均已支持。

子查询支持显式步长;省略步长时使用固定的 1 分钟,与外层查询步长无关。需要其他步长时使用 [range:step]。瞬时查询可返回 range vector;范围查询不接受 range-vector 根表达式。

当选择不存在的列时,它们将被视为一个所有值都为 "" 的列。该行为与 Prometheus 和 VictoriaMetrics 一致。

时间精度​

PromQL 的求值时刻和步长使用毫秒精度。样本选择保留存储的微秒或纳秒时间戳;timestamp() 将选中样本的时间戳转换到毫秒,再以秒为单位返回浮点数。

Binary​

  • 支持:
    Operator
    +
    -
    *
    /
    %
    ==
    !=
    >
    <
    >=
    <=
    ^
    atan2
    and
    or
    unless

支持 on、ignoring、group_left 和 group_right 向量匹配修饰符。部分重复匹配和重复标签集未被拒绝,示例见 v1.3.0 已知差异。

Aggregators​

  • 支持:
    AggregatorExample
    groupgroup by (foo)(metric)
    sumsum by (foo)(metric)
    avgavg by (foo)(metric)
    minmin by (foo)(metric)
    maxmax by (foo)(metric)
    stddevstddev by (foo)(metric)
    stdvarstdvar by (foo)(metric)
    topktopk(3, rate(instance_cpu_time_ns[5m]))
    bottomkbottomk(3, rate(instance_cpu_time_ns[5m]))
    count_valuescount_values("version", build_version)
    countcount (metric)
    quantilequantile(0.9, cpu_usage)

Instant Functions​

以下列表包含已实现的函数;行为差异和参数限制见 v1.3.0 已知差异。histogram_count、histogram_sum、histogram_avg、histogram_stddev 和 histogram_stdvar 用于原生直方图样本。

  • 支持:
    FunctionExample
    roundround(metric)
    vectorvector(1)
    timetime()
    yearyear()
    monthmonth()
    day_of_monthday_of_month()
    day_of_weekday_of_week()
    day_of_yearday_of_year()
    days_in_monthdays_in_month()
    hourhour()
    minuteminute()
    absabs(metric)
    ceilceil(metric)
    expexp(metric)
    lnln(metric)
    log2log2(metric)
    log10log10(metric)
    sqrtsqrt(metric)
    acosacos(metric)
    asinasin(metric)
    atanatan(metric)
    sinsin(metric)
    coscos(metric)
    tantan(metric)
    acoshacosh(metric)
    asinhasinh(metric)
    atanhatanh(metric)
    sinhsinh(metric)
    coshcosh(metric)
    scalarscalar(metric)
    tanhtanh(metric)
    timestamptimestamp(metric)
    sortsort(http_requests_total)
    sort_descsort_desc(http_requests_total)
    histogram_fractionhistogram_fraction(0, 1, request_duration)
    histogram_counthistogram_count(request_duration)
    histogram_sumhistogram_sum(request_duration)
    histogram_avghistogram_avg(request_duration)
    histogram_stddevhistogram_stddev(request_duration)
    histogram_stdvarhistogram_stdvar(request_duration)
    histogram_quantilehistogram_quantile(phi, metric)
    predict_linearpredict_linear(metric[5m], 120)
    absentabsent(nonexistent{job="myjob"})
    sgnsgn(metric)
    pipi()
    degdeg(metric)
    radrad(metric)
    floorfloor(metric)
    clampclamp(metric, 0, 12)
    clamp_maxclamp_max(metric, 12)
    clamp_minclamp_min(metric, 0)

Range Functions​

absent_over_time 的行为差异和未实现的 first_over_time 见 v1.3.0 已知差异。

  • 支持:
    FunctionExample
    ideltaidelta(metric[5m])
    avg_over_timeavg_over_time(metric[5m])
    min_over_timemin_over_time(metric[5m])
    max_over_timemax_over_time(metric[5m])
    sum_over_timesum_over_time(metric[5m])
    count_over_timecount_over_time(metric[5m])
    last_over_timelast_over_time(metric[5m])
    present_over_timepresent_over_time(metric[5m])
    quantile_over_timequantile_over_time(0.9, metric[5m])
    stddev_over_timestddev_over_time(metric[5m])
    stdvar_over_timestdvar_over_time(metric[5m])
    changeschanges(metric[5m])
    deltadelta(metric[5m])
    raterate(metric[5m])
    derivderiv(metric[5m])
    increaseincrease(metric[5m])
    irateirate(metric[5m])
    resetsresets(metric[5m])

Label 及其他函数​

  • 支持:
    FunctionExample
    label_joinlabel_join(up{job="api-server",src1="a",src2="b",src3="c"}, "foo", ",", "src1", "src2", "src3")
    label_replacelabel_replace(up{job="api-server",service="a:c"}, "foo", "$1", "service", "(.*):.*")
    sort_by_labelsort_by_label(metric, "foo", "bar")
    sort_by_label_descsort_by_label_desc(metric, "foo", "bar")