dd-trace 2.4.2 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE-3rdparty.csv +1 -2
  2. package/ci/init.js +6 -0
  3. package/ci/jest/env.js +16 -3
  4. package/ext/exporters.d.ts +2 -1
  5. package/ext/exporters.js +2 -1
  6. package/index.d.ts +17 -8
  7. package/package.json +20 -23
  8. package/packages/datadog-instrumentations/index.js +14 -0
  9. package/packages/datadog-instrumentations/src/connect.js +111 -0
  10. package/packages/datadog-instrumentations/src/cypress.js +8 -0
  11. package/packages/datadog-instrumentations/src/express.js +27 -0
  12. package/packages/datadog-instrumentations/src/fastify.js +187 -0
  13. package/packages/datadog-instrumentations/src/find-my-way.js +30 -0
  14. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +100 -0
  15. package/packages/datadog-instrumentations/src/http/server.js +1 -1
  16. package/packages/datadog-instrumentations/src/jest.js +175 -0
  17. package/packages/datadog-instrumentations/src/kafkajs.js +112 -0
  18. package/packages/datadog-instrumentations/src/knex.js +20 -0
  19. package/packages/datadog-instrumentations/src/koa.js +159 -0
  20. package/packages/datadog-instrumentations/src/limitd-client.js +21 -0
  21. package/packages/datadog-instrumentations/src/oracledb.js +128 -0
  22. package/packages/datadog-instrumentations/src/paperplane.js +77 -0
  23. package/packages/datadog-instrumentations/src/pg.js +2 -2
  24. package/packages/datadog-instrumentations/src/restify.js +58 -0
  25. package/packages/datadog-instrumentations/src/rhea.js +1 -1
  26. package/packages/datadog-instrumentations/src/router.js +177 -0
  27. package/packages/datadog-plugin-aws-sdk/src/helpers.js +4 -4
  28. package/packages/datadog-plugin-aws-sdk/src/index.js +1 -1
  29. package/packages/datadog-plugin-connect/src/index.js +10 -114
  30. package/packages/datadog-plugin-cucumber/src/index.js +16 -16
  31. package/packages/datadog-plugin-cypress/src/index.js +10 -5
  32. package/packages/datadog-plugin-cypress/src/plugin.js +18 -17
  33. package/packages/datadog-plugin-dns/src/index.js +12 -1
  34. package/packages/datadog-plugin-express/src/index.js +11 -25
  35. package/packages/datadog-plugin-fastify/src/index.js +17 -4
  36. package/packages/datadog-plugin-find-my-way/src/index.js +20 -0
  37. package/packages/datadog-plugin-fs/src/index.js +2 -0
  38. package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +56 -111
  39. package/packages/datadog-plugin-http/src/server.js +2 -10
  40. package/packages/datadog-plugin-jest/src/index.js +101 -3
  41. package/packages/datadog-plugin-jest/src/util.js +1 -29
  42. package/packages/datadog-plugin-kafkajs/src/index.js +64 -90
  43. package/packages/datadog-plugin-koa/src/index.js +12 -164
  44. package/packages/datadog-plugin-mocha/src/index.js +14 -15
  45. package/packages/datadog-plugin-oracledb/src/index.js +34 -100
  46. package/packages/datadog-plugin-paperplane/src/index.js +14 -100
  47. package/packages/datadog-plugin-paperplane/src/logger.js +11 -0
  48. package/packages/datadog-plugin-paperplane/src/server.js +24 -0
  49. package/packages/datadog-plugin-restify/src/index.js +13 -75
  50. package/packages/datadog-plugin-router/src/index.js +67 -164
  51. package/packages/datadog-plugin-web/src/index.js +20 -0
  52. package/packages/dd-trace/lib/version.js +1 -1
  53. package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +34 -12
  54. package/packages/dd-trace/src/appsec/index.js +7 -3
  55. package/packages/dd-trace/src/appsec/recommended.json +15 -5
  56. package/packages/dd-trace/src/appsec/reporter.js +33 -3
  57. package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
  58. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +32 -0
  59. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +51 -0
  60. package/packages/dd-trace/src/config.js +33 -4
  61. package/packages/dd-trace/src/encode/0.4.js +0 -1
  62. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +193 -0
  63. package/packages/dd-trace/src/encode/tags-processors.js +116 -0
  64. package/packages/dd-trace/src/exporter.js +3 -0
  65. package/packages/dd-trace/src/exporters/agent/index.js +1 -1
  66. package/packages/dd-trace/src/exporters/agent/writer.js +7 -32
  67. package/packages/dd-trace/src/exporters/{agent → common}/docker.js +0 -0
  68. package/packages/dd-trace/src/exporters/common/request.js +83 -0
  69. package/packages/dd-trace/src/exporters/common/writer.js +36 -0
  70. package/packages/dd-trace/src/exporters/{agent/scheduler.js → scheduler.js} +0 -0
  71. package/packages/dd-trace/src/format.js +9 -5
  72. package/packages/dd-trace/src/instrumenter.js +3 -0
  73. package/packages/dd-trace/src/pkg.js +11 -6
  74. package/packages/dd-trace/src/plugin_manager.js +13 -7
  75. package/packages/dd-trace/src/plugins/index.js +1 -2
  76. package/packages/dd-trace/src/plugins/log_plugin.js +8 -4
  77. package/packages/dd-trace/src/plugins/plugin.js +8 -0
  78. package/packages/dd-trace/src/plugins/util/test.js +79 -1
  79. package/packages/dd-trace/src/plugins/util/web.js +41 -12
  80. package/packages/dd-trace/src/profiling/config.js +8 -8
  81. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  82. package/packages/dd-trace/src/profiling/index.js +4 -4
  83. package/packages/dd-trace/src/profiling/profilers/{heap.js → space.js} +2 -2
  84. package/packages/dd-trace/src/profiling/profilers/{cpu.js → wall.js} +3 -3
  85. package/packages/dd-trace/src/proxy.js +2 -0
  86. package/packages/dd-trace/src/span_processor.js +4 -1
  87. package/packages/dd-trace/src/telemetry.js +187 -0
  88. package/scripts/install_plugin_modules.js +1 -0
  89. package/packages/datadog-plugin-fastify/src/fastify.js +0 -198
  90. package/packages/datadog-plugin-fastify/src/find-my-way.js +0 -37
  91. package/packages/datadog-plugin-jest/src/jest-environment.js +0 -272
  92. package/packages/datadog-plugin-jest/src/jest-jasmine2.js +0 -185
  93. package/packages/datadog-plugin-knex/src/index.js +0 -23
  94. package/packages/datadog-plugin-limitd-client/src/index.js +0 -30
  95. package/packages/dd-trace/src/exporters/agent/request.js +0 -86
  96. package/scripts/postpublish.js +0 -24
