同一条 api-a 告警的两个版本保留蓝色身份标签块和相同指纹,金色注解摘要从队列六项更新为八项。变化的是解释现场的上下文。

注解解释告警现场,同时保留稳定身份

告警标签标识正在跟踪哪一个条件,并提供路由与分组字段;注解则解释这个条件,例如当前值、简短摘要或操作手册链接。把变化中的说明文字放进标签,可能把同一个持续问题拆成多个身份;反过来,如果责任归属字段只存在于注解中,依赖标签的路由又可能无法识别应该由谁处理。两类字段都重要,但承担不同职责。 图解依据原文未修改的 Alertmanager 0.28.1 实验及明确提供的模板输入。稳定标签保留身份,共同字段是交集,Alerts 保留成员细节。集成重跑的历史阻塞状态不变,本轮没有执行。单独修改注解不保证立即通知,也不证明消息已送达。 区分身份与当前说明 队列告警可以保持 alertname、service 与 instance 标签稳定,同时把摘要从等待六项更新为等待八项。Alertmanager 可以在相同告警指纹下更新注解,而不是新增一条告警。指纹来自身份标签,不是通知渲染文本的哈希,所以文字改变不应该被直接理解为发生了另一个独立事件。这个边界也方便操作人员跟踪问题的持续变化。 该区别在进入 Alertmanager 之前也有影响。Prometheus 按告警标签集跟踪等待时长,如果标签中包含不断变化的当前值,就可能持续创建新身份,导致预期等待过程无法完成。除非数值确实定义另一种告警条件,否则应把它放在注解中。遇到反复等待却不触发的问题,应同时审阅规则标签和模板内容,而不是只调整等待参数。 ...

二月 22, 2028 · 3 分钟 · XB Field Notes
原始值在第零、一、二分钟上升,记录值则保持为一,直到第二分钟评估。中间查询看到原始值四、记录值一。

记录规则保存按周期计算的查询结果

