Files
worldmonitor/api/_cache-telemetry.js

54 lines
1.6 KiB
JavaScript

const statsByEndpoint = new Map();
const MAX_ENDPOINTS = 128;
const LOG_EVERY = Math.max(0, Number(process.env.CACHE_TELEMETRY_LOG_EVERY || 200));
function cleanupOldEndpoints() {
if (statsByEndpoint.size <= MAX_ENDPOINTS) return;
const entries = Array.from(statsByEndpoint.entries())
.sort((a, b) => a[1].lastSeen - b[1].lastSeen);
const overflow = statsByEndpoint.size - MAX_ENDPOINTS;
for (let i = 0; i < overflow; i++) {
statsByEndpoint.delete(entries[i][0]);
}
}
export function recordCacheTelemetry(endpoint, outcome) {
if (!endpoint || !outcome) return;
const now = Date.now();
const current = statsByEndpoint.get(endpoint) || {
total: 0,
outcomes: {},
firstSeen: now,
lastSeen: now,
};
current.total += 1;
current.outcomes[outcome] = (current.outcomes[outcome] || 0) + 1;
current.lastSeen = now;
statsByEndpoint.set(endpoint, current);
cleanupOldEndpoints();
if (LOG_EVERY > 0 && current.total % LOG_EVERY === 0) {
console.log(`[CacheTelemetry] ${endpoint} total=${current.total} outcomes=${JSON.stringify(current.outcomes)}`);
}
}
export function getCacheTelemetrySnapshot() {
const endpoints = Array.from(statsByEndpoint.entries())
.sort((a, b) => b[1].lastSeen - a[1].lastSeen)
.map(([endpoint, stats]) => ({
endpoint,
total: stats.total,
outcomes: stats.outcomes,
firstSeen: new Date(stats.firstSeen).toISOString(),
lastSeen: new Date(stats.lastSeen).toISOString(),
}));
return {
generatedAt: new Date().toISOString(),
endpointCount: endpoints.length,
endpoints,
note: 'In-memory per instance telemetry (resets on cold start).',
};
}