graphs: send service graphs
This commit is contained in:
+18
-12
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
exports = module.exports = {
|
exports = module.exports = {
|
||||||
getSystem,
|
getSystem,
|
||||||
getApp
|
getContainerStats
|
||||||
};
|
};
|
||||||
|
|
||||||
const apps = require('./apps.js'),
|
const apps = require('./apps.js'),
|
||||||
@@ -10,6 +10,7 @@ const apps = require('./apps.js'),
|
|||||||
BoxError = require('./boxerror.js'),
|
BoxError = require('./boxerror.js'),
|
||||||
docker = require('./docker.js'),
|
docker = require('./docker.js'),
|
||||||
safe = require('safetydance'),
|
safe = require('safetydance'),
|
||||||
|
services = require('./services.js'),
|
||||||
superagent = require('superagent');
|
superagent = require('superagent');
|
||||||
|
|
||||||
// for testing locally: curl 'http://${graphite-ip}:8000/graphite-web/render?format=json&from=-1min&target=absolute(collectd.localhost.du-docker.capacity-usage)'
|
// for testing locally: curl 'http://${graphite-ip}:8000/graphite-web/render?format=json&from=-1min&target=absolute(collectd.localhost.du-docker.capacity-usage)'
|
||||||
@@ -25,8 +26,8 @@ async function getGraphiteUrl() {
|
|||||||
return `http://${ip}:8000/graphite-web/render`;
|
return `http://${ip}:8000/graphite-web/render`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getApp(app, fromMinutes, noNullPoints) {
|
async function getContainerStats(name, fromMinutes, noNullPoints) {
|
||||||
assert.strictEqual(typeof app, 'object');
|
assert.strictEqual(typeof name, 'string');
|
||||||
assert.strictEqual(typeof fromMinutes, 'number');
|
assert.strictEqual(typeof fromMinutes, 'number');
|
||||||
assert.strictEqual(typeof noNullPoints, 'boolean');
|
assert.strictEqual(typeof noNullPoints, 'boolean');
|
||||||
|
|
||||||
@@ -34,13 +35,13 @@ async function getApp(app, fromMinutes, noNullPoints) {
|
|||||||
const graphiteUrl = await getGraphiteUrl();
|
const graphiteUrl = await getGraphiteUrl();
|
||||||
|
|
||||||
const targets = [
|
const targets = [
|
||||||
`summarize(collectd.localhost.docker-stats-${app.id}.gauge-cpu-perc, "${timeBucketSize}min", "avg")`,
|
`summarize(collectd.localhost.docker-stats-${name}.gauge-cpu-perc, "${timeBucketSize}min", "avg")`,
|
||||||
`summarize(collectd.localhost.docker-stats-${app.id}.gauge-mem-used, "${timeBucketSize}min", "avg")`,
|
`summarize(collectd.localhost.docker-stats-${name}.gauge-mem-used, "${timeBucketSize}min", "avg")`,
|
||||||
// `summarize(collectd.localhost.docker-stats-${app.id}.gauge-mem-max, "${timeBucketSize}min", "avg")`,
|
// `summarize(collectd.localhost.docker-stats-${name}.gauge-mem-max, "${timeBucketSize}min", "avg")`,
|
||||||
`summarize(collectd.localhost.docker-stats-${app.id}.counter-blockio-read, "${timeBucketSize}min", "sum")`,
|
`summarize(collectd.localhost.docker-stats-${name}.counter-blockio-read, "${timeBucketSize}min", "sum")`,
|
||||||
`summarize(collectd.localhost.docker-stats-${app.id}.counter-blockio-write, "${timeBucketSize}min", "sum")`,
|
`summarize(collectd.localhost.docker-stats-${name}.counter-blockio-write, "${timeBucketSize}min", "sum")`,
|
||||||
`summarize(collectd.localhost.docker-stats-${app.id}.counter-network-read, "${timeBucketSize}min", "sum")`,
|
`summarize(collectd.localhost.docker-stats-${name}.counter-network-read, "${timeBucketSize}min", "sum")`,
|
||||||
`summarize(collectd.localhost.docker-stats-${app.id}.counter-network-write, "${timeBucketSize}min", "sum")`,
|
`summarize(collectd.localhost.docker-stats-${name}.counter-network-write, "${timeBucketSize}min", "sum")`,
|
||||||
];
|
];
|
||||||
|
|
||||||
const results = [];
|
const results = [];
|
||||||
@@ -94,8 +95,13 @@ async function getSystem(fromMinutes, noNullPoints) {
|
|||||||
|
|
||||||
const appResponses = {};
|
const appResponses = {};
|
||||||
for (const app of await apps.list()) {
|
for (const app of await apps.list()) {
|
||||||
appResponses[app.id] = await getApp(app, fromMinutes, noNullPoints);
|
appResponses[app.id] = await getContainerStats(app.id, fromMinutes, noNullPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { cpu: memCpuResponse.body[0], memory: memCpuResponse.body[1], apps: appResponses };
|
const serviceResponses = {};
|
||||||
|
for (const serviceId of await services.listServices()) {
|
||||||
|
serviceResponses[serviceId] = await getContainerStats(serviceId, fromMinutes, noNullPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { cpu: memCpuResponse.body[0], memory: memCpuResponse.body[1], apps: appResponses, services: serviceResponses };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ exports = module.exports = {
|
|||||||
updateBackup,
|
updateBackup,
|
||||||
|
|
||||||
getLimits,
|
getLimits,
|
||||||
|
getGraphs,
|
||||||
|
|
||||||
load
|
load
|
||||||
};
|
};
|
||||||
@@ -68,6 +69,7 @@ const apps = require('../apps.js'),
|
|||||||
BoxError = require('../boxerror.js'),
|
BoxError = require('../boxerror.js'),
|
||||||
constants = require('../constants.js'),
|
constants = require('../constants.js'),
|
||||||
debug = require('debug')('box:routes/apps'),
|
debug = require('debug')('box:routes/apps'),
|
||||||
|
graphs = require('../graphs.js'),
|
||||||
HttpError = require('connect-lastmile').HttpError,
|
HttpError = require('connect-lastmile').HttpError,
|
||||||
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
||||||
safe = require('safetydance'),
|
safe = require('safetydance'),
|
||||||
@@ -959,3 +961,16 @@ async function getLimits(req, res, next) {
|
|||||||
|
|
||||||
next(new HttpSuccess(200, { limits }));
|
next(new HttpSuccess(200, { limits }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getGraphs(req, res, next) {
|
||||||
|
assert.strictEqual(typeof req.app, 'object');
|
||||||
|
|
||||||
|
if (!req.query.fromMinutes || !parseInt(req.query.fromMinutes)) return next(new HttpError(400, 'fromMinutes must be a number'));
|
||||||
|
|
||||||
|
const fromMinutes = parseInt(req.query.fromMinutes);
|
||||||
|
const noNullPoints = !!req.query.noNullPoints;
|
||||||
|
const [error, result] = await safe(graphs.getContainerStats(req.app.id, fromMinutes, noNullPoints));
|
||||||
|
if (error) return next(new HttpError(500, error));
|
||||||
|
|
||||||
|
next(new HttpSuccess(200, result));
|
||||||
|
}
|
||||||
|
|||||||
+14
-1
@@ -25,7 +25,8 @@ exports = module.exports = {
|
|||||||
getServerIpv6,
|
getServerIpv6,
|
||||||
getLanguages,
|
getLanguages,
|
||||||
syncExternalLdap,
|
syncExternalLdap,
|
||||||
syncDnsRecords
|
syncDnsRecords,
|
||||||
|
getSystemGraphs
|
||||||
};
|
};
|
||||||
|
|
||||||
const assert = require('assert'),
|
const assert = require('assert'),
|
||||||
@@ -36,6 +37,7 @@ const assert = require('assert'),
|
|||||||
debug = require('debug')('box:routes/cloudron'),
|
debug = require('debug')('box:routes/cloudron'),
|
||||||
eventlog = require('../eventlog.js'),
|
eventlog = require('../eventlog.js'),
|
||||||
externalLdap = require('../externalldap.js'),
|
externalLdap = require('../externalldap.js'),
|
||||||
|
graphs = require('../graphs.js'),
|
||||||
HttpError = require('connect-lastmile').HttpError,
|
HttpError = require('connect-lastmile').HttpError,
|
||||||
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
||||||
safe = require('safetydance'),
|
safe = require('safetydance'),
|
||||||
@@ -343,3 +345,14 @@ async function syncDnsRecords(req, res, next) {
|
|||||||
|
|
||||||
next(new HttpSuccess(201, { taskId }));
|
next(new HttpSuccess(201, { taskId }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getSystemGraphs(req, res, next) {
|
||||||
|
if (!req.query.fromMinutes || !parseInt(req.query.fromMinutes)) return next(new HttpError(400, 'fromMinutes must be a number'));
|
||||||
|
|
||||||
|
const fromMinutes = parseInt(req.query.fromMinutes);
|
||||||
|
const noNullPoints = !!req.query.noNullPoints;
|
||||||
|
const [error, result] = await safe(graphs.getSystem(fromMinutes, noNullPoints));
|
||||||
|
if (error) return next(new HttpError(500, error));
|
||||||
|
|
||||||
|
next(new HttpSuccess(200, result));
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
exports = module.exports = {
|
|
||||||
getSystemGraphs,
|
|
||||||
getAppGraphs
|
|
||||||
};
|
|
||||||
|
|
||||||
const assert = require('assert'),
|
|
||||||
graphs = require('../graphs.js'),
|
|
||||||
HttpError = require('connect-lastmile').HttpError,
|
|
||||||
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
|
||||||
safe = require('safetydance');
|
|
||||||
|
|
||||||
async function getSystemGraphs(req, res, next) {
|
|
||||||
if (!req.query.fromMinutes || !parseInt(req.query.fromMinutes)) return next(new HttpError(400, 'fromMinutes must be a number'));
|
|
||||||
|
|
||||||
const fromMinutes = parseInt(req.query.fromMinutes);
|
|
||||||
const noNullPoints = !!req.query.noNullPoints;
|
|
||||||
const [error, result] = await safe(graphs.getSystem(fromMinutes, noNullPoints));
|
|
||||||
if (error) return next(new HttpError(500, error));
|
|
||||||
|
|
||||||
next(new HttpSuccess(200, result));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getAppGraphs(req, res, next) {
|
|
||||||
assert.strictEqual(typeof req.app, 'object');
|
|
||||||
|
|
||||||
if (!req.query.fromMinutes || !parseInt(req.query.fromMinutes)) return next(new HttpError(400, 'fromMinutes must be a number'));
|
|
||||||
|
|
||||||
const fromMinutes = parseInt(req.query.fromMinutes);
|
|
||||||
const noNullPoints = !!req.query.noNullPoints;
|
|
||||||
const [error, result] = await safe(graphs.getApp(req.app, fromMinutes, noNullPoints));
|
|
||||||
if (error) return next(new HttpError(500, error));
|
|
||||||
|
|
||||||
next(new HttpSuccess(200, result));
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,6 @@ exports = module.exports = {
|
|||||||
domains: require('./domains.js'),
|
domains: require('./domains.js'),
|
||||||
eventlog: require('./eventlog.js'),
|
eventlog: require('./eventlog.js'),
|
||||||
filemanager: require('./filemanager.js'),
|
filemanager: require('./filemanager.js'),
|
||||||
graphs: require('./graphs.js'),
|
|
||||||
groups: require('./groups.js'),
|
groups: require('./groups.js'),
|
||||||
mail: require('./mail.js'),
|
mail: require('./mail.js'),
|
||||||
mailserver: require('./mailserver.js'),
|
mailserver: require('./mailserver.js'),
|
||||||
|
|||||||
+16
-1
@@ -7,12 +7,14 @@ exports = module.exports = {
|
|||||||
getLogs,
|
getLogs,
|
||||||
getLogStream,
|
getLogStream,
|
||||||
restart,
|
restart,
|
||||||
rebuild
|
rebuild,
|
||||||
|
getGraphs
|
||||||
};
|
};
|
||||||
|
|
||||||
const assert = require('assert'),
|
const assert = require('assert'),
|
||||||
AuditSource = require('../auditsource.js'),
|
AuditSource = require('../auditsource.js'),
|
||||||
BoxError = require('../boxerror.js'),
|
BoxError = require('../boxerror.js'),
|
||||||
|
graphs = require('../graphs.js'),
|
||||||
HttpError = require('connect-lastmile').HttpError,
|
HttpError = require('connect-lastmile').HttpError,
|
||||||
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
||||||
safe = require('safetydance'),
|
safe = require('safetydance'),
|
||||||
@@ -131,3 +133,16 @@ async function rebuild(req, res, next) {
|
|||||||
|
|
||||||
next(new HttpSuccess(202, {}));
|
next(new HttpSuccess(202, {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getGraphs(req, res, next) {
|
||||||
|
assert.strictEqual(typeof req.params.service, 'string');
|
||||||
|
|
||||||
|
if (!req.query.fromMinutes || !parseInt(req.query.fromMinutes)) return next(new HttpError(400, 'fromMinutes must be a number'));
|
||||||
|
|
||||||
|
const fromMinutes = parseInt(req.query.fromMinutes);
|
||||||
|
const noNullPoints = !!req.query.noNullPoints;
|
||||||
|
const [error, result] = await safe(graphs.getContainerStats(req.params.service, fromMinutes, noNullPoints));
|
||||||
|
if (error) return next(new HttpError(500, error));
|
||||||
|
|
||||||
|
next(new HttpSuccess(200, result));
|
||||||
|
}
|
||||||
|
|||||||
+3
-2
@@ -116,7 +116,7 @@ function initializeExpressSync() {
|
|||||||
router.post('/api/v1/cloudron/check_for_updates', json, token, authorizeAdmin, routes.cloudron.checkForUpdates);
|
router.post('/api/v1/cloudron/check_for_updates', json, token, authorizeAdmin, routes.cloudron.checkForUpdates);
|
||||||
router.get ('/api/v1/cloudron/reboot', token, authorizeAdmin, routes.cloudron.isRebootRequired);
|
router.get ('/api/v1/cloudron/reboot', token, authorizeAdmin, routes.cloudron.isRebootRequired);
|
||||||
router.post('/api/v1/cloudron/reboot', json, token, authorizeAdmin, routes.cloudron.reboot);
|
router.post('/api/v1/cloudron/reboot', json, token, authorizeAdmin, routes.cloudron.reboot);
|
||||||
router.get ('/api/v1/cloudron/graphs', token, authorizeAdmin, routes.graphs.getSystemGraphs);
|
router.get ('/api/v1/cloudron/graphs', token, authorizeAdmin, routes.cloudron.getSystemGraphs);
|
||||||
router.get ('/api/v1/cloudron/disks', token, authorizeAdmin, routes.cloudron.getDisks);
|
router.get ('/api/v1/cloudron/disks', token, authorizeAdmin, routes.cloudron.getDisks);
|
||||||
router.get ('/api/v1/cloudron/disk_usage', token, authorizeAdmin, routes.cloudron.getDiskUsage);
|
router.get ('/api/v1/cloudron/disk_usage', token, authorizeAdmin, routes.cloudron.getDiskUsage);
|
||||||
router.post('/api/v1/cloudron/disk_usage', token, authorizeAdmin, routes.cloudron.updateDiskUsage);
|
router.post('/api/v1/cloudron/disk_usage', token, authorizeAdmin, routes.cloudron.updateDiskUsage);
|
||||||
@@ -250,7 +250,7 @@ function initializeExpressSync() {
|
|||||||
router.get ('/api/v1/apps/:id/eventlog', token, routes.apps.load, authorizeOperator, routes.apps.listEventlog);
|
router.get ('/api/v1/apps/:id/eventlog', token, routes.apps.load, authorizeOperator, routes.apps.listEventlog);
|
||||||
router.get ('/api/v1/apps/:id/limits', token, routes.apps.load, authorizeOperator, routes.apps.getLimits);
|
router.get ('/api/v1/apps/:id/limits', token, routes.apps.load, authorizeOperator, routes.apps.getLimits);
|
||||||
router.get ('/api/v1/apps/:id/task', token, routes.apps.load, authorizeOperator, routes.apps.getTask);
|
router.get ('/api/v1/apps/:id/task', token, routes.apps.load, authorizeOperator, routes.apps.getTask);
|
||||||
router.get ('/api/v1/apps/:id/graphs', token, routes.apps.load, authorizeOperator, routes.graphs.getAppGraphs);
|
router.get ('/api/v1/apps/:id/graphs', token, routes.apps.load, authorizeOperator, routes.apps.getGraphs);
|
||||||
router.post('/api/v1/apps/:id/clone', json, token, routes.apps.load, authorizeAdmin, routes.apps.clone);
|
router.post('/api/v1/apps/:id/clone', json, token, routes.apps.load, authorizeAdmin, routes.apps.clone);
|
||||||
router.get ('/api/v1/apps/:id/download', token, routes.apps.load, authorizeOperator, routes.apps.downloadFile);
|
router.get ('/api/v1/apps/:id/download', token, routes.apps.load, authorizeOperator, routes.apps.downloadFile);
|
||||||
router.post('/api/v1/apps/:id/upload', json, token, multipart, routes.apps.load, authorizeOperator, routes.apps.uploadFile);
|
router.post('/api/v1/apps/:id/upload', json, token, multipart, routes.apps.load, authorizeOperator, routes.apps.uploadFile);
|
||||||
@@ -356,6 +356,7 @@ function initializeExpressSync() {
|
|||||||
router.get ('/api/v1/services', token, authorizeAdmin, routes.services.list);
|
router.get ('/api/v1/services', token, authorizeAdmin, routes.services.list);
|
||||||
router.get ('/api/v1/services/:service', token, authorizeAdmin, routes.services.get);
|
router.get ('/api/v1/services/:service', token, authorizeAdmin, routes.services.get);
|
||||||
router.post('/api/v1/services/:service', json, token, authorizeAdmin, routes.services.configure);
|
router.post('/api/v1/services/:service', json, token, authorizeAdmin, routes.services.configure);
|
||||||
|
router.get ('/api/v1/services/:service/graphs', token, authorizeAdmin, routes.services.getGraphs);
|
||||||
router.get ('/api/v1/services/:service/logs', token, authorizeAdmin, routes.services.getLogs);
|
router.get ('/api/v1/services/:service/logs', token, authorizeAdmin, routes.services.getLogs);
|
||||||
router.get ('/api/v1/services/:service/logstream', token, authorizeAdmin, routes.services.getLogStream);
|
router.get ('/api/v1/services/:service/logstream', token, authorizeAdmin, routes.services.getLogStream);
|
||||||
router.post('/api/v1/services/:service/restart', json, token, authorizeAdmin, routes.services.restart);
|
router.post('/api/v1/services/:service/restart', json, token, authorizeAdmin, routes.services.restart);
|
||||||
|
|||||||
+1
-1
@@ -310,7 +310,7 @@ async function containerStatus(containerName, tokenEnvName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function listServices() {
|
async function listServices() {
|
||||||
let serviceIds = Object.keys(SERVICES);
|
const serviceIds = Object.keys(SERVICES);
|
||||||
|
|
||||||
const result = await apps.list();
|
const result = await apps.list();
|
||||||
for (let app of result) {
|
for (let app of result) {
|
||||||
|
|||||||
Reference in New Issue
Block a user