TT Lab
开始
学习 学习路径 课程

PCA — Prometheus 认证助理

lint 没报错,桶却是反的

在 TT Lab 中继续学习

目标

用 promtool 的 lint 检查诊断并修复违反规范的 exporter 输出,从原始数据重新统计直方图的暴露,通过 OpenMetrics 导入 TSDB 并确认时间序列数量,然后只用标准库编写一个 exporter 并实际抓取。

为什么重要

Prometheus 对 exporter 给出的文本是原样信任的。计数器缺少 _total,或者单位混入毫秒,仪表板和规则就会按不同的含义去读;桶如果不是累积的,分位数就会悄悄出错。一个标签加上几个桶会把时间序列扩大到多少条,不实际导入一次也很难有概念。区分 lint 能抓到什么、抓不到什么,是埋点评审的起点。

已准备的环境

python3 /opt/fixtures/pca_exposition_lab.py init 会在 /root/pca-exposition/ 中放入 legacy.prom(违反规范的旧 exporter 输出)和 payload-sizes.csv(40 个请求大小)。用 lab-k8s 镜像中的 promtool 3.0.1 实际运行 check metrics(lint)和 tsdb create-blocks-from openmetrics(生成块)。不会启动 Prometheus 服务器。第 6、7 步的 exporter 由评分器临时用一个空闲端口启动,用完即关闭,所以你自己启动的进程与评分无关。

