dd-trace 2.12.0 → 2.13.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 (44) hide show
  1. package/LICENSE-3rdparty.csv +0 -1
  2. package/ext/formats.js +3 -5
  3. package/package.json +4 -5
  4. package/packages/datadog-instrumentations/index.js +1 -52
  5. package/packages/datadog-instrumentations/src/connect.js +5 -5
  6. package/packages/datadog-instrumentations/src/fastify.js +12 -25
  7. package/packages/datadog-instrumentations/src/helpers/hooks.js +68 -0
  8. package/packages/datadog-instrumentations/src/helpers/instrument.js +5 -34
  9. package/packages/datadog-instrumentations/src/helpers/instrumentations.js +3 -0
  10. package/packages/datadog-instrumentations/src/helpers/register.js +59 -0
  11. package/packages/datadog-instrumentations/src/koa.js +5 -5
  12. package/packages/datadog-instrumentations/src/mocha.js +4 -1
  13. package/packages/datadog-instrumentations/src/restify.js +27 -5
  14. package/packages/datadog-instrumentations/src/router.js +5 -5
  15. package/packages/datadog-plugin-aws-sdk/src/base.js +1 -2
  16. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -2
  17. package/packages/datadog-plugin-mocha/src/index.js +2 -2
  18. package/packages/datadog-plugin-restify/src/index.js +7 -0
  19. package/packages/datadog-plugin-router/src/index.js +13 -8
  20. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +220 -0
  21. package/packages/dd-trace/src/config.js +6 -0
  22. package/packages/dd-trace/src/encode/0.4.js +4 -0
  23. package/packages/dd-trace/src/{profiling/exporters → exporters/common}/form-data.js +0 -0
  24. package/packages/dd-trace/src/exporters/common/request.js +49 -34
  25. package/packages/dd-trace/src/exporters/common/writer.js +8 -1
  26. package/packages/dd-trace/src/id.js +16 -13
  27. package/packages/dd-trace/src/noop/span.js +12 -12
  28. package/packages/dd-trace/src/noop/tracer.js +8 -5
  29. package/packages/dd-trace/src/opentracing/propagation/text_map.js +6 -6
  30. package/packages/dd-trace/src/opentracing/span.js +63 -49
  31. package/packages/dd-trace/src/opentracing/span_context.js +1 -5
  32. package/packages/dd-trace/src/opentracing/tracer.js +31 -36
  33. package/packages/dd-trace/src/plugin_manager.js +95 -65
  34. package/packages/dd-trace/src/plugins/index.js +57 -45
  35. package/packages/dd-trace/src/plugins/util/ci.js +34 -9
  36. package/packages/dd-trace/src/plugins/util/git.js +52 -2
  37. package/packages/dd-trace/src/plugins/util/tags.js +4 -1
  38. package/packages/dd-trace/src/plugins/util/web.js +5 -2
  39. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  40. package/packages/dd-trace/src/profiling/profilers/cpu.js +3 -3
  41. package/packages/dd-trace/src/proxy.js +16 -12
  42. package/packages/dd-trace/src/startup-log.js +8 -19
  43. package/packages/dd-trace/src/telemetry.js +1 -14
  44. package/scripts/install_plugin_modules.js +17 -26
@@ -18,7 +18,6 @@ require,methods,MIT,Copyright 2013-2014 TJ Holowaychuk
18
18
  require,module-details-from-path,MIT,Copyright 2016 Thomas Watson Steen
19
19
  require,opentracing,MIT,Copyright 2016 Resonance Labs Inc
20
20
  require,path-to-regexp,MIT,Copyright 2014 Blake Embrey
21
- require,performance-now,MIT,Copyright 2013 Braveg1rl
22
21
  require,retry,MIT,Copyright 2011 Tim Koschützki Felix Geisendörfer
23
22
  require,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
24
23
  dev,autocannon,MIT,Copyright 2016 Matteo Collina
package/ext/formats.js CHANGED
@@ -1,10 +1,8 @@
1
1
  'use strict'
2
2
 
