feat(voyage): add lib/exporters/textfile-format.mjs — Prometheus text-format pure transform SC #12
Step 9 av v4.1-execute (Wave 2, Session 3). Pure function transformToPrometheus(records) → Prometheus text-format 0.0.4. Hard rules: - NO client-side timestamps (research/01 node_exporter#1284 mitigation) - Allowlist-redacted records ONLY (caller responsibility — Step 11 enforces) - UTF-8 metric names normalized: lowercase, [.\\-\\s] → _, voyage_ prefix - Empty input → empty string output - Sorted output for determinism (snapshot-test-friendly) Heuristic metric typing: - counter: *_total, *_count, *_passed, *_failed, *_skipped - histogram: *_ms, *_duration, *_p\\d+, *_seconds - gauge: everything else (Prometheus convention) Snapshot: tests/fixtures/expected.prom byte-for-byte match. Regenerate: node scripts/gen-expected-prom.mjs > tests/fixtures/expected.prom Tester (6 nye, baseline 400 → 406): - Snapshot byte-for-byte match (SC #12) - Empty input handling (null, undefined, []) - Allowlist-redaction sanity (post-bash-stats uten command_excerpt) - NO client-side timestamps (token-count-assertion per linje) - normalizeMetricName edge-cases - Determinism (identisk input → identisk output) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
f419121682
commit
2349d1d431
5 changed files with 297 additions and 0 deletions
21
plugins/voyage/scripts/gen-expected-prom.mjs
Normal file
21
plugins/voyage/scripts/gen-expected-prom.mjs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env node
|
||||
// scripts/gen-expected-prom.mjs
|
||||
// Regenerate tests/fixtures/expected.prom snapshot from tests/fixtures/stats-sample.jsonl.
|
||||
//
|
||||
// Usage:
|
||||
// node scripts/gen-expected-prom.mjs > tests/fixtures/expected.prom
|
||||
//
|
||||
// When the snapshot is stale (e.g. after intentional format change or new
|
||||
// stats-sample row), regenerate via the command above and inspect the diff.
|
||||
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { join, dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { transformToPrometheus } from '../lib/exporters/textfile-format.mjs';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const SAMPLE_PATH = join(__dirname, '..', 'tests', 'fixtures', 'stats-sample.jsonl');
|
||||
|
||||
const text = readFileSync(SAMPLE_PATH, 'utf-8');
|
||||
const records = text.trim().split('\n').filter(Boolean).map(line => JSON.parse(line));
|
||||
process.stdout.write(transformToPrometheus(records));
|
||||
Loading…
Add table
Add a link
Reference in a new issue