@@ -0,0 +1,128 @@
1
+ 'use strict'
2
+
3
+ const {
4
+ channel,
5
+ addHook,
6
+ AsyncResource
7
+ } = require('./helpers/instrument')
8
+ const shimmer = require('../../datadog-shimmer')
9
+
10
+ const connectionAttributes = new WeakMap()
11
+ const poolAttributes = new WeakMap()
12
+
13
+ const executeStartChannel = channel('apm:oracledb:execute:start')
14
+ const executeErrorChannel = channel('apm:oracledb:execute:error')
15
+ const executeFinishChannel = channel('apm:oracledb:execute:finish')
16
+
17
+ function finish (err) {
18
+ if (err) {
19
+ executeErrorChannel.publish(err)
20
+ }
21
+ executeFinishChannel.publish(undefined)
22
+ }
23
+
24
+ addHook({ name: 'oracledb', versions: ['5'] }, oracledb => {
25
+ shimmer.wrap(oracledb.Connection.prototype, 'execute', execute => {
26
+ return function wrappedExecute (dbQuery, ...args) {
27
+ if (!executeStartChannel.hasSubscribers) {
28
+ return execute.apply(this, arguments)
29
+ }
30
+
31
+ if (arguments.length && typeof arguments[arguments.length - 1] === 'function') {
32
+ const cb = arguments[arguments.length - 1]
33
+ const outerAr = new AsyncResource('apm:oracledb:outer-scope')
34
+ arguments[arguments.length - 1] = function wrappedCb (err, result) {
35
+ finish(err)
36
+ return outerAr.runInAsyncScope(() => cb.apply(this, arguments))
37
+ }
38
+ }
39
+
40
+ return new AsyncResource('apm:oracledb:inner-scope').runInAsyncScope(() => {
41
+ const connAttrs = connectionAttributes.get(this)
42
+ executeStartChannel.publish({ query: dbQuery, connAttrs })
43
+ try {
44
+ let result = execute.apply(this, arguments)
45
+
46
+ if (result && typeof result.then === 'function') {
47
+ result = result.then(
48
+ x => {
49
+ finish()
50
+ return x
51
+ },
52
+ e => {
53
+ finish(e)
54
+ throw e
55
+ }
56
+ )
57
+ }
58
+
59
+ return result
60
+ } catch (err) {
61
+ executeErrorChannel.publish(err)
62
+ throw err
63
+ }
64
+ })
65
+ }
66
+ })
67
+ shimmer.wrap(oracledb, 'getConnection', getConnection => {
68
+ return function wrappedGetConnection (connAttrs, callback) {
69
+ if (callback) {
70
+ arguments[1] = (err, connection) => {
71
+ if (connection) {
72
+ connectionAttributes.set(connection, connAttrs)
73
+ }
74
+ callback(err, connection)
75
+ }
76
+
77
+ getConnection.apply(this, arguments)
78
+ } else {
79
+ return getConnection.apply(this, arguments).then((connection) => {
80
+ connectionAttributes.set(connection, connAttrs)
81
+ return connection
82
+ })
83
+ }
84
+ }
85
+ })
86
+ shimmer.wrap(oracledb, 'createPool', createPool => {
87
+ return function wrappedCreatePool (poolAttrs, callback) {
88
+ if (callback) {
89
+ arguments[1] = (err, pool) => {
90
+ if (pool) {
91
+ poolAttributes.set(pool, poolAttrs)
92
+ }
93
+ callback(err, pool)
94
+ }
95
+
96
+ createPool.apply(this, arguments)
97
+ } else {
98
+ return createPool.apply(this, arguments).then((pool) => {
99
+ poolAttributes.set(pool, poolAttrs)
100
+ return pool
101
+ })
102
+ }
103
+ }
104
+ })
105
+ shimmer.wrap(oracledb.Pool.prototype, 'getConnection', getConnection => {
106
+ return function wrappedGetConnection () {
107
+ let callback
108
+ if (typeof arguments[arguments.length - 1] === 'function') {
109
+ callback = arguments[arguments.length - 1]
110
+ }
111
+ if (callback) {
112
+ arguments[arguments.length - 1] = (err, connection) => {
113
+ if (connection) {
114
+ connectionAttributes.set(connection, poolAttributes.get(this))
115
+ }
116
+ callback(err, connection)
117
+ }
118
+ getConnection.apply(this, arguments)
119
+ } else {
120
+ return getConnection.apply(this, arguments).then((connection) => {
121
+ connectionAttributes.set(connection, poolAttributes.get(this))
122
+ return connection
123
+ })
124
+ }
125
+ }
126
+ })
127
+ return oracledb
128
+ })
@@ -0,0 +1,77 @@
1
+ 'use strict'
2
+
3
+ const { addHook, channel } = require('./helpers/instrument')
4
+ const shimmer = require('../../datadog-shimmer')
5
+
6
+ const logChannel = channel('apm:paperplane:log')
7
+ const handleChannel = channel('apm:paperplane:request:handle')
8
+ const routeChannel = channel('apm:paperplane:request:route')
9
+
10
+ const nodeMajor = Number(process.versions.node.split('.')[0])
11
+ const name = 'paperplane'
12
+ const versions = nodeMajor <= 12 ? ['>=2.3.2'] : nodeMajor <= 14 ? ['>=3.1.1'] : []
13
+
14
+ const wrapRoute = handler => req => {
15
+ const { original, route } = req
16
+
17
+ if (routeChannel.hasSubscribers) {
18
+ routeChannel.publish({ req: original, route })
19
+ }
20
+
21
+ return handler(req)
22
+ }
23
+
24
+ const wrapLogger = logger => record => {
25
+ const event = { message: record }
26
+
27
+ logChannel.publish(event)
28
+
29
+ return logger(event.message)
30
+ }
31
+
32
+ const wrapMount = mount => opts => {
33
+ const handler = mount(opts)
34
+
35
+ return function (req, res) {
36
+ handleChannel.publish(req)
37
+
38
+ return handler.apply(this, arguments)
39
+ }
40
+ }
41
+
42
+ const wrapRoutes = routes => handlers => {
43
+ const traced = {}
44
+
45
+ for (const route in handlers) {
46
+ traced[route] = wrapRoute(handlers[route])
47
+ }
48
+
49
+ return routes(traced)
50
+ }
51
+
52
+ addHook({ name, versions, file: 'lib/logger.js' }, exports => {
53
+ shimmer.wrap(exports, 'logger', wrapLogger)
54
+
55
+ return exports
56
+ })
57
+
58
+ addHook({ name, versions, file: 'lib/mount.js' }, exports => {
59
+ shimmer.wrap(exports, 'mount', wrapMount)
60
+
61
+ return exports
62
+ })
63
+
64
+ addHook({ name, versions, file: 'lib/routes.js' }, exports => {
65
+ shimmer.wrap(exports, 'routes', wrapRoutes)
66
+
67
+ return exports
68
+ })
69
+
70
+ if (nodeMajor <= 12) {
71
+ addHook({ name, versions: ['2.3.0 - 2.3.1'] }, paperplane => {
72
+ shimmer.wrap(paperplane, 'mount', wrapMount)
73
+ shimmer.wrap(paperplane, 'routes', wrapRoutes)
74
+
75
+ return paperplane
76
+ })
77
+ }
@@ -12,12 +12,12 @@ const asyncEndCh = channel('apm:pg:query:async-end')
12
12
  const endCh = channel('apm:pg:query:end')
