📝 摘要 :给 Jenkins 配一套完整监控,一条龙走完四步:装 Prometheus metrics 插件接入 (两行配置,⚠️ 指标名前缀可配,照抄网上的多半对不上你的)、导 Grafana 看板 9964 (19 个面板逐块实测,4 个
No data、1 个数是错的都标出来了)、11 条告警规则 (从 Jenkinsfile 反模式反推,不是照指标列表堆的;已过promtool校验并真实加载运行)、以及配完之后怎么用两分钟确认它们不是哑弹。

起因是一次随手的
curl。我把这台 Jenkins 的
/prometheus/端点抓下来,想挑几个指标写告警规则,翻到构建那一段时看到这么一行:
text
default_jenkins_builds_running_build_duration_milliseconds{jenkins_job="order-sync/com.example:order-sync-api"} 1.805391805E9
1,805,391,805 毫秒。换算一下------这个构建已经「正在运行」20.9 天了。
它躺了三周,没有任何人知道 ------因为这台 Jenkins 上一条告警规则都没有 。说来有点讽刺:同一套 Prometheus 的规则目录里,ClickHouse、Flink、Redis、ZooKeeper、Kafka、MySQL、MongoDB、Elasticsearch、MinIO、RocketMQ、DolphinScheduler ------ 十来个组件,每个都有一份自己的
*-rules.yml,另外还有 5 个主机级的通用规则文件(CPU / 内存 / 磁盘 / 存活)。唯独 Jenkins,一条都没有。
于是有了这篇:接入、看板 9964、11 条告警规则,四步配完------规则在第五节,可以直接抄走。四步里每一步都有个坑,我在正文对应位置就地标出来了,照着走不用自己再踩一遍:
- 第一步接入完,指标名别照抄网上的------前缀是可配的,抄来的规则永远不会触发(第三节);
- 第二步看板导完,逐块看有没有数 ------9964 我实测 19 个面板,4 个
No data,还有 1 个显示「750 亿 %」(4.1);- 第三步规则写完,先
promtool再上线------写错一行,Prometheus 不是跳过那条规则,是拒绝启动,同一台机上十几个组件的告警跟着一起停(6.1,我就栽在这儿);- 第四步加载完,「一片绿」要验过才算数------表达式永远返回空的哑弹,长得和「确实没问题」一模一样(第六节)。
(开头那条构建后来我追了很久:它藏在哪儿、为什么 abort 按钮点下去纹丝不动,是另一篇的事------【待发布后补充引用关系:《Jenkins 构建卡了 23 天,abort 按钮点了没用》】。)
一、为什么 Jenkins 最容易被漏掉
不是忘了,是它的故障形态和别的组件不一样。
Redis 挂了,业务立刻报错;MySQL 挂了,电话马上打过来。这类组件不配告警你也扛不过五分钟。
Jenkins 不是:
| 故障 | 谁会发现 | 多久 |
|---|---|---|
| Jenkins 进程挂了 | 所有人 | 下一次发版,几分钟内 |
| 构建卡死不退出 | 没人 | ⭐ 可以躺三周 |
| executor 被占满 | 只有排队的人骂两句 | 半天 |
| controller 内存被吃掉 | 等它 OOM 那天 | 几周 |
| 节点掉线 | 构建变慢时才有人查 | 数天 |
Jenkins 挂了大家立刻知道------发不了版是最响的告警。真正没人知道的,是它「还活着但已经不干活了」。 上表里「可以躺三周」那一行不是修辞,就是开头那条构建------它最后是被第五节那条规则捞出来的。
这句话你要是觉得眼熟:我在《Jenkinsfile 反模式图鉴》里花了一整节讲「进程活着 ≠ 它在干活」,只不过那篇的主角是流水线,这篇的主角是 Jenkins 自己。
二、接入:一个插件,两行配置
前置:Prometheus + Grafana + Alertmanager 这套怎么搭,见《Prometheus + Grafana + AlertManager 监控体系搭建:Docker 一把梭》,本篇只讲 Jenkins 这一段。
第一步 :Jenkins 装 Prometheus metrics 插件(Manage Jenkins → Plugins 搜 Prometheus metrics)。装完默认就在 /prometheus/ 暴露指标,不用改任何配置。
第二步:Prometheus 加一个 job:
yaml
- job_name: 'jenkins'
static_configs:
- targets: ['jenkins.example.com:8080']
metrics_path: '/prometheus/' # ⚠️ 结尾这个斜杠不能少
metrics_path 默认是 /metrics,Jenkins 插件用的是 /prometheus/,忘了改就是一路 404。
验证:
bash
curl -s http://jenkins.example.com:8080/prometheus/ | head -5
有 # HELP default_jenkins_... 就通了。
不过 curl 通只说明Jenkins 这边在吐指标 ,还得确认Prometheus 真的在抓 ------去 Status → Target health,搜 jenkins:

