2022-09-14 13:03:14 +02:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
exports = module.exports = {
|
|
|
|
|
getByAppId
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const assert = require('assert'),
|
|
|
|
|
BoxError = require('./boxerror.js'),
|
2022-08-08 13:06:14 +02:00
|
|
|
fs = require('fs'),
|
2022-09-14 13:03:14 +02:00
|
|
|
safe = require('safetydance'),
|
2022-08-08 13:06:14 +02:00
|
|
|
superagent = require('superagent');
|
2022-09-14 13:03:14 +02:00
|
|
|
|
|
|
|
|
const GRAPHITE_RENDER_URL = 'http://127.0.0.1:8417/graphite-web/render';
|
|
|
|
|
|
2022-08-08 13:06:14 +02:00
|
|
|
// https://rootlesscontaine.rs/getting-started/common/cgroup2/#checking-whether-cgroup-v2-is-already-enabled
|
|
|
|
|
const CGROUP_VERSION = fs.existsSync('/sys/fs/cgroup/cgroup.controllers') ? '2' : '1';
|
|
|
|
|
|
2022-09-14 13:03:14 +02:00
|
|
|
async function getByAppId(appId, fromMinutes, noNullPoints) {
|
|
|
|
|
assert.strictEqual(typeof appId, 'string');
|
|
|
|
|
assert.strictEqual(typeof fromMinutes, 'number');
|
|
|
|
|
assert.strictEqual(typeof noNullPoints, 'boolean');
|
|
|
|
|
|
|
|
|
|
const timeBucketSize = fromMinutes > (24 * 60) ? (6*60) : 5;
|
|
|
|
|
|
|
|
|
|
const memoryQuery = {
|
2022-08-08 13:06:14 +02:00
|
|
|
target: null, // filled below
|
2022-09-14 13:03:14 +02:00
|
|
|
format: 'json',
|
|
|
|
|
from: `-${fromMinutes}min`,
|
|
|
|
|
until: 'now'
|
|
|
|
|
};
|
2022-08-08 13:06:14 +02:00
|
|
|
if (CGROUP_VERSION === '1') {
|
|
|
|
|
memoryQuery.target = `summarize(collectd.localhost.table-${appId}-memory.gauge-memsw_usage_in_bytes, "${timeBucketSize}min", "avg")`;
|
|
|
|
|
} else {
|
|
|
|
|
memoryQuery.target = `summarize(sum(collectd.localhost.table-${appId}-memory.gauge-memory_current, collectd.localhost.table-${appId}-memory.gauge-memory_swap_current), "${timeBucketSize}min", "avg")`;
|
|
|
|
|
}
|
2022-09-14 13:03:14 +02:00
|
|
|
if (noNullPoints) memoryQuery.noNullPoints = true;
|
|
|
|
|
|
|
|
|
|
const [memoryError, memoryResponse] = await safe(superagent.get(GRAPHITE_RENDER_URL)
|
|
|
|
|
.query(memoryQuery)
|
|
|
|
|
.timeout(30 * 1000)
|
|
|
|
|
.ok(() => true));
|
|
|
|
|
|
|
|
|
|
if (memoryError) throw new BoxError(BoxError.NETWORK_ERROR, memoryError.message);
|
|
|
|
|
if (memoryResponse.status !== 200) throw new BoxError(BoxError.EXTERNAL_ERROR, `Unknown error: ${memoryError.message}`);
|
|
|
|
|
|
|
|
|
|
const diskQuery = {
|
|
|
|
|
target: `summarize(collectd.localhost.du-${appId}.capacity-usage, "${timeBucketSize}min", "avg")`,
|
|
|
|
|
format: 'json',
|
|
|
|
|
from: `-${fromMinutes}min`,
|
|
|
|
|
until: 'now'
|
|
|
|
|
};
|
|
|
|
|
if (noNullPoints) diskQuery.noNullPoints = true;
|
|
|
|
|
|
|
|
|
|
const [diskError, diskResponse] = await safe(superagent.get(GRAPHITE_RENDER_URL)
|
|
|
|
|
.query(diskQuery)
|
|
|
|
|
.timeout(30 * 1000)
|
|
|
|
|
.ok(() => true));
|
|
|
|
|
|
|
|
|
|
if (diskError) throw new BoxError(BoxError.NETWORK_ERROR, diskError.message);
|
|
|
|
|
if (diskResponse.status !== 200) throw new BoxError(BoxError.EXTERNAL_ERROR, `Unknown error: ${diskError.message}`);
|
|
|
|
|
|
|
|
|
|
return { memory: memoryResponse.body[0], disk: diskResponse.body[0] };
|
|
|
|
|
}
|