记录规则在指定评估时刻执行 PromQL 表达式,把结果作为一个新指标保存。反复刷新的面板可以读取这个指标,减少重复计算。但简单把它称为缓存,会遮住一个重要区别:记录序列有自己的样本历史、写入节奏和标签集合,并不是任意查询请求的透明缓存。使用者必须知道读到的是哪次预计算,以及这个结果保留了哪些信息。 原文合成样例用每分钟输入和两分钟记录周期隔离节奏差异。新返回的查询可以读取更早的记录观测。历史本地 promtool 检查仅覆盖原文实验;本轮绘图没有新增执行或真实调度器证据。 三个时钟共同影响页面上的值 抓取决定原始观测何时进入存储,规则评估决定表达式何时生成记录样本,面板则决定何时以及以什么步长查询两者。把页面刷新得更快,不会让记录规则提前计算。因此,在两次规则评估之间读取记录指标,可能得到比同一时刻直接执行原表达式更旧的值。这是不同采样节奏的正常结果,不能仅凭两条曲线不同便断定计算错误。 规则组可以指定周期;未单独指定时,采用全局规则评估周期。同组规则按顺序执行,并使用相同的评估时间戳,所以后面的规则可以使用前面规则刚生成的结果。独立规则组即使写了相同的周期,也不能因此推导存在同样的先后顺序。依赖关系需要明确设计,不能依靠某次运行中碰巧出现的执行顺序。 预计算也改变了保留的数据 聚合表达式决定输出保留哪些维度。如果规则把 instance 求和消掉,面板之后就无法仅从这条记录序列恢复实例分布。仍需实例级排查时,应保留原始指标,并围绕已知消费者选择记录维度。每个剩余标签组合又是一条需要存储的新序列,因此把所有可能的聚合都做成规则,可能显著增加写入量和存储量,并不总是节省资源。 修改表达式会影响后续评估。正常重载规则不会用新定义重新计算全部旧样本,也不会自动填补规则创建之前的历史。在相同指标名下改变含义,可能让同一张图同时包含两套不兼容口径。应记录定义和时间窗口,在消费者要求历史可比时安排明确迁移,不能把正常重载解释为历史数据已经整体更新。 坏掉的样子 面板看起来停住,但原始样本仍在进入数据库时,应对照记录序列最近样本、规则组最近评估、执行耗时与错误。如果上一轮还没结束,下一次计划评估到来时会被跳过,直到当前轮完成或超时。把昂贵查询变成记录规则,只是把计算移入调度器,没有让计算成本消失。执行耗时长期接近周期时,新鲜度会比配置值更差。 查询变快也可能是因为聚合后回答的问题更窄。庆祝速度提升前,应确认被移除的维度确实不再需要。简单表达式通常不值得只为性能增加记录规则。应先测量重复查询成本和复用频率,再把新增序列、周期执行以及新鲜度延迟一起纳入判断。面板数量很多,也不等于每个表达式都必须预先保存。 快速验证 保存为 recording-cadence.py,运行 python3 recording-cadence.py。环境需要已经安装的 promtool,可以从 PATH 找到,或用 PROMTOOL 指定其可执行文件路径。此前记录的执行使用 Python 3.12.14 与 promtool 3.14.0;本轮文章复核没有重新运行该引擎。真实查询引擎在临时目录中评估合成样本,不启动服务器、监听端口或容器,也不联系外部服务。 from pathlib import Path from tempfile import TemporaryDirectory import os import shutil import subprocess # Uses a real, installed promtool; no server or Docker runtime is started. promtool = shutil.which(os.environ.get("PROMTOOL", "promtool")) if not promtool: raise SystemExit("Set PROMTOOL to an installed promtool executable") tests = r"""evaluation_interval: 2m rule_files: - rules.yml tests: - interval: 1m input_series: - series: "queue_depth{queue=\"orders\"}" values: "1 4 9 16" promql_expr_test: - expr: "sum(queue_depth)" eval_time: 1m exp_samples: - labels: "{}" value: 4 - expr: "queue:depth:sum" eval_time: 1m exp_samples: - labels: "{__name__=\"queue:depth:sum\"}" value: 1 - expr: "queue:depth:sum" eval_time: 2m exp_samples: - labels: "{__name__=\"queue:depth:sum\"}" value: 9 - expr: 'timestamp(queue:depth:sum)' eval_time: 1m exp_samples: - labels: '{}' value: 0 - expr: 'timestamp(queue:depth:sum)' eval_time: 2m exp_samples: - labels: '{}' value: 120 - expr: 'queue:depth:double' eval_time: 1m exp_samples: - labels: '{__name__="queue:depth:double"}' value: 2 - expr: 'queue:depth:double' eval_time: 2m exp_samples: - labels: '{__name__="queue:depth:double"}' value: 18 """ rules = r"""groups: - name: slow-recording interval: 2m rules: - record: queue:depth:sum expr: sum(queue_depth) - record: queue:depth:double expr: queue:depth:sum * 2 """ with TemporaryDirectory(prefix="prometheus-query-check-") as directory: root = Path(directory) (root / "tests.yml").write_text(tests, encoding="utf-8") if rules: (root / "rules.yml").write_text(rules, encoding="utf-8") result = subprocess.run([promtool, "test", "rules", "tests.yml"], cwd=root, text=True, capture_output=True, timeout=45) print(result.stdout, end="") if result.returncode: print(result.stderr, end="") raise SystemExit(result.returncode) 预期输出为 SUCCESS。第一分钟原始求和结果是四,但记录值仍为第零分钟的一;第二分钟记录序列更新为九。这里故意选择很便宜的表达式,以隔离周期差异,不是在建议为每个队列仪表值建立记录规则,也没有测量真实调度器在负载下的性能。输入时间线和断言直接说明为何同一时刻两个查询可以返回不同结果。 ...

一月 26, 2028 · 2 分钟 · XB Field Notes
十二条已存客户序列生成三行查询结果,原来的较大输入存储仍然保留。

高基数标签在查询之前就增加存储序列

