feat(producer): host/render telemetry in RenderPerfSummary (#1551)

Adds a `host` block (platform, arch, cpuCount, totalMemMb, nodeVersion,
gpuDisabled) to RenderPerfSummary so fleet-wide telemetry can correlate render
performance with the machine it ran on — chiefly cpuCount vs the existing
`workers` field (core over/under-subscription) and totalMemMb vs
lowMemoryMode / single-worker collapse. Capture mode + GPU mode already surface
via `observability`; this fills in the missing host facts.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vance Ingalls
2026-08-20 23:37:51 -07:00
committed by GitHub
co-authored by Claude Opus 4.8
parent 1ff99a50f5
commit 7e3bcd9ef1
3 changed files with 78 additions and 1 deletions
@@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest";
import { roundDb } from "./perfSummary.js";
import { buildRenderPerfSummary, roundDb } from "./perfSummary.js";
import type { RenderJob } from "../renderOrchestrator.js";
describe("roundDb", () => {
it("rounds to 1 decimal", () => {
@@ -20,3 +21,46 @@ describe("roundDb", () => {
expect(roundDb(roundDb(28.4373))).toBe(28.4);
});
});
// ponytail: minimal stub — only the fields buildRenderPerfSummary reads are real.
const baseInput = {
job: { id: "r1", config: { fps: { num: 30, den: 1 }, quality: "high" } } as unknown as RenderJob,
workerCount: 4,
enableChunkedEncode: false,
chunkedEncodeSize: 0,
compositionDurationSeconds: 5,
totalFrames: 150,
outputWidth: 1920,
outputHeight: 1080,
videoCount: 0,
audioCount: 0,
totalElapsedMs: 1234,
perfStages: {},
videoExtractBreakdown: undefined,
tmpPeakBytes: 0,
captureAttempts: [],
hdrDiagnostics: { videoExtractionFailures: 0, imageDecodeFailures: 0 },
peakRssBytes: 0,
peakHeapUsedBytes: 0,
dedupPerfs: [],
};
describe("buildRenderPerfSummary host telemetry", () => {
it("captures host facts and threads gpuDisabled through", () => {
const summary = buildRenderPerfSummary({ ...baseInput, gpuDisabled: true });
expect(summary.host).toBeDefined();
expect(summary.host?.gpuDisabled).toBe(true);
expect(summary.host?.cpuCount).toBeGreaterThan(0);
expect(summary.host?.totalMemMb).toBeGreaterThan(0);
expect(summary.host?.platform).toBe(process.platform);
expect(summary.host?.arch).toBe(process.arch);
expect(summary.host?.nodeVersion).toBe(process.version);
});
it("reflects gpuDisabled=false", () => {
const summary = buildRenderPerfSummary({ ...baseInput, gpuDisabled: false });
expect(summary.host?.gpuDisabled).toBe(false);
// workers vs cores is the headline correlation — both must be present.
expect(summary.workers).toBe(4);
});
});
@@ -3,6 +3,7 @@
* the `perf-summary.json` debug artifact.
*/
import { arch, cpus, platform, totalmem } from "node:os";
import { fpsToNumber } from "@hyperframes/core";
import type { CapturePerfSummary, SubTimelineWaitOutcome, WorkerSizing } from "@hyperframes/engine";
import type { CaptureCalibrationSample, CaptureCostEstimate } from "./captureCost.js";
@@ -221,6 +222,8 @@ export function buildRenderPerfSummary(input: {
/** Per-session/per-worker static-dedup perf; aggregated into `staticDedup`. */
dedupPerfs: CapturePerfSummary[];
drawElement?: DrawElementPerfInput;
/** `cfg.disableGpu` — the hard `--disable-gpu` flag, for the `host` GPU picture. */
gpuDisabled: boolean;
}): RenderPerfSummary {
return {
renderId: input.job.id,
@@ -282,5 +285,13 @@ export function buildRenderPerfSummary(input: {
input.dedupPerfs,
input.drawElement ?? { selfVerifyFallback: false },
),
host: {
platform: platform(),
arch: arch(),
cpuCount: cpus().length,
totalMemMb: Math.round(totalmem() / (1024 * 1024)),
nodeVersion: process.version,
gpuDisabled: input.gpuDisabled,
},
};
}
@@ -546,6 +546,27 @@ export interface RenderPerfSummary {
/** Per-frame "No cached paint record" screenshot fallbacks. */
ncprFallbacks: number;
};
/**
* Render-host facts, captured from the orchestrator process. Lets fleet-wide
* telemetry correlate render performance with the machine it ran on — most
* importantly `cpuCount` vs the top-level `workers` (are we under-/over-
* subscribing cores?) and `totalMemMb` (does `lowMemoryMode` / single-worker
* collapse track real memory pressure?). `gpuDisabled` completes the GPU
* picture alongside `observability.browserGpuMode`.
*
* Reflects the ORCHESTRATOR host. For distributed renders the chunk workers
* may run on different machines; this is still the right signal for the
* common single-machine render. Optional for back-compat with serialized
* older summaries.
*/
host?: {
platform: string;
arch: string;
cpuCount: number;
totalMemMb: number;
nodeVersion: string;
gpuDisabled: boolean;
};
}
export interface HdrDiagnostics {
@@ -3971,6 +3992,7 @@ async function executeRenderPipeline(input: {
observability: observabilitySummary,
peakRssBytes: memSampler.peakRssBytes(),
peakHeapUsedBytes: memSampler.peakHeapUsedBytes(),
gpuDisabled: cfg.disableGpu,
});
job.perfSummary = perfSummary;
if (job.config.debug) {