如何提取Jenkins构建控制台订单号并写入测试结果聚合报告
实现方案
整套方案不需要依赖额外付费插件,用Jenkins原生能力+简单脚本就能落地,分三步实现:
1. 从构建日志提取订单号并关联任务名
首先先确认你控制台里订单号的固定打印格式,比如常见格式是业务订单生成成功,订单号:ORD20240528001,先写好对应匹配的正则表达式,后续所有提取逻辑都基于这个正则做。
- 如果你用的是自由风格Maven任务:安装Post-build Task插件,在构建后操作中添加执行脚本,通过插件提供的日志匹配接口抓取订单号,核心逻辑参考:
// 替换成你实际的订单号正则 def matcher = manager.getLogMatcher(/.*订单号:([A-Z0-9]+).*/) if (matcher.matches()) { def orderNo = matcher.group(1) // 把订单号设置为当前构建的环境变量,后续步骤可直接调用 manager.build.addAction(new ParametersAction(new StringParameterValue('BUILD_ORDER_NO', orderNo))) // 加文件锁写入任务-订单号映射文件,避免并发写冲突 def lockFile = new File('/var/jenkins_home/order_mapping.lock') def lock = new FileLock(lockFile) lock.lock() try { def propFile = new File('/var/jenkins_home/order_mapping.properties') def props = new Properties() if (propFile.exists()) props.load(new FileInputStream(propFile)) props[manager.build.project.name] = orderNo props.store(new FileOutputStream(propFile), null) } finally { lock.release() lockFile.delete() } } - 如果你用的是Pipeline流水线任务,不需要额外装插件,直接在Maven构建步骤后加如下逻辑:
注意提前给Jenkins进程开放上述映射文件所在目录的读写权限,正则规则必须和你实际日志的打印格式完全对齐,避免误匹配。// 取最近1000行日志匹配,可根据实际日志量调整行数 def logContent = currentBuild.rawBuild.getLog(1000).join('\n') def orderMatch = (logContent =~ /.*订单号:([A-Z0-9]+).*/) if (orderMatch.find()) { env.BUILD_ORDER_NO = orderMatch.group(1) lock('order_mapping_resource') { def props = readProperties file: '/var/jenkins_home/order_mapping.properties' props[env.JOB_NAME] = env.BUILD_ORDER_NO writeProperties file: '/var/jenkins_home/order_mapping.properties', props: props } }
2. 将关联的订单信息插入Tests Results Aggregator HTML报告
不需要修改插件源码,两种实现方式按需选:
- 模板替换法:找到Tests Results Aggregator插件的报告模板(默认存放在插件目录的templates路径下,也可以自定义模板存到你自己的项目目录里),在报告的概览区域新增一个订单信息展示区块,在报告生成前读取之前存的
order_mapping.properties键值对,遍历生成<li>任务名:<strong>对应订单号</strong></li>格式的列表项,替换模板里提前留好的{{ORDER_INFO_SECTION}}占位符,再执行报告生成步骤即可。区块参考样式:<div style="margin: 16px 0; padding: 12px; border: 1px solid #eee; border-radius: 4px;"> <h4 style="margin-top:0">关联构建订单信息</h4> <ul> <!-- 遍历映射生成的列表项放这里 --> </ul> </div> - 后置插入法:如果不想改模板,直接在报告生成完成后,用脚本把拼好的订单信息区块插入到生成好的HTML文件里,示例shell脚本:
# 读取映射文件拼接HTML片段 ORDER_LIST=$(awk -F= '{print "<li>"$1":<strong>"$2"</strong></li>"}' /var/jenkins_home/order_mapping.properties) ORDER_BLOCK="<div style='margin: 16px 0; padding: 12px; border: 1px solid #eee; border-radius: 4px;'><h4 style='margin-top:0'>关联构建订单信息</h4><ul>${ORDER_LIST}</ul></div>" # 把片段插入到HTML的body标签开头位置,替换成你实际的报告文件路径 sed -i "s|<body>|<body>${ORDER_BLOCK}|" ./target/tests-results-aggregator/report.html
如果是多任务聚合场景,建议在聚合任务执行时,直接通过Jenkins原生接口拉取每个子任务最近一次成功构建的控制台日志,重新提取一次订单号做校验,避免映射文件因为并发写入出现脏数据。
避坑提示
- 订单号匹配正则要加足够的前后缀约束,比如指定订单号固定前缀、长度规则,避免把日志里其他格式相似的字符串误识别为订单号。
- 并发构建场景必须加锁,不管是用Pipeline的lock插件还是系统层面的flock文件锁,避免多个任务同时写映射文件导致文件损坏、数据错乱。
- 如果你的构建任务跑在不同的Jenkins代理节点上,不要把映射文件存在节点本地,统一存在Jenkins控制器可访问的共享存储里,或者用Jenkins全局配置存储键值对,保证聚合任务能读到全量的映射关系。
- 拼接HTML片段时注意转义特殊字符,避免订单号里的特殊字符破坏HTML结构导致报告渲染异常。
内容的提问来源于stack exchange,提问作者Alexander Grischenko
相关产品推荐
相关产品推荐

