graphs: send service graphs
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
exports = module.exports = {
|
||||
getSystem,
|
||||
getApp
|
||||
getContainerStats
|
||||
};
|
||||
|
||||
const apps = require('./apps.js'),
|
||||
@@ -10,6 +10,7 @@ const apps = require('./apps.js'),
|
||||
BoxError = require('./boxerror.js'),
|
||||
docker = require('./docker.js'),
|
||||
safe = require('safetydance'),
|
||||
services = require('./services.js'),
|
||||
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)'
|
||||
@@ -25,8 +26,8 @@ async function getGraphiteUrl() {
|
||||
return `http://${ip}:8000/graphite-web/render`;
|
||||
}
|
||||
|
||||
async function getApp(app, fromMinutes, noNullPoints) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
async function getContainerStats(name, fromMinutes, noNullPoints) {
|
||||
assert.strictEqual(typeof name, 'string');
|
||||
assert.strictEqual(typeof fromMinutes, 'number');
|
||||
assert.strictEqual(typeof noNullPoints, 'boolean');
|
||||
|
||||
@@ -34,13 +35,13 @@ async function getApp(app, fromMinutes, noNullPoints) {
|
||||
const graphiteUrl = await getGraphiteUrl();
|
||||
|
||||
const targets = [
|
||||
`summarize(collectd.localhost.docker-stats-${app.id}.gauge-cpu-perc, "${timeBucketSize}min", "avg")`,
|
||||
`summarize(collectd.localhost.docker-stats-${app.id}.gauge-mem-used, "${timeBucketSize}min", "avg")`,
|
||||
// `summarize(collectd.localhost.docker-stats-${app.id}.gauge-mem-max, "${timeBucketSize}min", "avg")`,
|
||||
`summarize(collectd.localhost.docker-stats-${app.id}.counter-blockio-read, "${timeBucketSize}min", "sum")`,
|
||||
`summarize(collectd.localhost.docker-stats-${app.id}.counter-blockio-write, "${timeBucketSize}min", "sum")`,
|
||||
`summarize(collectd.localhost.docker-stats-${app.id}.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}.gauge-cpu-perc, "${timeBucketSize}min", "avg")`,
|
||||
`summarize(collectd.localhost.docker-stats-${name}.gauge-mem-used, "${timeBucketSize}min", "avg")`,
|
||||
// `summarize(collectd.localhost.docker-stats-${name}.gauge-mem-max, "${timeBucketSize}min", "avg")`,
|
||||
`summarize(collectd.localhost.docker-stats-${name}.counter-blockio-read, "${timeBucketSize}min", "sum")`,
|
||||
`summarize(collectd.localhost.docker-stats-${name}.counter-blockio-write, "${timeBucketSize}min", "sum")`,
|
||||
`summarize(collectd.localhost.docker-stats-${name}.counter-network-read, "${timeBucketSize}min", "sum")`,
|
||||
`summarize(collectd.localhost.docker-stats-${name}.counter-network-write, "${timeBucketSize}min", "sum")`,
|
||||
];
|
||||
|
||||
const results = [];
|
||||
@@ -94,8 +95,13 @@ async function getSystem(fromMinutes, noNullPoints) {
|
||||
|
||||
const appResponses = {};
|
||||
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,
|
||||
|
||||
getLimits,
|
||||
getGraphs,
|
||||
|
||||
load
|
||||
};
|
||||
@@ -68,6 +69,7 @@ const apps = require('../apps.js'),
|
||||
BoxError = require('../boxerror.js'),
|
||||
constants = require('../constants.js'),
|
||||
debug = require('debug')('box:routes/apps'),
|
||||
graphs = require('../graphs.js'),
|
||||
HttpError = require('connect-lastmile').HttpError,
|
||||
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
||||
safe = require('safetydance'),
|
||||
@@ -959,3 +961,16 @@ async function getLimits(req, res, next) {
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@ exports = module.exports = {
|
||||
getServerIpv6,
|
||||
getLanguages,
|
||||
syncExternalLdap,
|
||||
syncDnsRecords
|
||||
syncDnsRecords,
|
||||
getSystemGraphs
|
||||
};
|
||||
|
||||
const assert = require('assert'),
|
||||
@@ -36,6 +37,7 @@ const assert = require('assert'),
|
||||
debug = require('debug')('box:routes/cloudron'),
|
||||
eventlog = require('../eventlog.js'),
|
||||
externalLdap = require('../externalldap.js'),
|
||||
graphs = require('../graphs.js'),
|
||||
HttpError = require('connect-lastmile').HttpError,
|
||||
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
||||
safe = require('safetydance'),
|
||||
@@ -343,3 +345,14 @@ async function syncDnsRecords(req, res, next) {
|
||||
|
||||
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'),
|
||||
eventlog: require('./eventlog.js'),
|
||||
filemanager: require('./filemanager.js'),
|
||||
graphs: require('./graphs.js'),
|
||||
groups: require('./groups.js'),
|
||||
mail: require('./mail.js'),
|
||||
mailserver: require('./mailserver.js'),
|
||||
|
||||
@@ -7,12 +7,14 @@ exports = module.exports = {
|
||||
getLogs,
|
||||
getLogStream,
|
||||
restart,
|
||||
rebuild
|
||||
rebuild,
|
||||
getGraphs
|
||||
};
|
||||
|
||||
const assert = require('assert'),
|
||||
AuditSource = require('../auditsource.js'),
|
||||
BoxError = require('../boxerror.js'),
|
||||
graphs = require('../graphs.js'),
|
||||
HttpError = require('connect-lastmile').HttpError,
|
||||
HttpSuccess = require('connect-lastmile').HttpSuccess,
|
||||
safe = require('safetydance'),
|
||||
@@ -131,3 +133,16 @@ async function rebuild(req, res, next) {
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ function initializeExpressSync() {
|
||||
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.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/disk_usage', token, authorizeAdmin, routes.cloudron.getDiskUsage);
|
||||
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/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/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.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);
|
||||
@@ -356,6 +356,7 @@ function initializeExpressSync() {
|
||||
router.get ('/api/v1/services', token, authorizeAdmin, routes.services.list);
|
||||
router.get ('/api/v1/services/:service', token, authorizeAdmin, routes.services.get);
|
||||
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/logstream', token, authorizeAdmin, routes.services.getLogStream);
|
||||
router.post('/api/v1/services/:service/restart', json, token, authorizeAdmin, routes.services.restart);
|
||||
|
||||
@@ -310,7 +310,7 @@ async function containerStatus(containerName, tokenEnvName) {
|
||||
}
|
||||
|
||||
async function listServices() {
|
||||
let serviceIds = Object.keys(SERVICES);
|
||||
const serviceIds = Object.keys(SERVICES);
|
||||
|
||||
const result = await apps.list();
|
||||
for (let app of result) {
|
||||
|
||||
Reference in New Issue
Block a user