Skip to content

Commit

Permalink
[UPDATE] README. Extract plugins.
Browse files Browse the repository at this point in the history
  • Loading branch information
kgryte committed Oct 17, 2014
1 parent 030616f commit dd46c1e
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 94 deletions.
89 changes: 85 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,106 @@ Monitor
> Connect middleware to monitor an application process.

---
## Installation

For use in Node.js,

``` bash
$ npm install connect-middleware-monitor
```

## Usage

To use the module,

``` javascript
var createMonitor = require( 'connect-middleware-monitor' );
```

#### createMonitor( [...plugin] )

The middleware generator accepts monitor plugins which append to a common metrics `object`.

``` javascript
var // Plugin which reports system metrics:
sPlugin = require( 'monitor-plugin-os' ),

// Plugin which reports current process metrics:
pPlugin = require( 'monitor-plugin-process' );

// Create the monitor middleware:
var monitor = createMonitor( sPlugin, pPlugin );
```

Note: plugins are executed in the same order as they are provided to the middleware generator.

Each plugin should be a single method which accepts two input arguments: [`object`, `clbk`]. The `object` is a shared `object` among all plugins, hence, when choosing plugins, ensure that they are property namespaced when appending to the `object`.

The callback should be invoked once the plugin finishes appending metrics. The callback takes an optional `error` argument, which will be bubbled up through the middleware.


#### monitor( request, response, next )

The generated middleware follows the [connect](https://github.com/senchalabs/connect) middleware pattern. Monitor metrics are appended to the `request` object via a `locals` object. Hence, downstream middleware consumers may access the metrics via

``` javascript
var metrics = request.locals.monitor;
```

See the examples below.

## Notes



## Examples

``` javascript
var express = require( 'express' ),
request = require( 'request' ),
sPlugin = require( 'monitor-plugin-os' ),
pPlugin = require( 'monitor-plugin-process' ),
createMonitor = require( 'connect-middleware-monitor' );

// Define a port:
var PORT = 7331;

// Create a new monitor:
var monitor = createMonitor( sPlugin, pPlugin );

// Create a new application:
var app = express();

// Bind a route using the monitor middleware:
app.get( '/', [ monitor, sendJSON ] );

// Spin up a new server:
var server = app.listen( PORT, onListen );


function onListen() {
request({
'method': 'GET',
'uri': 'http://127.0.0.1:' + PORT
}, onResponse );
}

function onResponse( error, response, body ) {
if ( error ) {
throw new Error( error );
}
console.log( body );
}

function sendJSON( request, response, next ) {
response
.status( 200 )
.send( JSON.stringify( request.locals.monitor ) );
}
```

To run an example from the top-level application directory,

``` bash
$ node ./examples/index.js
```


## Tests
Expand Down
43 changes: 43 additions & 0 deletions examples/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
var express = require( 'express' ),
request = require( 'request' ),
sPlugin = require( 'monitor-plugin-os' ),
pPlugin = require( 'monitor-plugin-process' ),
createMonitor = require( './../lib' );

// Define a port:
var PORT = 7331;

// Create a new monitor:
var monitor = createMonitor( sPlugin, pPlugin );

// Create a new application:
var app = express();

// Bind a route using the monitor middleware:
app.get( '/', [ monitor, sendJSON ] );

// Spin up a new server:
var server = app.listen( PORT, onListen );


function onListen() {
request({
'method': 'GET',
'uri': 'http://127.0.0.1:' + PORT
}, onResponse );
}

function onResponse( error, response, body ) {
if ( error ) {
throw new Error( error );
}
console.log( body );
server.close();
process.exit( -1 );
}

function sendJSON( request, response, next ) {
response
.status( 200 )
.send( JSON.stringify( request.locals.monitor ) );
}
111 changes: 25 additions & 86 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,6 @@
(function() {
'use strict';

// MODULES //

var // OS module:
os = require( 'os' ),

// Module which monitors the Node.js event loop and keeps track of 'lag' (i.e., how long requests wait in Node's event queue before being processed):
toobusy = require( 'toobusy' );


// MONITOR //

/**
Expand Down Expand Up @@ -66,92 +57,40 @@
* @param {Function} next - callback to invoke after gathering application metrics
*/
return function monitor( request, response, next ) {
var sys = {},
proc = {},
total,
free,
memUsage,
metrics,
error;


// SYSTEM METRICS //

// [1] Get the number of seconds the system has been running:
sys.uptime = os.uptime();

// [2] Get the 1, 5, and 15 minute load averages (does not work on Windows platforms):
sys.loadavg = os.loadavg(); // [...]

// [3] Get the total amount of system memory and the amount of free system memory in bytes:
total = os.totalmem();
free = os.freemem();

sys.memory = {
'total': total,
'free': free,
'utilization': ( total-free ) / total
};

// [4] Get individual CPU metrics:
sys.cpus = os.cpus(); // [...]


// PROCESS METRICS //

// [5] Get the process id:
proc.pid = process.pid;

// [6] Get the number of seconds the process has been running:
proc.uptime = process.uptime();

// [7] Extract process memory usage:
memUsage = process.memoryUsage();
proc.memory = {
'rss': memUsage.rss,
'heapUsed': memUsage.heapUsed,
'heapTotal': memUsage.heapTotal
};
var metrics = {};

// [8] Get the average amount of time requests have to wait in Node's event queue before being processed:
proc.lag = toobusy.lag();


// METRICS //

metrics = {
'system': sys,
'process': proc
};

// PLUGINS //

(function next( err ) {
if ( err ) {
error = err;
// Run all monitor plugins...
(function next( error ) {
if ( error ) {
done( error );
return;
}
if ( plugins.length > 0 ) {
plugins.shift().apply( {}, [ metrics, next ] );
} else {
done();
}
})();

if ( error ) {
next( error );
return;
}

// LOCALS //

if ( !request.hasOwnProperty( 'locals' ) ) {
request.locals = {};
}
request.locals.monitor = metrics;

// Proceed to next middleware:
next();
/**
* FUNCTION: done( [error] )
* Callback invoked once all plugins have reported back to the monitor.
*
* @private
* @param {Object} [error] - error object
*/
function done( error ) {
if ( error ) {
next( error );
return;
}
if ( !request.hasOwnProperty( 'locals' ) ) {
request.locals = {};
}
request.locals.monitor = metrics;
next();
} // end FUNCTION done()
}; // end FUNCTION monitor()

} // end FUNCTION createMonitor()


Expand Down
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,16 @@
"metrics",
"performance"
],
"dependencies": {
"toobusy": "^0.2.4"
},
"dependencies": {},
"devDependencies": {
"chai": "1.x.x",
"coveralls": "^2.11.1",
"express": "^4.9.7",
"istanbul": "^0.3.0",
"mocha": "1.x.x"
"mocha": "1.x.x",
"monitor-plugin-os": "^1.0.0",
"monitor-plugin-process": "^1.0.0",
"request": "^2.45.0"
},
"engines": {
"node": ">= 0.10.0"
Expand Down

0 comments on commit dd46c1e

Please sign in to comment.