156 lines
3.1 KiB
JavaScript
156 lines
3.1 KiB
JavaScript
|
const forceArray = require('force-array');
|
||
|
const get = require('lodash.get');
|
||
|
const date = require('date.js');
|
||
|
const timestamp = require('internet-timestamp');
|
||
|
const got = require('got');
|
||
|
const url = require('url');
|
||
|
const qs = require('qs');
|
||
|
|
||
|
const transform = (res) => {
|
||
|
return forceArray(res).reduce((sum, r) => {
|
||
|
const {
|
||
|
data
|
||
|
} = JSON.parse(r.body);
|
||
|
|
||
|
const result = !Array.isArray(data)
|
||
|
? data.result
|
||
|
: data;
|
||
|
|
||
|
return result.reduce((sum, inst) => {
|
||
|
const metric = !inst.job
|
||
|
? inst.metric
|
||
|
: inst;
|
||
|
|
||
|
const {
|
||
|
values = [],
|
||
|
value = []
|
||
|
} = inst;
|
||
|
|
||
|
const {
|
||
|
instance,
|
||
|
job,
|
||
|
__name__
|
||
|
} = metric;
|
||
|
|
||
|
const oldJob = get(sum, job, {});
|
||
|
const oldQuery = get(sum, `${job}.${__name__}`, {});
|
||
|
const _value = values.length ? values : value
|
||
|
|
||
|
return Object.assign(sum, {
|
||
|
[job]: Object.assign(oldJob, {
|
||
|
[instance]: Object.assign(oldQuery, {
|
||
|
[__name__]: _value
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
}, sum);
|
||
|
}, {});
|
||
|
};
|
||
|
|
||
|
const range = module.exports.range = ({
|
||
|
query = [],
|
||
|
ago = '1h ago',
|
||
|
step = '1s',
|
||
|
hostname = 'localhost'
|
||
|
}) => {
|
||
|
const end = timestamp(new Date());
|
||
|
const start = timestamp(date(ago));
|
||
|
|
||
|
return Promise.all(query.map((query) => {
|
||
|
return got(url.format({
|
||
|
protocol: 'http:',
|
||
|
slashes: true,
|
||
|
port: '9090',
|
||
|
hostname: hostname,
|
||
|
pathname: '/api/v1/query_range',
|
||
|
query: {
|
||
|
query,
|
||
|
end,
|
||
|
step,
|
||
|
start
|
||
|
}
|
||
|
}));
|
||
|
}))
|
||
|
.then(transform);
|
||
|
};
|
||
|
|
||
|
const query = module.exports.query = ({
|
||
|
hostname = 'localhost',
|
||
|
query = []
|
||
|
}) => {
|
||
|
return Promise.all(query.map((query) => {
|
||
|
return got(url.format({
|
||
|
protocol: 'http:',
|
||
|
slashes: true,
|
||
|
port: '9090',
|
||
|
hostname: hostname,
|
||
|
pathname: '/api/v1/query',
|
||
|
query: {
|
||
|
query: query
|
||
|
}
|
||
|
}));
|
||
|
}))
|
||
|
.then(transform);
|
||
|
};
|
||
|
|
||
|
const tree = module.exports.tree = ({
|
||
|
hostname = 'localhost',
|
||
|
query = []
|
||
|
}) => {
|
||
|
return got(url.format({
|
||
|
protocol: 'http:',
|
||
|
slashes: true,
|
||
|
port: '9090',
|
||
|
hostname: hostname,
|
||
|
pathname: '/api/v1/series',
|
||
|
search: qs.stringify({
|
||
|
match: query
|
||
|
}, {
|
||
|
arrayFormat: 'brackets'
|
||
|
})
|
||
|
}))
|
||
|
.then(transform);
|
||
|
};
|
||
|
|
||
|
if (!module.parent) {
|
||
|
process.on('unhandledRejection', (reason) => {
|
||
|
throw reason
|
||
|
});
|
||
|
|
||
|
const usage = () => {
|
||
|
console.error(`
|
||
|
Usage: node metrics.js --type={type} --query={metric} --step={step} --ago={ago}
|
||
|
node metrics.js --type=range --query=node_memory_heap_used_bytes --query=node_memory_heap_total_bytes
|
||
|
`.trim());
|
||
|
|
||
|
return process.exit(1);
|
||
|
}
|
||
|
|
||
|
const argv = require('minimist')(process.argv.slice(2));
|
||
|
|
||
|
if (!argv.query || !argv.type) {
|
||
|
return usage();
|
||
|
}
|
||
|
|
||
|
const handlers = {
|
||
|
tree,
|
||
|
range,
|
||
|
query
|
||
|
};
|
||
|
|
||
|
if (!handlers[argv.type]) {
|
||
|
return usage();
|
||
|
}
|
||
|
|
||
|
const conf = {
|
||
|
query: argv.query,
|
||
|
ago: argv.ago,
|
||
|
step: argv.step,
|
||
|
hostname: argv.hostname
|
||
|
};
|
||
|
|
||
|
handlers[argv.type](conf).then((res) => {
|
||
|
console.log(JSON.stringify(res, null, 2));
|
||
|
});
|
||
|
}
|