图:1 / 1 up、State UP,Endpoint 结尾那个斜杠也在。配错的典型症状是这里压根没有 jenkins 这个 job(配置没生效),或者 State 是 DOWN 并带一行 404(metrics_path 忘了改)。
三、⚠️ 指标名别照抄网上的,前缀是可配的
这是第一个坑,而且很多人是配完发现告警永远不触发才回头查的。
插件的指标带一个可配置的命名空间前缀,默认是 default,所以你看到的是:
text
default_jenkins_executors_available
default_jenkins_builds_duration_milliseconds_summary
这个前缀可以在插件配置页的 Default Namespace 改,也能用环境变量 PROMETHEUS_NAMESPACE 覆盖。网上文章写 jenkins_executors_* 的、写 default_jenkins_* 的都有------取决于作者那台机器怎么配的,照抄大概率对不上你的。
⇒ 动手前先自己捞一遍:
bash
# 看都有哪些指标(我这台实测 369 个)
curl -s http://jenkins.example.com:8080/prometheus/ | grep -c '^# HELP'
# 捞你要用的那几类
curl -s http://jenkins.example.com:8080/prometheus/ \
| grep -iE 'queue|executor|builds?_duration|jvm_memory' | grep -v '^#'
3.1 369 个指标里,真正该看的十来个
插件吐得很全(JVM、GC、线程池、每个 Job 的历史......),但写告警只需要这几类。下表的指标名是 2026-09 实测抓下来的:
| 关注什么 | 指标 | 说明 |
|---|---|---|
| 队列 | jenkins_queue_size_value |
排队总数 |
jenkins_queue_stuck_value |
⭐ Jenkins 自己判定「卡住」的,比你自己定阈值准 | |
jenkins_queue_blocked_value / _pending_value |
细分状态 | |
| 执行器 | jenkins_executor_count_value |
总数 |
jenkins_executor_in_use_value / _free_value |
占用 / 空闲 | |
default_jenkins_executors_*{label="..."} |
按节点标签分组的版本 | |
| 节点 | jenkins_node_online_value / _offline_value |
在线 / 离线数 |
| 构建 | default_jenkins_builds_running_build_duration_milliseconds |
⭐ 当前在跑的构建已跑多久,本文开头那条就是它 |
default_jenkins_builds_last_build_waiting_milliseconds |
上次构建排队等了多久 | |
default_jenkins_builds_total_build_count_total |
构建总数(counter) | |
default_jenkins_builds_failed_build_count_total |
失败数(counter) | |
| JVM | jvm_memory_bytes_used{area="heap"} / jvm_memory_bytes_max{area="heap"} |
controller 堆 |
| 插件 | jenkins_plugins_failed / _active / _inactive |
插件加载状态 |
💡 两套命名混着出现是正常的 :
default_jenkins_*来自插件自己的采集器,jenkins_*/vm_*是从 Jenkins 内置的 Metrics 插件(Dropwizard)转换过来的。前者带可配前缀,后者不带------所以你会在同一份输出里看到两种风格,别以为是抓错了。
四、看板:直接导 9964
Grafana 官方市场的 9964 · Jenkins: Performance and Health Overview,就是配这个插件用的,导入填一下 Prometheus 数据源即可。
⚠️ 两个提醒:
- 别导错 ------市场上还有个几乎同名的
9524,同样是给jenkinsci/prometheus-plugin用的 ,但面板更少(9964的描述多出Jenkins Job Status等一批)。别看到「Jenkins performance and health overview」就随手导9524,导完会发现少一半图。 - ⭐ 导完一定逐块看有没有数据 。社区看板普遍存在「指标名随版本改了、看板没跟上」的问题,典型症状是满屏 No Data,只有 Uptime 有数(这次恰好反过来------下面你会看到,偏偏就是 Uptime 没数)。我在 MinIO 上就吃过这个亏:社区那几个编号(6248 / 10946 / 12563)用的还是 2018--2020 的旧指标名,导进去基本全空。
4.1 实测:19 个面板,4 个没数据,1 个更糟
导完长这样:

