- VERSION file as authoritative version source - export.mjs reads VERSION with package.json fallback - bw-ota.ps1 DryRun mode for safe testing - auto-setup.ps1 bumped to v3.2.0 (Phase 8 OTA)
40 lines
1.2 KiB
JavaScript
40 lines
1.2 KiB
JavaScript
/**
|
|
* metrics.js — 异步指标发射器 + 自动轮转 (P0-1)
|
|
* 写入 debug/metrics-<category>.jsonl, >50MB 自动轮转保留 3 个
|
|
*/
|
|
'use strict';
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
let CLAUDE_ROOT;
|
|
try { CLAUDE_ROOT = require('./root.js'); } catch { CLAUDE_ROOT = path.resolve(__dirname, '..', '..'); }
|
|
|
|
const METRICS_DIR = path.join(CLAUDE_ROOT, 'debug');
|
|
const MAX_BYTES = 50 * 1024 * 1024;
|
|
const KEEP_ROTATED = 3;
|
|
|
|
function rotate(fp) {
|
|
try {
|
|
const s = fs.statSync(fp);
|
|
if (s.size < MAX_BYTES) return;
|
|
for (let i = KEEP_ROTATED; i >= 1; i--) {
|
|
const dst = fp + '.' + i;
|
|
if (i === KEEP_ROTATED) try { fs.unlinkSync(dst); } catch {}
|
|
const src = i === 1 ? fp : fp + '.' + (i - 1);
|
|
try { fs.renameSync(src, dst); } catch {}
|
|
}
|
|
} catch {}
|
|
}
|
|
|
|
function emit(category, data) {
|
|
try {
|
|
const fp = path.join(METRICS_DIR, 'metrics-' + category + '.jsonl');
|
|
try { fs.mkdirSync(METRICS_DIR, { recursive: true }); } catch {}
|
|
rotate(fp);
|
|
const entry = Object.assign({ ts: new Date().toISOString() }, data);
|
|
fs.appendFileSync(fp, JSON.stringify(entry) + '\n');
|
|
} catch {}
|
|
}
|
|
|
|
module.exports = { emit, rotate };
|