Prometheus 内置指标:每次抓取自动生成了哪些数据

Grafana 上一个服务的曲线停在两小时前,Prometheus 的 Status → Targets 里它却还是绿的,up 一直是 1,抓取从没失败过。

另一头,某个 exporter 的 scrape_duration_seconds 连续半小时顶在 10s,离 up 翻成 0 只差一次网络抖动,Targets 页面上却看不出任何异样。

这两个问题的答案都不在 exporter 的指标里,而在 Prometheus 每次抓取时自动写下的那批内置指标里:up、scrape_duration_seconds、scrape_samples_scraped......这些指标不需要部署任何东西。

本篇目标:把抓取链路自带的 8 个内置指标完整拆一遍。

一、这批指标从哪来

1、不是 exporter 给的

机制 :每次抓取结束,Prometheus 都会以 target 的 job、instance 标签为基准,额外生成一批样本写入 TSDB。数据源不是 target 的 /metrics 响应体,而是抓取过程本身。

拿一个还没接任何 exporter 的全新 job 试一下,up 已经在那了:

ini 复制代码
up{job="nginx"}

up{instance="nginx-gateway:9113", job="nginx"} 1

这批指标和 exporter 指标定位差异:

对比项 exporter 暴露的指标 内置抓取指标
来源 target 的 /metrics 响应体 Prometheus 抓取过程本身
是否要部署 要,且按组件各装各的 不用,开箱即有
覆盖范围 target 内部的状态 抓取链路的健康与规模
exporter 挂了会怎样 指标跟着消失 up 变 0,数据仍在
典型用途 业务与资源告警 采集链路排障与可用性

注意:exporter 挂了,它自己的指标就消失,想用 exporter 的指标监控"采集还在不在",逻辑上是死循环。内置指标是唯一站在 Prometheus 视角看链路的数据,也是其不可替代的原因。

2、8 个指标一张表

Prometheus 指标名 类型 含义说明
up Gauge 上次抓取是否成功。2xx 且响应体可解析才记 1,其余一律 0。监控体系自己的第一条告警
scrape_duration_seconds Gauge 上次抓取耗时,覆盖发起请求到解析完响应体的全过程
scrape_samples_scraped Gauge 上次抓取解析出的样本数(metric relabel 之前的近似值)
scrape_samples_post_metric_relabeling Gauge relabel 之后真正入库的样本数
scrape_series_added Gauge 上次抓取中首次出现的序列数
scrape_body_size_bytes Gauge 响应体未压缩大小,无法获知时为 -1
scrape_timeout_seconds Gauge 该 target 配置的抓取超时,随配置变化
scrape_sample_limit Gauge 该 target 的单次样本上限,0 表示不限

三个共同点,后面的 PromQL 都建立在这上面:

  • 全是 Gauge,描述"上一次抓取" 。没有 _total 后缀,不算累计,不需要 rate(),直接画原始值。
  • 全部携带 target 的标签 。job、instance、以及在 scrape config 里加的 env 等都带,按 target 一套。
  • 失败的抓取同样留痕 。up 记 0,scrape_duration_seconds 仍会记录这次尝试的耗时,所以"连不上"和"连上但拿不到合法数据",duration 曲线上是两种形状。

注意:

  • 官方明确 metric_relabel_configs 不作用于这批自动生成的序列。即无论在 relabel 里写什么,up 和 scrape_* 都会原样保留,它们是链路的"黑匣子",保证监控监控系统这件事不依赖任何被监控方的配合。
  • 前 5 个默认生成:up、scrape_duration_seconds、scrape_samples_scraped、scrape_samples_post_metric_relabeling、scrape_series_added。后 3 个需要开启 --enable-feature=extra-scrape-metrics:scrape_body_size_bytes、scrape_timeout_seconds、scrape_sample_limit。

3、在哪能看到

