Sync DNS2 production changes - removed obsolete test suite and refactored structure

This commit is contained in:
Krystie
2026-03-23 10:47:15 +01:00
parent 1ac50918ab
commit d76644d948
288 changed files with 8965 additions and 15731 deletions

View File

@@ -18,12 +18,12 @@ const ERROR_PATTERNS = [
/\berror\b/i, /\bfailed\b/i, /\bfatal\b/i, /\bpanic\b/i,
/\bcrash(ed)?\b/i, /\bexception\b/i, /\btimeout\b/i,
/\bOOM\b/, /\bout of memory\b/i, /\bkilled\b/i,
/\bdenied\b/i, /\bunauthorized\b/i, /\brefused\b/i,
/\bdenied\b/i, /\bunauthorized\b/i, /\brefused\b/i
];
const WARNING_PATTERNS = [
/\bwarn(ing)?\b/i, /\bdeprecated\b/i, /\bretry(ing)?\b/i,
/\bslow\b/i, /\blatency\b/i,
/\bslow\b/i, /\blatency\b/i
];
const EVENT_PATTERNS = [
@@ -31,7 +31,7 @@ const EVENT_PATTERNS = [
{ pattern: /\b(stop(ped|ping)?|shutdown|exit(ed|ing)?|terminat(ed|ing)?)\b/i, type: 'shutdown' },
{ pattern: /\b(restart(ed|ing)?|reload(ed|ing)?)\b/i, type: 'restart' },
{ pattern: /\bhealth.?check.*(fail|unhealthy)\b/i, type: 'health_failure' },
{ pattern: /\b(update|upgrade|migration)\b/i, type: 'update' },
{ pattern: /\b(update|upgrade|migration)\b/i, type: 'update' }
];
class LogDigest extends EventEmitter {
@@ -63,7 +63,7 @@ class LogDigest extends EventEmitter {
// Collect logs every hour
this.collectInterval = setInterval(() => {
this._collectHourlyLogs().catch(e =>
console.error('[LogDigest] Hourly collection failed:', e.message),
console.error('[LogDigest] Hourly collection failed:', e.message)
);
}, DOCKER.DIGEST.COLLECT_INTERVAL);
@@ -102,7 +102,7 @@ class LogDigest extends EventEmitter {
const hourSummary = {
hour: hourKey,
timestamp: now.toISOString(),
services: {},
services: {}
};
try {
@@ -123,7 +123,7 @@ class LogDigest extends EventEmitter {
events: [],
errorCount: 0,
warningCount: 0,
totalLines: 0,
totalLines: 0
};
if (isRunning) {
@@ -134,7 +134,7 @@ class LogDigest extends EventEmitter {
stderr: true,
since: sinceTimestamp,
tail: DOCKER.DIGEST.LOG_TAIL,
timestamps: true,
timestamps: true
});
const lines = this._parseDockerLogs(logBuffer);
@@ -147,7 +147,7 @@ class LogDigest extends EventEmitter {
if (serviceSummary.errors.length < 10) {
serviceSummary.errors.push({
time: line.timestamp || hourKey,
text: line.text.slice(0, 500),
text: line.text.slice(0, 500)
});
}
continue;
@@ -159,7 +159,7 @@ class LogDigest extends EventEmitter {
if (serviceSummary.warnings.length < 5) {
serviceSummary.warnings.push({
time: line.timestamp || hourKey,
text: line.text.slice(0, 300),
text: line.text.slice(0, 300)
});
}
continue;
@@ -171,7 +171,7 @@ class LogDigest extends EventEmitter {
serviceSummary.events.push({
type,
time: line.timestamp || hourKey,
text: line.text.slice(0, 300),
text: line.text.slice(0, 300)
});
break;
}
@@ -180,7 +180,7 @@ class LogDigest extends EventEmitter {
} catch (logErr) {
serviceSummary.errors.push({
time: now.toISOString(),
text: `Failed to fetch logs: ${logErr.message}`,
text: `Failed to fetch logs: ${logErr.message}`
});
serviceSummary.errorCount++;
}
@@ -188,7 +188,7 @@ class LogDigest extends EventEmitter {
serviceSummary.events.push({
type: 'not_running',
time: now.toISOString(),
text: `Container is ${containerInfo.State}`,
text: `Container is ${containerInfo.State}`
});
}
@@ -237,7 +237,7 @@ class LogDigest extends EventEmitter {
lines.push({
stream: streamType === 2 ? 'stderr' : 'stdout',
text: message,
timestamp,
timestamp
});
}
offset += 8 + size;
@@ -258,7 +258,7 @@ class LogDigest extends EventEmitter {
const delay = next.getTime() - now.getTime();
this.digestTimeout = setTimeout(() => {
this.generateDailyDigest().catch(e =>
console.error('[LogDigest] Daily digest generation failed:', e.message),
console.error('[LogDigest] Daily digest generation failed:', e.message)
);
// Reschedule for tomorrow
if (this.running) this._scheduleDailyDigest();
@@ -288,7 +288,7 @@ class LogDigest extends EventEmitter {
totalLines: 0,
lastState: svc.state,
topErrors: [],
events: [],
events: []
};
}
const agg = serviceAgg[appId];
@@ -332,8 +332,8 @@ class LogDigest extends EventEmitter {
totalServices: Object.keys(serviceAgg).length,
servicesWithErrors: Object.values(serviceAgg).filter(s => s.totalErrors > 0).length,
totalErrors: Object.values(serviceAgg).reduce((sum, s) => sum + s.totalErrors, 0),
totalWarnings: Object.values(serviceAgg).reduce((sum, s) => sum + s.totalWarnings, 0),
},
totalWarnings: Object.values(serviceAgg).reduce((sum, s) => sum + s.totalWarnings, 0)
}
};
// Write formatted digest file
@@ -369,7 +369,7 @@ class LogDigest extends EventEmitter {
lines.push('');
// Service summary table
lines.push(`-- Service Summary ${ '-'.repeat(36)}`);
lines.push('-- Service Summary ' + '-'.repeat(36));
const services = Object.values(digest.services);
if (services.length === 0) {
lines.push(' No managed services found.');
@@ -387,14 +387,14 @@ class LogDigest extends EventEmitter {
// Notable events
const events = digest.notableEvents;
if (events.length > 0) {
lines.push(`-- Notable Events ${ '-'.repeat(37)}`);
lines.push('-- Notable Events ' + '-'.repeat(37));
for (const evt of events) {
const time = (evt.time || '').slice(11, 16) || '??:??';
lines.push(` [${time}] ${evt.service}: ${evt.text.slice(0, 80)}`);
// Add guidance for where to look further
const containerName = `${DOCKER.CONTAINER_PREFIX}${evt.appId}`;
if (evt.type === 'health_failure' || evt.type === 'restart') {
const sinceDate = `${digest.date }T${ (evt.time || '').slice(11, 13) }:00:00`;
const sinceDate = digest.date + 'T' + (evt.time || '').slice(11, 13) + ':00:00';
lines.push(` See: docker logs ${containerName} --since ${sinceDate}`);
}
}
@@ -404,7 +404,7 @@ class LogDigest extends EventEmitter {
// Top errors per service
const errServices = services.filter(s => s.totalErrors > 0);
if (errServices.length > 0) {
lines.push(`-- Error Details ${ '-'.repeat(38)}`);
lines.push('-- Error Details ' + '-'.repeat(38));
for (const svc of errServices) {
lines.push(` ${svc.name} (${svc.totalErrors} errors):`);
for (const err of svc.topErrors) {
@@ -419,7 +419,7 @@ class LogDigest extends EventEmitter {
// Docker disk usage
if (digest.diskUsage) {
lines.push(`-- Docker Disk Usage ${ '-'.repeat(34)}`);
lines.push('-- Docker Disk Usage ' + '-'.repeat(34));
const du = digest.diskUsage;
lines.push(` Images: ${formatBytes(du.images.sizeBytes)} (${du.images.count} images)`);
lines.push(` Containers: ${formatBytes(du.containers.sizeBytes)}`);
@@ -439,7 +439,7 @@ class LogDigest extends EventEmitter {
lines.push(` Hours collected: ${digest.hoursCollected}/24`);
lines.push(hr);
return `${lines.join('\n') }\n`;
return lines.join('\n') + '\n';
}
/**
@@ -551,7 +551,7 @@ class LogDigest extends EventEmitter {
date: today,
hoursCollected: todayHours.length,
lastCollect: this.lastCollect,
services: serviceAgg,
services: serviceAgg
};
}
@@ -560,7 +560,7 @@ class LogDigest extends EventEmitter {
running: this.running,
lastCollect: this.lastCollect,
hourlySummaries: this.hourlySummaries.length,
digestDir: this.digestDir,
digestDir: this.digestDir
};
}
}
@@ -569,7 +569,7 @@ function formatBytes(bytes) {
if (bytes === 0) return '0 B';
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return `${(bytes / Math.pow(1024, i)).toFixed(1) } ${ units[i]}`;
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + units[i];
}
module.exports = new LogDigest();