1
0
mirror of https://github.com/yldio/copilot.git synced 2024-11-28 14:10:04 +02:00

perf(portal-api): reduce triton calls (slow)

This commit is contained in:
Sérgio Ramos 2017-09-01 00:16:25 +01:00
parent 9be6a27012
commit a5a87a686e
3 changed files with 54 additions and 122 deletions

View File

@ -99,7 +99,17 @@ const internals = {
}, },
isNotFound: (err) => { isNotFound: (err) => {
return err && (err['typeof'] === Boom.notFound); return err && (err['typeof'] === Boom.notFound);
} },
metricNames: [
'mem_agg_usage',
'cpu_sys_usage',
'net_agg_bytes_in'
],
metricNameEnum: [
'AVG_MEM_BYTES',
'AVG_LOAD_PERCENT',
'AGG_NETWORK_BYTES'
]
}; };
@ -2370,7 +2380,15 @@ class Data extends EventEmitter {
const { tags = [] } = containers[0]; const { tags = [] } = containers[0];
const services = containers.reduce((acc, { tags = [], id = '', state = '', name = '' }) => { const services = containers.reduce((acc, machine) => {
const {
tags = [],
id = '',
state = '',
name = '',
primaryIp = ''
} = machine;
const hash = tags[HASH]; const hash = tags[HASH];
const slug = ParamCase(tags[SERVICE]); const slug = ParamCase(tags[SERVICE]);
const attr = `${hash}-${slug}`; const attr = `${hash}-${slug}`;
@ -2378,7 +2396,8 @@ class Data extends EventEmitter {
const instance = { const instance = {
name: name, name: name,
machineId: id, machineId: id,
status: state.toUpperCase() status: state.toUpperCase(),
primaryIp: primaryIp
}; };
if (acc[attr]) { if (acc[attr]) {
@ -2481,80 +2500,12 @@ class Data extends EventEmitter {
this.createDeploymentGroup(deploymentGroup, handleNewDeploymentGroup); this.createDeploymentGroup(deploymentGroup, handleNewDeploymentGroup);
} }
// copied from container-pilot-watcher. todo: refactor static formatMetrics (metrics) {
_getNetworks (networkIds = [], cb) { return metrics.map((metric) => {
VAsync.forEachParallel({ const i = internals.metricNames.indexOf(metric.name);
inputs: networkIds,
func: (id, next) => {
this._triton.getNetwork(id, next);
}
}, (err, results) => {
cb(err, ForceArray((results || {}).successes));
});
}
// copied from container-pilot-watcher. todo: refactor
_getPublicIps (machine, cb) {
this._getNetworks(machine.networks, (err, networks) => {
if (err) {
return cb(err);
}
const privateNetworkSubnets = networks
.filter((network) => {
return !network['public'];
})
.map((network) => {
return network.subnet;
})
.filter(Boolean);
const cidr = new CIDRMatcher(privateNetworkSubnets);
const nonPrivateIps = machine.ips.filter((ip) => {
return !cidr.contains(ip);
});
cb(null, nonPrivateIps);
});
}
getMetrics ({ deploymentGroupId, names, instances, start, end }, cb) {
Hoek.assert(deploymentGroupId !== undefined, 'deploymentGroupId is required');
Hoek.assert(names && names.length, 'names are required');
Hoek.assert(instances && instances.length, 'instances are required');
const metricNames = [
'mem_agg_usage',
'cpu_sys_usage',
'net_agg_bytes_in'
];
const metricNameEnum = [
'AVG_MEM_BYTES',
'AVG_LOAD_PERCENT',
'AGG_NETWORK_BYTES'
];
const ctx = {};
const handleMetrics = (err, results) => {
if (err) {
return cb(err);
}
const metrics = results.successes.filter(Boolean).shift();
if (!metrics) {
return cb(null, []);
}
const formattedMetrics = metrics.map((metric) => {
const i = metricNames.indexOf(metric.name);
if (i !== -1) { if (i !== -1) {
metric.name = metricNameEnum[i]; metric.name = internals.metricNameEnum[i];
} }
metric.metrics = metric.metrics.map((entry) => { metric.metrics = metric.metrics.map((entry) => {
@ -2568,47 +2519,40 @@ class Data extends EventEmitter {
end: metric.metrics[metric.metrics.length - 1].time end: metric.metrics[metric.metrics.length - 1].time
}); });
}); });
}
cb(null, formattedMetrics);
getMetrics ({ deploymentGroupId, names, instances, start, end }, cb) {
Hoek.assert(deploymentGroupId !== undefined, 'deploymentGroupId is required');
Hoek.assert(names && names.length, 'names are required');
Hoek.assert(instances && instances.length, 'instances are required');
const ctx = {};
const handleMetrics = (err, metrics) => {
if (err) {
return cb(err);
}
cb(null, Data.formatMetrics(metrics));
}; };
const fetchMetrics = (ip, next) => { const fetchMetrics = (ip, cb) => {
const formattedNames = names.map((name) => { const formattedNames = names.map((name) => {
const i = metricNameEnum.indexOf(name); const i = internals.metricNameEnum.indexOf(name);
return (i === -1) ? name : metricNames[i]; return (i === -1) ? name : internals.metricNames[i];
}); });
const prometheus = new Prometheus({ url: `http://${ip}:9090` }); const prometheus = new Prometheus({ url: `http://${ip}:9090` });
prometheus.getMetrics({ prometheus.getMetrics({
names: formattedNames, names: formattedNames,
instances: ctx.machines.map(({ name }) => { return name; }), instances: ctx.instances.map(({ name }) => {
return name;
}),
start, start,
end end
}, (err, metrics) => { }, cb);
if (err) {
console.error(err);
}
next(null, metrics);
});
};
const handlePrometheusMachine = (err, machine) => {
if (err) {
return cb(err);
}
this._getPublicIps(machine, (err, ips) => {
if (err) {
return cb(err);
}
VAsync.forEachParallel({
inputs: ips,
func: fetchMetrics
}, handleMetrics);
});
}; };
const handlePrometheusInstances = (instances) => { const handlePrometheusInstances = (instances) => {
@ -2616,8 +2560,8 @@ class Data extends EventEmitter {
return cb(null, []); return cb(null, []);
} }
const { machineId } = instances.shift(); const { primaryIp } = instances.shift();
this._triton.getMachine(machineId, handlePrometheusMachine); fetchMetrics(primaryIp, handleMetrics);
}; };
const handlePrometheusServices = (err, services) => { const handlePrometheusServices = (err, services) => {
@ -2639,19 +2583,6 @@ class Data extends EventEmitter {
.catch(cb); .catch(cb);
}; };
const handleMachines = (err, machines) => {
if (err) {
return cb(err);
}
ctx.machines = machines.successes;
this.getServices({
deploymentGroupId,
name: 'prometheus'
}, handlePrometheusServices);
};
this.getInstances({ this.getInstances({
ids: instances ids: instances
}, (err, instances) => { }, (err, instances) => {
@ -2661,12 +2592,10 @@ class Data extends EventEmitter {
ctx.instances = instances; ctx.instances = instances;
VAsync.forEachParallel({ this.getServices({
inputs: instances, deploymentGroupId,
func: ({ machineId }, next) => { name: 'prometheus'
this._triton.getMachine(machineId, next); }, handlePrometheusServices);
}
}, handleMachines);
}); });
} }
} }

View File

@ -170,6 +170,7 @@ exports.fromInstance = function ({ instance, metrics }) {
id: instance.id, id: instance.id,
name: instance.name, name: instance.name,
machineId: instance.machine_id, machineId: instance.machine_id,
primaryIp: instance.primary_ip,
serviceId: instance.service_id, serviceId: instance.service_id,
deploymentGroupId: instance.deployment_group_id, deploymentGroupId: instance.deployment_group_id,
status: instance.status, status: instance.status,
@ -186,6 +187,7 @@ exports.toInstance = function (clientInstance) {
id: clientInstance.id, id: clientInstance.id,
name: clientInstance.name, name: clientInstance.name,
machine_id: clientInstance.machineId, machine_id: clientInstance.machineId,
primary_ip: clientInstance.primaryIp,
deployment_group_id: clientInstance.deploymentGroupId, deployment_group_id: clientInstance.deploymentGroupId,
service_id: clientInstance.serviceId, service_id: clientInstance.serviceId,
status: clientInstance.status, status: clientInstance.status,

View File

@ -178,7 +178,8 @@ module.exports = class MachineWatcher {
name: machine.name, name: machine.name,
status, status,
deploymentGroupId: deploymentGroup.id, deploymentGroupId: deploymentGroup.id,
machineId: machine.id machineId: machine.id,
primaryIp: machine.primaryIp
}; };
this._server.log(['debug'], '-> creating instance', Util.inspect(instance)); this._server.log(['debug'], '-> creating instance', Util.inspect(instance));