tm-apps-list-api
Version:
139 lines (116 loc) • 4.66 kB
JavaScript
const { commandFactory } = require('hystrixjs');
const request = require('request');
const promisify = require('util.promisify');
const callbackify = require('util').callbackify || function (promiser) {
return function (...args) {
const callback = args.pop();
promiser.apply(this, args).then(
result => callback(null, result),
error => callback(error)
);
};
};
module.exports = (redis, options) => {
const service = promisify((command_obj, callback) => {
command_obj.callback = callback;
});
const fallback = promisify((error, [command_obj], callback) => {
command_obj.command = command_obj.callback = null;
callback(error);
});
const breaker = commandFactory.getOrCreate(options.name)
.circuitBreakerErrorThresholdPercentage(options.errorThreshold)
.timeout(options.timeout)
.run(service)
.circuitBreakerRequestVolumeThreshold(options.volumeThreshold)
.requestVolumeRejectionThreshold(options.rejectionThreshold)
.circuitBreakerSleepWindowInMilliseconds(options.sleepWindow)
.statisticalWindowLength(options.windowLength)
.statisticalWindowNumberOfBuckets(options.windowBuckets)
.fallbackTo(fallback)
.build();
const { createClient } = redis;
redis.createClient = function () {
const client = createClient.apply(this, arguments);
const { internal_send_command } = client;
client.internal_send_command = function (command_obj) {
const { command, callback = function () {} } = command_obj;
if (!command) return true;
callbackify(breaker.execute).call(breaker, command_obj, callback);
return internal_send_command.call(this, command_obj);
};
return client;
};
if (options.influxdbUrl) {
const { hystrixSSEStream } = require('hystrixjs');
hystrixSSEStream.toObservable(options.statsWindow).subscribe(json => {
const data = JSON.parse(json);
Object.keys(data.latencyExecute).forEach(key => {
data[`latencyExecute_${key}`] = data.latencyExecute[key];
});
Object.keys(data.latencyTotal).forEach(key => {
data[`latencyTotal_${key}`] = data.latencyTotal[key];
});
const tags = [
'name',
'group'
];
const fields = [
'isCircuitBreakerOpen',
'errorPercentage',
'errorCount',
'requestCount',
'rollingCountFailure',
'rollingCountTimeout',
'rollingCountSuccess',
'rollingCountShortCircuited',
'rollingCountBadRequests',
'rollingCountCollapsedRequests',
'rollingCountExceptionsThrown',
'rollingCountFallbackFailure',
'rollingCountFallbackRejection',
'rollingCountFallbackSuccess',
'rollingCountResponsesFromCache',
'rollingCountSemaphoreRejected',
'rollingCountThreadPoolRejected',
'currentConcurrentExecutionCount',
'latencyExecute_mean',
'latencyExecute_0',
'latencyExecute_25',
'latencyExecute_50',
'latencyExecute_75',
'latencyExecute_90',
'latencyExecute_95',
'latencyExecute_99',
'latencyExecute_99.5',
'latencyExecute_100',
'latencyTotal_mean',
'latencyTotal_0',
'latencyTotal_25',
'latencyTotal_50',
'latencyTotal_75',
'latencyTotal_90',
'latencyTotal_95',
'latencyTotal_99',
'latencyTotal_99.5',
'latencyTotal_100'
];
const extract = (keys, obj) => {
return keys.map(key => {
const value = obj[key].replace(/\W/g, '_');
return [key, value].join('=');
});
};
const parts = [
['hystrix', ...extract(tags, data)],
[...extract(fields, data)],
[data.currentTime]
];
request.post({
url: `http://${options.influxdbUrl}:8086/write?db=telegraf&precision=ms`,
body: parts.map(part => part.join(',')).join(' ')
});
});
}
return redis;
};