HTTP API
当前稳定的 HTTP API 可在 Prometheus 服务器上的 /api/v1 下访问。任何不间断的添加都将添加到该端点下。
API 响应格式为 JSON。每个成功的 API 请求都会返回一个 2xx 状态代码。
Grafana 查询报错
比如,想在Grafana绘制折线图(Graph),因为需要很多时间点的值,似乎应该使用时间范围查询或者说是区间查询,因为指标查询(瞬时查询)只能查询当前的最新值,让我们试一试:
红色感叹号的内容为:
“invalid expression type “range vector” for range query, must be Scalar or instant Vector”。
意思是: 非法的表达式类型,区间向量用于区间查询,必须是标量(常数)或者瞬时向量。
这是因为在Grafana查询需要调用 prometheus 的 http api,所以首先了解 prometheus 的 http api 是什么?
query
通过使用如下API我们可以查询PromQL表达式在指定时间点下的计算结果。
1 | GET /api/v1/query |
URL 请求参数:
query=
:PromQL 表达式。time=
:指定时间戳。可选参数,默认情况下使用Prometheus当前系统时间。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37# curl -s 'http://192.168.55.11:9090/api/v1/query?query=node_cpu_seconds_total\{instance="192.168.55.12",mode="idle"\}&time=2021-10-11T08:30:33.781Z' |jq
{
"status": "success",
"data": {
"resultType": "vector",
"result": [
{
"metric": {
"__name__": "node_cpu_seconds_total",
"cpu": "0",
"instance": "192.168.55.12",
"job": "Host",
"mode": "idle",
"region": "dg2"
},
"value": [
1633941033.781,
"2498261.78"
]
},
{
"metric": {
"__name__": "node_cpu_seconds_total",
"cpu": "1",
"instance": "192.168.55.12",
"job": "Host",
"mode": "idle",
"region": "dg2"
},
"value": [
1633941033.781,
"2502205.33"
]
}
]
}
}
响应数据类型
当API调用成功后,Prometheus会返回 JSON 格式的响应内容,格式下所示。并且在data节点中返回查询结果。
1 | { |
PromQL 表达式可能返回多种数据类型,在响应内容中使用 resultType
表示当前返回的数据类型,包括:
瞬时向量:vector,当返回数据类型 resultType 为 vector 时,result 响应格式如下:
1
2
3
4
5
6
7[
{
"metric": { "<label_name>": "<label_value>", ... },
"value": [ <unix_time>, "<sample_value>" ]
},
...
]其中 metrics 表示当前时间序列的特征维度,value 只包含一个唯一的样本。
区间向量:matrix,当返回数据类型resultType为matrix时,result响应格式如下:
1
2
3
4
5
6
7[
{
"metric": { "<label_name>": "<label_value>", ... },
"values": [ [ <unix_time>, "<sample_value>" ], ... ]
},
...
]其中 metrics 表示当前时间序列的特征维度,values包含当前事件序列的一组样本,例如:
1 | # curl -g -s 'http://192.168.55.11:9090/api/v1/query?query=node_cpu_seconds_total{instance="192.168.55.12",mode="idle"}[5m]&time=2021-10-11T08:30:33.781Z' |jq |
query_range
使用如下 API,我们可以查询 PromQL 表达式在一段时间内的数据。
1 | GET /api/v1/query_range |
URL 请求参数:
query=
: PromQL表达式。start=
: 起始时间end=:
结束时间step=
: 查询步长
返回结果一定是一个区间向量:
1 | { |
比如:
1 | $ curl -s 'http://192.168.55.11:9090/api/v1/query_range?query=node_cpu_seconds_total\{instance="192.168.55.12",mode="idle"\}&start=2021-10-11T08:20:33.781Z&end=2021-10-11T08:30:33.781Z&step=2m'|jq |
需要注意的是,只能使用瞬时向量类型的表达式。这是因为区间数据查询实现,首先根据时间范围和步长计算时间点集合,然后查询距离每个时间点最近的值作为该时间点的值。而如果使用区间向量表达式,那么每个时间点计算结果将是一个区间,而目标查询结果也是区间,并且两个区间的含义不相同,所以无法融合在一块。
Grafana 报错原因
Grafana默认调用的 api 是query_range api,可通过【Query Inspector】按钮展开查询请求和结果,如下图:
所以 Grafana 中不能直接使用区间向量查询,而应该使用瞬时向量,然后调用区间数据查询API来查询指定时间范围的值(时间范围是Grafana 面板右上角选择的时间范围,步长默认15秒,可通过 Min step
设置)。Graph通过查询结果中的各个时间点的值绘制成线。
可以通过开启 Instant
开关,使 Grafana 调用瞬时数据查询API,例如
此时查看【Query Inspector】,可以看到 api 改成了query,并且 prometheus 返回了5个时间点的值,此时Graph不会连接成线。
区间向量的应用
前面说到通过瞬时向量查询 + query_rang API 可以查询到指定时间范围的值,那么区间向量查询似乎没啥用了?
区间向量可用于计算某个时间点的附近的状态,通过内置函数可以将区间向量转成瞬时向量,就能用在Graph图中了;
- 比如返回时间范围内中每个时间点的过去1分钟内 HTTP 请求数:
1 | increase(http_requests_total[1m]) |