Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

appmetrics

Package Overview
Dependencies
Maintainers
5
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 2.0.1 to 3.0.0

binaries/agentcore/tgz/agentcore-3.2.1-aix-ppc.tgz

73

extract_all_binaries.js

@@ -41,4 +41,4 @@ /*******************************************************************************

'win32-x64'];
var AGENTCORE_VERSION = "3.1.0";
var APPMETRICS_VERSION = "2.0.1";
var AGENTCORE_VERSION = "3.2.1";
var APPMETRICS_VERSION = "3.0.0";

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

console.log(platform + ' is not a currently supported platform. Exiting');
process.exit(1);
fail();
}

@@ -117,4 +117,4 @@ };

}
console.log('Unsupported version ' + process.version + '. Exiting.');
process.exit(1);
console.log('Unsupported version ' + process.version + '. Trying rebuild.');
fail();
};

@@ -136,25 +136,35 @@

if (agentCoreFlag) {
fs.createReadStream('binaries/agentcore/tgz/'+filepath).pipe(zlib.createGunzip()).on('error', function(err) {
console.log('ERROR: Failed to gunzip ' + filepath + ': ' + err.message);
process.exit(1);
})
.pipe(tar.Extract({path: destDir})).on('error', function(err) {
console.log('ERROR: Failed to untar ' + filepath + ': ' + err.message);
process.exit(1);
})
.on('close', function() {
console.log('Download and extract of ' + filepath + ' finished.');
});
if(fs.existsSync('binaries/agentcore/tgz/'+filepath)) {
fs.createReadStream('binaries/agentcore/tgz/'+filepath).pipe(zlib.createGunzip()).on('error', function(err) {
console.log('ERROR: Failed to gunzip ' + filepath + ': ' + err.message);
fail();
})
.pipe(tar.Extract({path: destDir})).on('error', function(err) {
console.log('ERROR: Failed to untar ' + filepath + ': ' + err.message);
fail();
})
.on('close', function() {
console.log('Download and extract of ' + filepath + ' finished.');
});
} else {
console.log(filepath + " does not exist.")
fail();
}
} else {
fs.createReadStream('binaries/appmetrics/tgz/'+filepath).pipe(zlib.createGunzip()).on('error', function(err) {
console.log('ERROR: Failed to gunzip ' + filepath + ': ' + err.message);
process.exit(1);
})
.pipe(tar.Extract({path: destDir})).on('error', function(err) {
console.log('ERROR: Failed to untar ' + filepath + ': ' + err.message);
process.exit(1);
})
.on('close', function() {
console.log('Download and extract of ' + filepath + ' finished.');
});
if(fs.existsSync('binaries/appmetrics/tgz/'+filepath)) {
fs.createReadStream('binaries/appmetrics/tgz/'+filepath).pipe(zlib.createGunzip()).on('error', function(err) {
console.log('ERROR: Failed to gunzip ' + filepath + ': ' + err.message);
fail();
})
.pipe(tar.Extract({path: destDir})).on('error', function(err) {
console.log('ERROR: Failed to untar ' + filepath + ': ' + err.message);
fail();
})
.on('close', function() {
console.log('Download and extract of ' + filepath + ' finished.');
});
} else {
console.log(filepath + " does not exist.")
fail();
}
}

@@ -164,10 +174,15 @@

function fail() {
console.log('Falling back to node-gyp rebuild');
process.exit(1);
}
var installWinRedis = function(filepath, destDir) {
fs.createReadStream('binaries/winredis/'+filepath).pipe(zlib.createGunzip()).on('error', function(err) {
console.log('ERROR: Failed to gunzip ' + filepath + ': ' + err.message);
process.exit(1);
fail();
})
.pipe(tar.Extract({path: destDir})).on('error', function(err) {
console.log('ERROR: Failed to untar ' + filepath + ': ' + err.message);
process.exit(1);
fail();
})

@@ -174,0 +189,0 @@ .on('close', function() {

@@ -30,2 +30,4 @@ /*******************************************************************************

var heapdump = require('./heapdump.js');
var VERSION = require('./package.json').version
var assert = require('assert')

@@ -121,2 +123,15 @@

if(global.Appmetrics) {
assert(
global.Appmetrics.VERSION === VERSION,
'Multiple versions of Node Application Metrics are being initialized.\n' +
'This version ' + VERSION + ' is incompatible with already initialized\n' +
'version ' + global.Appmetrics.VERSION+ '.\n'
);
module.exports = global.Appmetrics;
} else {
global.Appmetrics = module.exports;
module.exports.VERSION = VERSION;
}
/*

@@ -331,2 +346,7 @@ * Patch the module require function to run the probe attach function

process.on('exit', function () {
// take the event loop latency methods off the loop
if (latencyRunning === true) {
clearInterval(latencyCheckLoop);
clearInterval(latencyReportLoop);
}
var headlessMode = agent.getOption('com.ibm.diagnostics.healthcenter.headless');

@@ -333,0 +353,0 @@ am.stop();

@@ -24,6 +24,2 @@ module.exports = Reader

if (!props.path) {
self.error('Must provide a path', null, true)
}
// polymorphism.

@@ -89,2 +85,6 @@ // call fstream.Reader(dir) to get a DirReader object, etc.

if (!props.path) {
self.error('Must provide a path', null, true)
}
self.readable = true

@@ -91,0 +91,0 @@ self.writable = false

@@ -33,4 +33,2 @@ module.exports = Writer

if (!props.path) self.error('Must provide a path', null, true)
// polymorphism.

@@ -65,2 +63,4 @@ // call fstream.Writer(dir) to get a DirWriter object, etc.

if (!props.path) self.error('Must provide a path', null, true)
// props is what we want to set.

@@ -67,0 +67,0 @@ // set some convenience properties as well.

@@ -7,2 +7,3 @@ #!/usr/bin/env node

var dashdash = false
var noglob = false
var args = process.argv.slice(2).filter(function(arg) {

@@ -13,2 +14,6 @@ if (dashdash)

dashdash = true
else if (arg === '--no-glob' || arg === '-G')
noglob = true
else if (arg === '--glob' || arg === '-g')
noglob = false
else if (arg.match(/^(-+|\/)(h(elp)?|\?)$/))

@@ -18,3 +23,3 @@ help = true

return !!arg
});
})

@@ -30,3 +35,5 @@ if (help || args.length === 0) {

log('')
log(' -h, --help Display this usage info')
log(' -h, --help Display this usage info')
log(' -G, --no-glob Do not expand glob patterns in arguments')
log(' -g, --glob Expand glob patterns in arguments (default)')
process.exit(help ? 0 : 1)

@@ -39,3 +46,6 @@ } else

return
rimraf(args[n], function (er) {
var options = {}
if (noglob)
options = { glob: false }
rimraf(args[n], options, function (er) {
if (er)

@@ -42,0 +52,0 @@ throw er

@@ -109,3 +109,3 @@ var concatMap = require('concat-map');

var isSequence = isNumericSequence || isAlphaSequence;
var isOptions = /^(.*,)+(.+)?$/.test(m.body);
var isOptions = m.body.indexOf(',') >= 0;
if (!isSequence && !isOptions) {

@@ -112,0 +112,0 @@ // {a},b}

{
"name": "brace-expansion",
"description": "Brace expansion as known from sh/bash",
"version": "1.1.6",
"version": "1.1.7",
"repository": {

@@ -13,3 +13,4 @@ "type": "git",

"test": "tape test/*.js",
"gentest": "bash test/generate.sh"
"gentest": "bash test/generate.sh",
"bench": "matcha test/perf/bench.js"
},

@@ -21,2 +22,3 @@ "dependencies": {

"devDependencies": {
"matcha": "^0.7.0",
"tape": "^4.6.0"

@@ -47,11 +49,11 @@ },

},
"gitHead": "791262fa06625e9c5594cde529a21d82086af5f2",
"gitHead": "892512024872ca7680554be90f6e8ce065053372",
"bugs": {
"url": "https://github.com/juliangruber/brace-expansion/issues"
},
"_id": "brace-expansion@1.1.6",
"_shasum": "7197d7eaa9b87e648390ea61fc66c84427420df9",
"_id": "brace-expansion@1.1.7",
"_shasum": "3effc3c50e000531fb720eaff80f0ae8ef23cf59",
"_from": "brace-expansion@>=1.0.0 <2.0.0",
"_npmVersion": "2.15.8",
"_nodeVersion": "4.4.7",
"_npmVersion": "4.2.0",
"_nodeVersion": "7.8.0",
"_npmUser": {

@@ -62,4 +64,4 @@ "name": "juliangruber",

"dist": {
"shasum": "7197d7eaa9b87e648390ea61fc66c84427420df9",
"tarball": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz"
"shasum": "3effc3c50e000531fb720eaff80f0ae8ef23cf59",
"tarball": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz"
},

@@ -77,8 +79,8 @@ "maintainers": [

"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/brace-expansion-1.1.6.tgz_1469047715600_0.9362958471756428"
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/brace-expansion-1.1.7.tgz_1491552830231_0.7213963181711733"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz",
"_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz",
"readme": "ERROR: No README data found!"
}

@@ -8,2 +8,3 @@ # brace-expansion

[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion)
[![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/)

@@ -10,0 +11,0 @@ [![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion)

{
"name": "rimraf",
"version": "2.5.4",
"version": "2.6.1",
"main": "rimraf.js",

@@ -33,5 +33,5 @@ "description": "A deep deletion module for node (like `rm -rf`)",

"mkdirp": "^0.5.1",
"tap": "^6.1.1"
"tap": "^10.1.2"
},
"gitHead": "2af08bbbd0a03549b278414309dc5d8097699443",
"gitHead": "d84fe2cc6646d30a401baadcee22ae105a2d4909",
"bugs": {

@@ -41,7 +41,7 @@ "url": "https://github.com/isaacs/rimraf/issues"

"homepage": "https://github.com/isaacs/rimraf#readme",
"_id": "rimraf@2.5.4",
"_shasum": "96800093cbf1a0c86bd95b4625467535c29dfa04",
"_id": "rimraf@2.6.1",
"_shasum": "c2338ec643df7a1b7fe5c54fa86f57428a55f33d",
"_from": "rimraf@>=2.0.0 <3.0.0",
"_npmVersion": "3.10.6",
"_nodeVersion": "4.4.4",
"_npmVersion": "4.3.0",
"_nodeVersion": "8.0.0-pre",
"_npmUser": {

@@ -52,4 +52,4 @@ "name": "isaacs",

"dist": {
"shasum": "96800093cbf1a0c86bd95b4625467535c29dfa04",
"tarball": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz"
"shasum": "c2338ec643df7a1b7fe5c54fa86f57428a55f33d",
"tarball": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz"
},

@@ -63,8 +63,8 @@ "maintainers": [

"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/rimraf-2.5.4.tgz_1469206941888_0.8645927573088557"
"host": "packages-18-east.internal.npmjs.com",
"tmp": "tmp/rimraf-2.6.1.tgz_1487908074285_0.8205490333493799"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz",
"_resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
"readme": "ERROR: No README data found!"
}

@@ -88,3 +88,3 @@ module.exports = rimraf

if (er) {
if (isWindows && (er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") &&
if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") &&
busyTries < options.maxBusyTries) {

@@ -314,2 +314,3 @@ busyTries ++

throw er
rmdirSync(p, options, er)

@@ -344,3 +345,22 @@ }

})
options.rmdirSync(p, options)
// We only end up here once we got ENOTEMPTY at least once, and
// at this point, we are guaranteed to have removed all the kids.
// So, we know that it won't be ENOENT or ENOTDIR or anything else.
// try really hard to delete stuff on windows, because it has a
// PROFOUNDLY annoying habit of not closing handles promptly when
// files are deleted, resulting in spurious ENOTEMPTY errors.
var retries = isWindows ? 100 : 1
var i = 0
do {
var threw = true
try {
var ret = options.rmdirSync(p, options)
threw = false
return ret
} finally {
if (++i < retries && threw)
continue
}
} while (true)
}

@@ -9,3 +9,3 @@ {

"description": "Advanced file system stream things",
"version": "1.0.10",
"version": "1.0.11",
"repository": {

@@ -33,3 +33,3 @@ "type": "git",

"license": "ISC",
"gitHead": "24fabdec32e334dd3b130d77b38c010e3119b102",
"gitHead": "1e4527ffe8688d4f5325283d7cf2cf2d61f14c6b",
"bugs": {

@@ -39,14 +39,14 @@ "url": "https://github.com/npm/fstream/issues"

"homepage": "https://github.com/npm/fstream#readme",
"_id": "fstream@1.0.10",
"_shasum": "604e8a92fe26ffd9f6fae30399d4984e1ab22822",
"_id": "fstream@1.0.11",
"_shasum": "5c1fb1f117477114f0632a0eb4b71b3cb0fd3171",
"_from": "fstream@>=1.0.2 <2.0.0",
"_npmVersion": "3.10.0",
"_nodeVersion": "4.4.5",
"_npmVersion": "4.1.2",
"_nodeVersion": "7.7.1",
"_npmUser": {
"name": "othiym23",
"email": "ogd@aoaioxxysz.net"
"name": "zkat",
"email": "kat@sykosomatic.org"
},
"dist": {
"shasum": "604e8a92fe26ffd9f6fae30399d4984e1ab22822",
"tarball": "https://registry.npmjs.org/fstream/-/fstream-1.0.10.tgz"
"shasum": "5c1fb1f117477114f0632a0eb4b71b3cb0fd3171",
"tarball": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz"
},

@@ -72,8 +72,8 @@ "maintainers": [

"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/fstream-1.0.10.tgz_1466189553883_0.3062701092567295"
"host": "packages-18-east.internal.npmjs.com",
"tmp": "tmp/fstream-1.0.11.tgz_1488923219641_0.18055859790183604"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.10.tgz",
"_resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
"readme": "ERROR: No README data found!"
}
{
"name": "appmetrics",
"version": "2.0.1",
"version": "3.0.0",
"engines": { "node": ">=4" },
"description": "Node Application Metrics",

@@ -18,7 +19,8 @@ "bin": {

"node-gyp": "3.x",
"semver": "^5.3.0",
"tap": "7.x"
},
"scripts": {
"test": "tap --reporter tap --timeout=120 tests/*tests.js tests/probes/http-outbound-probe-test.js tests/headless_test.js",
"install": "node extract_all_binaries.js"
"test": "tap --reporter tap --timeout=120 tests/*tests.js tests/probes/http-outbound-probe-test.js tests/probes/http-probe-test.js tests/headless_test.js",
"install": "node extract_all_binaries.js || node extract_all_binaries.js"
},

@@ -25,0 +27,0 @@ "directories": {

@@ -123,9 +123,11 @@ /*******************************************************************************

AxonProbe.prototype.metricsEnd = function(context, methodName, methodArgs, socketType) {
context.timer.stop();
// default to quality of service (qos) 0, as that's what the axon module does
if( isSendMethod(socketType) ) {
am.emit('axon', {time: context.timer.startTimeMillis, method: methodName, duration: context.timer.timeDelta, type: socketType})
} else {
am.emit('axon', {time: context.timer.startTimeMillis, event: methodName, duration: context.timer.timeDelta, type: socketType})
};
if(context && context.timer) {
context.timer.stop();
// default to quality of service (qos) 0, as that's what the axon module does
if( isSendMethod(socketType) ) {
am.emit('axon', {time: context.timer.startTimeMillis, method: methodName, duration: context.timer.timeDelta, type: socketType})
} else {
am.emit('axon', {time: context.timer.startTimeMillis, event: methodName, duration: context.timer.timeDelta, type: socketType})
};
}
};

@@ -138,5 +140,5 @@

if (methodName === 'message') {
context.req = request.startRequest('AXON', methodName, true, context.timer);
context.req = request.startRequest('axon', methodName, true, context.timer);
} else {
context.req = request.startRequest('AXON', methodName, false, context.timer);
context.req = request.startRequest('axon', methodName, false, context.timer);
}

@@ -146,5 +148,6 @@ };

AxonProbe.prototype.requestEnd = function (context, methodName, methodArgs) {
context.req.stop({topic: methodArgs[0]});
if(context && context.req)
context.req.stop({topic: methodArgs[0]});
};
module.exports = AxonProbe;
module.exports = AxonProbe;

@@ -107,21 +107,23 @@ /*******************************************************************************

RiakProbe.prototype.metricsEnd = function(probeData, method, methodArgs) {
probeData.timer.stop();
eventTimer = probeData.timer;
if(probeData && probeData.timer) {
probeData.timer.stop();
eventTimer = probeData.timer;
//Work out if options, command or query are needed. Defaults to just method
var jsonToEmit = {time: eventTimer.startTimeMillis, method: method, duration: eventTimer.timeDelta};
var key = '';
//Work out if options, command or query are needed. Defaults to just method
var jsonToEmit = {time: eventTimer.startTimeMillis, method: method, duration: eventTimer.timeDelta};
var key = '';
if (optionsAndCallbackMethods.indexOf(method) > -1) {
key = 'options';
} else if (commandMethods.indexOf(method) > -1) {
key = 'command';
} else if (queryMethods.indexOf(method) > -1) {
key = 'query';
}
if (optionsAndCallbackMethods.indexOf(method) > -1) {
key = 'options';
} else if (commandMethods.indexOf(method) > -1) {
key = 'command';
} else if (queryMethods.indexOf(method) > -1) {
key = 'query';
}
if (key != '') {
jsonToEmit[key] = methodArgs[0];
if (key != '') {
jsonToEmit[key] = methodArgs[0];
}
am.emit('riak', jsonToEmit);
}
am.emit('riak', jsonToEmit);
};

@@ -133,9 +135,10 @@

RiakProbe.prototype.requestStart = function (probeData, method, methodArgs) {
probeData.req = request.startRequest( 'DB', 'query', false, probeData.timer );
probeData.req = request.startRequest( 'basho-riak-client', 'query', false, probeData.timer );
};
RiakProbe.prototype.requestEnd = function (probeData, method, methodArgs) {
probeData.req.stop({method: method});
if(probeData && probeData.req)
probeData.req.stop({method: method});
};
module.exports = RiakProbe;
module.exports = RiakProbe;

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

var urlRequested= "";
var headers = "";
if(typeof options === 'object') {

@@ -51,2 +52,5 @@ urlRequested = formatURL(options)

}
if(options.headers) {
headers = options.headers;
}
} else if (typeof options === 'string') {

@@ -58,2 +62,5 @@ urlRequested = options;

}
if(parsedOptions.headers) {
headers = parsedOptions.headers;
}
}

@@ -68,4 +75,4 @@

methodArgs.statusCode = args[0].statusCode
that.metricsProbeEnd(probeData, requestMethod, urlRequested, args[0]);
that.requestProbeEnd(probeData, requestMethod, urlRequested, args[0]);
that.metricsProbeEnd(probeData, requestMethod, urlRequested, args[0], headers);
that.requestProbeEnd(probeData, requestMethod, urlRequested, args[0], headers);
}, function(target, args, probeData, ret) {

@@ -86,2 +93,3 @@ // Don't need to do anything after the callback

var urlRequested= "";
var headers = "";
if(typeof options === 'object') {

@@ -92,2 +100,5 @@ urlRequested = formatURL(options)

}
if(options.headers) {
headers = options.headers;
}
} else if (typeof options === 'string') {

@@ -99,7 +110,10 @@ urlRequested = options;

}
if(parsedOptions.headers) {
headers = parsedOptions.headers;
}
}
// End metrics (no response available so pass empty object)
that.metricsProbeEnd(probeData, requestMethod, urlRequested, {});
that.requestProbeEnd(probeData, requestMethod, urlRequested, {});
that.metricsProbeEnd(probeData, requestMethod, urlRequested, {}, headers);
that.requestProbeEnd(probeData, requestMethod, urlRequested, {}, headers);
}

@@ -148,13 +162,16 @@ return rc;

* These provide:
* time: time event started
* method: HTTP method, eg. GET, POST, etc
* url: The url requested
* duration: the time for the request to respond
* contentType: HTTP content-type
* statusCode: HTTP status code
* time: time event started
* method: HTTP method, eg. GET, POST, etc
* url: The url requested
* requestHeaders: The HTTP headers for the request
* duration: The time for the request to respond
* contentType: HTTP content-type
* statusCode: HTTP status code
*/
HttpOutboundProbe.prototype.metricsEnd = function(probeData, method, url, res) {
probeData.timer.stop();
am.emit('http-outbound', {time: probeData.timer.startTimeMillis, method: method, url: url,
duration: probeData.timer.timeDelta, statusCode: res.statusCode, contentType:res.headers?res.headers['content-type']:"undefined"});
HttpOutboundProbe.prototype.metricsEnd = function(probeData, method, url, res, headers) {
if(probeData && probeData.timer) {
probeData.timer.stop();
am.emit('http-outbound', {time: probeData.timer.startTimeMillis, method: method, url: url,
duration: probeData.timer.timeDelta, statusCode: res.statusCode, contentType:res.headers?res.headers['content-type']:"undefined", requestHeaders: headers});
}
};

@@ -166,3 +183,3 @@

HttpOutboundProbe.prototype.requestStart = function (probeData, method, url) {
var reqType = 'HTTP Outbound';
var reqType = 'http-outbound';
// Do not mark as a root request

@@ -172,4 +189,5 @@ probeData.req = request.startRequest(reqType, url, false, probeData.timer);

HttpOutboundProbe.prototype.requestEnd = function (probeData, method, url, res) {
probeData.req.stop({url: url, statusCode: res.statusCode, contentType:res.headers?res.headers['content-type']:"undefined"});
HttpOutboundProbe.prototype.requestEnd = function (probeData, method, url, res, headers) {
if(probeData && probeData.req)
probeData.req.stop({url: url, statusCode: res.statusCode, contentType:res.headers?res.headers['content-type']:"undefined", requestHeaders: headers});
};

@@ -176,0 +194,0 @@

@@ -52,4 +52,4 @@ /*******************************************************************************

aspect.after(res, 'end', probeData, function(obj, methodName, args, probeData, ret) {
that.metricsProbeEnd(probeData, httpReq.method, traceUrl, res);
that.requestProbeEnd(probeData, httpReq.method, traceUrl);
that.metricsProbeEnd(probeData, httpReq.method, traceUrl, res, httpReq);
that.requestProbeEnd(probeData, httpReq.method, traceUrl, res, httpReq);
});

@@ -102,5 +102,7 @@ }

HttpProbe.prototype.metricsEnd = function(probeData, method, url, res) {
probeData.timer.stop();
am.emit('http', {time: probeData.timer.startTimeMillis, method: method, url: url, duration: probeData.timer.timeDelta, header: res._header, statusCode: res.statusCode, contentType: res.getHeader('content-type')});
HttpProbe.prototype.metricsEnd = function(probeData, method, url, res, httpReq) {
if(probeData && probeData.timer) {
probeData.timer.stop();
am.emit('http', {time: probeData.timer.startTimeMillis, method: method, url: url, duration: probeData.timer.timeDelta, header: res._header, statusCode: res.statusCode, contentType: res.getHeader('content-type'), requestHeader: httpReq.headers});
}
};

@@ -113,3 +115,3 @@

HttpProbe.prototype.requestStart = function (probeData, method, url) {
var reqType = 'HTTP';
var reqType = 'http';
// Mark as a root request as this happens due to an external event

@@ -119,6 +121,7 @@ probeData.req = request.startRequest(reqType, url, true, probeData.timer);

HttpProbe.prototype.requestEnd = function (probeData, method, url) {
probeData.req.stop({url: url });
HttpProbe.prototype.requestEnd = function (probeData, method, url, res, httpReq) {
if(probeData && probeData.req)
probeData.req.stop({url: url, method: method, requestHeader: httpReq.headers, statusCode: res.statusCode, header: res._header, contentType: res.getHeader('content-type')});
};
/*

@@ -142,2 +145,2 @@ * Set configuration by merging passed in config with current one

module.exports = HttpProbe;
module.exports = HttpProbe;

@@ -82,12 +82,14 @@ /*******************************************************************************

LeveldownProbe.prototype.metricsEnd = function(probeData, method, methodArgs) {
probeData.timer.stop();
if (method == 'put'){
am.emit('leveldown', {time: probeData.timer.startTimeMillis, method: method, key: methodArgs[0], value: methodArgs[1], duration: probeData.timer.timeDelta});
}
else if (method == 'del' || method == 'get'){
am.emit('leveldown', {time: probeData.timer.startTimeMillis, method: method, key: methodArgs[0], duration: probeData.timer.timeDelta});
}
else if(method == 'batch'){
am.emit('leveldown', {time: probeData.timer.startTimeMillis, method: method, opCount: methodArgs[0].length, duration: probeData.timer.timeDelta});
}
if(probeData && probeData.timer) {
probeData.timer.stop();
if (method == 'put'){
am.emit('leveldown', {time: probeData.timer.startTimeMillis, method: method, key: methodArgs[0], value: methodArgs[1], duration: probeData.timer.timeDelta});
}
else if (method == 'del' || method == 'get'){
am.emit('leveldown', {time: probeData.timer.startTimeMillis, method: method, key: methodArgs[0], duration: probeData.timer.timeDelta});
}
else if(method == 'batch'){
am.emit('leveldown', {time: probeData.timer.startTimeMillis, method: method, opCount: methodArgs[0].length, duration: probeData.timer.timeDelta});
}
}
};

@@ -99,3 +101,3 @@

LeveldownProbe.prototype.requestStart = function (probeData, dbTarget, method, methodArgs) {
req = request.startRequest( 'DB', "query" );
req = request.startRequest( 'leveldown', "query" );
req.setContext({leveldown: methodArgs[0]});

@@ -105,5 +107,6 @@ };

LeveldownProbe.prototype.requestEnd = function (probeData, method, methodArgs) {
req.stop({leveldown: methodArgs[0]});
if(probeData && probeData.req)
req.stop({leveldown: methodArgs[0]});
};
module.exports = LeveldownProbe;
module.exports = LeveldownProbe;

@@ -75,5 +75,7 @@ /*******************************************************************************

loopbackDJProbe.prototype.metricsEnd = function(probeData, method, methodArgs) {
probeData.timer.stop();
eventTimer = probeData.timer;
am.emit('loopback-datasource-juggler', {time: eventTimer.startTimeMillis, method: method, duration: eventTimer.timeDelta});
if(probeData && probeData.timer) {
probeData.timer.stop();
eventTimer = probeData.timer;
am.emit('loopback-datasource-juggler', {time: eventTimer.startTimeMillis, method: method, duration: eventTimer.timeDelta});
}
}

@@ -85,11 +87,11 @@

loopbackDJProbe.prototype.requestStart = function (probeData, target, method, methodArgs) {
req = request.startRequest( 'DB', "query" );
req.setContext({loopbackDJProbe: methodArgs[0]});
probeData.req = request.startRequest( 'loopback', "query" );
probeData.req.setContext({loopbackDJProbe: methodArgs[0]});
};
loopbackDJProbe.prototype.requestEnd = function (probeData, method, methodArgs) {
console.log("requestEnd called");
req.stop({loopbackDJProbe: methodArgs[0]});
if(probeData && probeData.req)
probeData.req.stop({loopbackDJProbe: methodArgs[0]});
};
module.exports = loopbackDJProbe;
module.exports = loopbackDJProbe;

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

MemcachedProbe.prototype.metricsEnd = function(context, method, methodArgs) {
context.timer.stop();
am.emit('memcached', {time: context.timer.startTimeMillis, method: method, key: methodArgs[0], duration: context.timer.timeDelta});
if(context && context.timer) {
context.timer.stop();
am.emit('memcached', {time: context.timer.startTimeMillis, method: method, key: methodArgs[0], duration: context.timer.timeDelta});
}
};

@@ -98,9 +100,10 @@

MemcachedProbe.prototype.requestStart = function (context, methodName, methodArgs) {
context.req = request.startRequest( 'Memcached', methodName, false, context.timer);
context.req = request.startRequest( 'memcached', methodName, false, context.timer);
};
MemcachedProbe.prototype.requestEnd = function (context, methodName, methodArgs) {
context.req.stop({key: methodArgs[0]});
if(context && context.req)
context.req.stop({key: methodArgs[0]});
};
module.exports = MemcachedProbe;
module.exports = MemcachedProbe;

@@ -117,5 +117,7 @@ /*******************************************************************************

MongoProbe.prototype.metricsEnd = function(probeData, collectionName, method, methodArgs) {
probeData.timer.stop();
am.emit('mongo', {time: probeData.timer.startTimeMillis, query: JSON.stringify(methodArgs[0]), duration: probeData.timer.timeDelta,
method: method, collection: collectionName});
if(probeData && probeData.timer) {
probeData.timer.stop();
am.emit('mongo', {time: probeData.timer.startTimeMillis, query: JSON.stringify(methodArgs[0]), duration: probeData.timer.timeDelta,
method: method, collection: collectionName});
}
};

@@ -127,9 +129,10 @@

MongoProbe.prototype.requestStart = function (probeData, target, method, methodArgs) {
probeData.req = request.startRequest( 'DB', method + "("+target.collectionName+")", false, probeData.timer );
probeData.req = request.startRequest( 'mongo', method + "("+target.collectionName+")", false, probeData.timer );
};
MongoProbe.prototype.requestEnd = function (probeData, method, methodArgs) {
probeData.req.stop( { query: JSON.stringify(methodArgs[0]) } );
if(probeData && probeData.req)
probeData.req.stop( { query: JSON.stringify(methodArgs[0]) } );
};
module.exports = MongoProbe;

@@ -102,38 +102,40 @@ /*******************************************************************************

MQLightProbe.prototype.metricsEnd = function(probeData, method, methodArgs, client) {
probeData.timer.stop();
if(method == 'message') {
var data = methodArgs[0];
if(data.length > 25) {
data = data.substring(0, 22) + "...";
}
var topic = methodArgs[1].message.topic;
am.emit('mqlight', {
time : probeData.timer.startTimeMillis,
clientid : client.id,
data : data,
method : method,
topic : topic,
duration : probeData.timer.timeDelta
});
} else if(method == 'send') {
var data = methodArgs[1];
if(data.length > 25) {
data = data.substring(0, 22) + "...";
}
var qos;
var options; // options are optional - check number of arguments.
if(methodArgs.length > 3) {
options = methodArgs[2];
qos = options[0];
}
am.emit('mqlight', {
time : probeData.timer.startTimeMillis,
clientid : client.id,
data : data,
method : method,
topic : methodArgs[0],
qos : qos,
duration : probeData.timer.timeDelta
});
}
if(probeData && probeData.timer) {
probeData.timer.stop();
if(method == 'message') {
var data = methodArgs[0];
if(data.length > 25) {
data = data.substring(0, 22) + "...";
}
var topic = methodArgs[1].message.topic;
am.emit('mqlight', {
time : probeData.timer.startTimeMillis,
clientid : client.id,
data : data,
method : method,
topic : topic,
duration : probeData.timer.timeDelta
});
} else if(method == 'send') {
var data = methodArgs[1];
if(data.length > 25) {
data = data.substring(0, 22) + "...";
}
var qos;
var options; // options are optional - check number of arguments.
if(methodArgs.length > 3) {
options = methodArgs[2];
qos = options[0];
}
am.emit('mqlight', {
time : probeData.timer.startTimeMillis,
clientid : client.id,
data : data,
method : method,
topic : methodArgs[0],
qos : qos,
duration : probeData.timer.timeDelta
});
}
}
};

@@ -146,5 +148,5 @@

if(method == 'message') {
probeData.req = request.startRequest('MQLight', method, true, probeData.timer);
probeData.req = request.startRequest('mqlight', method, true, probeData.timer);
} else {
probeData.req = request.startRequest('MQLight', method, false, probeData.timer);
probeData.req = request.startRequest('mqlight', method, false, probeData.timer);
}

@@ -154,24 +156,26 @@ };

MQLightProbe.prototype.requestEnd = function (probeData, method, methodArgs, client) {
if(method == 'message') {
var data = methodArgs[0];
if(data.length > 25) {
data = data.substring(0, 22) + "...";
}
var topic = methodArgs[1].message.topic;
probeData.req.stop({clientid: client.id, data: data, method: method, topic: methodArgs[0]});
} else if(method == 'send') {
var data = methodArgs[1];
if(data.length > 25) {
data = data.substring(0, 22) + "...";
}
var qos;
var options; // options are optional - check number of arguments.
if(methodArgs.length > 3) {
options = methodArgs[2];
qos = options[0];
}
probeData.req.stop({clientid: client.id, data: data, method: method, topic: methodArgs[0], qos: qos});
}
if(probeData && probeData.req) {
if(method == 'message') {
var data = methodArgs[0];
if(data.length > 25) {
data = data.substring(0, 22) + "...";
}
var topic = methodArgs[1].message.topic;
probeData.req.stop({clientid: client.id, data: data, method: method, topic: methodArgs[0]});
} else if(method == 'send') {
var data = methodArgs[1];
if(data.length > 25) {
data = data.substring(0, 22) + "...";
}
var qos;
var options; // options are optional - check number of arguments.
if(methodArgs.length > 3) {
options = methodArgs[2];
qos = options[0];
}
probeData.req.stop({clientid: client.id, data: data, method: method, topic: methodArgs[0], qos: qos});
}
}
};
module.exports = MQLightProbe;
module.exports = MQLightProbe;

@@ -104,9 +104,11 @@ /*******************************************************************************

MqttProbe.prototype.metricsEnd = function(context, methodName, methodArgs) {
context.timer.stop();
// default to quality of service (qos) 0, as that's what the mqtt module does
var qos = 0;
if (methodArgs[2] && (typeof(methodArgs[2]) !== 'function')) {
qos = methodArgs[2].qos;
}
am.emit('mqtt', {time: context.timer.startTimeMillis, method: methodName, topic: methodArgs[0], qos: qos, duration: context.timer.timeDelta});
if(context && context.timer) {
context.timer.stop();
// default to quality of service (qos) 0, as that's what the mqtt module does
var qos = 0;
if (methodArgs[2] && (typeof(methodArgs[2]) !== 'function')) {
qos = methodArgs[2].qos;
}
am.emit('mqtt', {time: context.timer.startTimeMillis, method: methodName, topic: methodArgs[0], qos: qos, duration: context.timer.timeDelta});
}
};

@@ -119,5 +121,5 @@

if (methodName === 'message') {
context.req = request.startRequest('MQTT', methodName, true, context.timer);
context.req = request.startRequest('mqtt', methodName, true, context.timer);
} else {
context.req = request.startRequest('MQTT', methodName, false, context.timer);
context.req = request.startRequest('mqtt', methodName, false, context.timer);
}

@@ -127,9 +129,11 @@ };

MqttProbe.prototype.requestEnd = function (context, methodName, methodArgs) {
var qos = 0;
if (methodArgs[2] && (typeof(methodArgs[2]) !== 'function')) {
qos = methodArgs[2].qos;
}
context.req.stop({topic: methodArgs[0], qos: qos});
if(context && context.req) {
var qos = 0;
if (methodArgs[2] && (typeof(methodArgs[2]) !== 'function')) {
qos = methodArgs[2].qos;
}
context.req.stop({topic: methodArgs[0], qos: qos});
}
};
module.exports = MqttProbe;
module.exports = MqttProbe;

@@ -68,5 +68,7 @@ /*******************************************************************************

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});
if(probeData && probeData.timer) {
probeData.timer.stop();
eventTimer = probeData.timer;
am.emit('mysql', {time: eventTimer.startTimeMillis, query: JSON.stringify(methodArgs[0]), duration: eventTimer.timeDelta});
}
};

@@ -78,9 +80,10 @@

MySqlProbe.prototype.requestStart = function (probeData, method, methodArgs) {
probeData.req = request.startRequest( 'DB', "query", false, probeData.timer );
probeData.req = request.startRequest( 'mysql', "query", false, probeData.timer );
};
MySqlProbe.prototype.requestEnd = function (probeData, method, methodArgs) {
probeData.req.stop({sql: JSON.stringify(methodArgs[0])});
if(probeData && probeData.req)
probeData.req.stop({sql: JSON.stringify(methodArgs[0])});
};
module.exports = MySqlProbe;
module.exports = MySqlProbe;

@@ -92,9 +92,11 @@ /*******************************************************************************

OracleProbe.prototype.metricsEnd = function(probeData, method, methodArgs) {
probeData.timer.stop();
var query = methodArgs[0];
am.emit('oracle', {
time : probeData.timer.startTimeMillis,
query : query,
duration : probeData.timer.timeDelta
});
if(probeData && probeData.timer) {
probeData.timer.stop();
var query = methodArgs[0];
am.emit('oracle', {
time : probeData.timer.startTimeMillis,
query : query,
duration : probeData.timer.timeDelta
});
}
};

@@ -106,10 +108,11 @@

OracleProbe.prototype.requestStart = function (probeData, method, methodArgs) {
probeData.req = request.startRequest('Oracle', method, false, probeData.timer);
probeData.req = request.startRequest('oracle', method, false, probeData.timer);
};
OracleProbe.prototype.requestEnd = function (probeData, method, methodArgs) {
var query = methodArgs[0];
probeData.req.stop({query:query});
if(probeData && probeData.req)
var query = methodArgs[0];
probeData.req.stop({query:query});
};
module.exports = OracleProbe;
module.exports = OracleProbe;

@@ -109,9 +109,11 @@ /*******************************************************************************

OracleDBProbe.prototype.metricsEnd = function(probeData, method, methodArgs) {
probeData.timer.stop();
var query = methodArgs[0];
am.emit('oracledb', {
time : probeData.timer.startTimeMillis,
query : query,
duration : probeData.timer.timeDelta
});
if(probeData && probeData.timer) {
probeData.timer.stop();
var query = methodArgs[0];
am.emit('oracledb', {
time : probeData.timer.startTimeMillis,
query : query,
duration : probeData.timer.timeDelta
});
}
};

@@ -123,10 +125,12 @@

OracleDBProbe.prototype.requestStart = function (probeData, method, methodArgs) {
probeData.req = request.startRequest('OracleDB', method, false, probeData.timer);
probeData.req = request.startRequest('oracledb', method, false, probeData.timer);
};
OracleDBProbe.prototype.requestEnd = function (probeData, method, methodArgs) {
var query = methodArgs[0];
probeData.req.stop({query:query});
if(probeData && probeData.req) {
var query = methodArgs[0];
probeData.req.stop({query:query});
}
};
module.exports = OracleDBProbe;

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

PostgresProbe.prototype.metricsEnd = function(probeData, method, methodArgs) {
probeData.timer.stop();
am.emit('postgres', {time: probeData.timer.startTimeMillis, query: methodArgs[0], duration: probeData.timer.timeDelta});
if(probeData && probeData.timer) {
probeData.timer.stop();
am.emit('postgres', {time: probeData.timer.startTimeMillis, query: methodArgs[0], duration: probeData.timer.timeDelta});
}
};

@@ -125,3 +127,3 @@

PostgresProbe.prototype.requestStart = function (probeData, target, method, methodArgs) {
probeData.req = request.startRequest( 'DB', "query", false, probeData.timer );
probeData.req = request.startRequest( 'postgres', "query", false, probeData.timer );
probeData.req.setContext({sql: methodArgs[0]});

@@ -131,5 +133,6 @@ };

PostgresProbe.prototype.requestEnd = function (probeData, method, methodArgs) {
probeData.req.stop({sql: methodArgs[0]});
if(probeData && probeData.req)
probeData.req.stop({sql: methodArgs[0]});
};
module.exports = PostgresProbe;
module.exports = PostgresProbe;

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

RedisProbe.prototype.metricsEnd = function(probeData, cmd, methodArgs) {
probeData.timer.stop();
am.emit('redis', {time: probeData.timer.startTimeMillis, cmd: cmd, duration: probeData.timer.timeDelta});
if(probeData && probeData.timer) {
probeData.timer.stop();
am.emit('redis', {time: probeData.timer.startTimeMillis, cmd: cmd, duration: probeData.timer.timeDelta});
}
};

@@ -156,7 +158,9 @@

RedisProbe.prototype.requestEnd = function (probeData, cmd, methodArgs) {
var context = {};
context.cmd = cmd;
probeData.req.stop(context);
if(probeData && probeData.req) {
var context = {};
context.cmd = cmd;
probeData.req.stop(context);
}
};
module.exports = RedisProbe;

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

SocketioProbe.prototype.metricsEnd = function(context, methodName, methodArgs) {
context.timer.stop();
am.emit('socketio', {time: context.timer.startTimeMillis, method: methodName, event: methodArgs[0], duration: context.timer.timeDelta});
if(context && context.timer) {
context.timer.stop();
am.emit('socketio', {time: context.timer.startTimeMillis, method: methodName, event: methodArgs[0], duration: context.timer.timeDelta});
}
};

@@ -158,5 +160,6 @@

SocketioProbe.prototype.requestEnd = function (context, methodName, methodArgs) {
context.req.stop({method: methodName, event: methodArgs[0]});
if(context && context.req)
context.req.stop({method: methodName, event: methodArgs[0]});
};
module.exports = SocketioProbe;

@@ -120,11 +120,13 @@ /*******************************************************************************

Strong_MQProbe.prototype.metricsEnd = function(context, methodName, methodArgs, eventType) {
context.timer.stop();
// default to quality of service (qos) 0, as that's what the strong-mq module does
var eventData ={time: context.timer.startTimeMillis, duration: context.timer.timeDelta, type: eventType}
if( methodName == 'publish') {
eventData.method = methodName;
} else {
eventData.event = 'message';
}
am.emit('strong-mq', eventData);
if(context && context.timer) {
context.timer.stop();
// default to quality of service (qos) 0, as that's what the strong-mq module does
var eventData ={time: context.timer.startTimeMillis, duration: context.timer.timeDelta, type: eventType}
if( methodName == 'publish') {
eventData.method = methodName;
} else {
eventData.event = 'message';
}
am.emit('strong-mq', eventData);
}
};

@@ -137,6 +139,6 @@

if (methodName === 'publish') {
context.req = request.startRequest('STRONG-MQ', methodName, false, context.timer);
context.req = request.startRequest('strong-mq', methodName, false, context.timer);
} else {
/* Received messages mark the start of requests. */
context.req = request.startRequest('STRONG-MQ', 'message', true, context.timer);
context.req = request.startRequest('strong-mq', 'message', true, context.timer);
}

@@ -146,5 +148,6 @@ };

Strong_MQProbe.prototype.requestEnd = function (context, methodName, methodArgs, socketType) {
context.req.stop({topic: methodArgs[0]});
if(context && context.req)
context.req.stop({topic: methodArgs[0]});
};
module.exports = Strong_MQProbe;
module.exports = Strong_MQProbe;

@@ -94,9 +94,11 @@ /*******************************************************************************

StrongOracleProbe.prototype.metricsEnd = function(probeData, method, methodArgs) {
probeData.timer.stop();
var query = methodArgs[0];
am.emit('strong-oracle', {
time : probeData.timer.startTimeMillis,
query : query,
duration : probeData.timer.timeDelta
});
if(probeData && probeData.timer) {
probeData.timer.stop();
var query = methodArgs[0];
am.emit('strong-oracle', {
time : probeData.timer.startTimeMillis,
query : query,
duration : probeData.timer.timeDelta
});
}
};

@@ -108,10 +110,12 @@

StrongOracleProbe.prototype.requestStart = function (probeData, method, methodArgs) {
probeData.req = request.startRequest('StrongOracle', method, false, probeData.timer);
probeData.req = request.startRequest('strong-oracle', method, false, probeData.timer);
};
StrongOracleProbe.prototype.requestEnd = function (probeData, method, methodArgs) {
var query = methodArgs[0];
probeData.req.stop({query:query});
if(probeData && probeData.req) {
var query = methodArgs[0];
probeData.req.stop({query:query});
}
};
module.exports = StrongOracleProbe;
module.exports = StrongOracleProbe;

@@ -20,3 +20,2 @@ # Node Application Metrics

Event Loop | Event loop latency information
Express | Express 4.x Web Framework application request monitoring
Loop | Event loop timing metrics

@@ -65,7 +64,7 @@ Function profiling | Node/V8 function profiling (disabled by default)

<a name="install"></a>
### Installation
Node Application Metrics can be installed using **npm** either locally or globally.
**When installed locally** you can access monitoring data via both the API and the Health Center client by modifying your application to use appmetrics (see *[Modifying your application to use the local installation](#run-local)*).
**When installed locally** you can access monitoring data via both the API and the Health Center client by modifying your application to use appmetrics (see *[Modifying your application to use the local installation](#modifying-your-application-to-use-the-local-installation)*).

@@ -78,3 +77,3 @@ To perform a local install:

**When installed globally** you can access monitoring data via the Health Center client (but not the API) by using the `node-hc` command-line utility (see *[The `node-hc` command](#run-global)*).
**When installed globally** you can access monitoring data via the Health Center client (but not the API) by using the `node-hc` command-line utility (see *[The `node-hc` command](#the-node-hc-command)*).

@@ -101,3 +100,2 @@ To perform a global install:

<a name="config"></a>
### Configuring Node Application Metrics

@@ -107,3 +105,3 @@

Node Application Metrics comes with a configuration file inside the [module installation directory](#install) (`.../node_modules/appmetrics/appmetrics.properties`). This can be used to configure connection options, logging and data source options.
Node Application Metrics comes with a configuration file inside the [module installation directory](#installation) (`.../node_modules/appmetrics/appmetrics.properties`). This can be used to configure connection options, logging and data source options.

@@ -126,5 +124,5 @@ Node Application Metrics will attempt to load `appmetrics.properties` from one of the following locations (in order):

## Running Node Application Metrics
<a name="run-global"></a>
### The `node-hc` command
If you [globally installed](#install) this module with npm, you can use the `node-hc` command to run your application instead of the `node` command. This will run your application as it would normally under node (including any node options) but additionally load and start `appmetrics`.
If you [globally installed](#installation) this module with npm, you can use the `node-hc` command to run your application instead of the `node` command. This will run your application as it would normally under node (including any node options) but additionally load and start `appmetrics`.

@@ -137,5 +135,4 @@ ```sh

<a name="run-local"></a>
### Modifying your application to use the local installation
If you [locally install](#install) this module with npm then you will additionally have access to the monitoring data via the `appmetrics` API (see *[API Documentation](#api-doc)*).
If you [locally install](#installation) this module with npm then you will additionally have access to the monitoring data via the `appmetrics` API (see *[API Documentation](#api-documentation)*).

@@ -173,7 +170,6 @@ To load `appmetrics` and get the monitoring API object, add the following to the start-up code for your application:

Note that both the API and the Health Center client can be used at the same time and will receive the same data. Use of the API requires a local install and application modification (see *[Modifying your application to use the local installation](#run-local)*).
Note that both the API and the Health Center client can be used at the same time and will receive the same data. Use of the API requires a local install and application modification (see *[Modifying your application to use the local installation](#modifying-your-application-to-use-the-local-installation)*).
Further information regarding the use of the Health Center client with Node Application Metrics can be found on the [appmetrics wiki][3]: [Using Node Application Metrics with the Health Center client](https://github.com/RuntimeTools/appmetrics/wiki/Using-Node-Application-Metrics-with-the-Health-Center-client).
<a name="api-doc"></a>
## API Documentation

@@ -200,5 +196,5 @@ ### appmetrics.configure(options)

### appmetrics.enable(`type`, `config`)
Enable data generation of the specified data type.
* `type` (String) the type of event to start generating data for. Values of `eventloop`, `express`, `profiling`, `http`, `http-outbound`, `mongo`, `socketio`, `mqlight`, `postgresql`, `mqtt`, `mysql`, `redis`, `riak`, `memcached`, `oracledb`, `oracle`, `strong-oracle`, `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.
Enable data generation of the specified data type. Cannot be called until the agent has been started by calling `start()` or `monitor()`.
* `type` (String) the type of event to start generating data for. Values of `eventloop`, `profiling`, `http`, `http-outbound`, `mongo`, `socketio`, `mqlight`, `postgresql`, `mqtt`, `mysql`, `redis`, `riak`, `memcached`, `oracledb`, `oracle`, `strong-oracle`, `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](#appmetricssetconfigtype-config)*) for more information.

@@ -208,6 +204,5 @@ The following data types are disabled by default: `profiling`, `requests`, `trace`

### appmetrics.disable(`type`)
Disable data generation of the specified data type.
* `type` (String) the type of event to stop generating data for. Values of `eventloop`, `express`, `profiling`, `http`, `mongo`, `socketio`, `mqlight`, `postgresql`, `mqtt`, `mysql`, `redis`, `riak`, `memcached`, `oracledb`, `oracle`, `strong-oracle`, `requests` and `trace` are currently supported.
Disable data generation of the specified data type. Cannot be called until the agent has been started by calling `start()` or `monitor()`.
* `type` (String) the type of event to stop generating data for. Values of `eventloop`, `profiling`, `http`, `mongo`, `socketio`, `mqlight`, `postgresql`, `mqtt`, `mysql`, `redis`, `riak`, `memcached`, `oracledb`, `oracle`, `strong-oracle`, `requests` and `trace` are currently supported.
<a name="set-config"></a>
### appmetrics.setConfig(`type`, `config`)

@@ -249,16 +244,10 @@ Set the configuration to be applied to a specific data type. The configuration available is specific to the data type.

### Event: 'memory'
Emitted when a memory monitoring sample is taken.
* `data` (Object) the data from the memory sample:
* `time` (Number) the milliseconds when the sample was taken. This can be converted to a Date using `new Date(data.time)`.
* `physical_total` (Number) the total amount of RAM available on the system in bytes.
* `physical_used` (Number) the total amount of RAM in use on the system in bytes.
* `physical_free` (Number) the total amount of free RAM available on the system in bytes.
* `virtual` (Number) the memory address space used by the Node.js application in bytes.
* `private` (Number) the amount of memory used by the Node.js application that cannot be shared with other processes, in bytes.
* `physical` (Number) the amount of RAM used by the Node.js application in bytes.
### 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: 'initialized'
Emitted when all possible environment variables have been collected. Use `appmetrics.monitor.getEnvironment()` to access the available environment variables.
### Event: 'gc'

@@ -273,9 +262,4 @@ Emitted when a garbage collection (GC) cycle occurs in the underlying V8 runtime.

### 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: 'initialized'
Emitted when all possible environment variables have been collected. Use `appmetrics.monitor.getEnvironment()` to access the available environment variables.

@@ -290,2 +274,13 @@ ### Event: 'loop'

### Event: 'memory'
Emitted when a memory monitoring sample is taken.
* `data` (Object) the data from the memory sample:
* `time` (Number) the milliseconds when the sample was taken. This can be converted to a Date using `new Date(data.time)`.
* `physical_total` (Number) the total amount of RAM available on the system in bytes.
* `physical_used` (Number) the total amount of RAM in use on the system in bytes.
* `physical_free` (Number) the total amount of free RAM available on the system in bytes.
* `virtual` (Number) the memory address space used by the Node.js application in bytes.
* `private` (Number) the amount of memory used by the Node.js application that cannot be shared with other processes, in bytes.
* `physical` (Number) the amount of RAM used by the Node.js application in bytes.
### Event: 'profiling'

@@ -303,2 +298,4 @@ Emitted when a profiling sample is available from the underlying V8 runtime.

## API: Dependency Events (probes)
### Event: 'http'

@@ -311,4 +308,5 @@ Emitted when a HTTP request is made of the application.

* `duration` (Number) the time taken for the HTTP request to be responded to in ms.
* `header` (String) the header for the HTTP request.
* `header` (String) the response header for the HTTP request.
* `contentType` (String) the content type of the HTTP request.
* `requestHeader` (Object) the request header for HTTP request.

@@ -324,17 +322,21 @@ ### Event: 'http-outbound'

* `duration` (Number) the time taken for the HTTP request to be responded to in ms.
* 'requestHeaders' (Object) the HTTP request headers.
### 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.
### 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: 'mysql'
Emitted when a MySQL query is made using the `mysql` module.
* `data` (Object) the data from the MySQL query:
* `time` (Number) the milliseconds when the MySQL query was made. This can be converted to a Date using `new Date(data.time)`.
* `query` (String) the query made of the MySQL database.
* `duration` (Number) the time taken for the MySQL query to be responded to in ms.
### 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.

@@ -350,11 +352,2 @@ ### Event: 'mongo'

### 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'

@@ -371,12 +364,39 @@ Emitted when a MQLight message is sent or received.

### 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: '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: 'mysql'
Emitted when a MySQL query is made using the `mysql` module.
* `data` (Object) the data from the MySQL query:
* `time` (Number) the milliseconds when the MySQL query was made. This can be converted to a Date using `new Date(data.time)`.
* `query` (String) the query made of the MySQL database.
* `duration` (Number) the time taken for the MySQL query to be responded to in ms.
### Event: 'oracle'
Emitted when a query is executed using the `oracle` module.
* `data` (Object) the data from the Oracle query:
* `time` (Number) the milliseconds when the Oracle query was made. This can be converted to a Date using `new Date(data.time)`.
* `query` (String) the query made of the Oracle database.
* `duration` (Number) the time taken for the Oracle query to be responded to in ms.
### Event: 'oracledb'
Emitted when a query is executed using the `oracledb` module.
* `data` (Object) the data from the OracleDB query:
* `time` (Number) the milliseconds when the OracleDB query was made. This can be converted to a Date using `new Date(data.time)`.
* `query` (String) the query made of the OracleDB database.
* `duration` (Number) the time taken for the OracleDB query to be responded to 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.
### Event: 'redis'

@@ -399,24 +419,10 @@ Emitted when a Redis command is sent.

### 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: '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.
### Event: 'oracledb'
Emitted when a query is executed using the `oracledb` module.
* `data` (Object) the data from the OracleDB query:
* `time` (Number) the milliseconds when the OracleDB query was made. This can be converted to a Date using `new Date(data.time)`.
* `query` (String) the query made of the OracleDB database.
* `duration` (Number) the time taken for the OracleDB query to be responded to in ms.
### Event: 'oracle'
Emitted when a query is executed using the `oracle` module.
* `data` (Object) the data from the Oracle query:
* `time` (Number) the milliseconds when the Oracle query was made. This can be converted to a Date using `new Date(data.time)`.
* `query` (String) the query made of the Oracle database.
* `duration` (Number) the time taken for the Oracle query to be responded to in ms.
### Event: 'strong-oracle'

@@ -428,13 +434,15 @@ Emitted when a query is executed using the `strong-oracle` module.

* `duration` (Number) the time taken for the Strong Oracle query to be responded to in ms.
## API: Requests
### Event: 'request'
Emitted when a request is made of the application that involves one or more monitored application level events. Request events are disabled by default.
Requests are a special type of event emitted by appmetrics. All the probes named above can also create request events if requests are enabled. Howver requests are nested within a root incoming request (usually http). Request events are disabled by default.
* `data` (Object) the data from the request:
* `time` (Number) the milliseconds when the request occurred. This can be converted to a Date using `new Date(data.time)`.
* `type` (String) The type of the request event. This can currently be set to 'HTTP' or 'DB'.
* `type` (String) The type of the request event. This is the name of the probe that sent the request data, e.g. `http`, `socketio` etc.
* `name` (String) The name of the request event. This is the request task, eg. the url, or the method being used.
* `request` (Object) the detailed data for the root request event:
* `type` (String) The type of the request event. This can currently be set to 'HTTP' or 'DB'.
* `type` (String) The type of the request event. This is the name of the probe that sent the request data, e.g. `http`, `socketio` etc.
* `name` (String) The name of the request event. This is the request task, eg. the url, or the method being used.
* `context` (Object) A map of any additional context information for the request event.
* `context` (Object) Additional context data (usually contains the same data as the associated non-request metric event).
* `stack` (String) An optional stack trace for the event call.

@@ -445,17 +453,2 @@ * `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.

### 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.
### Event: 'express'
Emitted when an express request finishes its response. Note. appmetrics has only been tested with express 4.x, support is not guaranteed for lower versions.
* `data` (Object) the data from the Express request/response.
* `method` (String) The HTTP method for this request.
* `url` (String) The target URL for this request.
* `statusCode` (Number) The HTTP status code of the response.
* `duration` (Number) The time in ms between receiving the request and sending the response.
## Troubleshooting

@@ -470,3 +463,3 @@ 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].

### Error "Conflicting appmetrics module was already loaded by node-hc. Try running with node instead." when using `node-hc`
This error indicates you are using `node-hc` to run an application that uses the Node Application Metrics monitoring API (see *[Modifying your application to use the local installation](#run-local)*). Resolve this by using `node` to run the application instead. **Alternatively**, you could remove (or disable temporarily) the use of the Node Application Metrics monitoring API in your application.
This error indicates you are using `node-hc` to run an application that uses the Node Application Metrics monitoring API (see *[Modifying your application to use the local installation](#modifying-your-application-to-use-the-local-installation)*). Resolve this by using `node` to run the application instead. **Alternatively**, you could remove (or disable temporarily) the use of the Node Application Metrics monitoring API in your application.

@@ -495,3 +488,3 @@ This error was added to prevent the scenario where 2 instances of the agent can be accidentally created and started in parallel -- the globally installed one created by `node-hc` and the locally installed one created by the `require('appmetrics');` call in an application modified to use the Node Application Metrics monitoring API.

### No profiling data present for Node.js applications
Method profiling data is not collected by default, check *[Configuring Node Application Metrics](#config)* for information on how to enable it.
Method profiling data is not collected by default, check *[Configuring Node Application Metrics](#configuring-node-application-metrics)* for information on how to enable it.

@@ -515,5 +508,6 @@ If collection is enabled, an absence of method profiling data from a Node.js application could be caused by the type of tasks that are being run by your application -- it may be running long, synchronous tasks that prevent collection events from being scheduled on the event loop.

## Version
2.0.1
3.0.0
## Release History
`3.0.0` - Remove express probe.
`2.0.1` - Remove support for Node.js 0.10, 0.12, 5. Add heapdump api call.

@@ -520,0 +514,0 @@ `1.2.0` - Add file data collection capability and option configuration via api.

@@ -16,6 +16,8 @@ /*******************************************************************************

*******************************************************************************/
'use strict'
var app = require('./test_app');
var appmetrics = app.start();
var monitor = app.appmetrics.monitor();
var semver = require('semver');
app.appmetrics.enable("profiling");

@@ -225,3 +227,3 @@

var ARCHS = ['x86', 'x86_64', 'ppc32', 'ppc64', 'ppc64le', 's390', 's390x'];
var OSES = ['AIX', 'Linux', 'Windows 7', 'Mac OS X'];
var OSES = ['AIX', 'Linux', 'Windows', 'Mac OS X'];

@@ -231,4 +233,10 @@ t.ok(ARCHS.indexOf(commonEnvData['os.arch']) != -1,

t.ok(OSES.indexOf(commonEnvData['os.name']) != -1,
"Contains a recognised value for os.name");
var found = false;
for (var entry in OSES) {
if ((commonEnvData['os.name']).indexOf(OSES[entry]) > -1) {
found = true;
break;
}
}
t.ok(found, "Contains a recognised value for os.name");

@@ -328,4 +336,3 @@ t.match(commonEnvData['os.version'],/\S/,

var nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
if(nodeVersion >= 6.5) { // issue 283
if(semver.gt(process.version, '6.5.0')) { // issue 283
t.ok(2*parseInt(nodeEnvData['max.semi.space.size']) + parseInt(nodeEnvData['max.old.space.size']) === parseInt(nodeEnvData['heap.size.limit']),

@@ -332,0 +339,0 @@ 'Values for max.old.space.size and max.semi.space.size match heap.size.limit');

@@ -24,3 +24,3 @@ /*******************************************************************************

tap.plan(2);
tap.plan(3);

@@ -34,3 +34,3 @@ tap.tearDown(function() {

monitor.on('http-outbound', function(data) {
if (completedTests < 2) {
if (completedTests < 3) {
tap.test("HTTP Outbound Event", function(t) {

@@ -49,4 +49,8 @@ checkHttpOutboundData(data, t);

"Should report GET as HTTP request method");
t.equals(data.url, "http://localhost:8000",
"Should report http://localhost:8000 as URL");
t.equals(data.url, "http://localhost:8000/",
"Should report http://localhost:8000/ as URL");
if (data.requestHeaders) {
t.equals(data.requestHeaders.hello, "world",
"Should report world as value of hello header");
}
}

@@ -62,7 +66,18 @@

var options = {
host: "localhost",
port: 8000,
headers: {
hello: "world"
}
}
// Request with a callback
http.get('http://localhost:8000', function (res) {});
http.get('http://localhost:8000/', function (res) {});
// Request without a callback
http.get('http://localhost:8000')
http.get('http://localhost:8000/')
// Request with headers
http.request(options).end()

@@ -29,1 +29,10 @@ /*******************************************************************************

});
tap.test('Appmetrics should be a global singleton', function(t) {
var appmetrics = require('../');
// Delete cached module
delete require.cache[require.resolve('../')]
var appmetrics2 = require('../');
t.equals(appmetrics, appmetrics2);
t.end();
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc