如何统计构建失败率与失败类型分布

统计构建失败率,关键在动手计算前先把统计对象、时间窗和分母口径定清楚,再为失败构建打上可操作的失败类型标签,才能得到有解释力的失败类型分布。重跑率需要单独统计,否则重跑触发的构建会稀释失败率。本文给出一套可复算的口径、字段清单、计算步骤和算例,并说明如何以自身历史基线判断是否启动专项治理。




要点总览(TL;DR)


  • 统计构建失败率前先声明三件事:统计对象是流水线还是构建任务、时间窗按天/周/发布周期、分母是否包含取消、跳过和重跑触发的构建,否则数字无法对齐。
  • 失败类型分布依赖可操作的标签体系,建议覆盖编译错误、单元测试失败、依赖下载失败、环境或资源问题、配置错误、超时、脚本错误等,未分类单列不并入其他。
  • 重跑率要单独统计并说明重跑成功是否回写原构建结果,重跑计入分母会稀释失败率,建议保留原始失败记录、重跑单独标记。
  • 判断是否构成专项治理问题,以自身历史基线为参照:失败率与重跑率连续多个周期偏高,且失败类型前三类集中度高或集中在少数流水线,才进入治理候选,不套用通用达标线。


评估目标:回答什么才算“构建频繁失败”


“构建频繁失败”是一句感受,无法直接指导行动。评估工作要把它拆成三个可以回答的问题,每个问题对应一个指标和一种判断方向。


  • 失败率处于什么水平:在选定的时间窗内,失败构建占总构建次数的比例是多少,按流水线、分支拆分后是否集中在少数对象上。
  • 失败类型是否集中:失败构建按原因归类后,前几类占多大比例。集中度高说明有明确的改进入口,分散则可能指向流程或环境层面的系统性问题。
  • 对重跑的依赖有多强:有多少构建是通过重跑才通过的,重跑率与重跑成功率共同反映流水线的稳定性。

评估对象需要先声明:统计的是流水线维度的构建,还是具体构建任务(Job)维度的执行。两者分母不同,结论也不同。按流水线统计适合判断某条交付链路是否稳定,按构建任务统计适合定位具体环节。同一份报告内应保持一种口径,跨报告比较前先确认对象一致。


评估结论的用途是判断是否需要启动专项治理、治理从哪里切入。它描述的是流水线和构建过程的状态,不用于评价某位工程师的工作表现。



指标与范围:失败率、类型分布、重跑率的定义


三个指标需要同时给出公式、分子分母、时间窗和单位,否则不同人算出的数字无法对齐。下表是一份可直接采用的定义框架。


指标 公式 分子 分母 单位
构建失败率 失败构建次数 ÷ 总构建次数 × 100% 结果状态为失败的构建次数 时间窗内纳入统计的全部构建次数 百分比
失败类型分布 某失败类型次数 ÷ 失败构建总次数 × 100% 该类型下的失败构建次数 失败构建总次数 百分比
重跑率 重跑构建次数 ÷ 总构建次数 × 100% 由重跑触发的构建次数 时间窗内纳入统计的全部构建次数 百分比

分母口径是争议最多的地方,需要在报告中写明。被取消和跳过的构建通常不计入分母,因为它们没有产生真实的构建结果;重跑触发的构建是否计入分母,取决于你想回答的问题——若关注“用户感知到的构建成功率”,重跑应计入分母;若关注“首次构建的质量”,则应以首次构建为分母单独计算首跑失败率。两种口径可以并存,但不能混用后互相比较。


失败类型分布需要约定单选还是多选。一次构建失败可能同时触发编译错误和超时,若允许多选,各类型占比之和会超过100%,此时应说明“占比之和大于100%属正常”。若要求单选,则需规定主因优先级的判定顺序,例如按根因层级从编译、依赖、测试到环境依次归类。


重跑率还需说明重跑成功是否回写原构建结果。若回写,原失败记录可能被覆盖,失败率会被低估;若不回写,原构建保留失败状态、重跑作为新记录,失败率更接近真实情况。建议保留原始记录,重跑单独标记,统计时按上述口径分别计算。


时间窗按天、周或发布周期设定,需与团队节奏匹配:日构建量大的流水线可按周统计,发布周期长的项目可按发布周期统计。统计粒度至少支持流水线、分支、项目三个层级。纳入范围要明确手动触发、定时任务、合并请求触发的构建是否计入,常见做法是全部纳入但在拆分分析时按触发方式分组,避免手动调试构建拉高整体失败率。



数据口径与证据:失败记录从哪里取、怎么打标签