三个入口,按快到慢排:

  • Status → Targets 页面 :Last Scrape、Duration、Samples 三列,就是 up、scrape_duration_seconds、scrape_samples_scraped 的最新值。看单点快,看趋势不行。
  • PromQL 直接查 :scrape_samples_scraped 拉出来就是每个 target 的样本数,趋势和对比都在这。
  • HTTP API :/api/v1/targets 返回每个 target 的元信息与最近几次抓取结果,写巡检脚本时用。

验证 :拿一个熟悉的 job 对一下数字,Targets 页面上的 Samples 和 scrape_samples_scraped 的最新值应该一致,Duration 和 scrape_duration_seconds 应该一致。若对不上先排查是否写错了标签。

二、核心指标逐个拆

1、up:整个体系的地基

Prometheus 指标名 类型 含义说明
up Gauge 上次抓取是否成功。1=HTTP 2xx 且响应体能解析出合法样本;0=连接拒绝、超时、非 2xx、解析失败、样本超限,全部算它

up 把五种完全不同的失败压成了一个 0。其价值在于覆盖面无可挑剔,链路上任何一环断掉都会翻 0;但同时也是其局限,翻 0 之后断在哪,要靠 scrape_duration_seconds 的形状来分:

  • duration 低 + up 0:秒拒。进程挂了、端口不通、DNS 解析失败。
  • duration 高 + up 0:超时。对端卡住,耗到了 timeout 才失败。

两个 up 覆盖不了的场景:

  • 业务健康 。up 验证的是"抓到了合法的指标数据",不是"服务正常"。应用已经半死,只要 /metrics 还能返回 200,up 就稳定是 1,无法判断服务是否真的活着。
  • 序列消失 。删掉一个 job 的配置、或服务发现把 target 清空后,up 序列直接消失而不是变 0。判断"整个 job 不见了"要用 absent()。
ini 复制代码
# 每个 target 近 5 分钟的可用性(0~1)
avg_over_time(up[5m])

# 整个 job 的可用性
avg by (job) (avg_over_time(up[5m]))

# up 抖动:15 分钟内翻转超过 4 次
changes(up[15m]) > 4

# 整个 job 消失(配置误删、服务发现空了)
absent(up{job="nginx"})

分析要点:

  • Targets 页面全绿不等于 up 稳定。页面是"最后一次抓取"的快照,抖动只能看曲线。
  • for: 2m 的 TargetDown 比 for: 0m 实用得多。抓取本身有周期,瞬时失败可能是目标重启,连续失败才是链路断了。

2、scrape_duration_seconds:抓取链路的性能指标

Prometheus 指标名 类型 含义说明
scrape_duration_seconds Gauge 上次抓取总耗时:TCP 连接、TLS 握手、发请求、等响应、收 body、解析,全程都算
scrape_timeout_seconds Gauge 该 target 的抓取超时。全局默认 10s,且不允许大于 scrape_interval,配置校验直接报错

scrape_duration_seconds 单独看没有意义,除以 scrape_timeout_seconds 才有,比值是"离失败还有多远"的水位。duration 顶满 timeout,抓取即失败,up 翻 0。但是,scrape_timeout_seconds 不是默认开启指标,从 v2.10 开始通过在启动命令增加 --enable-feature=extra-scrape-metrics 参数开启。

javascript 复制代码
# 抓取耗时水位:距离超时还有多远(0~1)
scrape_duration_seconds / scrape_timeout_seconds

# 找出最慢的 5 个 target
topk(5, max by (instance, job) (scrape_duration_seconds))

# 耗时突变:相对自身 1 小时前涨了 3 倍
scrape_duration_seconds / (scrape_duration_seconds offset 1h) > 3

分析要点:

  • duration 高不一定是 exporter 慢。很多 exporter 的 /metrics 是同步查被监控对象的:sql_exporter 要执行 SQL,blackbox 要发完整探测。被监控对象慢,duration 就高,根因常常在被监控的一侧。
  • 想把"抓取开销"和"target 响应"分开,可以拿 Prometheus 机器直接 time curl 一下 target 的 /metrics,两头一比,慢在哪一段就出来了。

3、两个样本数:scraped 与 post_metric_relabeling

