-
Notifications
You must be signed in to change notification settings - Fork 309
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
429 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
'use strict' | ||
|
||
function createWrapSend (tracer, config) { | ||
return function wrapSend (send) { | ||
return function sendWithTrace (msg, options) { | ||
const span = startSendSpan(tracer, config, this) | ||
|
||
try { | ||
const promise = send.apply(this, arguments) | ||
|
||
return wrapPromise(promise, span) | ||
} catch (e) { | ||
finish(span, e) | ||
throw e | ||
} | ||
} | ||
} | ||
} | ||
|
||
function createWrapMessageReceived (tracer, config) { | ||
return function wrapMessageReceived (messageReceived) { | ||
return function messageReceivedWithTrace (transferFrame) { | ||
if (transferFrame.aborted || transferFrame.more) { | ||
return messageReceived.apply(this, arguments) | ||
} | ||
|
||
const span = startReceiveSpan(tracer, config, this) | ||
|
||
process.nextTick(() => { | ||
tracer.scopeManager().activate(span, true) | ||
messageReceived.apply(this, arguments) | ||
}) | ||
} | ||
} | ||
} | ||
|
||
function startSendSpan (tracer, config, link) { | ||
const address = link.session.connection.address | ||
const target = getAddress(link) | ||
|
||
const span = tracer.startSpan(`amqp.send`, { | ||
tags: { | ||
'resource.name': `send ${target}`, | ||
'span.kind': 'producer', | ||
'amqp.link.target.address': target, | ||
'amqp.link.role': 'sender', | ||
'out.host': address.host, | ||
'out.port': address.port | ||
} | ||
}) | ||
|
||
addTags(tracer, config, span, link) | ||
|
||
return span | ||
} | ||
|
||
function startReceiveSpan (tracer, config, link) { | ||
const source = getAddress(link) | ||
const span = tracer.startSpan(`amqp.receive`, { | ||
tags: { | ||
'resource.name': `receive ${source}`, | ||
'span.kind': 'consumer', | ||
'amqp.link.source.address': source, | ||
'amqp.link.role': 'receiver' | ||
} | ||
}) | ||
|
||
addTags(tracer, config, span, link) | ||
|
||
return span | ||
} | ||
|
||
function addTags (tracer, config, span, link) { | ||
const address = link.session.connection.address | ||
|
||
span.addTags({ | ||
'service.name': config.service || `${tracer._service}-amqp`, | ||
'span.type': 'worker', | ||
'amqp.link.name': link.name, | ||
'amqp.link.handle': link.handle, | ||
'amqp.connection.host': address.host, | ||
'amqp.connection.port': address.port | ||
}) | ||
|
||
if (address.user) { | ||
span.setTag('amqp.connection.user', address.user) | ||
} | ||
|
||
return span | ||
} | ||
|
||
function finish (span, error) { | ||
if (error) { | ||
span.addTags({ | ||
'error.type': error.name, | ||
'error.msg': error.message, | ||
'error.stack': error.stack | ||
}) | ||
} | ||
|
||
span.finish() | ||
} | ||
|
||
function wrapPromise (promise, span) { | ||
if (!promise) { | ||
finish(span) | ||
return promise | ||
} | ||
|
||
return promise | ||
.then(() => { | ||
finish(span) | ||
return promise | ||
}) | ||
.catch(err => { | ||
finish(span, err) | ||
return promise | ||
}) | ||
} | ||
|
||
function getAddress (link) { | ||
return link.name.split('_').slice(0, -1).join('_') | ||
} | ||
|
||
module.exports = [ | ||
{ | ||
name: 'amqp10', | ||
file: 'lib/sender_link.js', | ||
versions: ['3.x'], | ||
patch (SenderLink, tracer, config) { | ||
this.wrap(SenderLink.prototype, 'send', createWrapSend(tracer, config)) | ||
}, | ||
unpatch (SenderLink) { | ||
this.unwrap(SenderLink.prototype, 'send') | ||
} | ||
}, | ||
{ | ||
name: 'amqp10', | ||
file: 'lib/receiver_link.js', | ||
versions: ['3.x'], | ||
patch (ReceiverLink, tracer, config) { | ||
this.wrap(ReceiverLink.prototype, '_messageReceived', createWrapMessageReceived(tracer, config)) | ||
}, | ||
unpatch (ReceiverLink) { | ||
this.unwrap(ReceiverLink.prototype, '_messageReceived') | ||
} | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
'use strict' | ||
|
||
require('../../..') | ||
.init({ plugins: false, sampleRate: 0 }) | ||
.use('amqp10') | ||
|
||
const test = require('tape') | ||
const profile = require('../../profile') | ||
|
||
test('amqp10 plugin should not leak', t => { | ||
const amqp = require('amqp10') | ||
const client = new amqp.Client() | ||
|
||
return client.connect('amqp://admin:admin@localhost:5673') | ||
.then(() => { | ||
return Promise.all([ | ||
client.createReceiver('amq.topic'), | ||
client.createSender('amq.topic') | ||
]) | ||
}) | ||
.then(handlers => { | ||
const receiver = handlers[0] | ||
const sender = handlers[1] | ||
|
||
profile(t, operation) | ||
.then(() => receiver.detach()) | ||
.then(() => sender.detach()) | ||
.then(() => client.disconnect()) | ||
|
||
function operation (done) { | ||
sender.send({ key: 'value' }) | ||
receiver.once('message', done) | ||
} | ||
}) | ||
}) |
Oops, something went wrong.