Prometheus 序列由指标名与完整标签集合识别。在计数器上增加客户或请求身份,即使所有面板都会立刻把这些身份求和,也仍可能创建大量序列。查询聚合改变返回结果,不会删除已经入库的原始序列。存储和写入成本在用户打开面板之前就已经产生,因此不能只看面板返回多少行来判断仪表化是否足够节制。 查询聚合减少返回行数;在生产端累计所需的路由总量才会减少导出的身份。数字示意原文的固定总量样例;本轮未重跑 Prometheus 集成。 统计实际组合,而不是孤立取值 一个新的标签值,不是在整个数据库中自动对应一条新序列。它在指标名及其他标签形成不同组合的位置上,分别构成新身份。在明确指标与目标范围内,可能取值数的乘积给出笛卡尔组合上界;只有每种组合实际出现时,它才等于观测数量。维度之间存在约束时,上界可能远大于现实。真实数量还受到目标标签与指标族形态影响,不能把理论乘积直接宣称为已经发生的序列数量。 来自少量路由模板的标签可以有边界,包含标识符和查询参数的完整 URL 往往没有。客户身份、请求编号、任意错误文本和时间戳也需要明确审视。带多个桶序列的直方图,还会进一步放大每组标签组合的影响。预算应依据真实输出和预期工作负载,而不是只看某一个维度有多少取值,也不能因为每条样本数值很小便忽略身份成本。 查询少几行,不代表少存几行 按路由求和的表达式,可以读取十二条客户级序列后只返回三个结果,但十二条输入仍然存在。如果指标契约需要的就是路由总量,仪表化可以直接维护路由级计数器,只导出三条序列。这是在源头减少输出身份,不是要求每个消费者都重复隐藏额外维度。两种方式可能显示相同总数,却具有不同的数据保留和成本含义。 入库时删除标签不等于完成上述累计。不同样本可能获得同一个身份,而重新标记不会替它们决定如何相加。应使用明确的仪表化变更,或定义清楚的记录查询;后者会新增派生序列,原始数据仍按照存储策略保留。确实需要详细关联时,可以放入日志或追踪,但它们同样需要各自的权限、保留期限与成本约束,不是完全没有代价的替代存储。 使用正确范围的清单诊断增长 TSDB 状态接口提供头部统计,其中包括按指标名汇总的序列数量。这些值有助于定位大型指标族,但不是完整成本模型。采样间隔、标签长度、身份更替、数据块处理、保留策略和存储行为都会影响资源。不能把一个小实验中减少的序列比例,直接换算成生产内存或磁盘会减少的相同比例,更不能把该比例当成容量压测结果。 当一些头部序列已经没有近期可选择样本时,即时查询计数与头部序列统计可能不同;历史存储块又是另一种范围。比较报告时应记录测量时刻和统计总体。某次发布改变标签值后,旧身份仍可能留在存储中,因此查询当前返回更少结果,不代表之前的全部成本都已经消失。需要分别观察新增速度、当前可见序列和保留历史。 每次抓取的样本上限是保护措施,不是选择性聚合。指标重新标记之后仍超过该上限时,Prometheus 会把整个抓取视为失败,并不是悄悄保留一个便宜的子集。因此,保护资源的同时也可能失去有用观测。应根据真实输出制定预算,并对抓取失败设置清楚的信号,不能把限制触发后的缺失误解成业务没有流量。 坏掉的样子 新增无边界标签可能持续增加写入与内存压力,直到抓取或查询受到影响。应先定位指标族与仪表化改动,再从源头或经过审阅的样本过滤策略阻止不必要的新身份。立即删除历史数据不是所有场景都必须采用的恢复步骤,改变保留时间也不会瞬间清除全部资源成本。处理方式应依据实际瓶颈,而不是套用统一删除命令。 更隐蔽的失败是查询聚合很成功,面板看起来很小,但原始指标仍持续增长。应同时审阅导出身份和查询输出,为新增维度说明预期取值范围、有用消费者与负责人。生产计数器速率查询还应保留正确的重置处理;本实验用于比较固定总量的即时求和,不能代替先求速率再聚合的运行监控语义。 快速验证 保存程序为 cardinality.py,执行 python3 cardinality.py。需要 Docker 与 Prometheus 3.5.1,必要时下载镜像。本地文本端点为三个路由分别导出四个合成客户身份,同时独立导出已经累计好的路由总量。真实服务器抓取这些样本,并提供查询结果与 TSDB 统计,实验不会使用任何真实客户信息。 ...

