forked from statsd/statsd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
stats.js
128 lines (103 loc) · 3.82 KB
/
stats.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
var dgram = require('dgram')
, sys = require('sys')
, net = require('net')
, config = require('./config')
var counters = {};
var timers = {};
var debugInt, flushInt, server;
config.configFile(process.argv[2], function (config, oldConfig) {
if (! config.debug && debugInt) {
clearInterval(debugInt);
debugInt = false;
}
if (config.debug) {
if (debugInt !== undefined) { clearInterval(debugInt); }
debugInt = setInterval(function () {
sys.log("Counters:\n" + sys.inspect(counters) + "\nTimers:\n" + sys.inspect(timers));
}, config.debugInterval || 10000);
}
if (server === undefined) {
server = dgram.createSocket('udp4', function (msg, rinfo) {
if (config.dumpMessages) { sys.log(msg.toString()); }
var bits = msg.toString().split(':');
var key = bits.shift()
.replace(/\s+/g, '_')
.replace(/\//g, '-')
.replace(/[^a-zA-Z_\-0-9\.]/g, '');
if (bits.length == 0) {
bits.push("1");
}
for (var i = 0; i < bits.length; i++) {
var sampleRate = 1;
var fields = bits[i].split("|");
if (fields[1].trim() == "ms") {
if (! timers[key]) {
timers[key] = [];
}
timers[key].push(Number(fields[0] || 0));
} else {
if (fields[2] && fields[2].match(/^@([\d\.]+)/)) {
sampleRate = Number(fields[2].match(/^@([\d\.]+)/)[1]);
}
if (! counters[key]) {
counters[key] = 0;
}
counters[key] += Number(fields[0] || 1) * (1 / sampleRate);
}
}
});
server.bind(config.port || 8125);
var flushInterval = Number(config.flushInterval || 10000);
flushInt = setInterval(function () {
var statString = '';
var ts = Math.round(new Date().getTime() / 1000);
var numStats = 0;
var key;
for (key in counters) {
var value = counters[key] / (flushInterval / 1000);
var message = 'stats.' + key + ' ' + value + ' ' + ts + "\n";
statString += message;
counters[key] = 0;
numStats += 1;
}
for (key in timers) {
if (timers[key].length > 0) {
var pctThreshold = config.percentThreshold || 90;
var values = timers[key].sort(function (a,b) { return a-b; });
var count = values.length;
var min = values[0];
var max = values[count - 1];
var mean = min;
var maxAtThreshold = max;
if (count > 1) {
var thresholdIndex = Math.round(((100 - pctThreshold) / 100) * count);
var numInThreshold = count - thresholdIndex;
values = values.slice(0, numInThreshold);
maxAtThreshold = values[numInThreshold - 1];
// average the remaining timings
var sum = 0;
for (var i = 0; i < numInThreshold; i++) {
sum += values[i];
}
mean = sum / numInThreshold;
}
timers[key] = [];
var message = "";
message += 'stats.timers.' + key + '.mean ' + mean + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.upper ' + max + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.upper_' + pctThreshold + ' ' + maxAtThreshold + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.lower ' + min + ' ' + ts + "\n";
message += 'stats.timers.' + key + '.count ' + count + ' ' + ts + "\n";
statString += message;
numStats += 1;
}
}
statString += 'statsd.numStats ' + numStats + ' ' + ts + "\n";
var graphite = net.createConnection(config.graphitePort, config.graphiteHost);
graphite.on('connect', function() {
this.write(statString);
this.end();
});
}, flushInterval);
}
});