diff --git a/packages/datadog-plugin-express/test/index.spec.js b/packages/datadog-plugin-express/test/index.spec.js index 45d9084af88..8a1c257daaa 100644 --- a/packages/datadog-plugin-express/test/index.spec.js +++ b/packages/datadog-plugin-express/test/index.spec.js @@ -820,6 +820,74 @@ describe('Plugin', () => { }) }) }) + + withVersions(plugin, 'loopback', loopbackVersion => { + let loopback + + beforeEach(() => { + loopback = require(`../../../versions/loopback@${loopbackVersion}`).get() + }) + + it('should handle loopback with express middleware', done => { + const app = loopback() + + app.get('/dd', (req, res) => { + res.status(200).send() + }) + + getPort().then(port => { + agent + .use(traces => { + const spans = sort(traces[0]) + + expect(spans[0]).to.have.property('service', 'test') + expect(spans[0]).to.have.property('type', 'web') + expect(spans[0]).to.have.property('resource', 'GET /dd') + expect(spans[0].meta).to.have.property('span.kind', 'server') + expect(spans[0].meta).to.have.property('http.url', `http://localhost:${port}/dd`) + expect(spans[0].meta).to.have.property('http.method', 'GET') + expect(spans[0].meta).to.have.property('http.status_code', '200') + }) + .then(done) + .catch(done) + + appListener = app.listen(port, 'localhost', () => { + axios.get(`http://localhost:${port}/dd`) + .catch(done) + }) + }) + }) + + it('should handle loopback re-sorting', done => { + const app = loopback() + + app.middleware('final', [], function throwError (req, res) { + throw new Error('should not reach') + }) + + app.get('/dd', function handleDD (req, res) { + res.status(200).send() + }) + + getPort().then(port => { + agent + .use(traces => { + const spans = sort(traces[0]) + + expect(spans[4]).to.have.property('name', 'express.middleware') + expect(spans[4]).to.have.property('service', 'test') + expect(spans[4]).to.have.property('resource', 'handleDD') + }) + .then(done) + .catch(done) + + appListener = app.listen(port, 'localhost', () => { + axios.get(`http://localhost:${port}/dd`) + .catch(done) + }) + }) + }) + }) }) describe('with configuration', () => { diff --git a/packages/datadog-plugin-router/src/index.js b/packages/datadog-plugin-router/src/index.js index b72ce7469f1..82a75db1956 100644 --- a/packages/datadog-plugin-router/src/index.js +++ b/packages/datadog-plugin-router/src/index.js @@ -55,15 +55,23 @@ function wrapRouterMethod (original) { function wrapLayerHandle (layer, handle) { handle._name = handle._name || layer.name + let wrapCallHandle + if (handle.length === 4) { - return function (error, req, res, next) { + wrapCallHandle = function (error, req, res, next) { return callHandle(layer, handle, req, [error, req, res, wrapNext(layer, req, next)]) } } else { - return function (req, res, next) { + wrapCallHandle = function (req, res, next) { return callHandle(layer, handle, req, [req, res, wrapNext(layer, req, next)]) } } + + // This is a workaround for the `loopback` library so that it can find the correct express layer + // that contains the real handle function + wrapCallHandle._datadog_orig = handle + + return wrapCallHandle } function wrapStack (stack, offset, matchers) { diff --git a/packages/dd-trace/test/plugins/externals.json b/packages/dd-trace/test/plugins/externals.json index 2c639fad848..58baaef9b82 100644 --- a/packages/dd-trace/test/plugins/externals.json +++ b/packages/dd-trace/test/plugins/externals.json @@ -1,4 +1,10 @@ { + "express": [ + { + "name": "loopback", + "versions": [">=2.13.0"] + } + ], "generic-pool": [ { "name": "generic-pool",