一月 10, 2028 · 2 分钟 · XB Field Notes
原文计数器样本先增长、急降重置,再次增长。第一个样本位于五分钟左开范围之外。箭头从所选观测指向原文样例的每秒 5/6 速率估计。

Prometheus rate 估计计数器每秒的增长速度

请求计数器回答进程累计记录了多少事件,速率则回答这些事件到来得有多快。Prometheus 的 rate 估计指定范围内每秒平均增长量,修正能够观测到的计数器重置,并向范围边界进行外推。结果具有明确的时间单位,适合观察负载变化;但它不是两次抓取之间全部事件的精确还原,更不能凭空补回没有采到的重启历史。 数值来自原文合成样本的 promtool 实验,其历史本地执行证据与本轮绘图分别保留。五分钟范围排除第零分钟,修正可见重置并外推。每条计数器应先求速率再求和。本轮未运行查询引擎或真实 Prometheus 服务。 采样决定能够推断多少事实 普通计数器在重置前持续增长,进程重启是常见的重置原因。相邻已观测样本出现下降时,计数器函数会按重置处理。不过,如果两次抓取之间已经重启并重新累计,而且新值超过旧样本,重置可能完全不可见。提高抓取频率可以提升观测分辨率,但任何查询都不能确定地恢复一段没有被记录的历史。 应先对每条计数器序列求 rate,然后聚合结果。如果先求和,一台实例的增长可能掩盖另一台实例的重置。标签决定序列身份,替换实例使用新标签时,是开始另一条序列,不是自动接续旧实例。队列长度等仪表值本来就允许正常下降,把它们交给计数器速率函数,会把真实下降错误解释为重置。 选择的范围也是指标含义的一部分 范围选择器左开右闭。在第五分钟求 [5m] 时,恰好位于第零分钟的样本不在范围内。对普通浮点计数器求速率至少需要两个可用样本;只有一个样本时得到空结果,并不表示业务流量为零。因此,范围不仅要覆盖正常抓取周期,还需要考虑偶发漏抓后的样本数量,不能仅凭希望曲线更灵敏就无限缩短。 较长窗口通常会平滑短促突发,也让突发离开平均值的时间更晚;较短窗口响应更快,但观测更少,而且可能变成空结果。应依据事件持续时间与检测目标选择范围,并在面板上明确标注。irate 使用最后两个样本,rate 使用所选范围,两者可以针对同一指标回答不同问题,只要面板清楚说明各自含义,不把数值当成同一种口径比较。告警通常应优先使用 rate:即使整体负载仍然偏高,irate 的短暂下降也可能重置待触发告警的 for 等待。 规则评估周期决定何时提出查询问题,不决定目标已经被抓取了多少次。如果目标每分钟才采集一次,即使面板每秒刷新,也不会凭空产生新的观测。分析告警响应速度时,需要分别检查采集与评估这两个周期,不能只缩短页面刷新时间。 坏掉的样子 刚创建的序列可能要等第二个样本到来后才出现在速率面板。把所有空值都补成零,可能掩盖采集故障。遇到空白,应先检查原始序列、时间戳和抓取状态,再判断业务是否空闲。另一种问题是窗口太长:短时间过载已经影响用户,但平均线被长窗口稀释,看起来始终平稳,告警因而没有达到阈值。 重置修正不代表缺口对准确性没有影响。漏抓可能隐藏突发或多次重启,范围边界的外推本身也属于估计。increase 以事件数量单位表达相应的范围估计,即使原始计数器只有整数,也可能返回小数。如果场景需要精确账务或计费总数,应依靠业务记账记录,不能把监控面板描述成可以完整重建交易流水的工具。 快速验证 保存为 rate.py,运行 python3 rate.py。环境需要已经安装的 promtool,可以从 PATH 找到,或用 PROMTOOL 指定其可执行文件路径。此前记录的执行使用 Python 3.12.14 与 promtool 3.14.0;本轮文章复核没有重新运行该引擎。真实查询引擎在临时目录中评估合成样本,不启动服务器、监听端口或容器,也不联系外部服务。 ...

