refactor(routes): Phase 3.5 - standardize monitoring.js (only 3 deps!)
This commit is contained in:
@@ -1,72 +1,81 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
|
const { success } = require('../response-helpers');
|
||||||
|
|
||||||
module.exports = function(ctx) {
|
/**
|
||||||
|
* Monitoring routes factory
|
||||||
|
* @param {Object} deps - Explicit dependencies
|
||||||
|
* @param {Object} deps.resourceMonitor - Resource monitoring manager
|
||||||
|
* @param {Object} deps.docker - Docker client wrapper
|
||||||
|
* @param {Function} deps.asyncHandler - Async route handler wrapper
|
||||||
|
* @returns {express.Router}
|
||||||
|
*/
|
||||||
|
module.exports = function({ resourceMonitor, docker, asyncHandler }) {
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// ===== RESOURCE MONITORING ENDPOINTS =====
|
// ===== RESOURCE MONITORING ENDPOINTS =====
|
||||||
|
|
||||||
// Get all container stats (from resource monitor module)
|
// Get all container stats (from resource monitor module)
|
||||||
router.get('/monitoring/stats', ctx.asyncHandler(async (req, res) => {
|
router.get('/monitoring/stats', asyncHandler(async (req, res) => {
|
||||||
const stats = ctx.resourceMonitor.getAllStats();
|
const stats = resourceMonitor.getAllStats();
|
||||||
res.json({ success: true, stats });
|
success(res, { stats });
|
||||||
}, 'monitoring-stats'));
|
}, 'monitoring-stats'));
|
||||||
|
|
||||||
// Get stats for specific container
|
// Get stats for specific container
|
||||||
router.get('/monitoring/stats/:containerId', ctx.asyncHandler(async (req, res) => {
|
router.get('/monitoring/stats/:containerId', asyncHandler(async (req, res) => {
|
||||||
const stats = ctx.resourceMonitor.getCurrentStats(req.params.containerId);
|
const stats = resourceMonitor.getCurrentStats(req.params.containerId);
|
||||||
if (!stats) {
|
if (!stats) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../errors');
|
||||||
throw new NotFoundError('Container');
|
throw new NotFoundError('Container');
|
||||||
}
|
}
|
||||||
res.json({ success: true, stats });
|
success(res, { stats });
|
||||||
}, 'monitoring-stats-container'));
|
}, 'monitoring-stats-container'));
|
||||||
|
|
||||||
// Get historical stats
|
// Get historical stats
|
||||||
router.get('/monitoring/history/:containerId', ctx.asyncHandler(async (req, res) => {
|
router.get('/monitoring/history/:containerId', asyncHandler(async (req, res) => {
|
||||||
const hours = parseInt(req.query.hours) || 24;
|
const hours = parseInt(req.query.hours) || 24;
|
||||||
const history = ctx.resourceMonitor.getHistoricalStats(req.params.containerId, hours);
|
const history = resourceMonitor.getHistoricalStats(req.params.containerId, hours);
|
||||||
res.json({ success: true, history, hours });
|
success(res, { history, hours });
|
||||||
}, 'monitoring-history'));
|
}, 'monitoring-history'));
|
||||||
|
|
||||||
// Get aggregated stats
|
// Get aggregated stats
|
||||||
router.get('/monitoring/aggregated/:containerId', ctx.asyncHandler(async (req, res) => {
|
router.get('/monitoring/aggregated/:containerId', asyncHandler(async (req, res) => {
|
||||||
const hours = parseInt(req.query.hours) || 24;
|
const hours = parseInt(req.query.hours) || 24;
|
||||||
const aggregated = ctx.resourceMonitor.getAggregatedStats(req.params.containerId, hours);
|
const aggregated = resourceMonitor.getAggregatedStats(req.params.containerId, hours);
|
||||||
if (!aggregated) {
|
if (!aggregated) {
|
||||||
const { NotFoundError } = require('../errors');
|
const { NotFoundError } = require('../errors');
|
||||||
throw new NotFoundError('Monitoring data');
|
throw new NotFoundError('Monitoring data');
|
||||||
}
|
}
|
||||||
res.json({ success: true, aggregated, hours });
|
success(res, { aggregated, hours });
|
||||||
}, 'monitoring-aggregated'));
|
}, 'monitoring-aggregated'));
|
||||||
|
|
||||||
// Configure alerts
|
// Configure alerts
|
||||||
router.post('/monitoring/alerts/:containerId', ctx.asyncHandler(async (req, res) => {
|
router.post('/monitoring/alerts/:containerId', asyncHandler(async (req, res) => {
|
||||||
ctx.resourceMonitor.setAlertConfig(req.params.containerId, req.body);
|
resourceMonitor.setAlertConfig(req.params.containerId, req.body);
|
||||||
res.json({ success: true, message: 'Alert configuration saved' });
|
success(res, { message: 'Alert configuration saved' });
|
||||||
}, 'monitoring-alerts-set'));
|
}, 'monitoring-alerts-set'));
|
||||||
|
|
||||||
// Get alert configuration
|
// Get alert configuration
|
||||||
router.get('/monitoring/alerts/:containerId', ctx.asyncHandler(async (req, res) => {
|
router.get('/monitoring/alerts/:containerId', asyncHandler(async (req, res) => {
|
||||||
const config = ctx.resourceMonitor.getAlertConfig(req.params.containerId);
|
const config = resourceMonitor.getAlertConfig(req.params.containerId);
|
||||||
res.json({ success: true, config: config || {} });
|
success(res, { config: config || {} });
|
||||||
}, 'monitoring-alerts-get'));
|
}, 'monitoring-alerts-get'));
|
||||||
|
|
||||||
// Delete alert configuration
|
// Delete alert configuration
|
||||||
router.delete('/monitoring/alerts/:containerId', ctx.asyncHandler(async (req, res) => {
|
router.delete('/monitoring/alerts/:containerId', asyncHandler(async (req, res) => {
|
||||||
ctx.resourceMonitor.removeAlertConfig(req.params.containerId);
|
resourceMonitor.removeAlertConfig(req.params.containerId);
|
||||||
res.json({ success: true, message: 'Alert configuration removed' });
|
success(res, { message: 'Alert configuration removed' });
|
||||||
}, 'monitoring-alerts-delete'));
|
}, 'monitoring-alerts-delete'));
|
||||||
|
|
||||||
// ===== CONTAINER STATS ENDPOINTS (legacy /stats/) =====
|
// ===== CONTAINER STATS ENDPOINTS (legacy /stats/) =====
|
||||||
|
|
||||||
// Get all container stats (live Docker stats)
|
// Get all container stats (live Docker stats)
|
||||||
router.get('/stats/containers', ctx.asyncHandler(async (req, res) => {
|
router.get('/stats/containers', asyncHandler(async (req, res) => {
|
||||||
const containers = await ctx.docker.client.listContainers({ all: false });
|
const containers = await docker.client.listContainers({ all: false });
|
||||||
const stats = [];
|
const stats = [];
|
||||||
|
|
||||||
for (const containerInfo of containers) {
|
for (const containerInfo of containers) {
|
||||||
try {
|
try {
|
||||||
const container = ctx.docker.client.getContainer(containerInfo.Id);
|
const container = docker.client.getContainer(containerInfo.Id);
|
||||||
const containerStats = await container.stats({ stream: false });
|
const containerStats = await container.stats({ stream: false });
|
||||||
|
|
||||||
// Calculate CPU percentage
|
// Calculate CPU percentage
|
||||||
@@ -114,12 +123,12 @@ module.exports = function(ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({ success: true, stats, timestamp: new Date().toISOString() });
|
success(res, { stats, timestamp: new Date().toISOString() });
|
||||||
}, 'stats-containers'));
|
}, 'stats-containers'));
|
||||||
|
|
||||||
// Get single container stats
|
// Get single container stats
|
||||||
router.get('/stats/container/:id', ctx.asyncHandler(async (req, res) => {
|
router.get('/stats/container/:id', asyncHandler(async (req, res) => {
|
||||||
const container = ctx.docker.client.getContainer(req.params.id);
|
const container = docker.client.getContainer(req.params.id);
|
||||||
const containerStats = await container.stats({ stream: false });
|
const containerStats = await container.stats({ stream: false });
|
||||||
const info = await container.inspect();
|
const info = await container.inspect();
|
||||||
|
|
||||||
@@ -143,8 +152,7 @@ module.exports = function(ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
success(res, {
|
||||||
success: true,
|
|
||||||
stats: {
|
stats: {
|
||||||
name: info.Name.replace(/^\//, ''),
|
name: info.Name.replace(/^\//, ''),
|
||||||
image: info.Config.Image,
|
image: info.Config.Image,
|
||||||
|
|||||||
@@ -1225,7 +1225,11 @@ apiRouter.use(healthRoutes({
|
|||||||
logError: ctx.logError,
|
logError: ctx.logError,
|
||||||
healthChecker: ctx.healthChecker
|
healthChecker: ctx.healthChecker
|
||||||
}));
|
}));
|
||||||
apiRouter.use(monitoringRoutes(ctx));
|
apiRouter.use(monitoringRoutes({
|
||||||
|
resourceMonitor: ctx.resourceMonitor,
|
||||||
|
docker: ctx.docker,
|
||||||
|
asyncHandler: ctx.asyncHandler
|
||||||
|
}));
|
||||||
apiRouter.use(updatesRoutes(ctx));
|
apiRouter.use(updatesRoutes(ctx));
|
||||||
apiRouter.use('/tailscale', tailscaleRoutes(ctx));
|
apiRouter.use('/tailscale', tailscaleRoutes(ctx));
|
||||||
apiRouter.use(sitesRoutes(ctx));
|
apiRouter.use(sitesRoutes(ctx));
|
||||||
|
|||||||
Reference in New Issue
Block a user