3
- const opentracing = require('opentracing')
4
-
5
3
  module.exports = {
6
- TEXT_MAP: opentracing.FORMAT_TEXT_MAP,
7
- HTTP_HEADERS: opentracing.FORMAT_HTTP_HEADERS,
8
- BINARY: opentracing.FORMAT_BINARY,
4
+ TEXT_MAP: 'text_map',
5
+ HTTP_HEADERS: 'http_headers',
6
+ BINARY: 'binary',
9
7
  LOG: 'log'
10
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "2.12.0",
3
+ "version": "2.13.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -59,9 +59,9 @@
59
59
  },
60
60
  "dependencies": {
61
61
  "@datadog/native-appsec": "^1.2.1",
62
- "@datadog/native-metrics": "^1.4.1",
63
- "@datadog/pprof": "^1.0.0",
64
- "@datadog/sketches-js": "^1.0.5",
62
+ "@datadog/native-metrics": "^1.4.2",
63
+ "@datadog/pprof": "^1.0.2",
64
+ "@datadog/sketches-js": "^2.0.0",
65
65
  "@types/node": ">=12",
66
66
  "crypto-randomuuid": "^1.0.0",
67
67
  "diagnostics_channel": "^1.1.0",
@@ -77,7 +77,6 @@
77
77
  "module-details-from-path": "^1.0.3",
78
78
  "opentracing": ">=0.12.1",
79
79
  "path-to-regexp": "^0.1.2",
80
- "performance-now": "^2.1.0",
81
80
  "retry": "^0.10.1",
82
81
  "semver": "^5.5.0"
83
82
  },
@@ -1,54 +1,3 @@
1
1
  'use strict'
2
2
 
3
- require('./src/amqplib')
4
- require('./src/amqp10')
5
- require('./src/aws-sdk')
6
- require('./src/bluebird')
7
- require('./src/bunyan')
8
- require('./src/cassandra-driver')
9
- require('./src/connect')
10
- require('./src/couchbase')
11
- require('./src/cucumber')
12
- require('./src/dns')
13
- require('./src/elasticsearch')
14
- require('./src/express')
15
- require('./src/fastify')
16
- require('./src/find-my-way')
17
- require('./src/generic-pool')
18
- require('./src/google-cloud-pubsub')
19
- require('./src/graphql')
20
- require('./src/grpc')
21
- require('./src/hapi')
22
- require('./src/http')
23
- require('./src/http2')
24
- require('./src/ioredis')
25
- require('./src/jest')
26
- require('./src/kafkajs')
27
- require('./src/knex')
28
- require('./src/koa')
29
- require('./src/memcached')
30
- require('./src/microgateway-core')
31
- require('./src/moleculer')
32
- require('./src/mongodb-core')
33
- require('./src/mongoose')
34
- require('./src/mysql')
35
- require('./src/mysql2')
36
- require('./src/mocha')
37
- require('./src/net')
38
- require('./src/next')
39
- require('./src/oracledb')
40
- require('./src/paperplane')
41
- require('./src/pino')
42
- require('./src/pg')
43
- require('./src/promise')
44
- require('./src/promise-js')
45
- require('./src/q')
46
- require('./src/redis')
47
- require('./src/restify')
48
- require('./src/router')
49
- require('./src/rhea')
50
- require('./src/sharedb')
51
- require('./src/tedious')
52
- require('./src/when')
53
- require('./src/winston')
54
- require('./src/limitd-client')
3
+ require('./src/helpers/register')
@@ -78,12 +78,12 @@ function wrapLayerHandle (layer) {
78
78
 
79
79
  try {
80
80
  return original.apply(this, arguments)
81
- } catch (e) {
82
- errorChannel.publish(e)
81
+ } catch (error) {
82
+ errorChannel.publish({ req, error })
83
83
  nextChannel.publish({ req })
84
84
  exitChannel.publish({ req })
85
85
 
86
- throw e
86
+ throw error
87
87
  }
88
88
  })
89
89
  })