十二月 24, 2027 · 2 分钟 · XB Field Notes
带 payments 团队和 critical 严重程度标签的告警进入根路由。支付路由匹配后继续检查后面的严重程度路由,选择 payments 与 pager 接收器。箭头表示按顺序选择,不表示已经送达。

Alertmanager 通过标签匹配树选择告警接收器

Alertmanager 根据告警标签遍历路由树,选择通知接收器。路由树表达责任归属与升级策略,接收器则定义实际通知集成。配置能够解析,并不代表每一类告警都被分配给正确目的地。因此,不能把重载成功当作路由有效的完成证据;应该先核对进入系统的标签契约,再验证整棵树针对典型告警的选择结果。 每个路由指定一个接收器,子路由继承未覆盖配置。先按顺序匹配并选择接收器,再单独验证送达链路。图示依据原文预期路由用例;未改动的 Docker/amtool 实验仍为受阻状态,本轮没有重跑。 既要看匹配,也要看何时停止 每条告警都会进入必须匹配所有告警的根路由。子路由继承没有主动覆盖的配置;没有子节点匹配时,由当前节点处理。否则,遍历通常在第一个匹配的子节点后停止。匹配节点配置 continue: true,才允许继续检查后续同级节点。这不表示配置中的所有接收器都会获得同一条告警,未匹配的节点仍然不会参与。 一个路由节点只能指定一个接收器。接收器内部可以包含多个通知集成,多条匹配路由也可以选择不同接收器,两者是向多个目的地通知的不同方式。不能把路由的 receiver 字段直接换成列表,就期待具有相同行为。选择方案时应核对是否会重复通知,以及不同目的地是否需要独立的分组方式、升级策略和发送节奏。 责任归属依赖稳定的标签契约 匹配 team="payments" 的路由,需要进入 Alertmanager 的告警真正带有这个标签值。名为 team 的注解不能满足该条件。Prometheus 表达式中的聚合可能提前移除一个维度,所以应该检查最终告警标签,包括告警重新标记的影响,不能假定原始指标上的标签会原样保留到通知阶段。原始指标存在团队字段,不足以证明路由可以看到它。 ...

十二月 8, 2027 · 2 分钟 · XB Field Notes
金色等待区间从第一分钟开始,经过两分钟评估后在第三分钟进入红色触发状态,第四分钟变为非活动状态。这些是通知送达之前的规则状态。

Prometheus 规则先跟踪告警状态,再交给通知链路

