Skip to content
Browse files

Added Data Sampling and fixed unix compatibility

  • Loading branch information...
1 parent 773dd7b commit 45791ec43dcc5e6aef765c47cb7cc239d16a978f Jason Brumwell committed
Showing with 109 additions and 17 deletions.
  1. +7 −5 lib/parsers/unix.js
  2. +8 −4 lib/parsers/win.js
  3. +21 −1 lib/vitals.js
  4. +10 −1 readme.md
  5. +63 −6 test/test.js
View
12 lib/parsers/unix.js
@@ -9,23 +9,25 @@ module.exports = function() {
lines.forEach(function(line) {
var trimmed = line.trim().replace(/\s+/g, ' '),
data = trimmed && trimmed.split(' ') || [],
- pid = data[0] && parseInt(data[0], 10),
+ pid = data[0],
pi = pids.indexOf(pid);
if (pid && pi !== -1) {
- _this.emit('data', _this._pids[pid], {
+ data = {
cputime: data[1].replace(':', '').replace(':', '.'),
memoryUsage: data[2] ? data[2].replace(/[^\d]/g, '') : '0',
uptime: new Date().getTime() - _this._pids[pid].meta._started
- })
+ };
+
+ _this.emit('data', _this._pids[pid], data)
+
+ _this._collect(_this._pids[pid], data);
delete pids[pi];
}
})
- console.log(lines, pids);
-
return pids;
}
}
View
12 lib/parsers/win.js
@@ -12,13 +12,17 @@ module.exports = function() {
pi = pids.indexOf(pid);
- if (pid && pi !== -1) {
- _this.emit('data', _this._pids[pid], {
+ if (pid && pi !== -1) {
+ data = {
cputime: data[ data.length - 2 ].replace(':', '').replace(':', '.'),
memoryUsage: data[4] ? data[4].replace(/[^\d]/g, '') : '0',
uptime: new Date().getTime() - _this._pids[pid].meta._started
- })
-
+ };
+
+ _this.emit('data', _this._pids[pid], data);
+
+ _this._collect(_this._pids[pid], data);
+
delete pids[pi];
}
});
View
22 lib/vitals.js
@@ -1,6 +1,6 @@
var util = require('util'),
os = require('os'),
- Parser = os.platform().indexOf('win') != -1 ? require('./parsers/win') : require('./parsers/linux'),
+ Parser = os.platform().indexOf('win') != -1 ? require('./parsers/win') : require('./parsers/unix'),
EventEmitter = require('events').EventEmitter;
@@ -11,6 +11,10 @@ function Vitals(options) {
options.interval = options.interval || 3000;
+ options.sampleRate = 0.5;
+
+ options.maxSamples = options.maxSamples || 100;
+
this.options = options;
this.length = 0;
@@ -173,6 +177,22 @@ Vitals.prototype._run = function() {
});
}
+Vitals.prototype._collect = function(proc, data) {
+ if (! Array.isArray(proc.meta._samples)) {
+ proc.meta._samples = [];
+ }
+
+ if (Math.random() <= this.options.sampleRate) {
+ data.collected = new Date().getTime();
+
+ proc.meta._samples.push(data);
+
+ if (proc.meta._samples.length > this.options.maxSamples) {
+ proc.meta._samples = proc.meta._samples.splice(this.options.maxSamples * -1);
+ }
+ }
+}
+
Vitals.prototype.emit = function() {
var _this = this,
args = arguments;
View
11 readme.md
@@ -9,12 +9,15 @@
## Features
- - Windows & Unix support
+ - Windows & Unix support
- Meta data support
+ - Data sampling
## Options
- `interval` the interval in which to poll the processes (Default 3000ms)
+ - `maxSamples` the maximum number of samples to retain
+ - `sampleRate` the rate at which to sample data between 0 (disabled) and 1 for 100%, ie: 0.15 for 15% of the time
## Events
@@ -80,6 +83,12 @@ Count number of processes being monitored
vitals.length
```
+Sampling Data
+vitals.on('data', function(proc, data) {
+ //proc.meta._samples == Array[data, data, data]
+ //data.collected is the time the sample was collected
+});
+
Events
```js
View
69 test/test.js
@@ -301,9 +301,7 @@ describe('Health Monitor', function(){
assert.exists(data.uptime);
assert.exists(data.memoryUsage);
done();
- });
-
- health.start();
+ });
})
it('should emit#data that contains process meta data', function(done) {
@@ -311,9 +309,7 @@ describe('Health Monitor', function(){
assert.exists(proc.meta.custom);
assert.equal('meta', proc.meta.custom);
done();
- });
-
- health.start();
+ });
})
afterEach(function() {
@@ -326,6 +322,67 @@ describe('Health Monitor', function(){
})
})
+ describe('Data Sampling', function() {
+ before(function() {
+ health.options.sampleRate = 1;
+ });
+
+ beforeEach(function() {
+ health.add(process.pid, {custom: 'meta'});
+ health.start();
+ })
+
+ it('should provide sample data', function(done) {
+ health.on('data', function(proc, data) {
+ assert.exists(proc.meta._samples);
+ assert.equal(1, proc.meta._samples.length);
+ done();
+ })
+ })
+
+ it('should emit#data that contains uptime, cputime, memory usage and timestamp when collected', function(done) {
+ health.on('data', function(proc, data) {
+ assert.exists(proc.meta._samples);
+ assert.exists(proc.meta._samples[0].cputime);
+ assert.exists(proc.meta._samples[0].uptime);
+ assert.exists(proc.meta._samples[0].memoryUsage);
+ assert.exists(proc.meta._samples[0].collected);
+ done();
+ })
+ })
+
+ it('should adhere to the max sampling rate', function(done) {
+ var count = 0,
+ until = 10;
+
+ health.options.maxSamples = 3;
+
+ this.timeout(10000);
+
+ health.on('data', function(proc, data) {
+ ++count;
+
+ assert.exists(proc.meta._samples);
+ assert.equal(count > 3 ? 3 : count, proc.meta._samples.length);
+
+ if (count >= until) {
+ assert(count > proc.meta._samples.length);
+ done();
+ }
+ })
+ })
+
+ afterEach(function() {
+ health.removeAllListeners('data');
+ health.remove();
+ health.stop();
+ })
+
+ after(function() {
+ health.remove();
+ })
+ });
+
describe('Stopping', function() {
before(function() {
health.add(process.pid, {custom: 'meta'});

0 comments on commit 45791ec

Please sign in to comment.
Something went wrong with that request. Please try again.