
【免费下载链接】beamApache Beam is a unified programming model for Batch and Streaming data processing.项目地址https://gitcode.com/gh_mirrors/beam18/beam点击查看免费下载Apache Beam 的.test-infra/jupyter目录承载着测试基础设施中一项重要工作用 Jupyter Notebook 从 Jenkins 上抓取、整理并可视化 Beam 各语言 PreCommit 任务的测试指标。本文基于该目录下的 README 与实战 notebook precommit_job_times.ipynb完整讲解环境搭建、Jenkins API 数据采集、任务排队/总耗时分析、95 分位统计以及单测耗时排查的整套流程读完即可复现 Beam 测试指标的采集与分析环境。目录定位测试指标分析工作台.test-infra/jupyter目录的唯一用途就是存放用于收集和分析测试指标的 Jupyter notebooks。与之对应的核心分析对象是 Jenkins 上 Apache Beam 项目持续运行的 CI 任务——尤其是各语言的 PreCommit提交前定时任务。目录结构非常精简.test-infra/jupyter/ ├── README.md # 环境搭建与贡献规范说明 └── precommit_job_times.ipynb # PreCommit 任务耗时分析 notebooknotebook 本身precommit_job_times.ipynb围绕Precommit Job Times这一主题按数据流划分为四个阶段从 Jenkins 拉取构建级统计 → 绘制排队/总耗时趋势图 → 计算 95 分位耗时指标 → 深入单个测试用例层级的耗时排序。上下文提醒根据 .test-infra/jenkins/README.md自 2023 年 11 月起 Beam 的 CI 已逐步迁移到自托管 GitHub ActionsJenkins 上的任务计划关闭但本 notebook 及其背后完整的 Jenkins 指标采集方法论对理解 CI 数据分析和迁移前的 Beam 测试体系仍有重要参考价值下文分析以仓库中 notebook 实际代码为准。环境搭建pip venv 快速启动README 给出了基于 Linux 的安装指引核心思路是使用 venv 隔离环境并安装 Jupyterpython3 -m venv ~/virtualenvs/jupyter source ~/virtualenvs/jupyter/bin/activate pip install jupyter # Optional packages, for example: pip install pandas matplotlib requests cd .test-infra/jupyter jupyter notebook # Should open a browser window.各步骤要点venv 隔离将环境创建在~/virtualenvs/jupyter激活后所有包安装不会污染系统 Pythonsource激活是每次会话进入环境的前提。核心依赖jupyter是运行 notebook 的基础pandas、matplotlib、requests为可选但实际必备——notebook 的导入单元格import pandas as pd、import numpy as np、import matplotlib.pyplot as plt、import matplotlib.dates as md、import requests直接依赖它们完成数据处理、绘图与 HTTP 请求。工作目录必须在.test-infra/jupyter下启动jupyter notebook保证 notebook 的相对资源访问正常。启动形态jupyter notebook默认打开浏览器窗口notebook 元数据中的kernelspec声明为 Python 3 内核。一个值得注意的细节notebook 的说明中特别提到可能需要重启 Jupyter 才能让 matplotlib 正常工作——这是因为 matplotlib 的后端加载时机问题遇到绘图不显示时优先尝试重启内核。数据采集读懂 Jenkins API 请求协议notebook 的第一段代码块完成了核心数据抓取其设计对任何 Jenkins API 使用者都有直接参考意义。API 地址与 tree 参数防封禁关键url https://ci-beam.apache.org/job/%s/api/json % job_name params { tree: %s[result,number,timestamp,actions[queuingDurationMillis,totalDurationMillis]] % builds_key} r requests.get(url, paramsparams) data r.json()notebook 在开头明确警告对ci-beam.apache.org的请求必须携带?depth或?tree参数否则 IP 会被封禁这一规则来自 ASF Jenkins API 的使用政策。代码中对tree参数做了精确限定只请求最小必要字段result构建结果如SUCCESS、FAILUREnumber构建号timestamp构建开始时间毫秒级 Unix 时间戳actions[queuingDurationMillis,totalDurationMillis]来自构建 Action 的排队时长与总时长。使用tree而非depth是更节省带宽和响应时间的方式——只抓取指定字段避免拉取每个构建的完整 JSON 对象。builds 与 allBuilds 的选择代码中通过可配置变量控制抓取范围# Can be builds (last 50) or allBuilds. builds_key allBuildsbuilds最近 50 次构建allBuilds全部构建历史。notebook 默认选择allBuilds以便支撑后文4 周 / 1 周 / 1 天三个时间窗口的切片分析。目标任务三大语言的 PreCommit Cronjob_names [beam_PreCommit_Java_Cron, beam_PreCommit_Python_Cron, beam_PreCommit_Go_Cron]这三个任务正是 Beam Jenkins 上的 PreCommit 定时任务。其命名规则可以从 CI 定义代码交叉印证在 .test-infra/jenkins/PrecommitJobBuilder.groovy 中任务名由scope.job(beam_PreCommit_${nameBase}_${nameSuffix})拼装而成即beam_PreCommit_ 语言/模块基名 后缀如CronBUILD_STATUS.md 的Pre-Commit Tests Status表格也逐一列出了beam_PreCommit_Java_Cron、beam_PreCommit_Python_Cron、beam_PreCommit_Go_Cron等任务及其状态徽章。构建记录的解析模型Build 类class Build(dict): def __init__(self, job_name, json): self[job_name] job_name self[result] json[result] self[number] json[number] self[timestamp] pd.Timestamp.utcfromtimestamp(json[timestamp] / 1000) self[queuingDurationMillis] -1 self[totalDurationMillis] -1 for action in json[actions]: if action.get(_class, None) jenkins.metrics.impl.TimeInQueueAction: self[queuingDurationMinutes] action[queuingDurationMillis] / 60000. self[totalDurationMinutes] action[totalDurationMillis] / 60000. if self[queuingDurationMinutes] -1: raise ValueError(could not find queuingDurationMillis in: %s, json) if self[totalDurationMinutes] -1: raise ValueError(could not find totalDurationMillis in: %s, json)这一模型揭示了 Jenkins 构建时长数据的底层来源构建的时间戳从毫秒 Unix 时间戳转为 pandasTimestamputcfromtimestamp(timestamp / 1000)为后续时间窗口过滤与时间轴绘图做准备排队时长queuing与总时长total并不直接出现在构建顶层而是藏在actions数组里、由jenkins.metrics.impl.TimeInQueueAction这个_class标识的 Action 提供两个时长从毫秒换算为分钟/ 60000.统一了后续统计与绘图的量纲若找不到该 Action代码会显式抛出ValueError防止静默使用 -1 脏数据。抓取完成后所有Build对象汇入 DataFramedf pd.DataFrame(builds)时间窗口切片与耗时趋势可视化按时间窗口过滤timestamp_cutoff pd.Timestamp.utcnow().tz_convert(None) - pd.Timedelta(weeks4) df_4weeks df[df.timestamp timestamp_cutoff] timestamp_cutoff pd.Timestamp.utcnow().tz_convert(None) - pd.Timedelta(weeks1) df_1week df[df.timestamp timestamp_cutoff] timestamp_cutoff pd.Timestamp.utcnow().tz_convert(None) - pd.Timedelta(days1) df_1day df[df.timestamp timestamp_cutoff]当前时间取 UTCpd.Timestamp.utcnow()去掉时区信息tz_convert(None)后与构建的 UTC 时间戳对齐用pd.Timedelta分别构造4 周、1 周、1 天三个回溯窗口得到三份切片 DataFrame供趋势图与分位统计复用。绘制耗时趋势图for job_name in job_names: duration_df df_4weeks[df_4weeks.job_name job_name] duration_df duration_df[[timestamp, queuingDurationMinutes, totalDurationMinutes]] ax duration_df.plot(xtimestamp) ax.set_title(job_name)对每个任务取最近 4 周数据以时间戳为 X 轴绘制queuingDurationMinutes与totalDurationMinutes两条曲线并分别以任务名作为图表标题。这样的图可以直观回答两类问题**总耗时total**是否随时间恶化反映 CI 本身的性能回归**排队耗时queuing**是否偏高反映执行机资源不足或任务调度拥塞。95 分位耗时指标量化 CI 性能基线数据分析的经典需求是CI 到底多慢。notebook 用 95 分位P95给出量化答案test_dfs {4 weeks: df_4weeks, 1 week: df_1week, 1 day: df_1day} metrics [] for sample_time, test_df in test_dfs.items(): for job_name in job_names: df_times test_df[test_df.job_name job_name] for percentile in [95]: total_all np.percentile(df_times.totalDurationMinutes, qpercentile) total_success np.percentile(df_times[df_times.result SUCCESS].totalDurationMinutes, qpercentile) queue np.percentile(df_times.queuingDurationMinutes, qpercentile) metrics.append({job_name: %s %s %dth % ( job_name.replace(beam_PreCommit_,).replace(_GradleBuild,), sample_time, percentile), totalDurationMinutes_all: total_all, totalDurationMinutes_success_only: total_success, queuingDurationMinutes: queue, }) pd.DataFrame(metrics).sort_values(job_name)这一统计逻辑包含三个层次的洞察区分全部构建与成功构建total_all统计所有构建的 P95 总耗时total_success只统计result SUCCESS的构建——成功构建的 P95 更能代表正常状态下的 CI 耗时基线两者差值可侧面反映失败构建拉长耗时的程度独立统计排队耗时queue单独给出 P95 排队时长用于评估调度拥塞任务名可读化通过replace去掉beam_PreCommit_与_GradleBuild前缀让输出的job_name更易读例如Java_Cron 4 weeks 95th。最终以表格形式pd.DataFrame(metrics).sort_values(job_name)输出三个时间窗口 × 三个任务 × 三个耗时指标的组合矩阵为 CI 性能报告提供可直接引用的数字。深入单测层级定位最慢的测试用例趋势图与分位统计回答CI 多慢而**定位哪个测试最慢**则需要另一条数据链路testReport API。按构建抓取测试报告MAX_FETCH_PER_JOB_TYPE 5 test_results_raw [] for job_name in list(df.job_name.unique()): if job_name beam_PreCommit_Go_Cron: # TODO: Go builds are missing testReport data on Jenkins. continue build_nums list(df.number[df.job_name job_name].unique()) num_fetched 0 for build_num in build_nums: url https://ci-beam.apache.org/job/%s/%s/testReport/api/json?depth1 % (job_name, build_num) print(., end) r requests.get(url) if not r.ok: # Typically a 404 means that the job is still running. print(skipping (%s): %s % (r.status_code, url)) continue raw_result r.json() raw_result[job_name] job_name raw_result[build_num] build_num test_results_raw.append(raw_result) num_fetched 1 if num_fetched MAX_FETCH_PER_JOB_TYPE: break print( done)这段代码的设计约束值得展开每个任务最多拉取 5 次构建MAX_FETCH_PER_JOB_TYPE 5在样本充分性与 API 负载之间取得平衡Go 任务被跳过notebook 用 TODO 注释明确说明Go builds are missing testReport data on Jenkins即 Jenkins 端没有 Go 构建的测试报告数据这是一个真实的平台限制分析时需留意404 处理testReport/api/json?depth1返回非 OK 状态通常意味着该构建仍在运行中报告尚未生成代码打印skipping后跳过不会中断整个抓取流程使用depth1此处与主 API 请求不同testReport 接口要求depth1展开嵌套的 suites/cases 结构顶层请求中特意省略了 tree 参数。测试用例结果解析与排序class TestResult(dict): def __init__(self, job_name, build_num, json): self[job_name] job_name self[build_num] build_num self[name] json[name] self[duration] json[duration] self[className] json[className] self[status] json[status]抓回的原始报告按suites → cases两级结构展开将每个测试用例case转成TestResult记录for suite in test_result_raw[suites]: for case in suite[cases]: test_results.append(TestResult(job_name, build_num, case)) df_tests pd.DataFrame(test_results) df_tests df_tests.drop(columns[build_num]) df_tests df_tests.groupby([className, job_name, name, status], as_indexFalse).max() df_tests df_tests.sort_values(duration, ascendingFalse)关键的处理步骤去重取最大值按className job_name name status分组后取max()即同一测试用例多次构建出现时只保留最慢的一次同时自然去除了build_num维度故先drop该列降序排序按duration从大到小排列最慢的测试排在最前。交互式过滤最慢测试def filter_test_results(job_name, status): res df_tests if job_name ! all: res res[res.job_name job_name] if status ! all: res res[res.status status] return res.head(n20) from ipywidgets import interact interact(filter_test_results, job_name[all] list(df_tests.job_name.unique()), status[all] list(df_tests.status.unique()))最后借助ipywidgets.interact生成交互式控件用户可从下拉框选择job_nameall或某个具体任务与statusall或具体状态即时查看耗时 Top 20 的测试用例head(n20)。这是整个分析流程的出口——从CI 慢了到具体是哪个类、哪个用例最耗时可以直接指导测试优化或失败用例排查。协作规范提交 notebook 前清理输出README 对贡献者提出一条明确要求是保持仓库整洁的关键约定To minimize file size, diffs, and ease reviews, please clear all cell output (cell - all output - clear) before committing.即在提交 notebook 前通过菜单cell → all output → clear清空所有单元格输出。这样做有三重收益减小文件体积.ipynb是 JSON 文本格式大量图片型输出尤其 matplotlib 图表 base64 编码会急剧膨胀文件精简 diff运行时间戳、随机图表数据等每次运行都会变化的输出若不清空会制造大量无关 diff简化评审评审者只需关注代码逻辑本身而不是海量输出截图。这也解释了仓库中precommit_job_times.ipynb的outputs: []状态——所有单元格均为未运行输出的干净形态与仓库约定完全一致。与周边测试基础设施的关联.test-infra/jupyter并非孤立存在它属于 Beam 测试基础设施的分析侧与周边组件形成完整闭环.test-infra/jenkins/Jenkins 任务定义Groovy DSL其中 PrecommitJobBuilder.groovy 定义了 notebook 所分析任务的命名与触发目录 README 说明其已进入弃用迁移状态.test-infra/metrics/Beam 的指标监控栈InfluxDB 时序库 Grafana 仪表盘 PostgreSQL 分析库提供另一条面向社区与测试结果的指标可视化路径.test-infra/BUILD_STATUS.md集中展示 PreCommit/PostCommit 任务状态徽章与触发短语其中 Pre-Commit Tests Status 表格与 notebook 分析的三个任务一一对应CI.mdGitHub Actions CI 的说明文档代表 Beam CI 的当前主流演进方向。在 Jenkins 时代这套 notebook 流程承担了从 Jenkins API 侧拉取数据做自主分析的轻量职责与面向生产部署的 InfluxDB/Grafana 监控栈形成互补——前者适合工程师临时探查具体慢测试后者适合持续观测整体指标。小结.test-infra/jupyter用两个文件提供了完整的 CI 指标分析范式README 给出了可复现的 venv 环境搭建步骤与协作规范precommit_job_times.ipynb则展示了从 Jenkins API 采集构建级与测试级数据、按时间窗口切片、绘制趋势图、计算 95 分位基线、交互式定位最慢用例的端到端流程。即使 Beam CI 已逐步迁移至 GitHub Actions这套用最小化 API 请求tree 参数守规矩地采集数据、用 DataFrame 做聚合统计、用分位数量化性能基线、用交互控件下钻到单测的方法论对任何需要分析 CI 效率的团队都具备直接的复用价值。赞分享【免费下载链接】beamApache Beam is a unified programming model for Batch and Streaming data processing.项目地址https://gitcode.com/gh_mirrors/beam18/beam点击查看免费下载相关推荐Apache Beam 测试指标分析用 Jupyter 从 Jenkins 采集与剖析 PreCommit 任务耗时Apache Beam 测试指标分析用 Jupyter 从 Jenkins 采集与剖析 PreCommit 任务耗时 本文围绕 Apache Beam 仓库中大数据批处理流处理数据工程5个PDF.js解决方案快速解决跨域、字体与移动端适配难题5个PDF.js解决方案快速解决跨域、字体与移动端适配难题 PDF.js作为一款基于HTML5的开源PDF渲染库为开发者提供了强大的PDF解析和显示能力。然前端如何用Apache Beam监控生产管道Metrics指标与任务调试完整指南如何用Apache Beam监控生产管道Metrics指标与任务调试完整指南 Apache Beam 是统一的批流一体数据处理编程模型而 监控生产管道 的可大数据批处理流处理数据工程上一篇JaCoCo代码覆盖率报告深度解析看懂每一行数据的秘密下一篇【亲测免费】 JavaCC 使用及开发指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考