Prometheus 指标名 类型 含义说明
scrape_samples_scraped Gauge 从响应体解析出的样本数,近似值;是 relabel 处理前的口径
scrape_samples_post_metric_relabeling Gauge 经过 metric_relabel_configs 之后真正入库的样本数

两者的关系是一条流水线:scraped →(metric_relabel_configs)→ post → 入库。差值就是 relabel 主动丢掉的部分。

通过 scrape_samples_scraped 查看 样本数

scrape_samples_scraped 是 Prometheus 采集目标时抓取到的样本总数‌,用来衡量每个 target 暴露了多少数据点,是判断采集数据量大小和发现异常采集目标的核心指标。

  • 作用‌:统计单次抓取从目标上拉取到的 sample(数据样本)数量,反映该目标暴露的指标规模。
  • ‌类型‌:gauge(仪表盘类型),每个被抓取的目标都会自动生成这个指标。
  • ‌标签 ‌:通常带有 job(任务名)和 instance(实例地址)标签,例如 scrape_samples_scraped{job="kubernetes-apiservers", instance="10.xxx.182.60:6443"} 表示该 apiserver 实例暴露了 29410 个样本。
  • ‌自生成‌:该指标由 Prometheus 在抓取时自动附加,无法通过 metric relabel 配置过滤掉。‌‌

常见用途

  • ‌监控采集规模 ‌:通过 topk(5, scrape_samples_scraped) 找出样本量最大的 target,定位采集压力来源。
  • ‌计算摄取率 ‌:结合时间窗口计算每秒摄取速率,公式为 sum_over_time(scrape_samples_scraped[5m]) / 300,用于评估 Prometheus 的写入压力。
  • ‌对比采集前后 ‌:与 scrape_samples_post_metric_relabeling 对比,后者是 relabel 后剩余的样本数,两者差值即被过滤掉的样本量。‌‌

⚠️ 注意: 单个 target 的 scrape_samples_scraped 值过大,通常意味着该目标暴露了过多指标,会增加 Prometheus 的内存和存储开销。建议结合 scrape_series_added 观察新增序列数量,判断是否需要优化采集配置或调整抓取间隔。

该指标族的三个用途:

  • 用途一:规模与成本。 TSDB 的写入量 ≈ 所有 target 的 post 之和 ÷ 抓取间隔。容量规划先看它。
  • 用途二:找基数大户。 一个 target 的标签基数失控(把 user_id、url、trace_id 塞进标签),它一个就能顶别人一百个。
  • 用途三:发现空响应。 up 是 1 但样本数是 0,说明链路通、内容空,这也是开篇第一个问题的直接证据。
ini 复制代码
# 样本大户 top5
topk(5, scrape_samples_scraped)

# relabel 砍掉的比例(长期偏高要回头审规则)
1 - scrape_samples_post_metric_relabeling / scrape_samples_scraped

# 抓到了却没数据:up 为 1 且样本为 0
scrape_samples_scraped == 0 and up == 1

# 样本量环比:对比 1 天前,识别基数漂移
scrape_samples_scraped / (scrape_samples_scraped offset 1d)

分析要点:

  • post 比 scraped 小是正常设计,relabel 本来就要丢无效指标。但砍掉比例长期大于 50%,要回头确认是不是误杀。
  • 样本数是解析时的近似计数,和 TSDB 里的序列数不严格相等。看趋势足够,对账不必较真。

4、scrape_series_added:序列增长探测器

Prometheus 指标名 类型 含义说明
scrape_series_added Gauge 上次抓取中"第一次见到"的序列数

scrape_samples_scraped 看的是"这次抓了多少样本",scrape_series_added 看的是"这次有多少条序列是以前没见过的"。样本数大不一定可怕,序列数持续新增才是 TSDB 索引和内存压力的根源。

一条序列 = 指标名 + 完整标签集。比如:

bash 复制代码
http_requests_total{job="api", instance="10.0.0.1:8080", method="GET", path="/user/1"}
http_requests_total{job="api", instance="10.0.0.1:8080", method="GET", path="/user/2"}

