Merge pull request #1016 from pikasTech/fix/1010-benchmark-log-bound

fix: bound CI benchmark logs
This commit is contained in:
Lyon
2026-06-26 19:24:33 +08:00
committed by GitHub
+26 -6
View File
@@ -591,7 +591,7 @@ function runCiBuildBenchmarkCommand(_config: ControlPlaneConfig, node: ControlPl
const parsed = parseRemoteJson(result.stdout);
const job = typeof parsed === "object" && parsed !== null ? parsed as Record<string, unknown> : { stdoutPreview: result.stdout.slice(0, 2000) };
return renderCiBuildBenchmarkResult({
ok: result.exitCode === 0 && ciBuildBenchmarkLiveOk(job, runtime.serviceIds),
ok: result.exitCode === 0 && ciBuildBenchmarkLiveOk(job, runtime.serviceIds, profile),
command: `hwlab nodes control-plane infra ci-build-benchmark ${options.action}`,
configPath: HWLAB_NODE_CONTROL_PLANE_CONFIG_PATH,
node: node.id,
@@ -790,7 +790,7 @@ function renderCiBuildBenchmarkResult(result: Record<string, unknown>): Rendered
const pipelineRun = record(job.pipelineRun);
const taskRows = ciBuildBenchmarkTaskRows(job);
const serviceRows = ciBuildBenchmarkServiceRows(job, benchmark.services);
const failures = ciBuildBenchmarkFailureRows(job, serviceRows);
const failures = ciBuildBenchmarkFailureRows(job, serviceRows, benchmark);
const profile = renderCell(result.profile ?? benchmark.profile ?? plan.profile, "unknown");
const node = renderCell(result.node);
const lane = renderCell(result.lane);
@@ -3149,6 +3149,7 @@ tmp_dir=pathlib.Path(sys.argv[3])
pipeline_run=sys.argv[4]
include_logs=sys.argv[5] == "true"
tail_lines=int(sys.argv[6])
log_tail_limit=min(6000, max(2000, tail_lines * 80))
def read_json(path):
try:
@@ -3234,7 +3235,7 @@ payload={
"pods": read_text(tmp_dir / "pods.err"),
"logs": read_text(tmp_dir / "logs.err") if include_logs else "",
},
"logTail": read_text(tmp_dir / "logs.txt", max(4000, tail_lines * 300)) if include_logs else "",
"logTail": read_text(tmp_dir / "logs.txt", log_tail_limit) if include_logs else "",
}
print(json.dumps(payload, ensure_ascii=False))
PY
@@ -3348,7 +3349,7 @@ function ciBuildBenchmarkStateDir(target: ControlPlaneTargetSpec, profile: strin
return `/tmp/unidesk-hwlab-node-control-plane/${target.id}/ci-build-benchmark-${profile}`;
}
function ciBuildBenchmarkLiveOk(job: Record<string, unknown>, expectedServices: readonly string[]): boolean {
function ciBuildBenchmarkLiveOk(job: Record<string, unknown>, expectedServices: readonly string[], profile: CiBuildBenchmarkProfileSpec): boolean {
const pipelineRun = record(job.pipelineRun);
const pipelineStatus = renderCell(pipelineRun.status, "");
if (pipelineStatus === "False") return false;
@@ -3357,7 +3358,7 @@ function ciBuildBenchmarkLiveOk(job: Record<string, unknown>, expectedServices:
for (const service of expectedServices) {
if (!taskRuns.some((task) => task.pipelineTask === `build-${service}`)) return false;
}
return true;
return ciBuildBenchmarkPolicyOk(job, profile.cachePolicy);
}
function ciBuildBenchmarkTaskRows(job: Record<string, unknown>): Record<string, string>[] {
@@ -3415,7 +3416,7 @@ function ciBuildBenchmarkServiceRows(job: Record<string, unknown>, servicesValue
});
}
function ciBuildBenchmarkFailureRows(job: Record<string, unknown>, serviceRows: readonly Record<string, string>[]): Record<string, string>[] {
function ciBuildBenchmarkFailureRows(job: Record<string, unknown>, serviceRows: readonly Record<string, string>[], benchmark: Record<string, unknown>): Record<string, string>[] {
const counts = new Map<string, { count: number; scopes: string[] }>();
const add = (family: string, scope: string): void => {
if (family === "-" || family.length === 0) return;
@@ -3429,9 +3430,28 @@ function ciBuildBenchmarkFailureRows(job: Record<string, unknown>, serviceRows:
if (pipelineRun.status === "False") {
add(classifyCiBuildBenchmarkFailure(`${renderCell(pipelineRun.reason, "")}\n${renderCell(pipelineRun.message, "")}`), "pipeline");
}
const cachePolicy = record(benchmark.cachePolicy);
if (cachePolicy.forbidBuildkitCache === true && ciBuildBenchmarkLogHasBuildkitCache(job)) add("cache-hit-forbidden", "buildkit-cache");
if (cachePolicy.forbidGitopsCatalogReuse === true && ciBuildBenchmarkLogHasReuse(job)) add("cache-hit-forbidden", "artifact-reuse");
return [...counts.entries()].map(([family, value]) => ({ family, count: String(value.count), scope: value.scopes.join(",") }));
}
function ciBuildBenchmarkPolicyOk(job: Record<string, unknown>, cachePolicy: CiBuildBenchmarkCachePolicy): boolean {
if (cachePolicy.forbidBuildkitCache && ciBuildBenchmarkLogHasBuildkitCache(job)) return false;
if (cachePolicy.forbidGitopsCatalogReuse && ciBuildBenchmarkLogHasReuse(job)) return false;
return true;
}
function ciBuildBenchmarkLogHasBuildkitCache(job: Record<string, unknown>): boolean {
const logTail = typeof job.logTail === "string" ? job.logTail : "";
return /buildkitCacheRef|--import-cache|--export-cache|writing cache image manifest/iu.test(logTail);
}
function ciBuildBenchmarkLogHasReuse(job: Record<string, unknown>): boolean {
const logTail = typeof job.logTail === "string" ? job.logTail : "";
return /"reusedFrom"\s*:\s*"(?!null)|"status"\s*:\s*"reused"/iu.test(logTail);
}
function ciBuildBenchmarkTaskRunRecords(job: Record<string, unknown>): Record<string, unknown>[] {
return Array.isArray(job.taskRuns) ? job.taskRuns.map(record) : [];
}