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

@@ -1,23 +1,19 @@
/**
* Monitoring and stats routes
* Refactored to use explicit dependencies
*/
const express = require('express');
const asyncHandler = require('../src/utils/async-handler');
module.exports = function({ docker, resourceMonitor }) {
module.exports = function(ctx) {
const router = express.Router();
// ===== RESOURCE MONITORING ENDPOINTS =====
router.get('/monitoring/stats', asyncHandler(async (req, res) => {
const stats = resourceMonitor.getAllStats();
// Get all container stats (from resource monitor module)
router.get('/monitoring/stats', ctx.asyncHandler(async (req, res) => {
const stats = ctx.resourceMonitor.getAllStats();
res.json({ success: true, stats });
}, 'monitoring-stats'));
router.get('/monitoring/stats/:containerId', asyncHandler(async (req, res) => {
const stats = resourceMonitor.getCurrentStats(req.params.containerId);
// Get stats for specific container
router.get('/monitoring/stats/:containerId', ctx.asyncHandler(async (req, res) => {
const stats = ctx.resourceMonitor.getCurrentStats(req.params.containerId);
if (!stats) {
const { NotFoundError } = require('../errors');
throw new NotFoundError('Container');
@@ -25,15 +21,17 @@ module.exports = function({ docker, resourceMonitor }) {
res.json({ success: true, stats });
}, 'monitoring-stats-container'));
router.get('/monitoring/history/:containerId', asyncHandler(async (req, res) => {
// Get historical stats
router.get('/monitoring/history/:containerId', ctx.asyncHandler(async (req, res) => {
const hours = parseInt(req.query.hours) || 24;
const history = resourceMonitor.getHistoricalStats(req.params.containerId, hours);
const history = ctx.resourceMonitor.getHistoricalStats(req.params.containerId, hours);
res.json({ success: true, history, hours });
}, 'monitoring-history'));
router.get('/monitoring/aggregated/:containerId', asyncHandler(async (req, res) => {
// Get aggregated stats
router.get('/monitoring/aggregated/:containerId', ctx.asyncHandler(async (req, res) => {
const hours = parseInt(req.query.hours) || 24;
const aggregated = resourceMonitor.getAggregatedStats(req.params.containerId, hours);
const aggregated = ctx.resourceMonitor.getAggregatedStats(req.params.containerId, hours);
if (!aggregated) {
const { NotFoundError } = require('../errors');
throw new NotFoundError('Monitoring data');
@@ -41,42 +39,49 @@ module.exports = function({ docker, resourceMonitor }) {
res.json({ success: true, aggregated, hours });
}, 'monitoring-aggregated'));
router.post('/monitoring/alerts/:containerId', asyncHandler(async (req, res) => {
resourceMonitor.setAlertConfig(req.params.containerId, req.body);
// Configure alerts
router.post('/monitoring/alerts/:containerId', ctx.asyncHandler(async (req, res) => {
ctx.resourceMonitor.setAlertConfig(req.params.containerId, req.body);
res.json({ success: true, message: 'Alert configuration saved' });
}, 'monitoring-alerts-set'));
router.get('/monitoring/alerts/:containerId', asyncHandler(async (req, res) => {
const config = resourceMonitor.getAlertConfig(req.params.containerId);
// Get alert configuration
router.get('/monitoring/alerts/:containerId', ctx.asyncHandler(async (req, res) => {
const config = ctx.resourceMonitor.getAlertConfig(req.params.containerId);
res.json({ success: true, config: config || {} });
}, 'monitoring-alerts-get'));
router.delete('/monitoring/alerts/:containerId', asyncHandler(async (req, res) => {
resourceMonitor.removeAlertConfig(req.params.containerId);
// Delete alert configuration
router.delete('/monitoring/alerts/:containerId', ctx.asyncHandler(async (req, res) => {
ctx.resourceMonitor.removeAlertConfig(req.params.containerId);
res.json({ success: true, message: 'Alert configuration removed' });
}, 'monitoring-alerts-delete'));
// ===== CONTAINER STATS ENDPOINTS (legacy /stats/) =====
router.get('/stats/containers', asyncHandler(async (req, res) => {
const containers = await docker.client.listContainers({ all: false });
// Get all container stats (live Docker stats)
router.get('/stats/containers', ctx.asyncHandler(async (req, res) => {
const containers = await ctx.docker.client.listContainers({ all: false });
const stats = [];
for (const containerInfo of containers) {
try {
const container = docker.client.getContainer(containerInfo.Id);
const container = ctx.docker.client.getContainer(containerInfo.Id);
const containerStats = await container.stats({ stream: false });
// Calculate CPU percentage
const cpuDelta = containerStats.cpu_stats.cpu_usage.total_usage -
(containerStats.precpu_stats.cpu_usage?.total_usage || 0);
const systemDelta = containerStats.cpu_stats.system_cpu_usage -
(containerStats.precpu_stats.system_cpu_usage || 0);
const cpuPercent = systemDelta > 0 ? (cpuDelta / systemDelta) * 100 * (containerStats.cpu_stats.online_cpus || 1) : 0;
// Calculate memory usage
const memUsage = containerStats.memory_stats.usage || 0;
const memLimit = containerStats.memory_stats.limit || 1;
const memPercent = (memUsage / memLimit) * 100;
// Network stats
let netRx = 0, netTx = 0;
if (containerStats.networks) {
for (const net of Object.values(containerStats.networks)) {
@@ -90,15 +95,21 @@ module.exports = function({ docker, resourceMonitor }) {
name: containerInfo.Names[0]?.replace(/^\//, '') || 'unknown',
image: containerInfo.Image,
status: containerInfo.State,
cpu: { percent: Math.round(cpuPercent * 100) / 100 },
cpu: {
percent: Math.round(cpuPercent * 100) / 100
},
memory: {
used: memUsage,
limit: memLimit,
percent: Math.round(memPercent * 100) / 100,
percent: Math.round(memPercent * 100) / 100
},
network: { rx: netRx, tx: netTx },
network: {
rx: netRx,
tx: netTx
}
});
} catch (e) {
// Skip containers we can't get stats for
console.log(`Could not get stats for ${containerInfo.Names[0]}:`, e.message);
}
}
@@ -106,20 +117,24 @@ module.exports = function({ docker, resourceMonitor }) {
res.json({ success: true, stats, timestamp: new Date().toISOString() });
}, 'stats-containers'));
router.get('/stats/container/:id', asyncHandler(async (req, res) => {
const container = docker.client.getContainer(req.params.id);
// Get single container stats
router.get('/stats/container/:id', ctx.asyncHandler(async (req, res) => {
const container = ctx.docker.client.getContainer(req.params.id);
const containerStats = await container.stats({ stream: false });
const info = await container.inspect();
// Calculate CPU percentage
const cpuDelta = containerStats.cpu_stats.cpu_usage.total_usage -
(containerStats.precpu_stats.cpu_usage?.total_usage || 0);
const systemDelta = containerStats.cpu_stats.system_cpu_usage -
(containerStats.precpu_stats.system_cpu_usage || 0);
const cpuPercent = systemDelta > 0 ? (cpuDelta / systemDelta) * 100 * (containerStats.cpu_stats.online_cpus || 1) : 0;
// Memory
const memUsage = containerStats.memory_stats.usage || 0;
const memLimit = containerStats.memory_stats.limit || 1;
// Network
let netRx = 0, netTx = 0;
if (containerStats.networks) {
for (const net of Object.values(containerStats.networks)) {
@@ -135,14 +150,16 @@ module.exports = function({ docker, resourceMonitor }) {
image: info.Config.Image,
status: info.State.Status,
started: info.State.StartedAt,
cpu: { percent: Math.round(cpuPercent * 100) / 100 },
cpu: {
percent: Math.round(cpuPercent * 100) / 100
},
memory: {
used: memUsage,
limit: memLimit,
percent: Math.round((memUsage / memLimit) * 100 * 100) / 100,
percent: Math.round((memUsage / memLimit) * 100 * 100) / 100
},
network: { rx: netRx, tx: netTx },
},
network: { rx: netRx, tx: netTx }
}
});
}, 'stats-container'));