图:9964 导入后的实际效果。注意左侧那个 JVM free memory ------ 它不是 No data,它显示的是「750 亿百分比」。
逐块看下来:
| 状态 | 面板 | 数量 |
|---|---|---|
| ✅ 正常 | Memory Usage、Jenkins health、CPU Usage、Failed Jobs、Executor free / In-use、Job Duration、队列相关...... | 14 |
⚠️ No data |
JVM Uptime、Total Jobs、Aborted Jobs、Unstable Jobs | 4 |
| 🔴 有数但是错的 | JVM free memory = 75040825700.0% |
1 |
两个值得说的地方:
① Total Jobs 没数据,可 Sucessful Jobs 有 5359、Failed Jobs 有 97。 (Sucessful 这个拼写是看板自带的,不是我打错) 同一组指标一半取得到一半取不到------这是社区看板的典型症状:看板的查询语句停留在某个旧版本的指标名上,插件改名后没人跟。所以第三节才反复强调「先自己捞一遍指标名」。
② 🔴 那个 750 亿百分比,比 No data 危险得多。
No data 是诚实的坏 ------你一眼看出这块不能信。而一个渲染出具体数字、还带着百分号的面板,看着完全正常。你要是没多想,就会把它当成一个真实读数。
这其实是本文反复在讲的同一个模式,只不过换了个地方出现:
坏掉的东西伪装成正常,比明显的坏更难对付。
构建僵在那里 21 天没人发现,是因为它「看着在跑」;一条哑弹告警骗过你,是因为它「看着一片绿」;这个面板骗过你,是因为它「看着有数」。
⇒ 实操建议 :导完看板别只扫一眼「有没有 No data」,还要看那些有数的面板,数值量级合不合理。百分比超过 100、内存是负数、耗时是天级------这些都是查询或单位配错的信号。
📌 诚实边界 :上面这 4 个
No data和 1 个错值,我只定位到「看板查询与当前指标名对不上」这一层,没有逐个去改看板的查询语句。要修的话,思路是打开面板编辑、把 query 里的指标名换成第三节捞出来的真实名字。
五、⭐ 告警规则:从反模式反推,而不是从指标正推
网上能搜到的 Jenkins 告警规则,基本停在两条:实例挂了、队列长了。因为它们是看着指标列表写出来的------有什么指标,就报什么。
我换了个方向:先想「Jenkinsfile 写错会造成什么后果」,再去找哪个指标能照出这个后果。
这套推导线索来自《Jenkinsfile 反模式图鉴》那 17 条:
| 反模式 | 它在监控上长什么样 | 对应规则 |
|---|---|---|
input 占着 executor 等人审批 |
⭐ executor 占满,可机器 CPU 是空的 | 执行器长期占满 |
| 失败自动无界重试 | 短时间刷出大量构建,每次都失败 | 构建速率异常突增 |
| poll 没设超时上限 | 单个构建永不退出 | 构建运行超时 |
| Groovy 重逻辑跑在 controller | controller 堆内存持续爬升 | 堆内存使用率过高 |
第一条最反直觉,也最值钱:监控面板上 executor 使用率 100%、看着一片繁忙,实际一台机器都没在干活------全卡在等人点「确认发布」。
5.1 完整的 jenkins-rules.yml
直接抄走。每条都在真实 Prometheus 上跑过(怎么跑见下一节):
yaml
# Jenkins 监控告警规则(jenkinsci/prometheus-plugin)
# ⚠️ 指标名请先按第三节自己捞一遍确认,前缀可配置
groups:
- name: jenkins-alerts
rules:
# ────────────── 可用性 ──────────────
- alert: Jenkins服务不可用
expr: up{job="jenkins"} == 0
for: 1m
labels: { severity: critical, group: jenkins }
annotations:
summary: "Jenkins 服务不可用"
description: "Jenkins {{ $labels.instance }} 已停止响应,所有发布中断"
- alert: Jenkins节点离线
expr: jenkins_node_offline_value > 0
for: 5m
labels: { severity: warning, group: jenkins }
annotations:
summary: "Jenkins 有节点离线"
description: "当前离线节点数 {{ $value }},构建能力下降"
# ────────────── 队列:没人能发版 ──────────────
- alert: Jenkins构建队列堆积
expr: jenkins_queue_size_value > 5
for: 10m
labels: { severity: warning, group: jenkins }
annotations:
summary: "Jenkins 构建队列持续堆积"
description: "队列长度 {{ $value }} 已持续 10 分钟------先看 executor 是不是被占满了"
# Jenkins 自己判定为「卡住」的队列项(等待远超同类任务的正常水平)
- alert: Jenkins队列出现卡死任务
expr: jenkins_queue_stuck_value > 0
for: 15m
labels: { severity: warning, group: jenkins }
annotations:
summary: "Jenkins 队列中有任务卡死"
description: "卡死任务数 {{ $value }}。常见原因:标签没有匹配的在线节点、或所需资源被长期占用"
# ────────────── ⭐ executor:占着不放 ──────────────
- alert: Jenkins执行器长期占满
expr: jenkins_executor_free_value == 0 and jenkins_executor_count_value > 0
for: 30m
labels: { severity: warning, group: jenkins }
annotations:
summary: "Jenkins 执行器已占满 30 分钟"
description: "空闲执行器为 0。若同期机器 CPU 很低,八成是有构建卡在 input 审批,占着号牌不干活"
# ────────────── ⭐ 构建:永不退出 ──────────────
# ⚠️ 这条的 description 是被实战改过一版的:原来只写「需手动 abort」,
# 结果真出事时,任务列表里根本找不到那个构建、abort 按钮点了也没反应。
# 经过见姊妹篇,这里直接给改后的版本。
- alert: Jenkins构建运行超时
expr: default_jenkins_builds_running_build_duration_milliseconds / 1000 / 3600 > 2
for: 5m
labels: { severity: warning, group: jenkins }
annotations:
summary: "Jenkins 构建运行超过 2 小时"
# ⚠️ 行尾反斜杠 = YAML 转义换行,折行后不会插入空格。
# 不加的话,渲染出来会变成「...小时。 若 executor...」------中文里多一个半角空格
description: "任务 {{ $labels.jenkins_job }} 已运行 {{ printf \"%.1f\" $value }} 小时。\
若 executor 未被占用,多半是没收干净的残留构建;任务列表里通常找不到它,\
去 groupId:artifactId 对应的模块页看构建历史。\
若 abort 按钮无效(executor 为 null),走 Script Console 把 Run 的 state 反射改成 COMPLETED(finish() 是 protected,调不动)"
- alert: Jenkins构建排队等待过久
expr: default_jenkins_builds_last_build_waiting_milliseconds / 1000 / 60 > 30
for: 5m
labels: { severity: warning, group: jenkins }
annotations:
summary: "Jenkins 构建排队等待过久"
description: "任务 {{ $labels.jenkins_job }} 上次构建在队列里等了 {{ printf \"%.0f\" $value }} 分钟才开始"
# ────────────── ⭐ 重试雪崩 ──────────────
- alert: Jenkins构建速率异常突增
expr: sum(rate(default_jenkins_builds_total_build_count_total[5m])) by (jenkins_job) * 300 > 10
for: 5m
labels: { severity: warning, group: jenkins }
annotations:
summary: "Jenkins 任务构建频率异常"
description: "任务 {{ $labels.jenkins_job }} 近 5 分钟触发约 {{ printf \"%.0f\" $value }} 次构建,检查是否存在无界自动重试"
- alert: Jenkins任务连续失败
expr: increase(default_jenkins_builds_failed_build_count_total[1h]) >= 3
for: 1m
labels: { severity: warning, group: jenkins }
annotations:
summary: "Jenkins 任务 1 小时内失败多次"
description: "任务 {{ $labels.jenkins_job }} 近 1 小时失败 {{ printf \"%.0f\" $value }} 次,多为配置错而非偶发,重试解决不了"
# ────────────── ⭐ controller 被拖垮 ──────────────
- alert: Jenkins堆内存使用率过高
expr: jvm_memory_bytes_used{area="heap", job="jenkins"} / jvm_memory_bytes_max{area="heap", job="jenkins"} > 0.85
for: 10m
labels: { severity: warning, group: jenkins }
annotations:
summary: "Jenkins controller 堆内存使用率超过 85%"
description: "当前 {{ $value | humanizePercentage }}。排查是否有流水线在 Groovy 里解析大 JSON / 读大日志------Groovy 全部跑在 controller 上"
# ────────────── 插件健康 ──────────────
- alert: Jenkins插件加载失败
expr: jenkins_plugins_failed > 0
for: 5m
labels: { severity: critical, group: jenkins }
annotations:
summary: "Jenkins 有插件加载失败"
description: "失败插件数 {{ $value }}。插件加载失败会让依赖它的 step 在流水线里直接报 NoSuchMethodError"
5.2 三个阈值怎么定的(别照抄数字,照抄思路)
| 规则 | 我给的值 | 依据 |
|---|---|---|
队列堆积 > 5 |
5 | 我这台只有 2 个 executor ,队列到 5 就是排了两轮以上。executor 多的机器要往上调 |
构建超时 > 2h |
2 小时 | 正常构建是分钟级,2h 是保守值。先按你最慢的那个 job 的 3 倍起步 |
执行器占满 for: 30m |
30 分钟 | 短时占满是正常繁忙,持续半小时才可疑 |
所有阈值都是「按自己环境量一遍再定」,直接抄我的数字大概率不合适。
六、⭐ 零告警不等于没问题:怎么验证规则不是哑弹
这一节是我认为最该讲、而几乎没人讲的部分。
规则写完加载上去,页面上一片绿,你会松一口气。但「没有告警」有两种截然不同的含义:
| 真实含义 | 你看到的 |
|---|---|
| 确实没问题 | 一片绿 ✅ |
| 指标名写错 / 标签选择器不匹配,表达式永远返回空 | 也是一片绿 ❌ |
后者就是一颗哑弹。而且它比没有规则更糟------没规则你知道自己在裸奔,有了这颗哑弹你以为自己安全了。
这和我在反模式图鉴里写的是同一件事:一道 fail-open 的检查,比没有检查更糟。 只不过那次说的是流水线里的判据,这次是告警规则本身。
验证方法:把每条 expr 直接打到 Prometheus 的查询接口上,看它到底能不能取到数。
bash
PROM=http://prometheus.example.com:9090
# ① 先验语法 + 能否取数
curl -s --get "$PROM/api/v1/query" \
--data-urlencode 'query=jenkins_queue_size_value > 5'
# ② ⭐ 关键一步:把阈值去掉,验「裸指标」有没有数据
# ①返回空 + ②也返回空 = 指标名或标签写错了,这条规则是哑弹
curl -s --get "$PROM/api/v1/query" \
--data-urlencode 'query=jenkins_queue_size_value'
判据很简单 :带阈值的查询返回空不能 说明没问题;必须把去掉阈值的裸指标也查一遍,确认它真的有数据点。
我这 11 条就是这么过的一遍:
text
✅ Jenkins服务不可用 → 当前命中 0 条
✅ Jenkins节点离线 → 当前命中 0 条
✅ Jenkins构建队列堆积 → 当前命中 0 条
✅ Jenkins队列出现卡死任务 → 当前命中 0 条
✅ Jenkins执行器长期占满 → 当前命中 0 条
✅ Jenkins构建运行超时 → 当前命中 1 条 ← 就是开头那条
✅ Jenkins构建排队等待过久 → 当前命中 0 条
✅ Jenkins构建速率异常突增 → 当前命中 0 条
✅ Jenkins任务连续失败 → 当前命中 0 条
✅ Jenkins堆内存使用率过高 → 当前命中 0 条
✅ Jenkins插件加载失败 → 当前命中 0 条
那 10 个 0 我都回头验了裸指标。举个例子------堆内存那条用了 job="jenkins" 这个选择器,万一 Prometheus 那边 job 名不叫这个,它就永远不会触发:
bash
$ curl -s --get "$PROM/api/v1/query" --data-urlencode 'query=jvm_memory_bytes_used{area="heap", job="jenkins"}'
# → 有数据,430742352 字节
有数。所以它的 0 是「堆用了 2.6%,确实没问题」,不是「选择器写错了」。这一步花不了两分钟,但它决定你这套告警是真的还是摆设。
6.1 ⚠️ 表达式验过,不等于规则能加载------我在这栽了一次
上面这套 api/v1/query 验证有个盲区,大到能让整个 Prometheus 起不来 。我是把文件放上去、重启,它没起来才发现的:
text
level=ERROR msg="Error loading rule file patterns from config"
err="parse rules from file \"/prometheus/rules/jenkins-rules.yml\":
group \"jenkins-alerts\", rule 6, \"Jenkins构建运行超时\":
annotation \"description\": template: function \"div\" not defined"
原因很低级:我在 annotation 里写了 {``{ printf "%.1f" (div $value 3600000) }},想把毫秒换算成小时。但 div / mul 不是 Prometheus 的模板函数 ------那是 Grafana 那套。Prometheus 的告警模板走 Go text/template,可用的是 humanize / humanizePercentage / humanizeDuration / printf / query 这些。
两个教训,第二个更要命:
① api/v1/query 只跑 expr,根本不碰 annotation。 所以模板里的错,前面那套验证一个都照不出来。expr 验过 ≠ 规则文件能加载。
② ⭐ 一个规则文件写错,整个 Prometheus 起不来------不是只有那条规则失效。 这点很多人没意识到:它不是「跳过坏规则、其余照常」,是拒绝启动。你以为在给监控加东西,实际是把整套监控停了。
⇒ 所以规则文件必须先离线校验再上线:
bash
# promtool 是 Prometheus 自带的,容器里就有
promtool check rules jenkins-rules.yml
# 没装本地二进制就借容器跑
# ⚠️ 必须 --entrypoint promtool:prom/prometheus 镜像的 ENTRYPOINT 是 /bin/prometheus,
# 直接把 promtool 当参数传会报 "unexpected promtool"
docker run --rm -v "$PWD:/r" --entrypoint promtool \
prom/prometheus:latest check rules /r/jenkins-rules.yml
promtool 会同时 校验表达式语法和 annotation 模板,正是 api/v1/query 覆盖不到的那半边。
换算怎么写才对 :把单位换算放进 expr,让 $value 本身就是你要的单位;比例用 humanizePercentage。上面第 5.1 节的规则已经是修正后的写法:
yaml
# ❌ 错:模板里做算术
expr: xxx_milliseconds > 2 * 60 * 60 * 1000
description: "已运行 {{ printf \"%.1f\" (div $value 3600000) }} 小时"
# ✅ 对:算术放 expr,模板只负责格式化
expr: xxx_milliseconds / 1000 / 3600 > 2
description: "已运行 {{ printf \"%.1f\" $value }} 小时"
💡 顺带一个中文特有的小坑 :description 写长了要折行时,行尾记得加反斜杠 。YAML 的普通折行会把换行变成一个空格,英文里正好,中文里就会渲染成「...小时。 若 executor...」------句号后面凭空多半个空格。行尾
\是转义换行,折完不插空格。第 5.1 节那条规则里就是这么写的。
6.2 加载规则
bash
# 放进 Prometheus 的规则目录(rule_files 通常配的是通配,不用改主配置)
cp jenkins-rules.yml /path/to/prometheus/rules/
# 热加载(需 Prometheus 启动时带 --web.enable-lifecycle)
curl -X POST $PROM/-/reload
# ⭐ 确认真的加载进去了,别只看 reload 返回 200
curl -s $PROM/api/v1/rules | grep -o 'jenkins-alerts'
最后那行同样是「别让它变成哑弹」的一部分:reload 成功 ≠ 你的规则组被加载了(文件放错目录、通配没匹配上,reload 一样返回成功)。
加载成功后,Prometheus 的 Alerts 页面长这样:

