工作技術筆記系列:Prometheus
工作開發心得 - Prometheus
keywords: Prometheus
What is Prometheus?

Prometheus collects and stores its metrics as time series data, i.e. metrics information is stored with the timestamp at which it was recorded, alongside optional key-value pairs called labels.
Prometheus 是一個 TSDB(Time Series Database)時間序列資料庫,提供以下功能:
- 蒐集來自不同 container 的 log 並建立 metrics
- 使用 PromQL query,找出想要的 log
- 提供簡單的 WebUI 供視覺化 (也可以用 Grafana)
- 自帶監控預警系統
Prometheus 的優點:
- 使用 pull metrics 減少流量
- 資訊視覺化的監控工具
- 支援雲端服務和 container
A Diagram of Prometheus
以下是 Prometheus 運作流程圖,大概可分為四個部份:
- Retrieval
- TSDB
- HTTP server
- Alertmanager

Prometheus server
包含 Retrieval、TSDB、HTTP server 三個物件
- Retrieval
- 會透過 pull metrics 定期向所有 Jobs/exporters 要資料,預設是用 /metrics 這個路徑要資料。也可以是其它 prometheus server
- 如果有一些時間週期很短的 Jobs 沒辦法等到 Prometheus 去 pull 它,可以先推送到 Pushgateway 上,再等 Prometheus 一段時間 pull 下來
- 用 pull metrics,可以避免有太多 endpoint 同時向 Monitor 發送資料,造成 Monitor 效能不好,甚至成為 buttleneck 的問題
- 使用 discover targets 可以自動發現 k8s 中的 log
- TSDB
- 將時間序列資料 (sample) 存至硬碟中
- HTTP Server
- 使用 PromQL (Prometheus Query Language) 查找特定的 log
- Prometheus 自己有 WebUI
- 也可以用更精美的 Grafana
Alertmanager
當值超過 alert rule 設定的 threshold,alert manager 就會將訊息送出,可以透過 Email、Slack 通知
Sample & Metric
Sample 是 Prometheus 資料存儲在 HDD 中的格式,包含三種屬性:metric, timestamp, value
1 | <--------------- metric ---------------------><-timestamp -><-value-> |
Metric 是由 metric name 以及描述特徵的 labelset 兩部份組成
1 | <metric name>{<label name>=<label value>, ...} |
Exporter 回傳給 Prometheus 的資料格式統一包含:metric、前面的註解
1 | # HELP node_cpu Seconds the cpus spent in each mode. |
註解有 HELP, TYPE 兩類
- help: 包含 metric name 以及 metric 的敘述
- type: 包含 metric name 以及 metric type (有四種)
| 欄述 | Counter | Gauge | Histogram/Summary |
|---|---|---|---|
| 主要功能 | 只增不減的數字 | 可增可減的數字 | 一段時間內的數值統計 |
| 主要功能 | how many times X happened? | what is the current value of X now? | how log or how big? |
| 例子 | 服務重新啟動次數 | 當前硬碟使用容量 | API request 回傳時間統計分佈 |
Histogram vs Summary
大多數情況會使用「平均值」值為量化的標準,例如平均 API request 回傳時間。但平均容易受到極端誤差影響,例如因網路不好回傳時間 >10s,這種情況下的平均值會比較沒參考價值。
一種解決方式是「分組」,例如回傳時間 0~10ms 一組、10~100ms 一組…。
Histogram 和 Summary 都是為了解決平均值誤差而設計的「分組」指標
Histogram
自己設計 bucket 範圍,Prometheus 只會計算 bucket 出現次數,原始資料會不見
資料包含:
- bucket 範圍,對每個點進行統計 [metric_name]_bucket{le="上邊界"}
- 計算累計和 [metric_name]_sum
- 計算次數[metric_name]_count
優點:
- 對客戶端計算低,只是一對一加總而已
- 可以做 aggregation 運算 (sum, avg…)
缺點:
- 不會存原始數值,bucket 範圍大小會影響誤差
- 伺服器端可使用 histogram_quantile 計算四分位數,但是在下 query 時計算
1 | # HELP prometheus_tsdb_compaction_chunk_range Final time range of chunks on their first compaction |
Summary
在一定時間內統計資料,計算成四分位圖 (quantile) 後儲存
資料包含:
- 四分位數值 (quantiles) basename value
- 計算累計和 [metric_name]_sum
- 計算次數 [metric_name]_count
優點:
- 數值精準
- query 可以直接拿到四分位值
缺點:
- 在客戶端計算四分位數,計算大
- 不能做 aggregation
1 | # HELP prometheus_tsdb_wal_fsync_duration_seconds Duration of WAL fsync. |
About PromQL
PromQL 是一種 query language,是 Prometheus 專門設計來 query 時間序列資料的語法
- 取得 vector
1 | http_requests_total |
- 用 tag 去指定 {tag_name=""}
1 | http_requests_total{job="apiserver", handler="/api/comments"} |
- 一些邏輯運算符
1 | http_requests_total{job!="apiserver"} |
- 用 [] 指定時間範圍,Querying basics | Prometheus
1 | http_requests_total{job="apiserver", handler="/api/comments"}[5m] |
- 用 =~ 支援 regex
1 | http_requests_total{job=~".*server"} |
- 內建很多 function 可以用,Query functions | Prometheus
1 | rate(http_requests_total[5m]) |
- 也內建很多 aggregation function,Operators | Prometheus
1 | # tag list matric_name/vactor |
Deploy & Setting
設計 Exporter → Prometheus
Python flask
開一個簡單的後端,設計 /metrics API
設計 Counter metric 每 5s 會 +1
1 | import prometheus_client |
prometheus.yaml
設定 prometheus 的地方
scrape_configs 裡面定義不同 job 設定,來源 ip、名稱…
1 | global: |
docker-compose.yaml
flask 開在 5000 port
prometheus console 開在 9090 port
1 | version: '3.7' |
console
打開 9090 port: http://localhost:9090
進到 Prometheus 自帶的 WebUI

在上面打 PromQL 就可以查找 log