步骤

  1. 用 python3 /opt/fixtures/pca_exposition_lab.py init 生成材料后,运行 promtool check metrics < /root/pca-exposition/legacy.prom。在 /root/pca-exposition/01-lint.txt 中写下 problems=(被指出的行数)、metrics=(被指出的指标名称,用逗号分隔,不重复)和 missed_by_lint=(lint 没有报错,但因为桶不是累积的而出错的序列名称)。
  2. 创建 /root/pca-exposition/fixed.prom,把 legacy.prom 中的五个序列迁移过来。http_requests 改为计数器 http_requests_total(保留两个样本),request_latency_ms 的 212 改为仪表 request_latency_seconds 的 0.212(补上 HELP),queueDepth 改为 queue_depth,cache_hits_total 改为仪表 cache_entries,job_duration_count 改为仪表 batch_jobs_running。payload_bytes 不迁移。promtool check metrics 不能指出任何问题。
  3. 用 /root/pca-exposition/payload-sizes.csv 中的请求大小创建直方图 http_request_size_bytes,并追加到 fixed.prom 末尾。边界是 100、1000、10000、+Inf,同时写出 _sum 和 _count。每个桶的值是请求大小不超过该边界(含边界)的请求的累积个数。lint 必须始终无问题。
  4. 把与 fixed.prom 相同的样本改写成 OpenMetrics 格式的 /root/pca-exposition/scrape.om。在每个样本末尾加上时间戳(秒,例如 1700000000),最后一行是 # EOF。用 promtool tsdb create-blocks-from openmetrics /root/pca-exposition/scrape.om /root/pca-exposition/tsdb 导入后,在 /root/pca-exposition/04-import.txt 中写下 series=(NUM SERIES)和 samples=(NUM SAMPLES)。
  5. 在 /root/pca-exposition/cardinality.om 中,把 http_request_size_bytes 直方图按 route 标签的三个值 /checkout、/search、/upload,配以 12 个有限边界和 +Inf 写出(每条路径都包含 _sum、_count,以及时间戳和 # EOF)。导入之前先计算时间序列的数量,写到 /root/pca-exposition/05-cardinality.txt 的 predicted_series= 中,再把导入结果写到 imported_series= 中。
  6. 只用标准库编写 /root/pca-exposition/exporter.py。在环境变量 PORT(没有则用 9464)指定端口的 127.0.0.1 上监听,每收到一次 GET /work?d=초(占位符为秒数),就把计数器 demo_jobs_processed_total 加 1,并把 d 记录到直方图 demo_job_duration_seconds(边界 0.1、0.5、1、5)中。GET /metrics 以 Content-Type: text/plain; version=0.0.4 返回带有 HELP、TYPE 的暴露格式。评分器会用空闲端口重新启动它,发送 d=0.05、0.5、2、7 之后进行抓取,确认 lint、计数器增长、累积桶和 _sum,然后关闭。
  7. 给 exporter.py 的计数器加上 queue 标签。使用 GET /work?d=초&queue=이름(占位符依次为秒数和名称)中的名称,没有则为 default。标签值按暴露格式的规则对反斜杠、双引号和换行做转义。评分器会发送 exports、say "hi"、c:\tmp 以及含换行的名称,确认 promtool 能接受这个暴露,并且四个名称都以原值各被读回一次。

参考

promtool 拒绝的六行

用 python3 /opt/fixtures/pca_exposition_lab.py init 生成材料后,运行 promtool check metrics < /root/pca-exposition/legacy.prom。在 /root/pca-exposition/01-lint.txt 中写下 problems=(被指出的行数)、metrics=(被指出的指标名称,用逗号分隔,不重复)和 missed_by_lint=(lint 没有报错,但因为桶不是累积的而出错的序列名称)。

lint 检查名称、HELP 和后缀规范,不检查直方图的桶是否累积,所以要按 le 的顺序亲自读 _bucket 的值。

让名称和单位符合规范

创建 /root/pca-exposition/fixed.prom,把 legacy.prom 中的五个序列迁移过来。http_requests 改为计数器 http_requests_total(保留两个样本),request_latency_ms 的 212 改为仪表 request_latency_seconds 的 0.212(补上 HELP),queueDepth 改为 queue_depth,cache_hits_total 改为仪表 cache_entries,job_duration_count 改为仪表 batch_jobs_running。payload_bytes 不迁移。promtool check metrics 不能指出任何问题。

只有计数器以 _total 结尾。_count、_sum、_bucket 是直方图和 Summary 使用的后缀。单位要换成基本单位(秒、字节),值也要一并换算。

从 CSV 重新统计累积桶

用 /root/pca-exposition/payload-sizes.csv 中的请求大小创建直方图 http_request_size_bytes,并追加到 fixed.prom 末尾。边界是 100、1000、10000、+Inf,同时写出 _sum 和 _count。每个桶的值是请求大小不超过该边界(含边界)的请求的累积个数。lint 必须始终无问题。

legacy 中的 payload_bytes 写的是各区间的个数,不是累积的。le="+Inf" 始终等于 _count。

用 OpenMetrics 导入并统计时间序列

把与 fixed.prom 相同的样本改写成 OpenMetrics 格式的 /root/pca-exposition/scrape.om。在每个样本末尾加上时间戳(秒,例如 1700000000),最后一行是 # EOF。用 promtool tsdb create-blocks-from openmetrics /root/pca-exposition/scrape.om /root/pca-exposition/tsdb 导入后,在 /root/pca-exposition/04-import.txt 中写下 series=(NUM SERIES)和 samples=(NUM SAMPLES)。

OpenMetrics 缺少 # EOF 或缺少时间戳时,导入会被拒绝。一个直方图中,每个桶以及 _sum、_count 各自都是一条时间序列。

一个标签加 12 个桶的代价

在 /root/pca-exposition/cardinality.om 中,把 http_request_size_bytes 直方图按 route 标签的三个值 /checkout、/search、/upload,配以 12 个有限边界和 +Inf 写出(每条路径都包含 _sum、_count,以及时间戳和 # EOF)。导入之前先计算时间序列的数量,写到 /root/pca-exposition/05-cardinality.txt 的 predicted_series= 中,再把导入结果写到 imported_series= 中。

时间序列的数量是标签值组合的乘积。一个直方图会产生(边界数 + 1)个桶,外加 _sum 和 _count。

抓取自己编写的 exporter

只用标准库编写 /root/pca-exposition/exporter.py。在环境变量 PORT(没有则用 9464)指定端口的 127.0.0.1 上监听,每收到一次 GET /work?d=초(占位符为秒数),就把计数器 demo_jobs_processed_total 加 1,并把 d 记录到直方图 demo_job_duration_seconds(边界 0.1、0.5、1、5)中。GET /metrics 以 Content-Type: text/plain; version=0.0.4 返回带有 HELP、TYPE 的暴露格式。评分器会用空闲端口重新启动它,发送 d=0.05、0.5、2、7 之后进行抓取,确认 lint、计数器增长、累积桶和 _sum,然后关闭。

桶按不超过边界的值累积统计。一个请求会加到所有比它大的边界以及 +Inf 上。评分器会提供 PORT,所以不要写死端口。

队列名称里混进了引号

给 exporter.py 的计数器加上 queue 标签。使用 GET /work?d=초&queue=이름(占位符依次为秒数和名称)中的名称,没有则为 default。标签值按暴露格式的规则对反斜杠、双引号和换行做转义。评分器会发送 exports、say "hi"、c:\tmp 以及含换行的名称,确认 promtool 能接受这个暴露,并且四个名称都以原值各被读回一次。

在暴露格式的标签值中,需要转义的字符只有三个。顺序很重要——如果不先替换反斜杠,新加入的反斜杠会被再次替换。