@@ -92,13 +92,13 @@ function wrapLayerHandle (layer) {
92
92
  function wrapNext (req, next) {
93
93
  return function (error) {
94
94
  if (error) {
95
- errorChannel.publish(error)
95
+ errorChannel.publish({ req, error })
96
96
  }
97
97
 
98
98
  nextChannel.publish({ req })
99
99
  exitChannel.publish({ req })
100
100
 
101
- next.apply(null, arguments)
101
+ next.apply(this, arguments)
102
102
  }
103
103
  }
104
104
 
@@ -6,7 +6,6 @@ const { addHook, channel, AsyncResource } = require('./helpers/instrument')
6
6
  const errorChannel = channel('apm:fastify:middleware:error')
7
7
  const handleChannel = channel('apm:fastify:request:handle')
8
8
 
9
- const requestResources = new WeakMap()
10
9
  const parsingResources = new WeakMap()
11
10
 
12
11
  function wrapFastify (fastify, hasParsingEvents) {
@@ -42,16 +41,13 @@ function wrapAddHook (addHook) {
42
41
 
43
42
  arguments[arguments.length - 1] = shimmer.wrap(fn, function (request, reply, done) {
44
43
  const req = getReq(request)
45
- const requestResource = requestResources.get(req)
46
-
47
- if (!requestResource) return fn.apply(this, arguments)
48
44
 
49
45
  try {
50
46
  if (typeof done === 'function') {
51
47
  done = arguments[arguments.length - 1]
52
48
 
53
49
  arguments[arguments.length - 1] = function (err) {
54
- publishError(err, requestResource)
50
+ publishError(err, req)
55
51
 
56
52
  if (name === 'onRequest' || name === 'preParsing') {
57
53
  const parsingResource = new AsyncResource('bound-anonymous-fn')
@@ -71,13 +67,13 @@ function wrapAddHook (addHook) {
71
67
  const promise = fn.apply(this, arguments)
72
68
 
73
69
  if (promise && typeof promise.catch === 'function') {
74
- return promise.catch(err => publishError(err, requestResource))
70
+ return promise.catch(err => publishError(err, req))
75
71
  }
76
72
 
77
73
  return promise
78
74
  }
79
75
  } catch (e) {
80
- throw publishError(e, requestResource)
76
+ throw publishError(e, req)
81
77
  }
82
78
  })
83
79
 
@@ -90,14 +86,10 @@ function onRequest (request, reply, done) {
90
86
 
91
87
  const req = getReq(request)
92
88
  const res = getRes(reply)
93
- const requestResource = new AsyncResource('bound-anonymous-fn')
94
89
 
95
- requestResources.set(req, requestResource)
90
+ handleChannel.publish({ req, res })
96
91
 
97
- return requestResource.runInAsyncScope(() => {
98
- handleChannel.publish({ req, res })
99
- return done()
100
- })
92
+ return done()
101
93
  }
102
94
 
103
95
  function preHandler (request, reply, done) {
@@ -105,9 +97,8 @@ function preHandler (request, reply, done) {
105
97
  if (!reply || typeof reply.send !== 'function') return done()
106
98
 
107
99
  const req = getReq(request)
108
- const requestResource = requestResources.get(req)
109
100
 
110
- reply.send = wrapSend(reply.send, requestResource)
101
+ reply.send = wrapSend(reply.send, req)
111
102
 
112
103
  done()
113
104
  }
@@ -133,12 +124,10 @@ function preParsing (request, reply, payload, done) {
133
124
  parsingResource.runInAsyncScope(() => done())
134
125
  }
135
126
 
136
- function wrapSend (send, resource) {
137
- return function sendWithTrace (payload) {
138
- if (payload instanceof Error) {
139
- resource.runInAsyncScope(() => {
140
- errorChannel.publish(payload)
141
- })
127
+ function wrapSend (send, req) {
128
+ return function sendWithTrace (error) {
129
+ if (error instanceof Error) {
130
+ errorChannel.publish({ req, error })
142
131
  }
143
132
 
144
133
  return send.apply(this, arguments)
@@ -153,11 +142,9 @@ function getRes (reply) {
153
142
  return reply && (reply.raw || reply.res || reply)
154
143
  }
155
144
 
156
- function publishError (error, resource) {
145
+ function publishError (error, req) {
157
146
  if (error) {
158
- resource.runInAsyncScope(() => {
159
- errorChannel.publish(error)
160
- })
147
+ errorChannel.publish({ error, req })
161
148
  }
162
149
 
163
150
  return error
@@ -0,0 +1,68 @@
1
+ 'use strict'
2
+
3
+ module.exports = {
4
+ '@cucumber/cucumber': () => require('../cucumber'),
5
+ '@elastic/elasticsearch': () => require('../elasticsearch'),
6
+ '@elastic/transport': () => require('../elasticsearch'),
7
+ '@google-cloud/pubsub': () => require('../google-cloud-pubsub'),
8
+ '@grpc/grpc-js': () => require('../grpc'),
9
+ '@hapi/hapi': () => require('../hapi'),
10
+ '@koa/router': () => require('../koa'),
11
+ '@node-redis/client': () => require('../redis'),
12
+ 'amqp10': () => require('../amqp10'),
13
+ 'amqplib': () => require('../amqplib'),
14
+ 'aws-sdk': () => require('../aws-sdk'),
15
+ 'bluebird': () => require('../bluebird'),
16
+ 'bunyan': () => require('../bunyan'),
17
+ 'cassandra-driver': () => require('../cassandra-driver'),
18
+ 'connect': () => require('../connect'),
19
+ 'couchbase': () => require('../couchbase'),
20
+ 'cypress': () => require('../cypress'),
21
+ 'dns': () => require('../dns'),
22
+ 'elasticsearch': () => require('../elasticsearch'),
23
+ 'express': () => require('../express'),
24
+ 'fastify': () => require('../fastify'),
25
+ 'find-my-way': () => require('../find-my-way'),
26
+ 'graphql': () => require('../graphql'),
27
+ 'grpc': () => require('../grpc'),
28
+ 'hapi': () => require('../hapi'),
29
+ 'http': () => require('../http'),
30
+ 'http2': () => require('../http2'),
31
+ 'https': () => require('../http'),
32
+ 'ioredis': () => require('../ioredis'),
33
+ 'jest-environment-node': () => require('../jest'),
34
+ 'jest-environment-jsdom': () => require('../jest'),
35
+ 'jest-jasmine2': () => require('../jest'),
36
+ 'koa': () => require('../koa'),
37
+ 'koa-router': () => require('../koa'),
38
+ 'kafkajs': () => require('../kafkajs'),
39
+ 'limitd-client': () => require('../limitd-client'),
40
+ 'memcached': () => require('../memcached'),
41
+ 'microgateway-core': () => require('../microgateway-core'),
42
+ 'mocha': () => require('../mocha'),
43
+ 'mocha-each': () => require('../mocha'),
44
+ 'moleculer': () => require('../moleculer'),
45
+ 'mongodb': () => require('../mongodb-core'),
46
+ 'mongodb-core': () => require('../mongodb-core'),
47
+ 'mongoose': () => require('../mongoose'),
48
+ 'mysql': () => require('../mysql'),
49
+ 'mysql2': () => require('../mysql2'),
50
+ 'net': () => require('../net'),
51
+ 'next': () => require('../next'),
52
+ 'oracledb': () => require('../oracledb'),
53
+ 'paperplane': () => require('../paperplane'),
54
+ 'pg': () => require('../pg'),
55
+ 'pino': () => require('../pino'),
56
+ 'pino-pretty': () => require('../pino'),
57
+ 'promise-js': () => require('../promise-js'),
58
+ 'promise': () => require('../promise'),
59
+ 'q': () => require('../q'),
60
+ 'redis': () => require('../redis'),
61
+ 'restify': () => require('../restify'),
62
+ 'rhea': () => require('../rhea'),
63
+ 'router': () => require('../router'),
64
+ 'sharedb': () => require('../sharedb'),
65
+ 'tedious': () => require('../tedious'),
66
+ 'when': () => require('../when'),
67
+ 'winston': () => require('../winston')
68
+ }
@@ -1,16 +1,12 @@
1
1
  'use strict'
2
2
 
3
3
  const dc = require('diagnostics_channel')
4
- const path = require('path')
5
4
  const semver = require('semver')
6
- const Hook = require('./hook')
7
- const requirePackageJson = require('../../../dd-trace/src/require-package-json')
5
+ const instrumentations = require('./instrumentations')
8
6
  const { AsyncResource } = require('async_hooks')
9
- const log = require('../../../dd-trace/src/log')
10
7
 
11
- const pathSepExpr = new RegExp(`\\${path.sep}`, 'g')
12
8
  const channelMap = {}
13
- exports.channel = function channel (name) {
9
+ exports.channel = function (name) {
14
10
  const maybe = channelMap[name]
15
11
  if (maybe) return maybe
16
12
  const ch = dc.channel(name)
@@ -19,36 +15,11 @@ exports.channel = function channel (name) {
19
15
  }
20
16
 
21
17
  exports.addHook = function addHook ({ name, versions, file }, hook) {
22
- const fullFilename = filename(name, file)
23
-
24
- Hook([name], (moduleExports, moduleName, moduleBaseDir) => {
25
- moduleName = moduleName.replace(pathSepExpr, '/')
26
-
27
- if (moduleName !== fullFilename || !matchVersion(getVersion(moduleBaseDir), versions)) {
28
- return moduleExports
29
- }
30
-
31
- try {
32
- return hook(moduleExports)
33
- } catch (e) {
34
- log.error(e)
35
- return moduleExports
36
- }
37
- })
38
- }
39
-
40
- function matchVersion (version, ranges) {
41
- return !version || (ranges && ranges.some(range => semver.satisfies(semver.coerce(version), range)))
42
- }
43
-
44
- function getVersion (moduleBaseDir) {
45
- if (moduleBaseDir) {
46
- return requirePackageJson(moduleBaseDir, module).version
18
+ if (!instrumentations[name]) {
19
+ instrumentations[name] = []
47
20
  }
48
- }
49
21
 
50
- function filename (name, file) {
51
- return [name, file].filter(val => val).join('/')
22
+ instrumentations[name].push({ name, versions, file, hook })
52
23
  }
53
24
 
54
25
  // AsyncResource.bind exists and binds `this` properly only from 17.8.0 and up.
@@ -0,0 +1,3 @@
1
+ 'use strict'
2
+
3
+ module.exports = {}
@@ -0,0 +1,59 @@
1
+ 'use strict'
2
+
3
+ const { channel } = require('diagnostics_channel')
4
+ const path = require('path')
5
+ const semver = require('semver')
6
+ const Hook = require('./hook')
7
+ const requirePackageJson = require('../../../dd-trace/src/require-package-json')
8
+ const log = require('../../../dd-trace/src/log')
9
+
10
+ const hooks = require('./hooks')
11
+ const instrumentations = require('./instrumentations')
12
+ const names = Object.keys(hooks)
13
+ const pathSepExpr = new RegExp(`\\${path.sep}`, 'g')
14
+
15
+ const loadChannel = channel('dd-trace:instrumentation:load')
16
+
17
+ // TODO: make this more efficient
18
+
19
+ for (const packageName of names) {
20
+ Hook([packageName], (moduleExports, moduleName, moduleBaseDir) => {
21
+ moduleName = moduleName.replace(pathSepExpr, '/')
22
+
23
+ hooks[packageName]()
24
+
25
+ for (const { name, file, versions, hook } of instrumentations[packageName]) {
26
+ const fullFilename = filename(name, file)
27
+
28
+ if (moduleName === fullFilename) {
29
+ const version = getVersion(moduleBaseDir)
30
+
31
+ if (matchVersion(version, versions)) {
32
+ try {
33
+ loadChannel.publish({ name, version, file })
34
+
35
+ moduleExports = hook(moduleExports)
36
+ } catch (e) {
37
+ log.error(e)
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ return moduleExports
44
+ })
45
+ }
46
+
47
+ function matchVersion (version, ranges) {
48
+ return !version || (ranges && ranges.some(range => semver.satisfies(semver.coerce(version), range)))
49
+ }
50
+
51
+ function getVersion (moduleBaseDir) {
52
+ if (moduleBaseDir) {
53
+ return requirePackageJson(moduleBaseDir, module).version
54
+ }
55
+ }
56
+
57
+ function filename (name, file) {
58
+ return [name, file].filter(val => val).join('/')
59
+ }
@@ -126,13 +126,13 @@ function wrapMiddleware (fn, layer) {
126
126
  }
127
127
 
128
128
  function fulfill (ctx, error) {
129
- if (error) {
130
- errorChannel.publish(error)
131
- }
132
-
133
129
  const req = ctx.req
134
130
  const route = ctx.routePath
135
131
 
132
+ if (error) {
133
+ errorChannel.publish({ req, error })
134
+ }
135
+
136
136
  // TODO: make sure that the parent class cannot override this in `enter`
137
137
  if (route) {
138
138
  routeChannel.publish({ req, route })
@@ -145,7 +145,7 @@ function wrapNext (req, next) {
145
145
  return function () {
146
146
  nextChannel.publish({ req })
147
147
 
148
- return next.apply(null, arguments)
148
+ return next.apply(this, arguments)
149
149
  }
150
150
  }
151
151
 
@@ -153,7 +153,10 @@ function mochaHook (Runner) {
153
153
  if (isHook && testOrHook.ctx) {
154
154
  test = testOrHook.ctx.currentTest
155
155
  }
156
- const asyncResource = getTestAsyncResource(test)
156
+ let asyncResource
157
+ if (test) {
158
+ asyncResource = getTestAsyncResource(test)
159
+ }
157
160
  if (asyncResource) {
158
161
  asyncResource.runInAsyncScope(() => {
159
162
  if (isHook) {
@@ -6,7 +6,10 @@ const handlers = ['use', 'pre']
6
6
  const methods = ['del', 'get', 'head', 'opts', 'post', 'put', 'patch']
7
7
 
8
8
  const handleChannel = channel('apm:restify:request:handle')
9
- const routeChannel = channel('apm:restify:request:route')
9
+ const errorChannel = channel('apm:restify:middleware:error')
10
+ const enterChannel = channel('apm:restify:middleware:enter')
11
+ const exitChannel = channel('apm:restify:middleware:exit')
12
+ const nextChannel = channel('apm:restify:middleware:next')
10
13
 
11
14
  function wrapSetupRequest (setupRequest) {
12
15
  return function (req, res) {
@@ -37,18 +40,37 @@ function wrapFn (fn) {
37
40
  if (Array.isArray(fn)) return wrapMiddleware(fn)
38
41
 
39
42
  return function (req, res, next) {
40
- if (req.route) {
41
- routeChannel.publish({ req, route: req.route })
43
+ if (typeof next === 'function') {
44
+ arguments[2] = wrapNext(req, next)
42
45
  }
43
46
 
44
- return fn.apply(this, arguments)
47
+ const route = req.route && req.route.path
48
+
49
+ enterChannel.publish({ req, route })
50
+
51
+ try {
52
+ return fn.apply(this, arguments)
53
+ } catch (error) {
54
+ errorChannel.publish({ req, error })
55
+ nextChannel.publish({ req })
56
+ exitChannel.publish({ req })
57
+ }
58
+ }
59
+ }
60
+
61
+ function wrapNext (req, next) {
62
+ return function () {
63
+ nextChannel.publish({ req })
64
+ exitChannel.publish({ req })
65
+
66
+ next.apply(this, arguments)
45
67
  }
46
68
  }
47
69
 
48
70
  addHook({ name: 'restify', versions: ['>=3'], file: 'lib/server.js' }, Server => {
49
71
  shimmer.wrap(Server.prototype, '_setupRequest', wrapSetupRequest)
50
72
  shimmer.massWrap(Server.prototype, handlers, wrapHandler)
51
- shimmer.wrap(Server.prototype, methods, wrapMethod)
73
+ shimmer.massWrap(Server.prototype, methods, wrapMethod)
52
74
 
53
75
  return Server
54
76
  })
@@ -49,12 +49,12 @@ function createWrapRouterMethod (name) {
49
49
 
50
50
  try {
51
51
  return original.apply(this, arguments)
52
- } catch (e) {
53
- errorChannel.publish(e)
52
+ } catch (error) {
53
+ errorChannel.publish({ req, error })
54
54
  nextChannel.publish({ req })
55
55
  exitChannel.publish({ req })
56
56
 
57
- throw e
57
+ throw error
58
58
  }
59
59
  })
60
60
  })
@@ -91,13 +91,13 @@ function createWrapRouterMethod (name) {
91
91
  function wrapNext (req, next) {
92
92
  return function (error) {
93
93
  if (error) {
94
- errorChannel.publish(error)
94
+ errorChannel.publish({ req, error })
95
95
  }
96
96
 
97
97
  nextChannel.publish({ req })
98
98
  exitChannel.publish({ req })
99
99
 
100
- next.apply(null, arguments)
100
+ next.apply(this, arguments)
101
101
  }
102
102
  }
103
103
 
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
2
 
3
- const Tags = require('opentracing').Tags
4
3
  const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
5
4
  const Plugin = require('../../dd-trace/src/plugins/plugin')
6
5
  const { storage } = require('../../datadog-core')
@@ -33,7 +32,7 @@ class BaseAwsSdkPlugin extends Plugin {
33
32
  const serviceName = this.getServiceName(serviceIdentifier)
34
33
  const childOf = this.tracer.scope().active()
35
34
  const tags = {
36
- [Tags.SPAN_KIND]: 'client',
35
+ 'span.kind': 'client',
37
36
  'service.name': serviceName,
38
37
  'aws.operation': operation,
39
38
  'aws.region': awsRegion,
@@ -1,6 +1,5 @@
1
1
  'use strict'
2
2
 
3
- const Tags = require('opentracing').Tags
4
3
  const log = require('../../../dd-trace/src/log')
5
4
  const BaseAwsSdkPlugin = require('../base')
6
5
  const { storage } = require('../../../datadog-core')
@@ -25,7 +24,7 @@ class Sqs extends BaseAwsSdkPlugin {
25
24
  tags: Object.assign(
26
25
  {},
27
26
  this.requestTags.get(request) || {},
28
- { [Tags.SPAN_KIND]: 'server' }
27
+ { 'span.kind': 'server' }
29
28
  )
30
29
  }
31
30
  const span = plugin.tracer.startSpan('aws.response', options)
@@ -161,12 +161,12 @@ class MochaPlugin extends Plugin {
161
161
  const testSuiteSpan = this._testSuites.get(test.parent)
162
162
 
163
163
  if (testSuiteSpan) {
164
- const testSuiteId = testSuiteSpan.context()._spanId.toString('hex')
164
+ const testSuiteId = testSuiteSpan.context()._spanId.toString(16)
165
165
  testSuiteTags[TEST_SUITE_ID] = testSuiteId
166
166
  }
167
167
 
168
168
  if (this.testSessionSpan) {
169
- const testSessionId = this.testSessionSpan.context()._traceId.toString('hex')
169
+ const testSessionId = this.testSessionSpan.context()._traceId.toString(16)
170
170
  testSuiteTags[TEST_SESSION_ID] = testSessionId
171
171
  testSuiteTags[TEST_COMMAND] = this.command
172
172
  }
@@ -19,6 +19,13 @@ class RestifyPlugin extends RouterPlugin {
19
19
  web.setRoute(req, route)
20
20
  })
21
21
  }
22
+
23
+ configure (config) {
24
+ return super.configure({
25
+ ...config,
26
+ middleware: false // not supported
27
+ })
28
+ }
22
29
  }
23
30
 
24
31
  module.exports = RestifyPlugin
@@ -16,7 +16,10 @@ class RouterPlugin extends WebPlugin {
16
16
  this._contexts = new WeakMap()
17
17
 
18
18
  this.addSub(`apm:${this.constructor.name}:middleware:enter`, ({ req, name, route }) => {
19
- const childOf = this._getActive(req)
19
+ const childOf = this._getActive(req) || this._getStoreSpan()
20
+
21
+ if (!childOf) return
22
+
20
23
  const span = this._getMiddlewareSpan(name, childOf)
21
24
  const context = this._createContext(req, route, childOf)
22
25
 
@@ -46,14 +49,16 @@ class RouterPlugin extends WebPlugin {
46
49
  context.middleware.pop().finish()
47
50
  })
48
51
 
49
- this.addSub(`apm:${this.constructor.name}:middleware:error`, err => {
50
- const store = storage.getStore()
52
+ this.addSub(`apm:${this.constructor.name}:middleware:error`, ({ req, error }) => {
53
+ web.addError(req, error)
51
54
 
52
- web.addError(store.req, err)
55
+ if (!this.config.middleware) return
53
56
 
54
- if (this.config.middleware) {
55
- this.addError(err)
56
- }
57
+ const span = this._getActive(req)
58
+
59
+ if (!span) return
60
+
61
+ span.setTag('error', error)
57
62
  })
58
63
 
59
64
  this.addSub(`apm:http:server:request:finish`, ({ req }) => {
@@ -72,7 +77,7 @@ class RouterPlugin extends WebPlugin {
72
77
  _getActive (req) {
73
78
  const context = this._contexts.get(req)
74
79
 
75
- if (!context) return this._getStoreSpan()
80
+ if (!context) return
76
81
  if (context.middleware.length === 0) return context.span
77
82
 
78
83
  return context.middleware[context.middleware.length - 1]