Skip to content
vxvx
GitHubBlueskydev.toRSS
Blog

Observability that cannot break a run

A broken telemetry plugin costs a warning, never a red build. A sink that throws is turned off for the run, and one that hangs is cut off after 3 seconds.

A broken telemetry plugin costs you a warning, never a red build. Here are two: one throws on every record, one never finishes its flush.

telemetry: () => ({ onRecord() { throw new Error('collector is down') } })
telemetry: () => ({ onRunSummary() {}, flush: () => new Promise<void>(() => {}) })
Terminal window
$ vx run build test --all
[vx] telemetry sink 'sink-that-throws' threw in onRecord; disabled for this run: collector is down
⏺︎ 9ms success miss packages/a#test
⏺︎ 15ms success miss packages/b#test
[vx] telemetry flush timed out after 3000ms (sink 'sink-that-hangs'); buffered records lost
8 success · 8 total
$ echo $?
0

Demo workspace, wall 3.19 s · vx 0be0367 · 2026-10-23

All green, exit 0, one warning per broken sink.

interface TelemetrySink {
readonly name?: string
readonly wants?: ReadonlyArray<'run.start' | 'task.start' | 'task.end' | 'task.log' | 'task.sample' | 'run.end'>
onRecord?(record: TelemetryRecord): void // must return promptly; buffer here
onRunSummary?(summary: RunSummaryRecord): void // one per run, at the end
flush?(signal: AbortSignal): Promise<void> // awaited at end of run, time-bounded;
// `signal` aborts at the deadline
}

A sink gets plain-data records and a read-only context: workspace root, cache folder, a warn function. Nothing it holds can change a build. Buffer in onRecord and send in flush.

With no telemetry plugin, vx adds no listener, builds no summary and spawns no git. A plugin whose setup() throws stops the run early and names itself.

  • @vzn/vx-otel sends OTLP traces, metrics and logs with no OpenTelemetry SDK. Each task’s span goes out as the task ends.
  • @vzn/vx-ci writes a GitHub job summary.

A remote cache follows the same rule. An error or timeout is a miss and a warning, and the run goes on.

Guide: Writing a vx plugin. More at vznjs.github.io/vx.

Turborepo, Nx and other product names are trademarks of their owners. vx is not affiliated with or endorsed by them.