news 2026/9/19 9:49:42

Ray 项目 Buildkite CI 日志获取与分析实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ray 项目 Buildkite CI 日志获取与分析实战指南

Ray 项目 Buildkite CI 日志获取与分析实战指南

【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray

导读

本指南以 Ray 仓库内置的 Claude Code 技能(Skill)fetch-buildkite-logs 为核心,系统讲解如何通过 Buildkite REST API 从一条构建 URL(或构建号)出发,依次完成构建解析 → 失败任务定位 → 单任务日志抓取 → ANSI 清理 → 失败归因,并在日志不足以定位根因时继续深入任务的 Artifacts(构建产物)挖掘更多日志。读完本文,你将掌握一套可直接复制运行的 Shell + Python 命令组合,能够独立完成 Ray CI 失败日志的自动化拉取与初步诊断,并了解其中涉及的 Token 权限、分页、HTTP 重定向等关键细节。

该技能是 Ray 仓库为 AI 编程助手配置的共享技能之一,相关使用说明与 Token 申请流程记录在 agent-development.md 中;仓库内 CI 自动化代码(如 release/ray_release/buildkite 目录)也大量基于 Buildkite 构建体系运行,本指南可视为该体系的"日志侧"配套操作手册。

一、前置条件:Buildkite API Token

技能的第一步不是任何 curl 命令,而是确认环境变量BUILDKITE_API_TOKEN已配置:

[ -n "$BUILDKITE_API_TOKEN" ] && echo "token set" || echo "token MISSING"

注意:验证时绝不能把 Token 本身回显出来,任何会打印秘密字符的命令都会被拦截,这是 Ray 团队在技能定义中明确的硬性安全约束。

Token 的申请与权限范围

Token 的完整申请流程记录在仓库文档 doc/source/ray-contribute/agent-development.md 中,核心要点如下:

  1. 在 Buildkite 的「API Access Tokens」页面新建 Token;
  2. 勾选以下三个权限范围(Scope):
    • read_builds—— 读取构建与任务元数据;
    • read_build_logs—— 读取任务日志;
    • read_artifacts—— 读取构建产物(仅在需要进一步翻 Artifacts 排查时必需);
  3. 将 Token 写入 Shell 配置文件并重载:
    # Add to ~/.bashrc or ~/.zshrc export BUILDKITE_API_TOKEN="your-token-here" source ~/.bashrc

缺少read_artifacts时,Artifacts 相关接口会直接返回HTTP 403,这是技能文档明确点出的常见坑:能拉日志但拉不了产物,多半是权限范围没勾全。

二、解析 Buildkite URL:提取 pipeline 与 build number

Buildkite 构建 URL 的标准形态为:

https://buildkite.com/ray-project/<PIPELINE>/builds/<BUILD_NUM>#<JOB_ID>

从 URL 中必须提取两个要素:

  • <PIPELINE>:流水线名,例如premerge(合入前)、postmerge(合入后)。技能明确警告:不能硬编码premerge——同一技能服务于所有流水线,从 URL 动态提取才是正确做法;
  • <BUILD_NUM>:构建号。

URL 中的#<JOB_ID>片段(fragment)指向的是一个真实存在的具体任务(而非 group/wait 这类聚合任务),存在时可以直接对该任务发起查询;不存在时则需先通过构建信息枚举出失败/异常的任务。

三、分步拉取日志:从构建到任务的完整调用链

技能将整个流程收敛为 7 个步骤,命令全部面向 Buildkite v2 REST API,组织方式为 Ray 官方流水线所属组织ray-project

1. 获取构建信息

curl -s -H "Authorization: Bearer $BUILDKITE_API_TOKEN" \ "https://api.buildkite.com/v2/organizations/ray-project/pipelines/<PIPELINE>/builds/<BUILD_NUM>"

返回的 JSON 中jobs数组携带该构建下所有任务的状态信息,是后续所有定位动作的数据源。

2. 有 JOB_ID:直接查询目标任务

当 URL 带#<JOB_ID>时,直接从jobs中按id精确匹配:

curl -s -H "Authorization: Bearer $BUILDKITE_API_TOKEN" \ "https://api.buildkite.com/v2/organizations/ray-project/pipelines/<PIPELINE>/builds/<BUILD_NUM>" \ | python3 -c "import sys,json; jobs=json.load(sys.stdin)['jobs']; [print(f\"{j['id']} {j.get('name')} -> {j.get('state')}\") for j in jobs if j['id']=='<JOB_ID>']"

3. 无 JOB_ID:枚举失败/异常任务

没有任务片段时,先筛选出failedbroken状态的任务,再逐个深入:

curl -s -H "Authorization: Bearer $BUILDKITE_API_TOKEN" \ "https://api.buildkite.com/v2/organizations/ray-project/pipelines/<PIPELINE>/builds/<BUILD_NUM>" \ | python3 -c "import sys,json; jobs=json.load(sys.stdin)['jobs']; [print(f\"{j['id']} {j.get('name')} -> {j['state']}\") for j in jobs if j.get('state') in ('failed','broken')]"

输出形如任务ID 任务名 -> 状态,据此挑出需要深挖的任务。

4. 拉取单个任务日志

curl -s -H "Authorization: Bearer $BUILDKITE_API_TOKEN" \ "https://api.buildkite.com/v2/organizations/ray-project/pipelines/<PIPELINE>/builds/<BUILD_NUM>/jobs/<JOB_ID>/log" \ > /tmp/log_<JOB_ID>.json

5. 清理 ANSI 转义序列

Buildkite 日志接口返回的是 JSON,日志正文在content字段中,且含有大量 ANSI 转义码(用于终端着色)。直接 grep 会得到满屏噪音,必须先用正则剥离:

re.sub(r'\x1b\[[0-9;]*m', '', content)

即匹配\x1b[开头的 CSI 序列(\x1b[31m之类的颜色码)并将其移除,得到纯文本后即可用greptail等工具定位失败栈。

6. 归纳失败原因并给出修复建议

对清理后的日志聚焦关键信号:测试断言、异常堆栈、超时、OOM 等,并结合任务名(如对应哪个测试文件)归纳根因。这也与仓库内 CI 测试判定逻辑(如 ci/pipeline/check-test-run.py、ci/pipeline/determine_tests_to_run.py 中对测试状态的分类思路)相互印证。

四、深入 Artifacts:当日志不足以定位根因时

很多时候任务日志只给出"测试挂了"的入口,真正的根因(如死锁栈、Core dump、覆盖率报告)散落在任务的 Artifacts 里。技能的 Artifacts 章节给出完整翻查流程。

1. 列出任务的 Artifacts(注意分页)

curl -s -H "Authorization: Bearer $BUILDKITE_API_TOKEN" \ "https://api.buildkite.com/v2/organizations/ray-project/pipelines/<PIPELINE>/builds/<BUILD_NUM>/jobs/<JOB_ID>/artifacts?per_page=100&page=1"

接口默认分页,当返回满 100 条时就要递增page参数继续翻页,否则会遗漏产物。

2. 按 id 下载指定 Artifact

curl -fsL -H "Authorization: Bearer $BUILDKITE_API_TOKEN" \ "https://api.buildkite.com/v2/organizations/ray-project/pipelines/<PIPELINE>/builds/<BUILD_NUM>/jobs/<JOB_ID>/artifacts/<ARTIFACT_ID>/download" \ -o /tmp/<ARTIFACT_ID>

这里有两个容易被忽略的细节,技能文档特别强调:

  • -L必不可少:下载接口返回HTTP 302并重定向到 S3 预签名地址,-L负责跟随重定向;
  • 跨主机跳转时 Authorization 头会被 curl 丢弃:这是期望行为——S3 只认预签名 URL,若强行把 Bearer 头带过去反而会触发400 InvalidRequest。因此保持默认行为即可,无需追加--location-trusted之类的参数。

3. 解压 zip 产物,循环排查

若下载到的 Artifact 是 zip 包,日志通常封装在包内,解压后继续检索;仍不足以定位根因时,就换下一个 Artifact 重复上述流程,直到找到可解释失败证据的日志为止。

五、认证故障排查

技能最后给出一个高频认证报错的处置口径:

  • curl返回{"message":"No organization found"},说明当前 Token 无权访问ray-project组织,需要更换 Token;
  • 用户手中可能持有其他组织维度(org-scoped)的 Token,此时应主动询问用户应 source 哪个环境变量,而不是臆断。

这类组织级权限问题在大型组织(Ray 有多个内部流水线)中很常见,排查时要先确认 Token 归属组织与请求 URL 中的组织名一致。

六、技能在整个 Agent 工作流中的定位

fetch-buildkite-logs是 Ray 仓库 .claude/skills 目录下五个共享技能之一,其余还包括/rebuild(基于改动文件引导重建)、/lint(运行 lint 与格式检查)、/backport-docs(将已合并文档 cherry-pick 到发布分支)与ray-dependencies。它们在 Claude Code 中以/<skill-name>形式按需加载,而本技能与仓库文档 agent-development.md 中「Using agents for development」的配置体系直接配套——从 Token 申请、个人环境配置(CLAUDE.local.md)到规则/技能的组织方式,形成一套完整的 AI 辅助开发闭环。

实践中,Agent 处理 CI 失败类问题的典型路径为:用户给出 Buildkite URL → 技能解析 pipeline 与 build → 枚举失败任务 → 拉日志并清理 ANSI → 归纳失败 → 必要时翻 Artifacts 深挖 → 给出修复建议并最终落地为代码改动,再交由/rebuild/lint验证。这也解释了为什么 Ray 仓库在 release/ray_release/buildkite 等目录中沉淀了大量与 Buildkite 流水线交互的自动化代码——CI 日志的获取与分析是整个发布/测试体系的可观测性底座。

小结

  • Token 先行BUILDKITE_API_TOKEN必须就位,且按需授予read_buildsread_build_logsread_artifacts三个 scope,验证时严禁回显 Token;
  • 动态解析:pipeline 与 build number 一律取自 URL,禁止硬编码premerge
  • 分层深入:构建级枚举失败任务 → 任务级拉取日志 → 剥离 ANSI 后 grep → 日志不足再下探 Artifacts(注意分页、-L跟随 302、跨主机丢弃 Authorization 头);
  • 报错有口径No organization found指向 Token 组织权限问题,应切换组织级 Token。

把这套命令链沉淀为可复用的排查流程,配合 Ray 仓库的 Agent 开发体系,即可把"CI 红了"这类问题从人工点网页、翻日志的苦差事,变成可批量、可复现、可自动化的一键式诊断。

【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 9:42:36

CSS Grid 网格布局从入门到实战:核心属性、响应式与踩坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 9:41:53

PLC控制立体仓库堆垛机:从坐标换算到顺序控制实践

简介&#xff1a;面向自动化专业毕业设计或立体仓库控制系统学习者&#xff0c;这份资料提供一套完整的基于PLC的堆垛机控制系统设计方案。内容围绕堆垛机水平与垂直定位、西门子S7-226PLC选型及电机参数计算展开&#xff0c;涵盖激光测距传感器、光电开关与认址片组合定位、双…

作者头像 李华