图:jenkins-alerts 规则组、11 条规则全部加载,右上角 FIRING (1) / INACTIVE (10)------那一条 firing 就是开头那个构建。(刚加载那几分钟它是 PENDING,for: 5m 走完才转 firing。)
七、这套能证明什么,不能证明什么
放在总结之前,因为它比上面所有内容都重要。
✅ 已经做到的:
- 指标名是实测抓的(369 个),不是从网上抄的;
- 11 条表达式在真实 Prometheus 上逐条查询验证过,语法有效、指标能取到数;
- 规则文件经
promtool check rules校验通过------⚠️ 这一步是补上的,第一版就因为模板函数写错导致 Prometheus 起不来(见 6.1); - 11 条规则已真实加载进 Prometheus 并运行 (
api/v1/rules可见规则组、11 条齐全),其中「构建运行超时」当场进入pending、for走完转firing,annotation 模板渲染正确; - 每条零命中的规则都回验了裸指标,确认不是哑弹;
- 那条僵尸构建是真实发现 ,不是构造的例子------它后来被追到了底(藏在 Maven 模块页、
abort按钮无效),完整过程见姊妹篇。
❌ 还没做到的:
- 还没有长期运行过 ------规则已加载并正常工作,但误报率要跑一段时间才知道 。
for时长和阈值大概率还要按实际噪声回调; - 看板的 4 个
No data和 1 个错值我没去修------只定位到「看板查询与当前指标名对不上」,没逐个改 query(见 4.1); - 没有跨版本验证 :Jenkins 插件的指标随版本增减,本文实测于 2026-09,你那边对不上很正常------所以第三节才要你自己捞一遍;
- 本篇不含那条构建的追查过程------它被拆成了姊妹篇,因为那是「告警响了之后怎么查」,和本篇「怎么把告警配对」是两件事。
所以这篇的定位是**「一套可以直接抄走的起点」,不是「我们线上跑了半年」的战报**。
八、总结
一句话版本 :给 Jenkins 配监控,难的不是接入和看板------那都是现成的;难的是想清楚要告什么警 ,以及怎么确认这些告警不是哑弹。
四件带走的事:
-
指标名先自己捞一遍。 插件前缀可配置,网上文章的指标名不一定是你的。一条
curl的事,省下的是「配完发现永远不触发」的两小时。 -
告警从「会出什么事」反推,别从「有什么指标」正推。 前者会让你写出「executor 占满但 CPU 空闲」这种规则,后者只会给你「实例挂了」。
-
⭐ 零告警要验过才算数。 带阈值的查询返回空,可能是没问题,也可能是指标名写错------把裸指标再查一遍,两分钟的事。否则你配的不是告警,是一排绿灯装饰。
-
🔴 规则文件上线前必须
promtool check rules。 这条单列出来,因为它的失败方式最反直觉:写错一行,Prometheus 不是跳过那条规则,是拒绝启动。 你以为在给监控加东西,实际是把整套监控停了------而且api/v1/query那套验证根本照不出模板里的错(见 6.1)。
最后说回开头那条构建。它不报错,也不会触发任何通知 ------除非有人主动去翻那个指标,否则三周里不会有任何人发现它。Jenkins 上这类「安静的坏掉」远比「进程挂了」常见------而它们唯一会留下痕迹的地方,就是你配的这几条规则。所以这些规则是不是哑弹,才这么要紧。
延伸阅读
| 想看 | 文章 |
|---|---|
| ⭐ 姊妹篇:本文那条「构建运行超时」告警响了之后,我花了半天才找到它------它藏在哪、为什么 abort 按钮点了没用 | 【待发布后补充引用关系:《Jenkins 构建卡了 23 天,abort 按钮点了没用》】 |
| 本文告警规则的推导来源:17 个把 CI/CD 流水线写崩的姿势 | 《Jenkinsfile 反模式图鉴》 |
| Prometheus + Grafana + Alertmanager 怎么搭 | 《Prometheus + Grafana + AlertManager 监控体系搭建:Docker 一把梭》 |
| 其它组件哪些要装 Exporter、哪些不用 | 【待发布后补充引用关系:《中间件监控一条龙:哪些要装 Exporter 哪些不用》】 |
| Jenkins Prometheus 插件官方说明(指标前缀、配置项) | Prometheus metrics · Jenkins Plugins |
| 插件暴露的全部指标清单 | prometheus-plugin · docs/metrics |
| 本文用的 Grafana 看板 | 9964 · Jenkins: Performance and Health Overview |
给读者的小问题:你的 Jenkins 上有几条告警规则? 如果答案是 0,建议先把「构建运行超时」那条加上------按我的经验,加完当天就可能抓到东西。
🏷️ 标签 :Jenkins Prometheus Grafana 告警规则 CI-CD 监控