123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- var $ = require('jquery');
- var _ = require('underscore');
- var Handlebars = require('hbsfy/runtime');
- var AppState = require('../app_state');
- var formatStatsdKey = function(metricType, key) {
- var fullKey = key;
- var fmt;
- if (metricType === 'counter') {
- fmt = AppState.get('STATSD_COUNTER_FORMAT');
- fullKey = fmt.replace(/%s/g, key);
- } else if (metricType === 'gauge') {
- fmt = AppState.get('STATSD_GAUGE_FORMAT');
- fullKey = fmt.replace(/%s/g, key);
- }
- return fullKey;
- };
- var statsdPrefix = function(host) {
- var prefix = AppState.get('STATSD_PREFIX');
- var statsdHostKey = host.replace(/[\.:]/g, '_');
- prefix = prefix.replace(/%s/g, statsdHostKey);
- if (prefix.substring(prefix.length, 1) !== '.') {
- prefix += '.';
- }
- return prefix;
- };
- /* eslint-disable key-spacing */
- var metricType = function(key) {
- return {
- 'depth': 'gauge',
- 'in_flight_count': 'gauge',
- 'deferred_count': 'gauge',
- 'requeue_count': 'counter',
- 'timeout_count': 'counter',
- 'message_count': 'counter',
- 'clients': 'gauge',
- '*_bytes': 'gauge',
- 'gc_pause_*': 'gauge',
- 'gc_runs': 'counter',
- 'heap_objects': 'gauge',
- 'e2e_processing_latency': 'gauge'
- }[key];
- };
- /* eslint-enable key-spacing */
- var genColorList = function(typ, key) {
- if (typ === 'topic' || typ === 'channel') {
- if (key === 'depth' || key === 'deferred_count') {
- return 'red';
- }
- } else if (typ === 'node') {
- return 'red,green,blue,purple';
- } else if (typ === 'counter') {
- return 'green';
- }
- return 'blue';
- };
- // sanitizeGraphiteKey removes special characters from a graphite key
- // this matches behavior of bitly/statsdaemon
- // https://github.com/bitly/statsdaemon/blob/fc46d9cfe29b674a0c8abc723afaa9370430cdcd/statsdaemon.go#L64-L88
- var sanitizeGraphiteKey = function(s) {
- return s.replaceAll(' ', '_').replaceAll('/', '-').replaceAll(/[^a-zA-Z0-9-_.]/g, '');
- }
- var genTargets = function(typ, node, ns1, ns2, key) {
- var targets = [];
- var prefix = statsdPrefix(node ? node : '*');
- var fullKey;
- var target;
- if (typ === 'topic') {
- fullKey = formatStatsdKey(metricType(key), prefix + 'topic.' + sanitizeGraphiteKey(ns1) + '.' + key);
- targets.push('sumSeries(' + fullKey + ')');
- } else if (typ === 'channel') {
- fullKey = formatStatsdKey(metricType(key), prefix + 'topic.' + sanitizeGraphiteKey(ns1) + '.channel.' +
- sanitizeGraphiteKey(ns2) + '.' + key);
- targets.push('sumSeries(' + fullKey + ')');
- } else if (typ === 'node') {
- target = prefix + 'mem.' + key;
- if (key === 'gc_runs') {
- target = 'movingAverage(' + target + ',45)';
- }
- targets.push(formatStatsdKey(metricType(key), target));
- } else if (typ === 'e2e') {
- targets = _.map(ns1['percentiles'], function(p) {
- var t;
- if (ns1['channel'] !== '') {
- t = prefix + 'topic.' + ns1['topic'] + '.channel.' + ns1['channel'] + '.' +
- key + '_' + (p['quantile'] * 100);
- } else {
- t = prefix + 'topic.' + ns1['topic'] + '.' + key + '_' + (p['quantile'] * 100);
- }
- if (node === '*') {
- t = 'averageSeries(' + t + ')';
- }
- return 'scale(' + formatStatsdKey(metricType(key), t) + ',0.000001)';
- });
- } else if (typ === 'counter') {
- fullKey = formatStatsdKey(metricType(key), prefix + 'topic.*.channel.*.' + key);
- targets.push('sumSeries(' + fullKey + ')');
- }
- return targets;
- };
- Handlebars.registerHelper('default', function(x, defaultValue) {
- return x ? x : defaultValue;
- });
- Handlebars.registerHelper('ifeq', function(a, b, options) {
- return (a === b) ? options.fn(this) : options.inverse(this);
- });
- Handlebars.registerHelper('unlesseq', function(a, b, options) {
- return (a !== b) ? options.fn(this) : options.inverse(this);
- });
- Handlebars.registerHelper('ifgteq', function(a, b, options) {
- return (a >= b) ? options.fn(this) : options.inverse(this);
- });
- Handlebars.registerHelper('iflteq', function(a, b, options) {
- return (a <= b) ? options.fn(this) : options.inverse(this);
- });
- Handlebars.registerHelper('length', function(xs) {
- return xs.length;
- });
- Handlebars.registerHelper('lowercase', function(s) {
- return s.toLowerCase();
- });
- Handlebars.registerHelper('uppercase', function(s) {
- return s.toUpperCase();
- });
- // this helper is inclusive of the top number
- Handlebars.registerHelper('for', function(from, to, incr, block) {
- var accum = '';
- for (var i = from; i <= to; i += incr) {
- accum += block.fn(i);
- }
- return accum;
- });
- // Logical operators as helper functions, which can be useful when used within
- // an `if` or `unless` block via the new helper composition syntax, like so:
- //
- // {{#if (or step.unlocked step.is_finished)}}
- // Step is unlocked or finished!
- // {{/if}}
- //
- // Any number of arguments may be given to either helper. NOTE: _.initial() is
- // used below because every helper takes an options hash as its last argument.
- Handlebars.registerHelper('and', function() {
- return _.all(_.initial(arguments));
- });
- Handlebars.registerHelper('or', function() {
- return _.any(_.initial(arguments));
- });
- Handlebars.registerHelper('eq', function(a, b) {
- return a === b;
- });
- Handlebars.registerHelper('neq', function(a, b) {
- return a !== b;
- });
- Handlebars.registerHelper('urlencode', function(a) {
- return encodeURIComponent(a);
- });
- Handlebars.registerHelper('floatToPercent', function(f) {
- return Math.floor(f * 100);
- });
- Handlebars.registerHelper('percSuffix', function(f) {
- var v = Math.floor(f * 100) % 10;
- if (v === 1) {
- return 'st';
- } else if (v === 2) {
- return 'nd';
- } else if (v === 3) {
- return 'rd';
- }
- return 'th';
- });
- Handlebars.registerHelper('commafy', function(n) {
- n = n || 0;
- return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
- });
- function round(num, places) {
- var multiplier = Math.pow(10, places);
- return Math.round(num * multiplier) / multiplier;
- }
- Handlebars.registerHelper('nanotohuman', function(n) {
- var s = '';
- var v;
- if (n >= 3600000000000) {
- v = Math.floor(n / 3600000000000);
- n = n % 3600000000000;
- s = v + 'h';
- }
- if (n >= 60000000000) {
- v = Math.floor(n / 60000000000);
- n = n % 60000000000;
- s += v + 'm';
- }
- if (n >= 1000000000) {
- n = round(n / 1000000000, 2);
- s += n + 's';
- } else if (n >= 1000000) {
- n = round(n / 1000000, 2);
- s += n + 'ms';
- } else if (n >= 1000) {
- n = round(n / 1000, 2);
- s += n + 'us';
- } else {
- s = n + 'ns';
- }
- return s;
- });
- Handlebars.registerHelper('sparkline', function(typ, node, ns1, ns2, key) {
- var q = {
- 'colorList': genColorList(typ, key),
- 'height': '20',
- 'width': '120',
- 'hideGrid': 'true',
- 'hideLegend': 'true',
- 'hideAxes': 'true',
- 'bgcolor': 'ff000000', // transparent
- 'fgcolor': 'black',
- 'margin': '0',
- 'yMin': '0',
- 'lineMode': 'connected',
- 'drawNullAsZero': 'false',
- 'from': '-' + AppState.get('graph_interval'),
- 'until': '-1min'
- };
- var interval = AppState.get('STATSD_INTERVAL') + 'sec';
- q['target'] = _.map(genTargets(typ, node, ns1, ns2, key), function(t) {
- return 'summarize(' + t + ',"' + interval + '","avg")';
- });
- return AppState.get('GRAPHITE_URL') + '/render?' + $.param(q);
- });
- Handlebars.registerHelper('large_graph', function(typ, node, ns1, ns2, key) {
- var q = {
- 'colorList': genColorList(typ, key),
- 'height': '450',
- 'width': '800',
- 'bgcolor': 'ff000000', // transparent
- 'fgcolor': '999999',
- 'yMin': '0',
- 'lineMode': 'connected',
- 'drawNullAsZero': 'false',
- 'from': '-' + AppState.get('graph_interval'),
- 'until': '-1min'
- };
- var interval = AppState.get('STATSD_INTERVAL') + 'sec';
- q['target'] = _.map(genTargets(typ, node, ns1, ns2, key), function(t) {
- if (metricType(key) === 'counter') {
- var scale = 1 / AppState.get('STATSD_INTERVAL');
- t = 'scale(' + t + ',' + scale + ')';
- }
- return 'summarize(' + t + ',"' + interval + '","avg")';
- });
- return AppState.get('GRAPHITE_URL') + '/render?' + $.param(q);
- });
- Handlebars.registerHelper('rate', function(typ, node, ns1, ns2) {
- return genTargets(typ, node, ns1, ns2, 'message_count')[0];
- });
- Handlebars.registerPartial('error', require('../views/error.hbs'));
- Handlebars.registerPartial('warning', require('../views/warning.hbs'));
- Handlebars.registerHelper('basePath', function(p) {
- return AppState.basePath(p);
- });
|