告警规则评估 PromQL 表达式,并持续跟踪表达式返回的标签集。Prometheus 判断每个告警是等待还是触发,Alertmanager 接收告警信息后负责通知路由、分组、静默与抑制。排查时应分别追踪这些环节:规则显示正在触发,是规则状态的证据,不能直接证明某个人已经收到消息。把状态和送达混为一谈,会使漏通知问题很难定位。 时间线来自原文合成规则实验:稳定的队列身份、每分钟评估与 for: 2m。采用默认恢复行为,没有配置 keep_firing_for。历史本地 promtool 结果保持不变,本轮没有重新执行。分组、抑制和送达仍需独立证据。 表达式返回元素就会激活告警候选项 表达式返回的每个元素代表一个活动告警候选项。queue_depth > 5 这样的比较会过滤不满足条件的数值;但加上 bool 修饰符之后,不满足条件的比较仍会留下数值为零的元素。告警规则依据元素是否存在来激活候选项,因此误用该修饰符,可能让数值已经为零的结果也进入告警流程。这是查询看似合理、规则却持续激活的常见原因。 标签定义告警身份。服务、队列与严重程度等稳定路由维度适合放在标签中,变化中的说明值则适合放在注解中。如果把当前队列大小写进标签,每次数值变化都可能创建一个新身份,重新开始等待。把大小写进注解则可以解释现场状态,同时保留原有告警身份。需要审阅的不只是阈值,还有标签和注解承担的职责。 等待时长通过评估时刻观察 配置 for: 2m 后,一个新出现的标签集会先等待,直到它在评估中持续活动两分钟。如果规则每分钟评估一次,第一分钟首次看到异常,就可能在第三分钟进入触发状态。引擎观察的是评估结果,不是样本之间连续发生的全部物理事实。因此,实际发现时间还包括等待下一次评估的时间,不能只用配置的等待时长计算最坏延迟。 省略 for 时,活动表达式可以在第一次评估就触发。这可能适合含义明确且必须立即处理的故障,但也意味着一个异常样本便足够触发。应根据失败语义主动选择,而不是由于忘记配置而意外采用默认行为。 ...

九月 1, 2027 · 2 分钟 · XB Field Notes
每秒十个请求和每秒一个请求的两组不等流量分别合并错误量与请求量,得到服务加权占比 0.6 除以 11,约百分之五点四五。

记录规则应保留比例的分子和分母

