Merge: 92 app templates + Authelia deployment on test server
This commit is contained in:
@@ -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' });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user