13
13
  const errorCh = channel('apm:pg:query:error')
14
14
 
15
- addHook({ name: 'pg', versions: ['>=4'] }, pg => {
15
+ addHook({ name: 'pg', versions: ['>=4.5.5'] }, pg => {
16
16
  shimmer.wrap(pg.Client.prototype, 'query', query => wrapQuery(query))
17
17
  return pg
18
18
  })
19
19
 
20
- addHook({ name: 'pg', file: 'lib/native/index.js', versions: ['>=4'] }, Client => {
20
+ addHook({ name: 'pg', file: 'lib/native/index.js', versions: ['>=4.5.5'] }, Client => {
21
21
  shimmer.wrap(Client.prototype, 'query', query => wrapQuery(query))
22
22
  return Client
23
23
  })
@@ -0,0 +1,58 @@
1
+ 'use strict'
2
+
3
+ const shimmer = require('../../datadog-shimmer')
4
+ const { addHook, channel, AsyncResource } = require('./helpers/instrument')
5
+ const handlers = ['use', 'pre']
6
+ const methods = ['del', 'get', 'head', 'opts', 'post', 'put', 'patch']
7
+
8
+ const handleChannel = channel('apm:restify:request:handle')
9
+ const routeChannel = channel('apm:restify:request:route')
10
+
11
+ function wrapSetupRequest (setupRequest) {
12
+ return function setupRequestWithTrace (req, res) {
13
+ handleChannel.publish({ req, res })
14
+ return setupRequest.apply(this, arguments)
15
+ }
16
+ }
17
+
18
+ function wrapMethod (method) {
19
+ return function methodWithTrace (path) {
20
+ const middleware = wrapMiddleware(Array.prototype.slice.call(arguments, 1))
21
+
22
+ return method.apply(this, [path].concat(middleware))
23
+ }
24
+ }
25
+
26
+ function wrapHandler (method) {
27
+ return function methodWithTrace () {
28
+ return method.apply(this, wrapMiddleware(arguments))
29
+ }
30
+ }
31
+
32
+ function wrapMiddleware (middleware) {
33
+ return Array.prototype.map.call(middleware, wrapFn)
34
+ }
35
+
36
+ function wrapFn (fn) {
37
+ if (Array.isArray(fn)) return wrapMiddleware(fn)
38
+
39
+ return function (req, res, next) {
40
+ if (typeof next === 'function') {
41
+ arguments[2] = AsyncResource.bind(next)
42
+ }
43
+
44
+ if (req.route) {
45
+ routeChannel.publish({ req, route: req.route })
46
+ }
47
+
48
+ return fn.apply(this, arguments)
49
+ }
50
+ }
51
+
52
+ addHook({ name: 'restify', versions: ['>=3'], file: 'lib/server.js' }, Server => {
53
+ shimmer.wrap(Server.prototype, '_setupRequest', wrapSetupRequest)
54
+ shimmer.massWrap(Server.prototype, handlers, wrapHandler)
55
+ shimmer.wrap(Server.prototype, methods, wrapMethod)
56
+
57
+ return Server
58
+ })
@@ -147,7 +147,7 @@ function wrapDeliveryUpdate (obj, update) {
147
147
  function patchCircularBuffer (proto, Session) {
148
148
  Object.defineProperty(proto, 'outgoing', {
149
149
  configurable: true,
150
- get () {},
150
+ get () { return undefined },
151
151
  set (outgoing) {
152
152
  delete proto.outgoing // removes the setter on the prototype
153
153
  this.outgoing = outgoing // assigns on the instance, like normal
@@ -0,0 +1,177 @@
1
+ 'use strict'
2
+
3
+ const METHODS = require('methods').concat('all')
4
+ const pathToRegExp = require('path-to-regexp')
5
+ const shimmer = require('../../datadog-shimmer')
6
+ const { addHook, channel, AsyncResource } = require('./helpers/instrument')
7
+
8
+ function createWrapRouterMethod (name) {
9
+ const enterChannel = channel(`apm:${name}:middleware:enter`)
10
+ const errorChannel = channel(`apm:${name}:middleware:error`)
11
+ const exitChannel = channel(`apm:${name}:middleware:exit`)
12
+
13
+ const layerMatchers = new WeakMap()
14
+ const regexpCache = Object.create(null)
15
+
16
+ function wrapLayerHandle (layer, original) {
17
+ original._name = original._name || layer.name
18
+
19
+ const handle = shimmer.wrap(original, function () {
20
+ if (!enterChannel.hasSubscribers) return original.apply(this, arguments)
21
+
22
+ const matchers = layerMatchers.get(layer)
23
+ const middlewareResource = new AsyncResource('bound-anonymous-fn')
24
+ const lastIndex = arguments.length - 1
25
+ const name = original._name || original.name
26
+ const req = arguments[arguments.length > 3 ? 1 : 0]
27
+ const next = AsyncResource.bind(arguments[lastIndex])
28
+
29
+ if (typeof next === 'function') {
30
+ arguments[lastIndex] = wrapNext(req, middlewareResource.bind(next))
31
+ }
32
+
33
+ return middlewareResource.runInAsyncScope(() => {
34
+ let route
35
+
36
+ if (matchers) {
37
+ // Try to guess which path actually matched
38
+ for (let i = 0; i < matchers.length; i++) {
39
+ if (matchers[i].test(layer)) {
40
+ route = matchers[i].path
41
+
42
+ break
43
+ }
44
+ }
45
+ }
46
+
47
+ enterChannel.publish({ name, req, route })
48
+
49
+ try {
50
+ return original.apply(this, arguments)
51
+ } catch (e) {
52
+ errorChannel.publish(e)
53
+ exitChannel.publish({ req })
54
+
55
+ throw e
56
+ }
57
+ })
58
+ })
59
+
60
+ // This is a workaround for the `loopback` library so that it can find the correct express layer
61
+ // that contains the real handle function
62
+ handle._datadog_orig = original
63
+
64
+ return handle
65
+ }
66
+
67
+ function wrapStack (stack, offset, matchers) {
68
+ [].concat(stack).slice(offset).forEach(layer => {
69
+ if (layer.__handle) { // express-async-errors
70
+ layer.__handle = wrapLayerHandle(layer, layer.__handle)
71
+ } else {
72
+ layer.handle = wrapLayerHandle(layer, layer.handle)
73
+ }
74
+
75
+ layerMatchers.set(layer, matchers)
76
+
77
+ if (layer.route) {
78
+ METHODS.forEach(method => {
79
+ if (typeof layer.route.stack === 'function') {
80
+ layer.route.stack = [{ handle: layer.route.stack }]
81
+ }
82
+
83
+ layer.route[method] = wrapMethod(layer.route[method])
84
+ })
85
+ }
86
+ })
87
+ }
88
+
89
+ function wrapNext (req, next) {
90
+ return function (error) {
91
+ if (error) {
92
+ errorChannel.publish(error)
93
+ }
94
+
95
+ exitChannel.publish({ req })
96
+
97
+ next.apply(null, arguments)
98
+ }
99
+ }
100
+
101
+ function extractMatchers (fn) {
102
+ const arg = flatten([].concat(fn))
103
+
104
+ if (typeof arg[0] === 'function') {
105
+ return []
106
+ }
107
+
108
+ return arg.map(pattern => ({
109
+ path: pattern instanceof RegExp ? `(${pattern})` : pattern,
110
+ test: layer => {
111
+ const matchers = layerMatchers.get(layer)
112
+
113
+ return !isFastStar(layer, matchers) &&
114
+ !isFastSlash(layer, matchers) &&
115
+ cachedPathToRegExp(pattern).test(layer.path)
116
+ }
117
+ }))
118
+ }
119
+
120
+ function isFastStar (layer, matchers) {
121
+ if (layer.regexp.fast_star !== undefined) {
122
+ return layer.regexp.fast_star
123
+ }
124
+
125
+ return matchers.some(matcher => matcher.path === '*')
126
+ }
127
+
128
+ function isFastSlash (layer, matchers) {
129
+ if (layer.regexp.fast_slash !== undefined) {
130
+ return layer.regexp.fast_slash
131
+ }
132
+
133
+ return matchers.some(matcher => matcher.path === '/')
134
+ }
135
+
136
+ function flatten (arr) {
137
+ return arr.reduce((acc, val) => Array.isArray(val) ? acc.concat(flatten(val)) : acc.concat(val), [])
138
+ }
139
+
140
+ function cachedPathToRegExp (pattern) {
141
+ const maybeCached = regexpCache[pattern]
142
+ if (maybeCached) {
143
+ return maybeCached
144
+ }
145
+ const regexp = pathToRegExp(pattern)
146
+ regexpCache[pattern] = regexp
147
+ return regexp
148
+ }
149
+
150
+ function wrapMethod (original) {
151
+ return function methodWithTrace (fn) {
152
+ const offset = this.stack ? [].concat(this.stack).length : 0
153
+ const router = original.apply(this, arguments)
154
+
155
+ if (typeof this.stack === 'function') {
156
+ this.stack = [{ handle: this.stack }]
157
+ }
158
+
159
+ wrapStack(this.stack, offset, extractMatchers(fn))
160
+
161
+ return router
162
+ }
163
+ }
164
+
165
+ return wrapMethod
166
+ }
167
+
168
+ const wrapRouterMethod = createWrapRouterMethod('router')
169
+
170
+ addHook({ name: 'router', versions: ['>=1'] }, Router => {
171
+ shimmer.wrap(Router.prototype, 'use', wrapRouterMethod)
172
+ shimmer.wrap(Router.prototype, 'route', wrapRouterMethod)
173
+
174
+ return Router
175
+ })
176
+
177
+ module.exports = { createWrapRouterMethod }
@@ -19,7 +19,7 @@ function getService (Service) {
19
19
  }
20
20
 
21
21
  const helpers = {
22
- finish (span, err) {
22
+ finish (config, span, response, err) {
23
23
  if (err) {
24
24
  span.setTag('error', err)
25
25
 
@@ -28,6 +28,8 @@ const helpers = {
28
28
  }
29
29
  }
30
30
 
31
+ config.hooks.request(span, response)
32
+
31
33
  span.finish()
32
34
  },
33
35
 
@@ -43,14 +45,12 @@ const helpers = {
43
45
  : true
44
46
  },
45
47
 
46
- addResponseTags (span, response, serviceName, config) {
48
+ addResponseTags (span, response, serviceName) {
47
49
  if (!span) return
48
50
 
49
51
  if (response.request) {
50
52
  this.addServicesTags(span, response, serviceName)
51
53
  }
52
-
53
- config.hooks.request(span, response)
54
54
  },
55
55
 
56
56
  addServicesTags (span, response, serviceName) {
@@ -36,7 +36,7 @@ function createWrapRequest (tracer, config) {
36
36
  if (!span) return
37
37
 
38
38
  awsHelpers.addResponseTags(span, response, serviceIdentifier, config, tracer)
39
- awsHelpers.finish(span, response.error)
39
+ awsHelpers.finish(config, span, response, response.error)
40
40
  })
41
41
 
42
42
  analyticsSampler.sample(span, config.measured)
@@ -1,123 +1,19 @@
1
1
  'use strict'
2
2
 
3
- const web = require('../../dd-trace/src/plugins/util/web')
3
+ const RouterPlugin = require('../../datadog-plugin-router/src')
4
4
 
5
- function createWrapConnect (tracer, config) {
6
- return function wrapConnect (connect) {
7
- if (typeof connect !== 'function') return connect
8
-
9
- return function connectWithTrace () {
10
- const app = connect()
11
-
12
- if (!app) return app
13
-
14
- app.use = createWrapUse()(app.use)
15
- app.handle = createWrapHandle(tracer, config)(app.handle)
16
-
17
- return app
18
- }
19
- }
20
- }
21
-
22
- function createWrapUse () {
23
- return function wrapUse (use) {
24
- if (typeof use !== 'function') return use
25
-
26
- return function useWithTrace (route, fn) {
27
- const result = use.apply(this, arguments)
28
-
29
- if (!this || !Array.isArray(this.stack)) return result
30
-
31
- const index = this.stack.length - 1
32
- const layer = this.stack[index]
33
-
34
- if (layer && layer.handle) {
35
- this.stack[index].handle = wrapLayerHandle(layer)
36
- }
37
-
38
- return result
39
- }
5
+ class ConnectPlugin extends RouterPlugin {
6
+ static get name () {
7
+ return 'connect'
40
8
  }
41
- }
42
-
43
- function createWrapHandle (tracer, config) {
44
- config = web.normalizeConfig(config)
45
9
 
46
- return function wrapHandle (handle) {
47
- if (typeof handle !== 'function') return handle
10
+ constructor (...args) {
11
+ super(...args)
48
12
 
49
- return function handleWithTrace (req, res, out) {
50
- return web.instrument(tracer, config, req, res, 'connect.request', () => {
51
- return handle.apply(this, arguments)
52
- })
53
- }
13
+ this.addSub('apm:connect:request:handle', ({ req }) => {
14
+ this.setFramework(req, 'connect', this.config)
15
+ })
54
16
  }
55
17
  }
56
18
 
57
- function wrapLayerHandle (layer) {
58
- if (typeof layer.handle !== 'function') return layer.handle
59
-
60
- const handle = layer.handle
61
-
62
- if (layer.handle.length === 4) {
63
- return function (error, req, res, next) {
64
- return callLayerHandle(layer, handle, req, [error, req, res, wrapNext(layer, req, next)])
65
- }
66
- } else {
67
- return function (req, res, next) {
68
- return callLayerHandle(layer, handle, req, [req, res, wrapNext(layer, req, next)])
69
- }
70
- }
71
- }
72
-
73
- function callLayerHandle (layer, handle, req, args) {
74
- const route = layer.route
75
-
76
- if (route !== '/') {
77
- web.enterRoute(req, route)
78
- }
79
-
80
- return web.wrapMiddleware(req, handle, 'connect.middleware', () => {
81
- return handle.apply(layer, args)
82
- })
83
- }
84
-
85
- function wrapNext (layer, req, next) {
86
- if (typeof next !== 'function' || !web.active(req)) return next
87
-
88
- return function nextWithTrace (error) {
89
- if (!error && layer.route !== '/') {
90
- web.exitRoute(req)
91
- }
92
-
93
- web.finish(req, error)
94
-
95
- next.apply(this, arguments)
96
- }
97
- }
98
-
99
- module.exports = [
100
- {
101
- name: 'connect',
102
- versions: ['>=3'],
103
- patch (connect, tracer, config) {
104
- // `connect` is a function so we return a wrapper that will replace its export.
105
- return this.wrapExport(connect, createWrapConnect(tracer, config)(connect))
106
- },
107
- unpatch (connect) {
108
- this.unwrapExport(connect)
109
- }
110
- },
111
- {
112
- name: 'connect',
113
- versions: ['2.2.2'],
114
- patch (connect, tracer, config) {
115
- this.wrap(connect.proto, 'use', createWrapUse())
116
- this.wrap(connect.proto, 'handle', createWrapHandle(tracer, config))
117
- },
118
- unpatch (connect) {
119
- this.unwrap(connect.proto, 'use')
120
- this.unwrap(connect.proto, 'handle')
121
- }
122
- }
123
- ]
19
+ module.exports = ConnectPlugin