可复算的前提是每条构建记录都有稳定字段。数据主要来自流水线运行记录和构建日志,失败原因字段若流水线工具本身提供则直接取用,不提供则从日志中提取关键错误信息。


必备字段清单如下:


  • 构建ID:唯一标识,用于去重和关联重跑。
  • 流水线名称与分支:用于拆分统计。
  • 触发方式:手动、定时、合并请求、重跑等。
  • 开始时间与结束时间:用于确定时间窗归属和计算构建时长。
  • 结果状态:成功、失败、取消、跳过。
  • 重跑关联ID:标记该构建是否为某次构建的重跑,以及重跑的是哪一次。
  • 失败类型:标签字段,允许为空。

失败类型标签体系应覆盖团队实际遇到的主要问题,并保留兜底类别。一个可用的初始分类如下:


失败类型 典型表现
编译错误 代码语法、类型不匹配、编译阶段报错
单元测试失败 测试用例断言失败、覆盖率门禁未通过
依赖下载失败 包仓库不可达、版本冲突、制品缺失
环境或资源问题 构建节点不可用、磁盘或内存不足、网络超时
配置错误 流水线配置、凭据、参数设置错误
超时 构建或测试阶段超过设定时限
脚本错误 构建脚本、部署脚本执行异常
其他 无法归入以上类别的失败
未分类 尚未打标签的失败构建,单列统计

标签由谁打、何时打需要固定下来。常见做法是规则自动归类处理高频且特征明确的类型,例如日志中出现依赖下载超时关键词即归为依赖下载失败;剩余记录由流水线负责人或值班人员在处理失败时补充标注。自动归类覆盖率高时人工负担小,但规则需要定期复核,避免误判累积。未分类记录必须单列,不并入“其他”,否则类型分布会失真,也无法反映标注工作的完成度。


在数据采集与流转环节,ONES 可自动同步编排的流水线数据,更新执行状态和日志,并将流水线与项目关联,在项目、迭代、需求中可视化代码提交、流水线构建和产品发布过程。这意味着构建记录可以与需求、迭代上下文放在一起查看,失败构建对应的需求变更和提交范围更容易追溯,为失败类型标注提供背景信息。ONES 支持多种数据报表,可追溯团队在 DevOps 工具链上的操作,用于集中度量和分析。具体报表是否内置失败率或失败类型分布指标,需以实际配置为准。



计算与评估步骤:从原始记录到判断结论


以下五步构成一条可重复执行的流程,每一步都有明确的产物。


  1. 导出并去重。导出时间窗内全部构建记录,按构建ID去重,剔除重复同步产生的副本。产物是一张干净的构建明细表。
  2. 计算失败率与重跑率。按声明的分母口径计算整体失败率和重跑率,再按流水线、分支拆分。产物是分层的指标表,能看出整体水平和分布差异。
  3. 打标签并计算类型分布。对失败构建逐条标注失败类型,计算各类型占比和前三类集中度。产物是失败类型分布表和集中度数值。
  4. 与自身历史基线对比。取前若干周期的同口径数据作为基线,观察当前周期失败率和重跑率是否持续偏高。单周期波动不构成结论,连续多个周期偏离才值得关注。
  5. 定位集中点并形成判断。检查失败是否集中在少数流水线或少数失败类型上,结合重跑成功率判断稳定性问题的性质,输出是否进入专项治理候选的结论。

判断规则可以写成:失败率与重跑率连续N个周期高于自身基线,且失败类型前三类占比超过设定阈值(例如60%),或失败集中在少数几条流水线上,则进入专项治理候选。N和阈值由团队根据构建频次和历史波动自行设定,不套用外部通用达标线。若失败率偏高但类型高度分散、重跑率正常,更可能是流程或环境层面的问题,治理方向应放在环境稳定性和构建规范上,而非逐个修复失败用例。



算例:一周构建数据的失败率与类型分布


以下为演示数据,用于说明计算过程,不代表任何真实团队的水平。


某项目一周内共有500次构建,其中失败60次,重跑触发的构建40次。失败构建的类型分布为:编译错误18次、单元测试失败15次、依赖下载失败12次、环境或资源问题6次、配置错误4次、超时3次、未分类2次。


计算过程:


  • 构建失败率 = 60 ÷ 500 × 100% = 12%。
  • 重跑率 = 40 ÷ 500 × 100% = 8%。
  • 编译错误占比 = 18 ÷ 60 × 100% = 30%;单元测试失败 = 15 ÷ 60 × 100% = 25%;依赖下载失败 = 12 ÷ 60 × 100% = 20%;环境或资源问题 = 10%;配置错误 ≈ 6.7%;超时 = 5%;未分类 ≈ 3.3%。
  • 前三类集中度 = 30% + 25% + 20% = 75%。

