UNPKG

tm-apps-list-api

Version:

139 lines (116 loc) 4.66 kB
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; };