ca-apm-probe
Version:
CA APM Node.js Agent monitors real-time health and performance of Node.js applications
89 lines (81 loc) • 3.55 kB
JavaScript
/**
* Copyright (c) 2015 CA. All rights reserved.
*
* This software and all information contained therein is confidential and proprietary and
* shall not be duplicated, used, disclosed or disseminated in any way except as authorized
* by the applicable license agreement, without the express written permission of CA. All
* authorized reproductions must be marked with this language.
*
* EXCEPT AS SET FORTH IN THE APPLICABLE LICENSE AGREEMENT, TO THE EXTENT
* PERMITTED BY APPLICABLE LAW, CA PROVIDES THIS SOFTWARE WITHOUT WARRANTY
* OF ANY KIND, INCLUDING WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL CA BE
* LIABLE TO THE END USER OR ANY THIRD PARTY FOR ANY LOSS OR DAMAGE, DIRECT OR
* INDIRECT, FROM THE USE OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, LOST
* PROFITS, BUSINESS INTERRUPTION, GOODWILL, OR LOST DATA, EVEN IF CA IS
* EXPRESSLY ADVISED OF SUCH LOSS OR DAMAGE.
*/
var agent = require('../agent');
var logger = require("../logger.js");
var proxy = require('../proxy');
var targetModule = new Object;
module.exports = function(redis) {
targetModule.redis = redis;
logger.info('redis: instrument()');
var redis = this.targetModule;
proxy.before(targetModule.redis.RedisClient.prototype, 'internal_send_command',
function(obj, args, storage) {
if (agent.paused) return;
var command = args[0];
if(!command) return;
var input = command.callback;
input = [input];
if (obj.connection_options) {
if (obj.connection_options.host) {
var hostName = obj.connection_options.host;
}
if (obj.connection_options.port) {
var port = obj.connection_options.port;
}
}
var eventNameFormatted = 'redis.' + command.command;
var ctx = storage.get('ctx');
ctx = agent.asynchEventStart(ctx, eventNameFormatted, {
hostname: hostName,
port: port
});
storage.set('ctx', ctx);
var callbackIndex = 0;
if (typeof input[callbackIndex] === 'function') {
proxy.callback(input, callbackIndex, handle, afterHandle);
} else {
if (typeof input[callbackIndex] !== 'function') {
input.push(function() {});
callbackIndex += 1;
}
proxy.callback(input, callbackIndex, handle, afterHandle);
}
command.callback = input[callbackIndex];
function handle(obj, args, storage) {
var errorObject = agent.checkAndSetErrorObject(args, 'redisError');
if (ctx != null) {
logger.debug('%s[%d %d %d]: callback', eventNameFormatted, ctx.txid, ctx.lane, ctx.evtid);
ctx = agent.asynchEventDone(ctx, eventNameFormatted, null, errorObject);
storage.set('ctx', ctx);
}
}
function afterHandle(obj, args) {
if (ctx != null) agent.asynchEventFinish(ctx);
}
});
};
function getMethodsWithProbes() {
var mt = new Object;
mt[0] = 'redis#send_command';
return mt;
}
function instrument(redis) {
targetModule.redis = redis;
}
module.exports.instrument = instrument.bind(module.exports);
module.exports.getMethodsWithProbes = getMethodsWithProbes;