若该分支在某一周没有任何构建,分母为零,失败率应记为“无数据”而非0%,避免把“没有构建”误读为“构建全部成功”。同理,若某类型失败次数为零,其占比记为0%,不参与集中度排序。


从这组数据可以读出:失败率12%、重跑率8%,前三类集中度75%,说明失败主要集中在编译、测试和依赖三个环节,具备明确的改进入口。若该团队历史基线为失败率8%、重跑率4%,则本周两项指标同时偏高,且类型集中,符合进入专项治理候选的条件。治理可从依赖下载失败入手,检查包仓库可用性和依赖版本锁定策略,再处理编译错误的常见模式。



解读与限制:指标能说明什么、不能说明什么


失败率反映的是构建结果的比例,不能直接等同于工程质量。构建频次高、分支策略激进、合并频繁的团队,失败率天然可能更高;环境不稳定也会推高失败率,而这类失败与代码质量无关。解读时应结合失败类型分布,区分代码相关失败和环境相关失败。


重跑率低不代表流水线健康。若团队习惯在失败后直接修改代码重新提交而不使用重跑,重跑率会很低,但失败率可能并不低。重跑率需要与重跑成功率和失败类型一起看:重跑成功率高说明失败多为偶发,重跑率低且失败率高则可能说明失败被掩盖或未被处理。


不同流水线、不同项目之间的横向比较需要先对齐口径。分母是否包含重跑、触发方式构成、时间窗长度不同,都会让数字失去可比性。跨团队比较前,应统一分母定义、触发方式范围和统计周期,否则比较结果没有意义。


本文不设通用达标线。失败率多少算高,取决于团队自身的构建频次、技术栈和历史水平,基线应来自自身历史数据,并随团队规模和技术演进定期更新。单指标也不能作为绩效依据,失败率、重跑率、失败类型分布和具体定位结果需要一起看,才能支撑改进决策。



常见问题


构建被取消或跳过时,应该计入失败率的分母吗?


通常不计入。被取消和跳过的构建没有产生真实的构建结果,放进分母会让失败率偏低,也无法反映流水线的实际稳定性。建议在报告中明确写出排除规则,并在明细表中保留这些记录的状态字段,便于复核时还原。如果团队关心的是“所有触发过的构建中有多少失败”,也可以单独算一个含取消的口径,但两个口径要分开呈现,不能混用后互相比较。


失败类型允许多选时,各类型占比加起来超过100%怎么解释?


这是多选口径下的正常现象。一次构建失败可能同时涉及编译错误和超时,两个标签都会计入。此时应在报告里注明“占比之和大于100%属正常”,并把集中度计算方式写清楚,例如按失败构建去重后统计“至少命中前三类之一的构建占比”。如果团队更习惯单选口径,就需要规定主因优先级,例如按编译、依赖、测试、环境的顺序归类,保证每条失败构建只落一个类型。


重跑成功之后,原来那次失败还要算进失败率吗?


建议保留原始失败记录并计入失败率,重跑作为新记录单独标记。如果把重跑成功回写到原构建、覆盖失败状态,失败率会被系统性低估,也看不出团队对重跑的依赖程度。实际操作中可以同时给出两个数字:含重跑的失败率反映用户感知到的构建结果,以首次构建为分母的首跑失败率反映代码提交本身的质量。两个口径并存时,需在报告中注明各自的分母定义。


失败类型标签由人工打还是规则自动归类?


常见做法是两者结合。特征明确、高频的类型用规则自动归类,例如日志中出现依赖下载超时关键词即归为依赖下载失败;规则覆盖不到的记录由流水线负责人或值班人员在处理失败时补充标注。自动归类比例高时人工负担小,但规则需要定期复核,避免误判累积。无论哪种方式,未打标签的记录都要单列为“未分类”,不并入“其他”,这样类型分布才不失真,也能反映标注工作的完成度。


不同团队之间可以直接比较构建失败率吗?


直接比较通常没有意义,需要先对齐口径。分母是否包含重跑、触发方式构成(手动调试构建多会拉高失败率)、时间窗长度、统计对象是流水线还是构建任务,任何一项不同都会让数字失去可比性。跨团队比较前,应统一分母定义、触发方式范围和统计周期,并说明各自的基线水平。更稳妥的做法是各团队与自身历史基线对比,把横向比较限定在口径完全一致的前提下。

animation hi
animation dot left
animation dot right
animation dot right bottom
avatar circle
WeChat QR Code
长按将二维码保存为图片

售前电话

400-188-1518

文章配图预览