fix(web-probe): bound observe analyzer to recent samples (#744)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -2023,6 +2023,7 @@ import { createInterface } from "node:readline";
|
||||
|
||||
const stateDir = path.resolve(process.env.UNIDESK_WEB_OBSERVE_STATE_DIR || process.argv[2] || ".state/web-observe/manual");
|
||||
const archivePrefix = safeArchivePrefix(process.env.UNIDESK_WEB_OBSERVE_ANALYZE_ARCHIVE_PREFIX || "");
|
||||
const analyzeTailSamples = positiveInteger(process.env.UNIDESK_WEB_OBSERVE_ANALYZE_TAIL_SAMPLES, 360);
|
||||
const alertThresholds = parseAlertThresholds(process.env.UNIDESK_WEB_OBSERVE_ALERT_THRESHOLDS_JSON);
|
||||
const dataDir = archivePrefix ? path.join(stateDir, "archive") : stateDir;
|
||||
const dataFile = (name) => path.join(dataDir, archivePrefix ? archivePrefix + "-" + name : name);
|
||||
@@ -2030,12 +2031,14 @@ const analysisDir = path.join(stateDir, "analysis");
|
||||
const reportJsonPath = path.join(analysisDir, "report.json");
|
||||
const reportMdPath = path.join(analysisDir, "report.md");
|
||||
const jsonlReadIssues = [];
|
||||
const samples = await readJsonl(dataFile("samples.jsonl"), { compact: compactSampleForAnalysis });
|
||||
const control = await readJsonl(dataFile("control.jsonl"));
|
||||
const network = await readJsonl(dataFile("network.jsonl"));
|
||||
const consoleEvents = await readJsonl(dataFile("console.jsonl"));
|
||||
const errors = await readJsonl(dataFile("errors.jsonl"));
|
||||
const artifacts = await readJsonl(dataFile("artifacts.jsonl"));
|
||||
const sourceSamples = await readJsonl(dataFile("samples.jsonl"), { compact: compactSampleForAnalysis });
|
||||
const samples = analyzeTailSamples > 0 ? sourceSamples.slice(-analyzeTailSamples) : sourceSamples;
|
||||
const sampleWindow = sampleTimeWindow(samples, 60_000);
|
||||
const control = filterRowsByTimeWindow(await readJsonl(dataFile("control.jsonl")), sampleWindow);
|
||||
const network = filterRowsByTimeWindow(await readJsonl(dataFile("network.jsonl")), sampleWindow);
|
||||
const consoleEvents = filterRowsByTimeWindow(await readJsonl(dataFile("console.jsonl")), sampleWindow);
|
||||
const errors = filterRowsByTimeWindow(await readJsonl(dataFile("errors.jsonl")), sampleWindow);
|
||||
const artifacts = filterRowsByTimeWindow(await readJsonl(dataFile("artifacts.jsonl")), sampleWindow);
|
||||
const manifest = await readJson(path.join(stateDir, "manifest.json"));
|
||||
const heartbeat = await readJson(path.join(stateDir, "heartbeat.json"));
|
||||
|
||||
@@ -2096,7 +2099,7 @@ const report = {
|
||||
command: "web-probe-observe analyze",
|
||||
generatedAt: new Date().toISOString(),
|
||||
stateDir,
|
||||
jsonlScope: { mode: archivePrefix ? "archive" : "current", archivePrefix: archivePrefix || null, dataDir, valuesRedacted: true },
|
||||
jsonlScope: { mode: archivePrefix ? "archive" : "current", archivePrefix: archivePrefix || null, dataDir, analyzeTailSamples, sourceSampleCount: sourceSamples.length, effectiveSampleCount: samples.length, sampleWindow, valuesRedacted: true },
|
||||
alertThresholds,
|
||||
manifest: compactManifest(manifest),
|
||||
heartbeat: compactHeartbeat(heartbeat),
|
||||
@@ -2343,6 +2346,26 @@ async function readJsonl(file, options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
function sampleTimeWindow(samples, paddingMs) {
|
||||
const times = samples
|
||||
.map((item) => Date.parse(String(item && item.ts || "")))
|
||||
.filter((value) => Number.isFinite(value));
|
||||
if (times.length === 0) return { startMs: null, endMs: null, startAt: null, endAt: null, paddingMs };
|
||||
const startMs = Math.max(0, Math.min(...times) - Math.max(0, paddingMs || 0));
|
||||
const endMs = Math.max(...times) + Math.max(0, paddingMs || 0);
|
||||
return { startMs, endMs, startAt: new Date(startMs).toISOString(), endAt: new Date(endMs).toISOString(), paddingMs };
|
||||
}
|
||||
|
||||
function filterRowsByTimeWindow(rows, window) {
|
||||
if (!window || !Number.isFinite(window.startMs) || !Number.isFinite(window.endMs)) return rows;
|
||||
return rows.filter((item) => {
|
||||
const value = item && (item.ts || item.observedAt || item.startedAt || item.finishedAt || item.createdAt || item.updatedAt);
|
||||
const ms = Date.parse(String(value || ""));
|
||||
if (!Number.isFinite(ms)) return true;
|
||||
return ms >= window.startMs && ms <= window.endMs;
|
||||
});
|
||||
}
|
||||
|
||||
function compactSampleForAnalysis(sample) {
|
||||
if (!sample || typeof sample !== "object") return sample;
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user