这是两条序列。只要 path 里塞了用户 ID、URL、trace_id,序列数就会爆炸,而 scrape_samples_scraped 可能只是线性增长,scrape_series_added 会直接告诉你"新序列还在源源不断地出现"。

bash 复制代码
# 最近一次抓取新增序列最多的 target
topk(10, scrape_series_added)

# 按 job 汇总新增序列
sum by (job) (scrape_series_added)

# 新增序列突增:比 1 小时前高 5 倍
scrape_series_added / (scrape_series_added offset 1h) > 5

# 新增序列持续偏高
scrape_series_added > 1000

分析要点:

  • 短暂新增可能是发布、扩容、新标签、新实例上线;持续新增通常意味着标签基数失控。
  • 和 scrape_samples_scraped 联用:
    • 样本多、新增少:大盘稳定,成本高但可预测。
    • 样本不算多、新增多:基数爆炸,最危险。
  • scrape_series_added 是近似值,且序列可能因删除、重启、out-of-order 等因素再次出现。适合看趋势和突发,不适合精确计费。
  • 如果某个 target 的 scrape_series_added 长期大于 0,说明它的标签组合还在膨胀,应该去查 exporter 或业务代码的标签设计。

5、extra-scrape-metrics 三兄弟:body、timeout、sample_limit

这三个指标默认不生成,需要 Prometheus 启动参数开启:

ini 复制代码
--enable-feature=extra-scrape-metrics

大规模 target 下要评估这点额外开销,但通常远小于它们带来的排障价值。

5.1 scrape_body_size_bytes

Prometheus 指标名 类型 含义说明
scrape_body_size_bytes Gauge 最近一次成功抓取响应体的未压缩大小。抓取失败通常为 0;因超出 body_size_limit 失败时为 -1

该指标回答的是"这个 target 的 /metrics 到底有多大"。压缩传输小不代表 Prometheus 内存压力小,因为 Prometheus 拿到 body 后还要解压、解析。

bash 复制代码
# 响应体最大的 target
topk(5, scrape_body_size_bytes)

# body_size_limit 被触发
scrape_body_size_bytes < 0

# 平均每个样本占多少字节(需要先过滤 0 样本)
scrape_body_size_bytes / scrape_samples_scraped > 1000
  and scrape_samples_scraped > 0

分析要点:

  • scrape_body_size_bytes 大,通常和高基数、大文本、debug 信息暴露过多有关。
  • 如果 up=0 且 scrape_body_size_bytes=-1,优先怀疑 body_size_limit 配小了,或者 exporter 暴露了异常巨大的响应。
  • 压缩率很高的 target,网络传输可能不大,但 Prometheus 解析开销仍然高。

5.2 scrape_timeout_seconds

Prometheus 指标名 类型 含义说明
scrape_timeout_seconds Gauge 该 target 配置的抓取超时。默认 10s,且不能大于 scrape_interval

scrape_duration_seconds 是"实际花了多久",scrape_timeout_seconds 是"最多允许花多久"。只看 duration 无法判断离失败有多近,因为不同 job 的 timeout 可能不同。

bash 复制代码
# 抓取耗时水位:越接近 1 越危险
scrape_duration_seconds / scrape_timeout_seconds

# 查看非默认 timeout 的 target
scrape_timeout_seconds != 10

分析要点:

  • 用绝对值告警 scrape_duration_seconds > 5 容易误报,因为有的 job timeout 是 30s,有的只有 5s。水位比值更通用。
  • scrape_timeout_seconds 随配置变化,适合和 duration 放在同一张图里对照。
  • 如果水位长期大于 0.8,即使 up 还是 1,也应该提前处理,否则一次网络抖动就会翻 0。

5.3 scrape_sample_limit

Prometheus 指标名 类型 含义说明
scrape_sample_limit Gauge 该 target 的单次样本上限,0 表示不限

sample_limit 是保护 Prometheus 不被单个 target 拖垮的硬限制。超过限制时,整次抓取会失败,up 翻 0。scrape_sample_limit 让你在失败前看到自己离上限还有多远。

