UNPKG

appdynamics

Version:

Performance Profiler and Monitor

108 lines (95 loc) 4.01 kB
'use strict'; var url = require('url'); const CONNECTION_ATTRIBUTES = Symbol('appdynamics.connection_attributes'); function RabbitMQExitProbe(agent) { this.agent = agent; } exports.RabbitMQExitProbe = RabbitMQExitProbe; RabbitMQExitProbe.prototype.init = function () { }; RabbitMQExitProbe.prototype.attach = function (obj, moduleName) { var self = this; if(moduleName == 'amqplib/lib/connect') { self.wrapConnect(obj); } else if(moduleName == 'amqplib/lib/callback_model') { self.wrapPublish(obj); } else if(moduleName == 'amqplib/lib/channel_model') { self.wrapPublish(obj); } }; RabbitMQExitProbe.prototype.wrapConnect = function(obj) { var self = this; self.agent.proxy.after(obj, 'connect', function(obj, args) { if (!args || args.length < 1 || !args[0]) return; var urlParam = args[0]; var connectionAttributes = {}; var urlParsed = urlParam; if (typeof(urlParam) != 'object') { urlParsed = url.parse(urlParam); } connectionAttributes['host'] = urlParsed.host || urlParsed.hostname || 'localhost'; connectionAttributes['port'] = urlParsed.port || (urlParsed.protocol && (urlParsed.protocol == 'amqp:') ? 5672 : 5671); self.agent.proxy.callback(args, -1, function(obj, retArgs) { if (!retArgs || retArgs.length < 2 || !retArgs[1]) return; var conn = retArgs[1]; Object.defineProperty(conn, CONNECTION_ATTRIBUTES, { value: connectionAttributes, enumerable: false, }); }); }, false, false, self.agent.thread.current()); }; RabbitMQExitProbe.prototype.getCorrelationHeader = function(exitCall) { var self = this; var correlationHeaderValue = self.agent.backendConnector.getCorrelationHeader(exitCall); if (correlationHeaderValue) { const noTxDetectHeader = self.agent.correlation.DISABLE_TRANSACTION_DETECTION + '=true'; const doNotResolveSubHeader = self.agent.correlation.DONOTRESOLVE + '=true'; correlationHeaderValue = correlationHeaderValue != noTxDetectHeader ? correlationHeaderValue + '*' + doNotResolveSubHeader : correlationHeaderValue; } return correlationHeaderValue; }; RabbitMQExitProbe.prototype.wrapPublish = function(obj) { var self = this; var proxy = self.agent.proxy; var profiler = self.agent.profiler; proxy.around(obj.Channel.prototype, 'publish', function(channel, args, locals) { var argsArray = Array.prototype.slice.call(args); locals.time = profiler.time(); locals.exitCall = createExitCall(self.agent, channel, locals.time, args); if (locals.exitCall) { var correlationHeaderValue = self.getCorrelationHeader(locals.exitCall); if (correlationHeaderValue) { self.agent.logger.debug(`RabbitMq Correlation Header is ${correlationHeaderValue}`); var options = args[3] || {}; options.headers = options.headers ? options.headers : {}; options.headers[self.agent.correlation.HEADER_NAME] = correlationHeaderValue; argsArray[3] = options; } return argsArray; } }, function(obj, args, ret, locals) { var errorObject = {}; if (!ret) { errorObject = { message: "RabbitMQError", name: "RabbitMQ pubish to queue failed" }; profiler.addExitCall(locals.time, locals.exitCall, errorObject); } else { profiler.addExitCall(locals.time, locals.exitCall); } }, false, self.agent.thread.current()); }; function createExitCall(agent, channel, time, args) { var props = { 'HOST': channel.connection[CONNECTION_ATTRIBUTES] && channel.connection[CONNECTION_ATTRIBUTES].host || 'amqp://localhost', 'PORT': channel.connection[CONNECTION_ATTRIBUTES] && channel.connection[CONNECTION_ATTRIBUTES].port || 5672, 'EXCHANGE': args[0] || '<default>', 'ROUTING_KEY': args[1] || '<default>' }; var ec = agent.profiler.createExitCall(time, { exitType: 'RABBITMQ', supportedProperties: props, stackTrace: agent.profiler.stackTrace(), }); return ec; }