atatus-nodejs
Version:
Atatus APM agent for Node.js
102 lines (77 loc) • 3.1 kB
JavaScript
;
const semver = require('semver');
const constants = require('../../../constants');
const shimmer = require('../../shimmer');
const { shouldIgnoreTopic } = require('./utils');
const NAME = 'RabbitMQ'
const TYPE = 'messaging';
const SUBTYPE = 'rabbitmq';
module.exports = function instrumentAMQPChannel(mod, agent, { version, enabled }) {
if (!enabled || !semver.satisfies(version, '>=0.5')) {
return mod;
}
const config = agent._conf;
const ins = agent._instrumentation;
agent.logger.debug('shimming AMQP Channel class');
shimmer.wrap(mod.Channel.prototype, 'sendMessage', wrapperSendMessage);
return mod;
function wrapperSendMessage(origSendMessage) {
return function wrappedSendMessage() {
const fields = arguments[0];
const topic = fields.routingKey;
if (shouldIgnoreTopic(topic, config)) {
return origSendMessage.apply(this, arguments)
}
const span = ins.createSpan(
`${NAME} SEND MESSAGE to ${topic}`,
TYPE,
SUBTYPE,
'send',
{ exitSpan: true },
);
const runContext = ins.currRunContext();
const parentSpan = span || runContext.currSpan() || runContext.currTransaction();
if (parentSpan) {
const newHeaders = Object.assign({}, (fields && fields.headers) || {});
parentSpan.propagateTraceContextHeaders(
newHeaders,
function (carrier, name, value) {
if (name.startsWith('atatus-')) {
return;
}
carrier[name] = value;
},
);
fields.headers = newHeaders;
// console.log(newHeaders,fields.headers)
}
if (!span) {
return origSendMessage.apply(this, arguments);
}
span.setMessageContext({ queue: { exchange: fields.exchange, routingKey: fields.routingKey, headers: fields.headers } });
const service = {
resource: `${SUBTYPE}/${topic}`,
type: SUBTYPE,
name: topic,
};
span._setDestinationContext({ service });
agent.logger.debug(`Sending message to queue: ${topic}`);
let result, err;
try {
result = origSendMessage.apply(this, arguments);
} catch (ex) {
// Save the error for use in `finally` below, but re-throw it to
// not impact code flow.
err = ex;
agent.logger.error(`Error in sendToQueue for topic ${topic}:`, err);
throw ex;
} finally {
span.setOutcome(
err ? constants.OUTCOME_FAILURE : constants.OUTCOME_SUCCESS,
);
span.end();
}
return result;
}
}
}