Merge: 92 app templates + Authelia deployment on test server

This commit is contained in:
Krystie
2026-08-12 18:07:13 -07:00
parent 9a1998288e
commit ae54927210
2 changed files with 19 additions and 3 deletions
@@ -19,6 +19,7 @@ const STATS_HOURLY_FILE = process.env.STATS_HOURLY_FILE || path.join(platformPat
const STATS_DAILY_FILE = process.env.STATS_DAILY_FILE || path.join(platformPaths.dataDir, 'container-stats-daily.json'); const STATS_DAILY_FILE = process.env.STATS_DAILY_FILE || path.join(platformPaths.dataDir, 'container-stats-daily.json');
const ALERT_CONFIG_FILE = process.env.ALERT_CONFIG_FILE || path.join(platformPaths.dataDir, 'alert-config.json'); const ALERT_CONFIG_FILE = process.env.ALERT_CONFIG_FILE || path.join(platformPaths.dataDir, 'alert-config.json');
const ALERT_HISTORY_FILE = process.env.ALERT_HISTORY_FILE || path.join(platformPaths.dataDir, 'alert-history.json'); const ALERT_HISTORY_FILE = process.env.ALERT_HISTORY_FILE || path.join(platformPaths.dataDir, 'alert-history.json');
const MAX_STATS_PER_CONTAINER = parseInt(process.env.STATS_MAX_ENTRIES || '500', 10); // Cap to prevent disk explosion
const STATS_RETENTION_HOURS = parseInt(process.env.STATS_RETENTION_HOURS || '168', 10); // 7 days raw const STATS_RETENTION_HOURS = parseInt(process.env.STATS_RETENTION_HOURS || '168', 10); // 7 days raw
const STATS_HOURLY_RETENTION_DAYS = parseInt(process.env.STATS_HOURLY_RETENTION_DAYS || '30', 10); // 30 days hourly const STATS_HOURLY_RETENTION_DAYS = parseInt(process.env.STATS_HOURLY_RETENTION_DAYS || '30', 10); // 30 days hourly
const STATS_DAILY_RETENTION_DAYS = parseInt(process.env.STATS_DAILY_RETENTION_DAYS || '365', 10); // 365 days daily const STATS_DAILY_RETENTION_DAYS = parseInt(process.env.STATS_DAILY_RETENTION_DAYS || '365', 10); // 365 days daily
@@ -242,6 +243,11 @@ class ResourceMonitor extends EventEmitter {
containerStats.history = containerStats.history.filter(s => containerStats.history = containerStats.history.filter(s =>
new Date(s.timestamp).getTime() > cutoffTime new Date(s.timestamp).getTime() > cutoffTime
); );
// Also cap total entries per container (disk explosion fix)
if (containerStats.history.length > MAX_STATS_PER_CONTAINER) {
containerStats.history = containerStats.history.slice(-MAX_STATS_PER_CONTAINER);
}
} }
/** /**
@@ -620,7 +626,7 @@ class ResourceMonitor extends EventEmitter {
saveStats() { saveStats() {
try { try {
const data = Object.fromEntries(this.stats); const data = Object.fromEntries(this.stats);
fs.writeFileSync(STATS_FILE, JSON.stringify(data, null, 2)); fs.writeFileSync(STATS_FILE, JSON.stringify(data)); // Compact JSON to reduce file size
} catch (error) { } catch (error) {
log.error('monitor', error, { operation: 'saveStats' }); log.error('monitor', error, { operation: 'saveStats' });
} }
+12 -2
View File
@@ -30,6 +30,7 @@ const LEGACY_HEALTH_CONFIG_FILE = path.join(__dirname, 'health-config.json');
const LEGACY_HEALTH_HISTORY_FILE = path.join(__dirname, 'health-history.json'); const LEGACY_HEALTH_HISTORY_FILE = path.join(__dirname, 'health-history.json');
const CHECK_INTERVAL = parseInt(process.env.HEALTH_CHECK_INTERVAL || '30000', 10); // 30 seconds const CHECK_INTERVAL = parseInt(process.env.HEALTH_CHECK_INTERVAL || '30000', 10); // 30 seconds
const MAX_CHECK_INTERVAL = parseInt(process.env.HEALTH_CHECK_MAX_INTERVAL || '300000', 10); // 5 minutes max backoff const MAX_CHECK_INTERVAL = parseInt(process.env.HEALTH_CHECK_MAX_INTERVAL || '300000', 10); // 5 minutes max backoff
const MAX_ENTRIES_PER_SERVICE = parseInt(process.env.HEALTH_MAX_ENTRIES || '500', 10); // Cap to prevent disk explosion
const HISTORY_RETENTION_DAYS = parseInt(process.env.HEALTH_HISTORY_RETENTION || '30', 10); const HISTORY_RETENTION_DAYS = parseInt(process.env.HEALTH_HISTORY_RETENTION || '30', 10);
class HealthChecker extends EventEmitter { class HealthChecker extends EventEmitter {
@@ -217,7 +218,7 @@ class HealthChecker extends EventEmitter {
statusCode: res.statusCode, statusCode: res.statusCode,
message: healthy ? 'Service is healthy' : 'Service check failed', message: healthy ? 'Service is healthy' : 'Service check failed',
details: { details: {
headers: res.headers, headers: res.headers ? { server: res.headers.server } : undefined, // Compact: disk explosion fix
bodyLength: data.length bodyLength: data.length
} }
}); });
@@ -286,6 +287,11 @@ class HealthChecker extends EventEmitter {
this.history[serviceId].push(status); this.history[serviceId].push(status);
// Cap entries to prevent unbounded growth (disk explosion fix)
if (this.history[serviceId].length > MAX_ENTRIES_PER_SERVICE) {
this.history[serviceId] = this.history[serviceId].slice(-MAX_ENTRIES_PER_SERVICE);
}
// Emit status event // Emit status event
this.emit('status-check', status); this.emit('status-check', status);
@@ -565,6 +571,10 @@ class HealthChecker extends EventEmitter {
this.history[serviceId] = this.history[serviceId].filter(h => this.history[serviceId] = this.history[serviceId].filter(h =>
new Date(h.timestamp).getTime() > cutoffTime new Date(h.timestamp).getTime() > cutoffTime
); );
// Also cap total entries per service
if (this.history[serviceId].length > MAX_ENTRIES_PER_SERVICE) {
this.history[serviceId] = this.history[serviceId].slice(-MAX_ENTRIES_PER_SERVICE);
}
} }
} }
@@ -616,7 +626,7 @@ class HealthChecker extends EventEmitter {
*/ */
saveHistory() { saveHistory() {
try { try {
fs.writeFileSync(HEALTH_HISTORY_FILE, JSON.stringify(this.history, null, 2)); fs.writeFileSync(HEALTH_HISTORY_FILE, JSON.stringify(this.history)); // Compact JSON (no pretty-print) to reduce file size
} catch (error) { } catch (error) {
this.emit('log', 'error', `Error saving history: ${error.message}`); this.emit('log', 'error', `Error saving history: ${error.message}`);
} }