当查询成本和复用频率足以支持预计算时,反复使用的服务级查询适合做成记录规则。关键问题是保存什么。如果只保存每个实例的错误百分比,可能丢掉之后聚合必需的流量规模;同时保存错误速率与请求速率,则保留了分子和分母,消费者能够据此计算按实际请求量加权的服务错误占比,而不是把每台实例当成相同流量。 保留分子与分母,先求速率再聚合,并对齐流量总体、时间窗口和服务标签。数值来自原文本地合成规则实验。历史通过范围保持不变;本轮没有新增测试或性能结论。 百分比必须对应明确的总体 假设繁忙实例每秒处理十个请求,每秒发生零点一个错误;空闲实例每秒处理一个请求,却每秒发生零点五个错误。两个实例的错误占比分别为百分之一与百分之五十。直接平均得到百分之二十五点五,相当于给两个实例相同权重,但它们的请求量实际上相差十倍。这个数描述平均实例百分比,不描述服务处理的全部请求。 服务合计每秒处理十一个请求,发生零点六个错误,因此错误占比是 0.6/11,约百分之五点四五。这是聚合错误量除以聚合请求量。两侧必须描述同一组符合条件的流量,并使用相同时间窗口。如果分子排除了分母包含的一类失败,或者两侧聚合了不同服务,面板即使计算得很快,结果也仍然不成立。 按顺序建立规则依赖 先对每条计数器序列应用 rate,使已经观测到的重置能够在聚合前得到处理,再按照消费者确实需要的维度求和。本例依次记录服务与实例维度的请求速率、服务请求速率、服务错误速率,以及最终服务错误占比。第一个实例级中间结果用于展示明确的前后依赖,后续规则实际消费这个结果,而不是重复写一个看似相关的名字。 四条规则位于同一个组,按声明顺序运行,使用相同评估时间。分子与分母都保留匹配的 service 标签,因此除法能够把对应服务配对。如果分母额外保留实例标签,就会改变向量匹配关系,可能导致没有结果,或需要重新设计连接方式。测试应同时检查输出标签和数值,不能只看到一个合理百分比就认为查询正确。 命名应说明聚合层级和范围。两分钟速率与三十分钟速率即使当前值恰好相同,也不是同一种量。应在规则旁记录哪些事件计入总体,并明确消费它的面板与告警。沿用旧名称但修改公式,只会改变未来记录样本,不会重新解释已经写入的历史。需要保持时间可比性时,定义变更必须被消费者看见。 坏掉的样子 平均百分比可能让一台低流量故障实例主导整个服务报告,也可能掩盖高流量实例的失败。提高评估频率不会修复这个算术问题,应恢复底层计数或速率,在分别聚合后再相除。如果最后只保留了百分比,通常无法仅靠这些百分比重建原始流量权重,因为相同占比可以来自完全不同的请求数量。 零流量是另一类情况。分母为零时,错误占比并没有被定义为零;分子缺失也可能代表仪表化缺少序列,而不是没有错误。应根据指标契约明确这些语义,避免自动把所有空结果或未定义数值显示成健康的零。还应确认健康期间错误计数器是否持续导出,避免只有发生错误后才创建序列,导致正常状态与数据缺失难以区分。 快速验证 保存为 recording-weighted.py,在 PATH 中准备已安装的 promtool,或用 PROMTOOL 指定可执行文件,再运行 python3 recording-weighted.py。保留的 2026-10-15 审核记录说明,完整程序在 promtool 3.14.0 与 Python 3.12.14 上通过;本次源码审核没有重跑规则引擎。真实规则引擎评估每分钟一份的合成计数器,包含权重明显不同的实例,以及独立的零流量、序列缺失案例。 from pathlib import Path from tempfile import TemporaryDirectory import os import shutil import subprocess promtool = shutil.which(os.environ.get("PROMTOOL", "promtool")) if promtool is None: raise SystemExit("Set PROMTOOL to an installed promtool executable") promtool = str(Path(promtool).resolve()) tests = r"""evaluation_interval: 1m rule_files: - rules.yml tests: - interval: 1m input_series: - series: "http_requests_total{service=\"checkout\",instance=\"busy\"}" values: "0+600x5" - series: "http_errors_total{service=\"checkout\",instance=\"busy\"}" values: "0+6x5" - series: "http_requests_total{service=\"checkout\",instance=\"quiet\"}" values: "0+60x5" - series: "http_errors_total{service=\"checkout\",instance=\"quiet\"}" values: "0+30x5" promql_expr_test: - expr: "service:http_requests:rate2m" eval_time: 5m exp_samples: - labels: "{__name__=\"service:http_requests:rate2m\",service=\"checkout\"}" value: 11 - expr: "abs(service:http_errors:rate2m - 0.6) < bool 1e-12" eval_time: 5m exp_samples: - labels: "{service=\"checkout\"}" value: 1 - expr: "abs(service:http_errors:ratio_rate2m - 0.6/11) < bool 1e-12" eval_time: 5m exp_samples: - labels: "{service=\"checkout\"}" value: 1 - expr: "abs(avg(rate(http_errors_total[2m]) / rate(http_requests_total[2m])) - 0.255) < bool 1e-12" eval_time: 5m exp_samples: - labels: "{}" value: 1 - interval: 1m input_series: - series: 'http_requests_total{service="idle",instance="one"}' values: "0+0x5" - series: 'http_errors_total{service="idle",instance="one"}' values: "0+0x5" promql_expr_test: - expr: 'count(service:http_errors:ratio_rate2m != service:http_errors:ratio_rate2m)' eval_time: 5m exp_samples: - labels: "{}" value: 1 - interval: 1m input_series: [] promql_expr_test: - expr: 'count(service:http_errors:ratio_rate2m) or vector(0)' eval_time: 5m exp_samples: - labels: "{}" value: 0 """ rules = r"""groups: - name: service-rates interval: 1m rules: - record: instance:http_requests:rate2m expr: sum by (service, instance) (rate(http_requests_total[2m])) - record: service:http_requests:rate2m expr: sum by (service) (instance:http_requests:rate2m) - record: service:http_errors:rate2m expr: sum by (service) (rate(http_errors_total[2m])) - record: service:http_errors:ratio_rate2m expr: service:http_errors:rate2m / service:http_requests:rate2m """ with TemporaryDirectory(prefix="prom-rule-test-") as directory: work = Path(directory) (work / "tests.yml").write_text(tests, encoding="utf-8") (work / "rules.yml").write_text(rules, encoding="utf-8") subprocess.run([promtool, "test", "rules", "tests.yml"], cwd=work, check=True, timeout=45) 预期输出为 SUCCESS。记录请求速率为十一,错误速率为零点六,最终占比为 0.6/11。另外一项断言明确展示,错误的实例比例平均法得到 0.255。涉及浮点除法的比较使用很小的数值容差,标签断言则确认仍保留 checkout 服务身份。这些检查同时覆盖计算次序、依赖输出和最终聚合口径。 ...

