Prometheus API 使用了 JSON 格式的響應内容。 當 API 調用成功後将會傳回查詢結果。所有的 API 請求均使用以下的 JSON 格式:
{
"status": "success" | "error",
"data": <data>,
// Only set if status is "error". The data field may still hold
// additional data.
"errorType": "<string>",
"error": "<string>"
}
我們可以通過如下的 get 請求向普羅米修斯發送查詢請求:
http://promurl:port/api/v1/query?query=kube_pod_container_info&time=1636457100
- api 路徑都是/api/v1/query
- 有兩種查詢類型, 這裡面我們用的查詢類型就是 query 類型(還有另一個叫 query_range)
- 在路徑和查詢類型後跟着的就是 PromQL 語句了。
- 最後的 time 是時間戳, 代表着查詢的時間基線。 就是我們的 PromQL 是以哪個時間點為基準查詢的。 我們說過普羅米修斯本身就是一個時序資料庫。它預設儲存 14 天的資料, 超過 14 天就會自動删除。 是以這個時間戳可以讓我們以過去某個時間點為基礎進行查詢。如果在 UI 上查詢的話,隻能以目前時間為基線進行查詢。
下面貼一個例子看一下我們查詢的 json 結果是什麼樣子的:
$ curl 'http://localhost:9090/api/v1/query?query=up&time=2015-07-01T20:10:51.781Z'
{
"status" : "success",
"data" : {
"resultType" : "vector",
"result" : [
{
"metric" : {
"__name__" : "up",
"job" : "prometheus",
"instance" : "localhost:9090"
},
"value": [ 1435781451.781, "1" ]
},
{
"metric" : {
"__name__" : "up",
"job" : "node",
"instance" : "localhost:9100"
},
"value" : [ 1435781451.781, "0" ]
}
]
}
}
響應資料類型
當 API 調用成功後,Prometheus 會傳回 JSON 格式的響應内容,格式如上小節所示。并且在 data 節點中傳回查詢結果。data 節點格式如下:
{
"resultType": "matrix" | "vector" | "scalar" | "string",
"result": <value>
}
PromQL 表達式可能傳回多種資料類型,在響應内容中使用 resultType 表示目前傳回的資料類型,包括:
- 瞬時向量:vector
當傳回資料類型 resultType 為 vector 時,result 響應格式如下:
[
{
"metric": { "<label_name>": "<label_value>", ... },
"value": [ <unix_time>, "<sample_value>" ]
},
...
]
其中 metrics 表示目前時間序列的特征次元,value 隻包含一個唯一的樣本。
- 區間向量:matrix
當傳回資料類型 resultType 為 matrix 時,result 響應格式如下:
[
{
"metric": { "<label_name>": "<label_value>", ... },
"values": [ [ <unix_time>, "<sample_value>" ], ... ]
},
...
]
其中 metrics 表示目前時間序列的特征次元,values 包含目前事件序列的一組樣本。
- 标量:scalar
當傳回資料類型 resultType 為 scalar 時,result 響應格式如下:
[ <unix_time>, "<scalar_value>" ]
由于标量不存在時間序列一說,是以 result 表示為目前系統時間一個标量的值。
- 字元串:string
當傳回資料類型 resultType 為 string 時,result 響應格式如下:
[ <unix_time>, "<string_value>" ]
字元串類型的響應内容格式和标量相同。
區間資料查詢
使用 QUERY_RANGE API 我們則可以直接查詢 PromQL 表達式在一段時間傳回内的計算結果。
GET /api/v1/query_range
URL 請求參數:
- query=: PromQL 表達式。
- start=: 起始時間。
- end=: 結束時間。
- step=: 查詢步長。
- timeout=: 逾時設定。可選參數,預設情況下使用-query,timeout 的全局設定。
當使用 QUERY_RANGE API 查詢 PromQL 表達式時,傳回結果一定是一個區間向量:
{
"resultType": "matrix",
"result": <value>
}
需要注意的是,在 QUERY_RANGE API 中 PromQL 隻能使用瞬時向量選擇器類型的表達式。
例如使用以下表達式查詢表達式 up 在 30 秒範圍内以 15 秒為間隔計算 PromQL 表達式的結果。
$ curl 'http://localhost:9090/api/v1/query_range?query=up&start=2015-07-01T20:10:30.781Z&end=2015-07-01T20:11:00.781Z&step=15s'
{
"status" : "success",
"data" : {
"resultType" : "matrix",
"result" : [
{
"metric" : {
"__name__" : "up",
"job" : "prometheus",
"instance" : "localhost:9090"
},
"values" : [
[ 1435781430.781, "1" ],
[ 1435781445.781, "1" ],
[ 1435781460.781, "1" ]
]
},
{
"metric" : {
"__name__" : "up",
"job" : "node",
"instance" : "localhost:9091"
},
"values" : [
[ 1435781430.781, "0" ],
[ 1435781445.781, "0" ],
[ 1435781460.781, "1" ]
]
}
]
}
}
實戰示範
最近做了一個資源優化專項,目的是實際了解一下業務運作時産品 160+ 的服務每個服務所使用的 cpu 和記憶體情況。 并對比他們申請的 request 和 limit 的值,計算服務是否申請了過多的資源導緻資源浪費。 是以我們要通過 HTTP PromQL 把相關的資料查詢出來。
prom_url = 'http://1.117.219.41:30778'
start_time = str(int(datetime.strptime("09/11/2021 19:25:00", "%d/%m/%Y %H:%M:%S").timestamp()))
end_time = str(int(datetime.strptime("09/11/2021 21:25:00", "%d/%m/%Y %H:%M:%S").timestamp()))
result = {}
r = requests.get(
url='{prom_url}/api/v1/query_range?query=sum(node_namespace_pod_container%3Acontainer_cpu_usage_seconds_total%3Asum_rate%7Bcluster%3D%22cls-hchrqyex%22%7D)%20by%20(pod)&start={start}&end={end}&step=30'.format(
start=start_time, end=end_time, prom_url=prom_url))
datas = r.json()['data']['result']
for data in datas:
pod_name = data['metric']['pod']
cpu_usages = []
for c in data['values']:
cpu_usages.append(float(c[1]))
max_value = max(cpu_usages)
avg_value = statistics.mean(cpu_usages)
result[pod_name] = {
'cpu_max_usage': max_value,
'cpu_avg_usage': avg_value
}
上面代碼中的 PromQL 是sum(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate) by (pod) 首先 node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate 是一個預定義的查詢别名。 有些查詢語句過于複雜,是以我們可以給複雜的語句一個别名, 這樣再使用 的時候就比較友善了。 而我們使用的這個别名就如同它的名字一樣, 是查詢每個容器的 cpu 使用率的。 因為一個 pod 裡可能會有多個容器, 是以需要使用 sum by (pod) 的方式統計出每個 pod 的 cpu 使用率總和。 這裡我們使用的就是一個 query_range 的查詢類型。
因為我們希望查詢在測試期間的 2 個小時内 cpu 使用率的最大值和平均值。 是以我們在請求最後使用step=30這個參數來指定每個 30s 計算一次名額,然後我們再使用 start 和 end 參數指定了一個時間範圍。是以在指定的這 2 個小時内,每隔 30s 就會使用 PromQL 查詢一次,這樣傳回結果裡我們就有了很多個采樣資料, 反應了随着時間變化 CPU 使用率的情況。 這時候我們再編寫 python 代碼把傳回的 json 取出來計算最大值和平均值即可。
搜尋微信公衆号:TestingStudio霍格沃茲的幹貨都很硬核