十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

定位 ClickHouse 无状态测试 CI 失败:Stateless/Fast test 产物(Artifacts)抓取与解压实战

定位 ClickHouse 无状态测试 CI 失败:Stateless/Fast test 产物(Artifacts)抓取与解压实战 定位 ClickHouse 无状态测试 CI 失败Stateless/Fast test 产物Artifacts抓取与解压实战【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouseClickHouse 的 CI 基于 Praktika 框架每个 job 的失败现场都以 S3 对象的形式保留为若干独立的日志产物clickhouse-server.log、clickhouse-server.err.log、job.log等。无状态测试Stateless tests与快速测试Fast test的产物布局是排查“结果 diff”“服务器异常/退出”“运行器基础设施失败”三类问题的核心依据。本文基于仓库内 artifacts-stateless.md 完整继承其文件目录、抓取命令与按失败类型的关键文件速查并结合 ci/praktika/s3.py、ci/praktika/settings.py 与 .claude/tools/fetch_ci_report.js 的源码深入讲清“为什么同一个日志文件有时是纯文本、有时是.zst压缩包”这一关键机制以及透明解压工具如何兜底。读完本文你将能够给定任意一次 stateless/fast test 的 CI 失败列出并正确抓取所需的日志产物识别失败类型后直达最关键的日志文件并从源码层面理解 Praktika 的对象级压缩规则避免手工拼 URL 时的 404 陷阱。产物总览全部是独立文件用--links拿 URLStateless / Fast test 与其他 job 家族如 integration test 的logs.tar.gz大包不同它的每个产物都是单独的文件对象而不是一个归档包。排查的第一步永远是先列出 URL再按需抓取不要盲目下载# 用 --links 列出该报告的全部产物 URL node .claude/tools/fetch_ci_report.js report-url --failed --links拿到 URL 列表后只下载与失败类型相关的那一两个文件即可。注意压缩与否取决于文件大小。Praktika 上传时小文件以纯文本对象形式存放大文件则以 zstd 压缩的.zst对象形式存放。--links显示的 URL 反映的是 S3 上实际的 key因此应原样使用。如果必须手工构造 URL先尝试不带后缀的原始文件名若得到 404再追加.zst并解压。永远不要假定某个固定文件必有固定扩展名。文件目录每个产物文件包含什么以下是 stateless / fast test 产物的完整文件目录继承自 artifacts-stateless.md文件内容clickhouse-server.log[.zst]ClickHouse 服务器主日志clickhouse-server.err.log[.zst]服务器 stderr启动错误、致命信号clickhouse-local.log[.zst]clickhouse-local输出仅 Fast testclickhouse-local.err.log[.zst]clickhouse-localstderr仅 Fast teststderr.log[.zst]测试运行器 stderrjob.log[.zst]CI job 脚本执行日志coordination.tar.gzKeeper 协调日志仅 Fast test几点使用提示文件名中的[.zst]表示该文件可能以 zstd 压缩形式存在具体以--links输出为准机制见后文源码解析。clickhouse-local.*与coordination.tar.gz只在 Fast test 场景出现——Fast test 是用clickhouse-local进程内嵌运行测试并内置 Keeper 协调的轻量变体因此没有独立 server 日志。对应测试的 Docker 镜像定义见 ci/docker/stateless-test/Dockerfile可用于了解这些日志在容器内是如何产生的。抓取方法按 URL 扩展名选择处理方式拿到 URL 后先检查 URL 的扩展名再决定管道# 纯文本文件URL 无 .zst 后缀 curl -sL url | tail -200 # Zstd 压缩文件URL 带 .zst 后缀 curl -sL url | zstd -dcq | grep -i error\|exception\|fatal | tail -50 # 不确定时——先下载再判断 curl -sL url -o tmp/investigate/$SHA/artifact file tmp/investigate/$SHA/artifact # 显示 Zstandard compressed data 或 ASCII text 等 # 然后zstd -dcq tmp/investigate/$SHA/artifact | ... 或 cat tmp/investigate/$SHA/artifact | ...其中zstd -dcq表示按 zstd 格式解压到 stdout 且不打印进度file命令用于在不确定对象真实编码时判别。仓库自带的 fetch_ci_report.js 对这种不确定性做了自动化兜底值得了解其行为源码见下文透明解压maybeDecompress按魔数magic bytes检测对象是否为 zstd/gzip 编码是则自动解压——因此无论是明文、.zst还是 gzip 对象读到的都是解码后的文本404/403 自动重试.zst兄弟对象若请求一个不带后缀的 URL 返回 403 或 404且 URL 尚未以.zst结尾工具会自动追加.zst再请求一次。这正是“先试原名、404 再试.zst”规则的程序化实现。所以上述手工流程在多数情况下可以用node .claude/tools/fetch_ci_report.js report-url --failed --links一步替代但理解手工流程能让你在工具不可用或需要精确定位时不慌。按失败类型定位关键文件CI 失败的第一现场通常不在产物里而在报告本身。按失败类型分四种情况继承自 artifacts-stateless.md1. 失败原因已在result.info中绝大多数 stateless 失败工具已经展示失败原因Reason: type:后跟实际输出或 diff。只有当原因部分被截断、或需要服务器端上下文时才去翻产物。2. 测试输出 diffReason: result differsdiff 本身在result.info里要看完整测试输出取stderr.log测试运行器输出包含 actual vs expected 对比。3. 服务器异常/退出Reason: having exception in stdout、Server diedclickhouse-server.err.log.zst—— 包含完整异常及堆栈clickhouse-server.log.zst—— 围绕result.info中的时间戳前后搜索。4. 测试运行器基础设施失败超时、Docker 问题job.log—— 原始 CI job 脚本输出显示执行到哪一步、在哪里停住。排查顺序建议result.info→ 按类型选 12 个产物文件 → 仍无法定因时再考虑更大的归档或二进制产物。这与调查技能 SKILL.md 的整体策略一致先读错误信息与源码只有当信息仍不足时才下载产物且只下载恰好能补上缺口的那几个文件。源码解析为什么压缩与否取决于文件大小--links的 URL 是“实际 S3 key 的映射”这个承诺背后是 Praktika 上传管线中的一段阈值判断。压缩开关与阈值。在 ci/praktika/settings.py 中TEXT_CONTENT_EXTENSIONS: Iterable[str] frozenset([.txt, .log]) # Compress if text file size exceeds this threshold (in MB, 0 - disable compression) COMPRESS_THRESHOLD_MB: int 0只有“文本类”内容.txt、.log等才有资格走压缩分支——日志正好都在这类里COMPRESS_THRESHOLD_MB是阈值单位 MB默认0表示禁用ClickHouse CI 部署时由环境配置给出实际值超过该阈值的文本文件就会被压缩。上传时的判断点。ci/praktika/s3.py 的_upload_file_to_s3约 L645-L669是这条规则的执行处if text and Settings.COMPRESS_THRESHOLD_MB 0: file_size_mb os.path.getsize(local_file_path) / (1024 * 1024) if file_size_mb Settings.COMPRESS_THRESHOLD_MB: print( fNOTE: File [{local_file_path}] exceeds threshold [...] - compress ) text False local_file_path Utils.compress_file(local_file_path)注意两点判断发生在上传前且压缩后文件路径直接改变——随后以新路径带压缩后缀作为 S3 key 上传。这就是为什么同一个逻辑文件一次构建里是明文、另一次构建里是.zst同一代码逻辑不同文件大小/阈值组合得出不同 key。另一条压缩路径compress_zst标志。在 ci/praktika/runner.py 的产物发布逻辑中约 L930-L945注册了compress_zstTrue的产物会在上传前显式调用Utils.compress_zst(...)就地转换为 zstd 对象ci/praktika/utils.py 提供该实现产物定义本身见 ci/praktika/artifact.py 中的compress_zst字段。也就是说Praktika 里“小文件明文、大文件 zstd”是两套机制共同的结果阈值触发压缩 显式声明压缩的产物。工具侧的对应实现。.claude/tools/fetch_ci_report.js 的注释明确指向这套机制maybeDecompress约 L52-L60按魔数检测对象级压缩优先用 Node 内置zlib.zstdDecompressSync缺失时回退到zstd -dcq子进程带 2 GiB 缓冲与超时上限防止卡死的 zstd 拖住整个 helper403/404 回退约 L95-L99请求明文 URL 失败且 URL 未以.zst结尾时自动改请求.zst兄弟对象——源码注释同样指向ci/praktika/s3.py的阈值压缩行为。因此文档中“--links的 URL 反映实际 S3 key原样使用即可”这句话等价于URL 是上传时 key 的直接映射客户端不需要再做任何 key 猜测。小结一张速查表场景首选信息源想知道“为什么失败”报告的result.infoReason:段result differsresult.info的 diff stderr.log看完整输出异常 /Server diedclickhouse-server.err.log.zst异常堆栈clickhouse-server.log.zst按时间戳定位超时 / Docker 等基础设施问题job.log手工拼 URL 得到 404追加.zst后请求并用file判别真实编码核心原则一句话先看result.infoURL 一律以--links输出为准压缩扩展名以对象实际状态为准——这套流程与源码中 s3.py 的阈值压缩逻辑、fetch_ci_report.js 的透明解压共同保证了排查的可复现性。若失败属于 integration test 或 stress test 家族则应改用各自的产物布局文档artifacts-integration.md、artifacts-stress.md。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表