八月 31, 2027 · 2 分钟 · XB Field Notes
Prometheus 主动向两个目标端点发出 HTTP 请求。合法响应返回样本并产生 up=1;被拒绝的抓取在红色停止标记处终止,产生 up=0。这些都是采集结果。

Prometheus 主动抓取指标,并记录抓取结果

Prometheus 会主动请求每个已配置目标的 HTTP 指标端点。目标负责暴露观测值,采集器决定抓取时刻、解析响应并保存样本。这种安排让采集故障能够从采集器一侧被看见,但不能保证端点一定可达、所有预期目标都被发现,也不能保证用户的登录或下单流程正常。理解这些边界,才能把采集结果转换成准确的告警和排查动作。 对于已配置实例,Prometheus 生成 up:抓取成功为 1,失败为 0。移除的目标之后可能不再出现在查询中。采集成功不保证应用健康,也不保证全部业务指标存在。本轮绘图没有重跑原文实验。 一个任务包含多个独立抓取的实例 任务通常把用途相同的目标组织在一起,例如一组接口服务副本。每个目标仍是独立实例,具有自己的抓取结果。常见的 job 与 instance 标签标识这层上下文,最终标签也可能经过重新标记而改变。服务发现提供候选目标,抓取配置再决定实际访问的端点、协议、周期、超时和认证方式。因此,目标没有被发现与目标已经配置但抓取失败,是两类不同的问题。 采集器必须能够连接目标。虽然导出器不需要主动向采集器上传指标,目标仍然需要允许经过授权的采集器访问其入站端口。网络策略、证书身份、认证凭据与路由不会因为采用拉取模式而消失。拉取只是改变连接由哪一方发起,不能把任意导出器变成可以直接暴露在公网的安全接口。部署时要从采集器所在网络检查这条路径。 准确理解系统生成的指标 对于已配置的实例,Prometheus 会生成 up 指标,抓取成功时为一,失败时为零。它是指标名称,不是所谓的 up 标签。抓取耗时与样本数量则补充了采集质量的证据。导出器可能在后端数据库不可用时仍返回合法响应,也可能漏掉一项重要业务指标,因此即使 up 为一,也不能推导后端依赖和全部业务观测都正常。 这些进一步的问题应由应用结果指标、导出器专门提供的依赖状态,以及实际业务探测回答。反过来,up=0 描述的是采集失败,监控网络故障可能使它变为零,而用户请求仍然成功。告警措辞应写清采集目标与错误证据,避免让响应人员把所有监控链路问题直接当成客户故障。业务影响仍需要另一组证据确认。 指标重新标记不会应用于 up 这类自动生成序列。因此,即使过滤掉了全部业务样本,也可能仍然看到抓取成功。调整过滤规则时,应把预期指标族或样本量纳入验收,分清主动丢弃观测与导出器故障。一个绿色采集指标不能证明过滤后的业务数据仍满足面板和告警所需的契约。 坏掉的样子 连接被拒绝、请求超时、证书校验失败或导出格式无效,都可能让抓取失败。先查看目标的最近抓取错误,再决定需要调整什么。延长周期无法修复错误端口;增大超时可能让缓慢的导出器看起来恢复,却不会消除它的执行成本。采集变贵时还应检查输出序列数量和响应大小,确认是否新增了不必要的标签组合或昂贵查询。抓取超时不能超过配置周期,缩短周期前则应评估导出器负载。更快的轮询可能成倍增加导出器对数据库的查询次数,却不会降低每次查询的成本。 ...

八月 30, 2027 · 2 分钟 · XB Field Notes