@cryptotaxi247 / netdata-1 / commits / c1e21bad8

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>