added support for 64 bit numbers in node.d.plugin #75
Costa Tsaousis (ktsaou) committed
Apr 2, 2016 at 14:25 UTC
c1e21bad8f77a1363439dfba5b96440a8e18b565
5 files changed
+286
-2
LICENSE.md
+5
@@ -138,3 +138,8 @@ connectivity is not available.
138
Copyright 2015, Joseph Huckaby
139
[MIT License](https://github.com/jhuckaby/pixl-xml)
140
141
+- [node-int64](https://github.com/broofa/node-int64)
142
+
143
+ Copyright 2014, Robert Kieffer
144
+ [MIT License](https://github.com/broofa/node-int64/blob/master/LICENSE)
145
+
node.d/Makefile.am
+1
@@ -14,6 +14,7 @@ dist_nodemodules_DATA = \
14
node_modules/pixl-xml.js \
15
node_modules/net-snmp.js \
16
node_modules/asn1.js \
17
+ node_modules/node-int64.js \
18
$(NULL)
19
20
nodemodulesberdir=$(nodedir)/node_modules/ber
node.d/node_modules/netdata.js
+9
-2
@@ -3,6 +3,7 @@
3
var url = require('url');
4
var http = require('http');
5
var util = require('util');
6
+var Int64 = require('node-int64');
7
8
/*
9
var netdata = require('netdata');
@@ -339,8 +340,14 @@ var netdata = {
340
if(typeof value === 'undefined' || value === null)
341
return false;
342
342
- if(this._current_chart._dimensions_count !== 0)
343
- this.queue('SET ' + dimension + ' = ' + value);
343
+ if(this._current_chart._dimensions_count !== 0) {
344
+ if (value instanceof Buffer) {
345
+ var value64 = new Int64(value);
346
+ this.queue('SET ' + dimension + ' = ' + value64.toString(10));
347
+ }
348
+ else
349
+ this.queue('SET ' + dimension + ' = ' + value.toString());
350
+ }
351
352
return true;
353
};
node.d/node_modules/node-int64.js
new
+268
@@ -0,0 +1,268 @@
1
+// Int64.js
2
+//
3
+// Copyright (c) 2012 Robert Kieffer
4
+// MIT License - http://opensource.org/licenses/mit-license.php
5
+
6
+/**
7
+ * Support for handling 64-bit int numbers in Javascript (node.js)
8
+ *
9
+ * JS Numbers are IEEE-754 binary double-precision floats, which limits the
10
+ * range of values that can be represented with integer precision to:
11
+ *
12
+ * 2^^53 <= N <= 2^53
13
+ *
14
+ * Int64 objects wrap a node Buffer that holds the 8-bytes of int64 data. These
15
+ * objects operate directly on the buffer which means that if they are created
16
+ * using an existing buffer then setting the value will modify the Buffer, and
17
+ * vice-versa.
18
+ *
19
+ * Internal Representation
20
+ *
21
+ * The internal buffer format is Big Endian. I.e. the most-significant byte is
22
+ * at buffer[0], the least-significant at buffer[7]. For the purposes of
23
+ * converting to/from JS native numbers, the value is assumed to be a signed
24
+ * integer stored in 2's complement form.
25
+ *
26
+ * For details about IEEE-754 see:
27
+ * http://en.wikipedia.org/wiki/Double_precision_floating-point_format
28
+ */
29
+
30
+// Useful masks and values for bit twiddling
31
+var MASK31 = 0x7fffffff, VAL31 = 0x80000000;
32
+var MASK32 = 0xffffffff, VAL32 = 0x100000000;
33
+
34
+// Map for converting hex octets to strings
35
+var _HEX = [];
36
+for (var i = 0; i < 256; i++) {
37
+ _HEX[i] = (i > 0xF ? '' : '0') + i.toString(16);
38
+}
39
+
40
+//
41
+// Int64
42
+//
43
+
44
+/**
45
+ * Constructor accepts any of the following argument types:
46
+ *
47
+ * new Int64(buffer[, offset=0]) - Existing Buffer with byte offset
48
+ * new Int64(Uint8Array[, offset=0]) - Existing Uint8Array with a byte offset
49
+ * new Int64(string) - Hex string (throws if n is outside int64 range)
50
+ * new Int64(number) - Number (throws if n is outside int64 range)
51
+ * new Int64(hi, lo) - Raw bits as two 32-bit values
52
+ */
53
+var Int64 = module.exports = function(a1, a2) {
54
+ if (a1 instanceof Buffer) {
55
+ this.buffer = a1;
56
+ this.offset = a2 || 0;
57
+ } else if (Object.prototype.toString.call(a1) == '[object Uint8Array]') {
58
+ // Under Browserify, Buffers can extend Uint8Arrays rather than an
59
+ // instance of Buffer. We could assume the passed in Uint8Array is actually
60
+ // a buffer but that won't handle the case where a raw Uint8Array is passed
61
+ // in. We construct a new Buffer just in case.
62
+ this.buffer = new Buffer(a1);
63
+ this.offset = a2 || 0;
64
+ } else {
65
+ this.buffer = this.buffer || new Buffer(8);
66
+ this.offset = 0;
67
+ this.setValue.apply(this, arguments);
68
+ }
69
+};
70
+
71
+
72
+// Max integer value that JS can accurately represent
73
+Int64.MAX_INT = Math.pow(2, 53);
74
+
75
+// Min integer value that JS can accurately represent
76
+Int64.MIN_INT = -Math.pow(2, 53);
77
+
78
+Int64.prototype = {
79
+
80
+ constructor: Int64,
81
+
82
+ /**
83
+ * Do in-place 2's compliment. See
84
+ * http://en.wikipedia.org/wiki/Two's_complement
85
+ */
86
+ _2scomp: function() {
87
+ var b = this.buffer, o = this.offset, carry = 1;
88
+ for (var i = o + 7; i >= o; i--) {
89
+ var v = (b[i] ^ 0xff) + carry;
90
+ b[i] = v & 0xff;
91
+ carry = v >> 8;
92
+ }
93
+ },
94
+
95
+ /**
96
+ * Set the value. Takes any of the following arguments:
97
+ *
98
+ * setValue(string) - A hexidecimal string
99
+ * setValue(number) - Number (throws if n is outside int64 range)
100
+ * setValue(hi, lo) - Raw bits as two 32-bit values
101
+ */
102
+ setValue: function(hi, lo) {
103
+ var negate = false;
104
+ if (arguments.length == 1) {
105
+ if (typeof(hi) == 'number') {
106
+ // Simplify bitfield retrieval by using abs() value. We restore sign
107
+ // later
108
+ negate = hi < 0;
109
+ hi = Math.abs(hi);
110
+ lo = hi % VAL32;
111
+ hi = hi / VAL32;
112
+ if (hi > VAL32) throw new RangeError(hi + ' is outside Int64 range');
113
+ hi = hi | 0;
114
+ } else if (typeof(hi) == 'string') {
115
+ hi = (hi + '').replace(/^0x/, '');
116
+ lo = hi.substr(-8);
117
+ hi = hi.length > 8 ? hi.substr(0, hi.length - 8) : '';
118
+ hi = parseInt(hi, 16);
119
+ lo = parseInt(lo, 16);
120
+ } else {
121
+ throw new Error(hi + ' must be a Number or String');
122
+ }
123
+ }
124
+
125
+ // Technically we should throw if hi or lo is outside int32 range here, but
126
+ // it's not worth the effort. Anything past the 32'nd bit is ignored.
127
+
128
+ // Copy bytes to buffer
129
+ var b = this.buffer, o = this.offset;
130
+ for (var i = 7; i >= 0; i--) {
131
+ b[o+i] = lo & 0xff;
132
+ lo = i == 4 ? hi : lo >>> 8;
133
+ }
134
+
135
+ // Restore sign of passed argument
136
+ if (negate) this._2scomp();
137
+ },
138
+
139
+ /**
140
+ * Convert to a native JS number.
141
+ *
142
+ * WARNING: Do not expect this value to be accurate to integer precision for
143
+ * large (positive or negative) numbers!
144
+ *
145
+ * @param allowImprecise If true, no check is performed to verify the
146
+ * returned value is accurate to integer precision. If false, imprecise
147
+ * numbers (very large positive or negative numbers) will be forced to +/-
148
+ * Infinity.
149
+ */
150
+ toNumber: function(allowImprecise) {
151
+ var b = this.buffer, o = this.offset;
152
+
153
+ // Running sum of octets, doing a 2's complement
154
+ var negate = b[o] & 0x80, x = 0, carry = 1;
155
+ for (var i = 7, m = 1; i >= 0; i--, m *= 256) {
156
+ var v = b[o+i];
157
+
158
+ // 2's complement for negative numbers
159
+ if (negate) {
160
+ v = (v ^ 0xff) + carry;
161
+ carry = v >> 8;
162
+ v = v & 0xff;
163
+ }
164
+
165
+ x += v * m;
166
+ }
167
+
168
+ // Return Infinity if we've lost integer precision
169
+ if (!allowImprecise && x >= Int64.MAX_INT) {
170
+ return negate ? -Infinity : Infinity;
171
+ }
172
+
173
+ return negate ? -x : x;
174
+ },
175
+
176
+ /**
177
+ * Convert to a JS Number. Returns +/-Infinity for values that can't be
178
+ * represented to integer precision.
179
+ */
180
+ valueOf: function() {
181
+ return this.toNumber(false);
182
+ },
183
+
184
+ /**
185
+ * Return string value
186
+ *
187
+ * @param radix Just like Number#toString()'s radix
188
+ */
189
+ toString: function(radix) {
190
+ return this.valueOf().toString(radix || 10);
191
+ },
192
+
193
+ /**
194
+ * Return a string showing the buffer octets, with MSB on the left.
195
+ *
196
+ * @param sep separator string. default is '' (empty string)
197
+ */
198
+ toOctetString: function(sep) {
199
+ var out = new Array(8);
200
+ var b = this.buffer, o = this.offset;
201
+ for (var i = 0; i < 8; i++) {
202
+ out[i] = _HEX[b[o+i]];
203
+ }
204
+ return out.join(sep || '');
205
+ },
206
+
207
+ /**
208
+ * Returns the int64's 8 bytes in a buffer.
209
+ *
210
+ * @param {bool} [rawBuffer=false] If no offset and this is true, return the internal buffer. Should only be used if
211
+ * you're discarding the Int64 afterwards, as it breaks encapsulation.
212
+ */
213
+ toBuffer: function(rawBuffer) {
214
+ if (rawBuffer && this.offset === 0) return this.buffer;
215
+
216
+ var out = new Buffer(8);
217
+ this.buffer.copy(out, 0, this.offset, this.offset + 8);
218
+ return out;
219
+ },
220
+
221
+ /**
222
+ * Copy 8 bytes of int64 into target buffer at target offset.
223
+ *
224
+ * @param {Buffer} targetBuffer Buffer to copy into.
225
+ * @param {number} [targetOffset=0] Offset into target buffer.
226
+ */
227
+ copy: function(targetBuffer, targetOffset) {
228
+ this.buffer.copy(targetBuffer, targetOffset || 0, this.offset, this.offset + 8);
229
+ },
230
+
231
+ /**
232
+ * Returns a number indicating whether this comes before or after or is the
233
+ * same as the other in sort order.
234
+ *
235
+ * @param {Int64} other Other Int64 to compare.
236
+ */
237
+ compare: function(other) {
238
+
239
+ // If sign bits differ ...
240
+ if ((this.buffer[this.offset] & 0x80) != (other.buffer[other.offset] & 0x80)) {
241
+ return other.buffer[other.offset] - this.buffer[this.offset];
242
+ }
243
+
244
+ // otherwise, compare bytes lexicographically
245
+ for (var i = 0; i < 8; i++) {
246
+ if (this.buffer[this.offset+i] !== other.buffer[other.offset+i]) {
247
+ return this.buffer[this.offset+i] - other.buffer[other.offset+i];
248
+ }
249
+ }
250
+ return 0;
251
+ },
252
+
253
+ /**
254
+ * Returns a boolean indicating if this integer is equal to other.
255
+ *
256
+ * @param {Int64} other Other Int64 to compare.
257
+ */
258
+ equals: function(other) {
259
+ return this.compare(other) === 0;
260
+ },
261
+
262
+ /**
263
+ * Pretty output in console.log
264
+ */
265
+ inspect: function() {
266
+ return '[Int64 value:' + this + ' octets:' + this.toOctetString(' ') + ']';
267
+ }
268
+};
web/index.html
+3
@@ -407,6 +407,9 @@
407
<i class="fa fa-circle"></i> <a href="http://D3js.org/" target="_blank">D3</a>,
408
<i class="fa fa-copyright"></i> Copyright 2015, Mike Bostock, <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">BSD License</a>
409
410
+ <i class="fa fa-circle"></i> <a href="https://github.com/broofa/node-int64" target="_blank">node-int64</a>,
411
+ <i class="fa fa-copyright"></i> Copyright 2014, Robert Kieffer, <a href="https://github.com/broofa/node-int64/blob/master/LICENSE" target="_blank">MIT License</a>
412
+
413
</small>
414
</div>
415
</div>