bash 复制代码
# 配置了 sample_limit 的 target
scrape_sample_limit > 0

# 样本数接近上限(超过 80%)
scrape_sample_limit > 0
  and scrape_samples_scraped / scrape_sample_limit > 0.8

分析要点:

  • 超限会导致抓取失败,而且失败时 scrape_samples_scraped 可能不完整,事后不好判断到底超了多少。
  • 提前看水位,比等 up=0 再查要主动得多。
  • 调高 sample_limit 不是唯一解。先看是 relabel 没过滤干净,还是 exporter 暴露了不该暴露的高基数指标。

三、告警与记录规则建议

以下供参考,阈值按环境调整。

yaml 复制代码
groups:

  - name: prometheus-scrape
    rules:
      - alert: TargetDown
        expr: up == 0
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Target {{ $labels.instance }} 抓取失败"
          description: "job={{ $labels.job }} instance={{ $labels.instance }} 已连续 2 分钟 up=0。"

      - alert: TargetAbsent
        expr: absent(up{job="nginx"})
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "job {{ $labels.job }} 的 up 序列消失"

      - alert: ScrapeSlow
        expr: scrape_duration_seconds / scrape_timeout_seconds > 0.8
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Target {{ $labels.instance }} 抓取耗时接近超时"
          description: "抓取水位已超过 80%,离 up=0 只差一次抖动。"

      - alert: ScrapeEmpty
        expr: up == 1 and scrape_samples_scraped == 0
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Target {{ $labels.instance }} 抓取成功但样本为 0"
          description: "链路通但内容空,检查 /metrics 或 relabel 规则。"

      - alert: ScrapeSeriesAddedBurst
        expr: sum by (job) (scrape_series_added) > 10000
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "job {{ $labels.job }} 新增序列突增"
          description: "可能存在标签基数爆炸。"

      - alert: ScrapeBodySizeLimitExceeded
        expr: scrape_body_size_bytes < 0
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Target {{ $labels.instance }} 响应体超过 body_size_limit"

      - alert: ScrapeSampleLimitClose
        expr: scrape_sample_limit > 0 and scrape_samples_scraped / scrape_sample_limit > 0.8
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Target {{ $labels.instance }} 样本数接近 sample_limit"

注意:使用 scrape_timeout_seconds、scrape_sample_limit、scrape_body_size_bytes 的规则,必须开启 --enable-feature=extra-scrape-metrics,否则表达式无数据。

四、小总

Prometheus 每次抓取,都会自动写下这批内置指标。它们不来自 exporter,不依赖被监控方配合,是监控采集链路自身的第一手数据。

可按三层理解:

  • 可用性层 :up。抓取成没成,第一条告警。
  • 性能层 :scrape_duration_seconds、scrape_timeout_seconds。抓取多慢,离失败多远。
  • 规模层 :scrape_samples_scraped、scrape_samples_post_metric_relabeling、scrape_series_added、scrape_body_size_bytes、scrape_sample_limit。抓了多少、入库多少、新增多少、响应多大、离限制多近。

​

​

相关推荐
cws2004012 天前
监控摄像头选型指南
运维·网络·监控
鸿观工坊3 天前
第13篇 监控安全与权限治理
监控
鸿观工坊3 天前
第11篇 监控报告编写:SLO/SLI 与数据分析方法
监控
鸿观工坊6 天前
第09篇 告警体系设计:Alertmanager 路由与告警治理
监控
做萤石二次开发的哈哈10 天前
视频解码器怎么对接?解码上墙、电视墙开窗与场景切换的ISAPI接入实战
人工智能·物联网·监控·视频编解码·大屏端·萤石开放平台·蓝海aiot一站式工作台
lisanmengmeng10 天前
nagios 图形化监控部署
监控·nagios
鸿观工坊10 天前
第5篇 Nginx 监控:流量、连接与性能指标
监控
鸿观工坊11 天前
第4篇 Spring Boot 应用监控:Micrometer 与 JVM 指标
监控
鸿观工坊11 天前
第1篇 Prometheus 监控体系全景与基础环境搭建
监控