New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

appmetrics

Package Overview
Dependencies
Maintainers
4
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

appmetrics - npm Package Compare versions

Comparing version

to
1.0.4

probes/leveldown-probe.js

6

appmetrics-api.js

@@ -123,4 +123,6 @@ /*******************************************************************************

var values = message.split(/[,=]+/);
var systemUsed = values[3] - values[11];
var memory = {time: parseInt(values[1]), physical_total: parseInt(values[3]), physical_used: parseInt(systemUsed), physical: parseInt(values[5]), private: parseInt(values[7]), virtual: parseInt(values[9]), physical_free: parseInt(values[11])};
var physicalTotal = parseInt(values[3]);
var physicalFree = parseInt(values[11]);
var physicalUsed = (physicalTotal >= 0 && physicalFree >= 0) ? (physicalTotal - physicalFree) : -1;
var memory = {time: parseInt(values[1]), physical_total: physicalTotal, physical_used: physicalUsed, physical: parseInt(values[5]), private: parseInt(values[7]), virtual: parseInt(values[9]), physical_free: physicalFree};
that.emit('memory', memory);

@@ -127,0 +129,0 @@ };

@@ -44,3 +44,3 @@ /*******************************************************************************

var AGENTCORE_VERSION = "3.0.6";
var APPMETRICS_VERSION = "1.0.3";
var APPMETRICS_VERSION = "1.0.4";

@@ -47,0 +47,0 @@ var LOG_FILE = path.join(INSTALL_DIR, 'install.log');

@@ -52,2 +52,45 @@ /*******************************************************************************

var latencyData = {
count: 0,
min: 1 * 60 * 1000,
max: 0,
total: 0
}
var latencyCheck = function() {
var start = process.hrtime();
setImmediate(function(start) {
var delta = process.hrtime(start);
var latency = (delta[0] * 1000) + (delta[1] / 1000000);
latencyData.count++;
latencyData.min = Math.min(latencyData.min, latency);
latencyData.max = Math.max(latencyData.max, latency);
latencyData.total = latencyData.total + latency;
}, start);
}
var latencyReport = function() {
if (latencyData.count == 0) return;
var latency = {
min: latencyData.min,
max: latencyData.max,
avg: latencyData.total / latencyData.count
};
var avg = latencyData.total / latencyData.count;
exports.emit('eventloop', {time: Date.now(), latency: latency});
latencyData.count = 0;
latencyData.min = 1 * 60 * 1000;
latencyData.max = 0;
latencyData.total = 0;
}
var latencyCheckInterval = 500;
var latencyReportInterval = 5000;
var latencyRunning = true;
var latencyCheckLoop = setInterval(latencyCheck, latencyCheckInterval);
var latencyReportLoop = setInterval(latencyReport, latencyReportInterval);
latencyCheckLoop.unref();
latencyReportLoop.unref();
/*

@@ -57,12 +100,18 @@ * Patch the module require function to run the probe attach function

*/
aspect.after(module.__proto__, 'require', function(obj, args, ret) {
for (var i = 0; i < probes.length; i++) {
if (probes[i].name === args[0]) {
probes[i].attach(args[0], ret, module.exports);
var data = {};
aspect.after(module.__proto__, 'require', data, function(obj, methodName, args, context, ret) {
if (ret.__ddProbeAttached__) {
return ret;
} else {
for (var i = 0; i < probes.length; i++) {
if (probes[i].name === args[0]) {
ret = probes[i].attach(args[0], ret, module.exports);
}
if (probes[i].name === 'trace') {
ret = probes[i].attach(args[0], ret);
}
}
if (probes[i].name === 'trace') {
ret = probes[i].attach(args[0], ret);
}
return ret;
}
return ret;
});

@@ -92,2 +141,8 @@

break;
case 'eventloop':
if (latencyRunning === true) break;
latencyRunning = true;
latencyCheckLoop = setInterval(latencyCheck, latencyCheckInterval);
latencyReportLoop = setInterval(latencyReport, latencyReportInterval);
break;
default:

@@ -119,2 +174,8 @@ probes.forEach(function (probe) {

break;
case 'eventloop':
if (latencyRunning === false) break;
latencyRunning = false;
clearInterval(latencyCheckLoop);
clearInterval(latencyReportLoop);
break;
default:

@@ -121,0 +182,0 @@ probes.forEach(function (probe) {

@@ -17,60 +17,3 @@ /*******************************************************************************

function aspect(type) {
return function(target, meths, hook1, hook2) {
if(!Array.isArray(meths)) {
meths = [meths];
}
meths.forEach(function(methodName) {
var existing = target[methodName];
if(!existing) return;
var hookBefore, hookAfter;
if((type == 'before') && hook1) {
hookBefore = hook1;
} else if(type == "around" && hook1 && hook2) {
hookBefore = hook1;
hookAfter = hook2;
} else if((type == 'after') && hook1) {
hookAfter = hook1;
}
var newFunc;
if(type == 'before') {
newFunc = function() {
hookBefore(this, arguments);
return existing.apply(this, arguments);
};
}
else if(type == "around") {
newFunc = function() {
hookBefore(this, arguments);
var ret = existing.apply(this, arguments);
if(process.version.split('.')[0] == 'v0' && process.version.split('.')[1] < 8){
hookAfter(this, arguments, ret);
return ret;
}else{
return hookAfter(this, arguments, ret);
}
};
}
else if(type == 'after') {
newFunc = function() {
var ret = existing.apply(this, arguments);
if(process.version.split('.')[0] == 'v0' && process.version.split('.')[1] < 8){
hookAfter(this, arguments, ret);
return ret;
} else {
return hookAfter(this, arguments, ret);
}
};
}
newFunc.prototype = existing.prototype;
target[methodName] = newFunc;
});
};
}
exports.aroundCallback = function(args, hookBefore, hookAfter) {
exports.aroundCallback = function(args, context, hookBefore, hookAfter) {
var position = this.findCallbackArg(args);

@@ -83,3 +26,3 @@ if(position == undefined) return;

if(hookBefore) {
hookBefore(this, arguments);
hookBefore(this, arguments, context);
}

@@ -90,7 +33,7 @@

if(hookAfter) {
hookAfter(this, arguments);
hookAfter(this, arguments, context, ret);
}
return ret;
};
}
};

@@ -106,8 +49,81 @@ exports.findCallbackArg = function(args) {

return position;
}
};
exports.before = aspect("before");
exports.before = function(target, meths, hookBefore) {
if(!Array.isArray(meths)) {
meths = [meths];
}
meths.forEach(function(methodName) {
var existing = target[methodName];
if(!existing) return;
exports.around = aspect("around");
var newFunc = function() {
var context = {};
hookBefore(this, methodName, arguments, context);
return existing.apply(this, arguments);
};
newFunc.prototype = existing.prototype;
exports.after = aspect("after");
target[methodName] = newFunc;
});
};
exports.around = function(target, meths, hookBefore, hookAfter) {
if(!Array.isArray(meths)) {
meths = [meths];
}
meths.forEach(function(methodName) {
var existing = target[methodName];
if(!existing) return;
var newFunc = function() {
var context = {};
hookBefore(this, methodName, arguments, context);
var ret = existing.apply(this, arguments);
return hookAfter(this, methodName, arguments, context, ret);
};
newFunc.prototype = existing.prototype;
target[methodName] = newFunc;
});
};
exports.after = function(target, meths, context, hookAfter) {
if(!Array.isArray(meths)) {
meths = [meths];
}
meths.forEach(function(methodName) {
var existing = target[methodName];
if(!existing) return;
var newFunc = function() {
var ret = existing.apply(this, arguments);
return hookAfter(this, methodName, arguments, context, ret);
};
newFunc.prototype = existing.prototype;
target[methodName] = newFunc;
});
};
exports.afterConstructor = function (target, context, hookAfter) {
if (typeof(target) === 'function') {
var newFunc = function() {
var ret = target.apply(null, arguments);
return hookAfter(this, '()', arguments, context, ret);
};
for (var property in target) {
if (target.hasOwnProperty(property)){
newFunc[property] = target[property];
}
}
newFunc.prototype = target.prototype;
newFunc.exports = target.exports;
return newFunc;
} else {
return target;
}
};

@@ -19,2 +19,3 @@ /*******************************************************************************

var request = require('./request.js');
var timer = require('./timer.js');

@@ -31,3 +32,3 @@ function Probe(name) {

*/
Probe.prototype.attach = function(name, target, hc) {
Probe.prototype.attach = function(name, target) {
return target;

@@ -55,7 +56,9 @@ };

*/
Probe.prototype.metricsStart = function(req, res, am) {
start = Date.now();
Probe.prototype.metricsStart = function(probeData) {
probeData.timer = timer.start();
};
Probe.prototype.metricsEnd = function(req, res, am) {
// Implentors should stop the timer and emit an event.
Probe.prototype.metricsEnd = function(probeData) {
probeData.timer.stop();
};

@@ -66,3 +69,2 @@

*/
var request = require('../lib/request.js');

@@ -69,0 +71,0 @@ Probe.prototype.requestStart = function (req, res, am) {};

@@ -85,3 +85,3 @@ /*******************************************************************************

if( this.timer.timeDelta >= config.minClockStack || this.timer.cpuTimeDelta >= config.minCpuStack ) {
if((config.minClockStack != -1) && (this.timer.timeDelta >= config.minClockStack)) {
this.stack = this.fetchStack();

@@ -103,3 +103,5 @@ }

this.active = true;
this.timer = timer.start();
if( !this.timer ) {
this.timer = timer.start();
}
if (process.domain) {

@@ -121,3 +123,3 @@ process.domain.currentRequest = this;

if( this.timer.timeDelta >= config.minClockTrace || this.timer.cpuTimeDeltaInMs() >= config.minCpuTrace ) {
if((config.minClockTrace != -1) && (this.timer.timeDelta >= config.minClockTrace)) {
this.traceStart(); // delayed start tracing (will call parent tracing if needed)

@@ -173,4 +175,7 @@ this.traceStop();

exports.startRequest = function( type, name, root ) {
exports.startRequest = function( type, name, root, eventTimer ) {
var req = new Request( type, name, root );
if( eventTimer ) {
req.timer = eventTimer;
}
req.start();

@@ -180,4 +185,7 @@ return req;

exports.startMethod = function( name ) {
exports.startMethod = function( name , eventTimer) {
var req = new Request( null, name );
if( eventTimer ) {
req.timer = eventTimer;
}
req.start();

@@ -191,3 +199,3 @@ return req;

minCpuStack: 0,
minClockStack: 0
minClockStack: -1
}

@@ -194,0 +202,0 @@

@@ -17,31 +17,17 @@ /*******************************************************************************

function clockTime() {
var time = process.hrtime();
return time[0] * 1000 + (time[1] / 1000000.0);
}
/*
* CPU time of requests/events not currently implemented
*/
function clockCpuTime() {
return 0;
}
function Timer() {
this.startTime = clockTime();
this.startTimeMillis = Date.now();
this.startCpuTime = clockCpuTime();
this.startTime = process.hrtime();
this.startTimeMillis = Date.now();
this.timeDelta = -1;
this.cpuTimeDelta = -1;
}
Timer.prototype.stop = function() {
this.stopTime = clockTime();
this.stopTimeMillis = Date.now();
this.timeDelta = this.stopTimeMillis - this.startTimeMillis;
this.cpuTimeDelta = -1;
}
// Prevent the timer being stopped twice.
if( this.timeDelta == -1 ) {
var dur = process.hrtime(this.startTime);
this.timeDelta = (dur[0] * 1000) + (dur[1] / 1000000);
}
};
Timer.prototype.cpuTimeDeltaInMs = function() {
return 0;
}
exports.start = function(){ return new Timer(); };
{
"name": "appmetrics",
"version": "1.0.3",
"version": "1.0.4",
"description": "Node Application Metrics",

@@ -5,0 +5,0 @@ "bin": { "node-hc": "bin/appmetrics-cli.js" },

@@ -21,2 +21,3 @@ /*******************************************************************************

var url = require('url');
var am = require('appmetrics');

@@ -31,34 +32,30 @@ function HttpProbe() {

HttpProbe.prototype.attach = function(name, target, am) {
HttpProbe.prototype.attach = function(name, target) {
var that = this;
if( name == 'http' ) {
if(target.__probeAttached__) return;
if(target.__probeAttached__) return target;
target.__probeAttached__ = true;
var methods = ['on', 'addListener'];
var start;
aspect.before(target.Server.prototype, methods,
function(obj, args) {
function(obj, methodName, args, probeData) {
if(args[0] !== 'request') return;
if(obj.__httpProbe__) return;
obj.__httpProbe__ = true;
aspect.aroundCallback(args, function(obj, args) {
var req = args[0];
aspect.aroundCallback(args, probeData, function(obj, args, probeData) {
var httpReq = args[0];
var res = args[1];
var reqDomain;
var tr;
// Filter out urls where filter.to is ''
var traceUrl = that.filterUrl(req);
var traceUrl = that.filterUrl(httpReq);
if (traceUrl !== '') {
that.metricsProbeStart(req, res);
that.requestProbeStart(traceUrl, res);
aspect.after(res, 'end',function(obj, args, ret) {
if (traceUrl !== '') {
that.metricsProbeEnd(req, res, am);
that.requestProbeEnd(req, res);
}
that.metricsProbeStart(probeData, httpReq.method, traceUrl);
that.requestProbeStart(probeData, httpReq.method, traceUrl);
aspect.after(res, 'end', probeData, function(obj, methodName, args, probeData, ret) {
that.metricsProbeEnd(probeData, httpReq.method, traceUrl);
that.requestProbeEnd(probeData, httpReq.method, traceUrl);
});
}
});
});
}
});
}
return target;

@@ -68,6 +65,17 @@ };

/*
* Custom req.url parser that strips out any trailing query
*/
var parse = function (url) {
['?','#'].forEach(function (separator) {
var index = url.indexOf(separator);
if (index !== -1) url = url.substring(0, index);
});
return url;
};
/*
* Ignore requests for URLs which we've been configured via regex to ignore
*/
HttpProbe.prototype.filterUrl = function(req) {
var resultUrl = url.parse( req.url, true ).pathname;
var resultUrl = parse(req.url);
var filters = this.config.filters;

@@ -96,4 +104,5 @@ if (filters.length == 0) return resultUrl;

HttpProbe.prototype.metricsEnd = function(req, res, am) {
am.emit('http', {time: start, method: req.method, url: req.url, duration: Date.now() - start});
HttpProbe.prototype.metricsEnd = function(probeData, method, url) {
probeData.timer.stop();
am.emit('http', {time: probeData.timer.startTimeMillis, method: method, url: url, duration: probeData.timer.timeDelta});
};

@@ -105,11 +114,10 @@

HttpProbe.prototype.requestStart = function (traceUrl, res, am) {
HttpProbe.prototype.requestStart = function (probeData, method, url) {
var reqType = 'HTTP';
// Mark as a root request as this happens due to an external event
tr = request.startRequest(reqType, traceUrl, true);
probeData.req = request.startRequest(reqType, url, true, probeData.timer);
};
HttpProbe.prototype.requestEnd = function (req, res, am) {
var reqUrl = url.parse( req.url, true ).pathname;
tr.stop({url: reqUrl });
HttpProbe.prototype.requestEnd = function (probeData, method, url) {
probeData.req.stop({url: url });
};

@@ -116,0 +124,0 @@

@@ -20,2 +20,3 @@ /*******************************************************************************

var util = require('util');
var am = require('appmetrics');

@@ -27,20 +28,20 @@ function MongoProbe() {

MongoProbe.prototype.aspectCollectionMethod = function(coll, method, am) {
MongoProbe.prototype.aspectCollectionMethod = function(coll, method) {
var that = this;
var req;
aspect.around( coll, method,
function(target, methodArgs) {
that.metricsProbeStart(target, method, methodArgs);
that.requestProbeStart(target, method, methodArgs);
function(target, methodName, methodArgs, probeData) {
that.metricsProbeStart(probeData, target, method, methodArgs);
that.requestProbeStart(probeData, target, method, methodArgs);
if (aspect.findCallbackArg(methodArgs) != undefined) {
aspect.aroundCallback( methodArgs, function(target,args){
that.metricsProbeEnd(method, methodArgs, am);
that.requestProbeEnd(method, methodArgs);
aspect.aroundCallback( methodArgs, probeData, function(target,args, probeData){
that.metricsProbeEnd(probeData, method, methodArgs);
that.requestProbeEnd(probeData, method, methodArgs);
} );
}
},
function(target, methodArgs, rc) {
},
function(target, methodName, methodArgs, probeData, rc) {
if (aspect.findCallbackArg(methodArgs) == undefined) {
that.metricsProbeEnd(method, methodArgs, am);
that.requestProbeEnd(method, methodArgs);
that.metricsProbeEnd(probeData, method, methodArgs);
that.requestProbeEnd(probeData, method, methodArgs);
}

@@ -52,3 +53,3 @@ return rc;

MongoProbe.prototype.attach = function( name, target, am ) {
MongoProbe.prototype.attach = function(name, target) {
var that = this;

@@ -60,18 +61,17 @@ if( name != "mongodb" ) return target;

var coll = target['Collection'].prototype;
var req;
var method = 'find';
aspect.around( coll, "find",
function(target, methodArgs){
that.metricsProbeStart(target, method, methodArgs, am);
that.requestProbeStart(target, method, methodArgs, am);
function(target, methodName, methodArgs, probeData){
that.metricsProbeStart(probeData, target, method, methodArgs);
that.requestProbeStart(probeData, target, method, methodArgs);
},
function(target, findArgs, rc){
function(target, methodName, findArgs, probeData, rc){
if (rc == undefined) {
that.metricsProbeEnd(method, findArgs, am);
that.requestProbeEnd(method, findArgs, am);
that.metricsProbeEnd(probeData, method, findArgs);
that.requestProbeEnd(probeData, method, findArgs);
} else {
aspect.before( rc, "toArray", function(target, args){
aspect.aroundCallback( args, function(target, args){
that.metricsProbeEnd(method, findArgs, am);
that.requestProbeEnd(method, findArgs, am);
aspect.before( rc, "toArray", function(target, methodName, args, context){
aspect.aroundCallback( args, probeData, function(target, args, probeData){
that.metricsProbeEnd(probeData, method, findArgs);
that.requestProbeEnd(probeData, method, findArgs);
});

@@ -83,11 +83,11 @@ });

that.aspectCollectionMethod(coll, "insert", am);
that.aspectCollectionMethod(coll, "save", am);
that.aspectCollectionMethod(coll, "update", am);
that.aspectCollectionMethod(coll, "remove", am);
that.aspectCollectionMethod(coll, "findOne", am);
that.aspectCollectionMethod(coll, "count", am);
that.aspectCollectionMethod(coll, "findAndModify", am);
that.aspectCollectionMethod(coll, "findAndRemove", am);
that.aspectCollectionMethod(coll, "aggregate", am);
that.aspectCollectionMethod(coll, "insert");
that.aspectCollectionMethod(coll, "save");
that.aspectCollectionMethod(coll, "update");
that.aspectCollectionMethod(coll, "remove");
that.aspectCollectionMethod(coll, "findOne");
that.aspectCollectionMethod(coll, "count");
that.aspectCollectionMethod(coll, "findAndModify");
that.aspectCollectionMethod(coll, "findAndRemove");
that.aspectCollectionMethod(coll, "aggregate");

@@ -106,19 +106,18 @@ return target;

*/
MongoProbe.prototype.metricsEnd = function(method, methodArgs, am) {
am.emit('mongo', {time: start, query: JSON.stringify(methodArgs[0]), duration: Date.now() - start});
MongoProbe.prototype.metricsEnd = function(probeData, method, methodArgs) {
probeData.timer.stop();
am.emit('mongo', {time: probeData.timer.startTimeMillis, query: JSON.stringify(methodArgs[0]), duration: probeData.timer.timeDelta});
};
/*
* Heavyweight request probes for MonngoDB queries
* Heavyweight request probes for MongoDB queries
*/
MongoProbe.prototype.requestStart = function (target, method, methodArgs, am) {
start = Date.now();
req = request.startRequest( 'DB', method + "("+target.collectionName+")" );
req.setContext( { query: JSON.stringify(methodArgs[0]) } );
MongoProbe.prototype.requestStart = function (probeData, target, method, methodArgs) {
probeData.req = request.startRequest( 'DB', method + "("+target.collectionName+")", false, probeData.timer );
};
MongoProbe.prototype.requestEnd = function (method, methodArgs, am) {
req.stop( { query: JSON.stringify(methodArgs[0]) } );
MongoProbe.prototype.requestEnd = function (probeData, method, methodArgs) {
probeData.req.stop( { query: JSON.stringify(methodArgs[0]) } );
};
module.exports = MongoProbe;

@@ -20,2 +20,3 @@ /*******************************************************************************

var util = require('util');
var am = require('appmetrics');

@@ -27,3 +28,3 @@ function MySqlProbe() {

MySqlProbe.prototype.attach = function( name, target, am ) {
MySqlProbe.prototype.attach = function(name, target) {
var that = this;

@@ -33,13 +34,13 @@ if( name != "mysql" ) return target;

aspect.after(target, 'createConnection', function(target, args, rc) {
var data = {};
aspect.after(target, 'createConnection', data, function(target, methodName, args, probeData, rc ) {
aspect.before( rc, 'query',
function(target, methodArgs) {
var req;
function(target, methodName, methodArgs, probeData) {
var method = 'query';
that.metricsProbeStart(method, methodArgs);
that.requestProbeStart(method, methodArgs);
that.metricsProbeStart(probeData, method, methodArgs);
that.requestProbeStart(probeData, method, methodArgs);
if (aspect.findCallbackArg(methodArgs) != undefined) {
aspect.aroundCallback( methodArgs, function(target,args){
that.metricsProbeEnd(method, methodArgs, am);
that.requestProbeEnd(method, methodArgs);
aspect.aroundCallback( methodArgs, probeData, function(target,args){
that.metricsProbeEnd(probeData, method, methodArgs);
that.requestProbeEnd(probeData, method, methodArgs);
});

@@ -62,4 +63,6 @@ };

*/
MySqlProbe.prototype.metricsEnd = function(method, methodArgs, am) {
am.emit('mysql', {time: start, query: JSON.stringify(methodArgs[0]), duration: Date.now() - start});
MySqlProbe.prototype.metricsEnd = function(probeData, method, methodArgs) {
probeData.timer.stop();
eventTimer = probeData.timer;
am.emit('mysql', {time: eventTimer.startTimeMillis, query: JSON.stringify(methodArgs[0]), duration: eventTimer.timeDelta});
};

@@ -70,12 +73,10 @@

*/
MySqlProbe.prototype.requestStart = function (method, methodArgs) {
start = Date.now();
req = request.startRequest( 'DB', "query" );
req.setContext({sql: JSON.stringify(methodArgs[0])});
MySqlProbe.prototype.requestStart = function (probeData, method, methodArgs) {
probeData.req = request.startRequest( 'DB', "query", false, probeData.timer );
};
MySqlProbe.prototype.requestEnd = function (method, methodArgs) {
req.stop({sql: JSON.stringify(methodArgs[0])});
MySqlProbe.prototype.requestEnd = function (probeData, method, methodArgs) {
probeData.req.stop({sql: JSON.stringify(methodArgs[0])});
};
module.exports = MySqlProbe;

@@ -18,3 +18,2 @@ /*******************************************************************************

var request = require('../lib/request.js');
var aspect = require('../lib/aspect');
var util = require('util');

@@ -50,3 +49,3 @@ var path = require('path');

ret = function () {
var rc = target.apply(null, arguments);
var rc = target.apply(this, arguments);
instrumentMethods(moduleName, rc);

@@ -122,3 +121,3 @@ return rc;

resArg.send = function() {
req.stop(cxtFunc);
req.stop(cxtFunc());
return sendCb.apply(resArg, arguments);

@@ -129,3 +128,3 @@ }

resArg.render = function() {
req.stop(cxtFunc);
req.stop(cxtFunc());
return renderCb.apply(resArg, arguments);

@@ -136,4 +135,4 @@ }

arguments[arguments.length-1] = function() {
req.stop(cxtFunc);
cb.apply(this, arguments);
req.stop(cxtFunc());
return cb.apply(this, arguments);
}

@@ -144,3 +143,3 @@ }

if( !isCallback ) {
req.stop(cxtFunc);
req.stop(cxtFunc());
}

@@ -147,0 +146,0 @@ return res;

@@ -17,6 +17,14 @@ # Node Application Metrics

GC | Node/V8 garbage collection statistics
Event Loop | Event loop latency information
Function profiling | Node/V8 function profiling (disabled by default)
HTTP | HTTP request calls made of the application
socket.io | WebSocket data sent and received by the application
LevelDB | LevelDB queries made by the application
MySQL | MySQL queries made by the application
MongoDB | MongoDB queries made by the application
PostgreSQL | PostgreSQL queries made by the application
MQTT | MQTT messages sent and received by the application
MQLight | MQLight messages sent and received by the application
Memcached | Data that stored or manupulated in Memcached
Redis | Redis commands issued by the application
Request tracking | A tree of application requests, events and optionally trace (disabled by default)

@@ -159,3 +167,3 @@ Function trace | Tracing of application function calls that occur during a request (disabled by default)

Enable data generation of the specified data type.
* `type` (String) the type of event to start generating data for. Values of 'profiling', 'http', 'mongo', 'mysql', 'requests' and 'trace' are currently supported. As `trace` is added to request data, both `requests` and `trace` must be enabled in order to receive trace data.
* `type` (String) the type of event to start generating data for. Values of `eventloop`, `profiling`, `http`, `mongo`, `socketio`, `mqlight`, `postgresql`, `mqtt`, `mysql`, `redis`, `memcached`, `requests` and `trace` are currently supported. As `trace` is added to request data, both `requests` and `trace` must be enabled in order to receive trace data.
* `config` (Object) (optional) configuration map to be added for the data type being enabled. (see *[setConfig](#set-config)*) for more information.

@@ -167,3 +175,3 @@

Disable data generation of the specified data type.
* `type` (String) the type of event to stop generating data for. Values of `profiling`, `http`, `mongo`, `mysql`, `requests` and `trace` are currently supported.
* `type` (String) the type of event to stop generating data for. Values of `eventloop`, `profiling`, `http`, `mongo`, `socketio`, `mqlight`, `postgresql`, `mqtt`, `mysql`, `redis`, `memcached`, `requests` and `trace` are currently supported.

@@ -222,2 +230,10 @@ <a name="set-config"></a>

### Event: 'eventloop'
Emitted every 5 seconds, summarising sample based information of the event loop latency
* `data` (Object) the data from the event loop sample:
* `time` (Number) the milliseconds when the event was emitted. This can be converted to a Date using `new Date(data.time)`.
* `latency.min` (Number) the shortest sampled latency, in milliseconds.
* `latency.max` (Number) the longest sampled latency, in milliseconds.
* `latency.avg` (Number) the average sampled latency, in milliseconds.
### Event: 'profiling'

@@ -242,2 +258,10 @@ Emitted when a profiling sample is available from the underlying V8 runtime.

* `duration` (Number) the time taken for the HTTP request to be responded to in ms.
### Event: 'socketio'
Emitted when WebSocket data is sent or received by the application using socketio.
* `data` (Object) the data from the socket.io request:
* `time` (Number) the milliseconds when the event occurred. This can be converted to a Date using `new Date(data.time)`.
* `method` (String) whether the event is a `broadcast` or `emit` from the application, or a `receive` from a client .
* `event` (String) the name used for the event.
* `duration` (Number) the time taken for event to be sent or for a received event to be handled.

@@ -258,2 +282,47 @@ ### Event: 'mysql'

### Event: 'mqtt'
Emitted when a MQTT message is sent or received.
* `data` (Object) the data from the MQTT event:
* `time` (Number) the time in milliseconds when the MQTT event occurred. This can be converted to a Date using new Date(data.time).
* `method` (String) the name of the call or event (will be one of 'publish' or 'message').
* `topic` (String) the topic on which a message is published or received.
* `qos` (Number) the QoS level for the message.
* `duration` (Number) the time taken in milliseconds.
### Event: 'mqlight'
Emitted when a MQLight message is sent or received.
* `data` (Object) the data from the MQLight event:
* `time` (Number) the time in milliseconds when the MQLight event occurred. This can be converted to a Date using new Date(data.time).
* `clientid` (String) the id of the client.
* `data` (String) the data sent if a 'send' or 'message', undefined for other calls. Truncated if longer than 25 characters.
* `method` (String) the name of the call or event (will be one of 'send' or 'message').
* `topic` (String) the topic on which a message is sent/received.
* `qos` (Number) the QoS level for a 'send' call, undefined if not set.
* `duration` (Number) the time taken in milliseconds.
### Event: 'leveldown'
Emitted when a LevelDB query is made using the `leveldown` module.
* `data` (Object) the data from the LevelDB query:
* `time` (Number) the time in milliseconds when the LevelDB query was made. This can be converted to a Date using `new Date(data.time)`.
* `method` (String) The leveldown method being used.
* `key` (Object) The key being used for a call to `get`, `put` or `del` (Undefined for other methods)
* `value` (Object) The value being added to the LevelDB database using the `put` method (Undefined for other methods)
* `opCount` (Number) The number of operations carried out by a `batch` method (Undefined for other methods)
* `duration` (Number) the time taken for the LevelDB query to be responded to in ms.
### Event: 'redis'
Emitted when a Redis command is sent.
* `data` (Object) the data from the Redis event:
* `time` (Number) the time in milliseconds when the MQLight event occurred. This can be converted to a Date using new Date(data.time).
* `cmd` (String) the Redis command sent to the server or 'batch.exec'/'multi.exec' for groups of command sent using batch/multi calls.
* `duration` (Number) the time taken in milliseconds.
### Event: 'memcached'
Emitted when a data is stored, retrieved or modified in Memcached using the `memcached` module.
* `data` (Object) the data from the memcached event:
* `time` (Number) the milliseconds when the memcached event occurred. This can be converted to a Date using `new Date(data.time)`
* `method` (String) the method used in the memcached client, eg `set`, `get`, `append`, `delete`, etc.
* `key` (String) the key associated with the data.
* `duration` (Number) the time taken for the operation on the memcached data to occur.
### Event: 'request'

@@ -269,3 +338,3 @@ Emitted when a request is made of the application that involves one or more monitored application level events. Request events are disabled by default.

* `context` (Object) A map of any additional context information for the request event.
* `stack` (String) A stack trace for the event call.
* `stack` (String) An optional stack trace for the event call.
* `children` (Array) An array of child request events that occurred as part of the overall request event. Child request events may include function trace entries, which will have a `type` of null.

@@ -275,2 +344,9 @@ * `duration` (Number) the time taken for the request to complete in ms.

### Event: 'postgres'
Emitted when a PostgreSQL query is made to the `pg` module.
* `data` (Object) the data from the PostgreSQL query:
* `time` (Number) the milliseconds when the PostgreSQL query was made. This can be converted to a Date using `new Date(data.time)`.
* `query` (String) the query made of the PostgreSQL database.
* `duration` (Number) the time taken for the PostgreSQL query to be responded to in ms.
## Troubleshooting

@@ -328,6 +404,7 @@ Find below some possible problem scenarios and corresponding diagnostic steps. Updates to troubleshooting information will be made available on the [appmetrics wiki][3]: [Troubleshooting](https://github.com/RuntimeTools/appmetrics/wiki/Troubleshooting). If these resources do not help you resolve the issue, you can open an issue on the Node Application Metrics [appmetrics issue tracker][5].

## Version
1.0.3
1.0.4
## Release History
`1.0.3` - Node.js v4 support
`1.0.4` - Redis, Leveldown, Postgresql, Memcached, MQLight and MQTT support, higher precision timings, and improved performance.
`1.0.3` - Node.js v4 support
`1.0.2` - HTTP, MySQL, MongoDB, request tracking and function tracing support

@@ -334,0 +411,0 @@ `1.0.1` - Mac OS X support, io.js v2 support

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet