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 | var os = require('os');
|
26 |
|
27 |
|
28 | var nt;
|
29 | var metrics = {};
|
30 |
|
31 |
|
32 | exports.init = function() {
|
33 | nt = global.nodetime;
|
34 |
|
35 | setInterval(function() {
|
36 | try {
|
37 | aggregate();
|
38 | }
|
39 | catch(e) {
|
40 | nt.error(e);
|
41 | }
|
42 | }, 60000);
|
43 |
|
44 |
|
45 | setTimeout(function() {
|
46 | try {
|
47 | initial();
|
48 | }
|
49 | catch(e) {
|
50 | nt.error(e);
|
51 | }
|
52 | }, 1000);
|
53 | };
|
54 |
|
55 |
|
56 | exports.add = function(scope, name, value, unit, op) {
|
57 | if(!scope || !name || typeof(value) !== 'number')
|
58 | throw new Error('parameter(s) missing');
|
59 |
|
60 | process.nextTick(function() {
|
61 | var key = scope + ':' + name;
|
62 |
|
63 |
|
64 | if(!metrics[key]) {
|
65 | metrics[key] = {
|
66 | scope: scope,
|
67 | name: name,
|
68 | value: 0,
|
69 | _count: 0,
|
70 | unit: unit,
|
71 | op: op,
|
72 | history: nt.history
|
73 | };
|
74 |
|
75 | if(op === 'hist')
|
76 | metrics[key].value = {};
|
77 | }
|
78 |
|
79 |
|
80 |
|
81 | var obj = metrics[key];
|
82 |
|
83 | if(!op || op === 'val') {
|
84 | obj.value = value;
|
85 | }
|
86 | else if(op === 'hist') {
|
87 | var bin = Math.pow(10, Math.floor(Math.log(value) / Math.LN10) + 1);
|
88 | if(obj.value[bin]) {
|
89 | obj.value[bin]++;
|
90 | }
|
91 | else {
|
92 | obj.value[bin] = 1;
|
93 | }
|
94 | }
|
95 | else {
|
96 | obj.value += value;
|
97 | obj._count++;
|
98 | }
|
99 |
|
100 | if(!nt.history) {
|
101 | obj.history = false;
|
102 | }
|
103 | });
|
104 | };
|
105 |
|
106 |
|
107 | var emit = function(obj) {
|
108 | try {
|
109 | delete obj._count;
|
110 | obj.source = os.hostname() + '[' + process.pid + ']';
|
111 | obj._id = nt.nextId++;
|
112 | obj._ns = 'metrics';
|
113 | obj._ts = nt.millis();
|
114 |
|
115 | nt.emit('metric', obj);
|
116 | }
|
117 | catch(err) {
|
118 | nt.error(err);
|
119 | }
|
120 | };
|
121 |
|
122 | var initial = function() {
|
123 | for (var key in metrics) {
|
124 | var obj = metrics[key];
|
125 |
|
126 | if(!obj.op || obj.op === 'val') {
|
127 | emit(obj);
|
128 |
|
129 | delete metrics[key];
|
130 | }
|
131 | }
|
132 | };
|
133 |
|
134 |
|
135 | var aggregate = function() {
|
136 | for (var key in metrics) {
|
137 | var obj = metrics[key];
|
138 |
|
139 | if(obj.op === 'avg') {
|
140 | obj.value = Math.round(obj.value / obj._count);
|
141 | }
|
142 |
|
143 | emit(obj);
|
144 | }
|
145 |
|
146 | metrics = {};
|
147 | };
|
148 |
|