dd-trace 0.36.1 → 0.36.5

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 (78) hide show
  1. package/LICENSE-3rdparty.csv +5 -6
  2. package/index.d.ts +10 -0
  3. package/package.json +4 -5
  4. package/packages/datadog-plugin-aws-sdk/src/index.js +3 -5
  5. package/packages/datadog-plugin-cucumber/src/index.js +1 -2
  6. package/packages/datadog-plugin-elasticsearch/src/index.js +23 -26
  7. package/packages/datadog-plugin-fastify/src/fastify.js +53 -0
  8. package/packages/datadog-plugin-graphql/src/index.js +6 -6
  9. package/packages/datadog-plugin-http/src/client.js +13 -9
  10. package/packages/datadog-plugin-jest/src/index.js +26 -7
  11. package/packages/datadog-plugin-mocha/src/index.js +7 -2
  12. package/packages/datadog-plugin-mongodb-core/src/unified.js +42 -1
  13. package/packages/datadog-plugin-next/src/index.js +70 -8
  14. package/packages/datadog-plugin-tedious/src/index.js +0 -8
  15. package/packages/dd-trace/lib/version.js +1 -1
  16. package/packages/dd-trace/src/dogstatsd.js +15 -6
  17. package/packages/dd-trace/src/histogram.js +4 -10
  18. package/packages/dd-trace/src/plugins/util/web.js +1 -0
  19. package/packages/dd-trace/src/proxy.js +9 -2
  20. package/prebuilds/darwin-ia32/node-57.node +0 -0
  21. package/prebuilds/darwin-ia32/node-59.node +0 -0
  22. package/prebuilds/darwin-ia32/node-64.node +0 -0
  23. package/prebuilds/darwin-ia32/node-67.node +0 -0
  24. package/prebuilds/darwin-ia32/node-72.node +0 -0
  25. package/prebuilds/darwin-ia32/node-79.node +0 -0
  26. package/prebuilds/darwin-ia32/node-83.node +0 -0
  27. package/prebuilds/darwin-ia32/node-88.node +0 -0
  28. package/prebuilds/darwin-ia32/node-93.node +0 -0
  29. package/prebuilds/darwin-x64/node-57.node +0 -0
  30. package/prebuilds/darwin-x64/node-59.node +0 -0
  31. package/prebuilds/darwin-x64/node-64.node +0 -0
  32. package/prebuilds/darwin-x64/node-67.node +0 -0
  33. package/prebuilds/darwin-x64/node-72.node +0 -0
  34. package/prebuilds/darwin-x64/node-79.node +0 -0
  35. package/prebuilds/darwin-x64/node-83.node +0 -0
  36. package/prebuilds/darwin-x64/node-88.node +0 -0
  37. package/prebuilds/darwin-x64/node-93.node +0 -0
  38. package/prebuilds/linux-ia32/node-57.node +0 -0
  39. package/prebuilds/linux-ia32/node-59.node +0 -0
  40. package/prebuilds/linux-ia32/node-64.node +0 -0
  41. package/prebuilds/linux-ia32/node-67.node +0 -0
  42. package/prebuilds/linux-ia32/node-72.node +0 -0
  43. package/prebuilds/linux-ia32/node-79.node +0 -0
  44. package/prebuilds/linux-x64/node-57.node +0 -0
  45. package/prebuilds/linux-x64/node-59.node +0 -0
  46. package/prebuilds/linux-x64/node-64.node +0 -0
  47. package/prebuilds/linux-x64/node-67.node +0 -0
  48. package/prebuilds/linux-x64/node-72.node +0 -0
  49. package/prebuilds/linux-x64/node-79.node +0 -0
  50. package/prebuilds/linux-x64/node-83.node +0 -0
  51. package/prebuilds/linux-x64/node-88.node +0 -0
  52. package/prebuilds/linux-x64/node-93.node +0 -0
  53. package/prebuilds/win32-ia32/node-57.node +0 -0
  54. package/prebuilds/win32-ia32/node-59.node +0 -0
  55. package/prebuilds/win32-ia32/node-64.node +0 -0
  56. package/prebuilds/win32-ia32/node-67.node +0 -0
  57. package/prebuilds/win32-ia32/node-72.node +0 -0
  58. package/prebuilds/win32-ia32/node-79.node +0 -0
  59. package/prebuilds/win32-ia32/node-83.node +0 -0
  60. package/prebuilds/win32-ia32/node-88.node +0 -0
  61. package/prebuilds/win32-ia32/node-93.node +0 -0
  62. package/prebuilds/win32-x64/node-57.node +0 -0
  63. package/prebuilds/win32-x64/node-59.node +0 -0
  64. package/prebuilds/win32-x64/node-64.node +0 -0
  65. package/prebuilds/win32-x64/node-67.node +0 -0
  66. package/prebuilds/win32-x64/node-72.node +0 -0
  67. package/prebuilds/win32-x64/node-79.node +0 -0
  68. package/prebuilds/win32-x64/node-83.node +0 -0
  69. package/prebuilds/win32-x64/node-88.node +0 -0
  70. package/prebuilds/win32-x64/node-93.node +0 -0
  71. package/scripts/check_licenses.js +38 -17
  72. package/scripts/postpublish.js +16 -3
  73. package/scripts/prebuilds.js +2 -2
  74. package/scripts/prepublish.js +1 -1
  75. package/scripts/version.js +31 -22
  76. package/NOTICE +0 -4
  77. package/packages/dd-trace/src/metrics_worker.js +0 -18
  78. package/scripts/tracer-runner.js +0 -13
@@ -1,7 +1,7 @@
1
1
  Component,Origin,License,Copyright
2
+ require,@datadog/sketches-js,Apache license 2.0,Copyright 2020 Datadog Inc.
2
3
  require,@types/node,MIT,Copyright Authors
3
4
  require,form-data,MIT,Copyright 2012 Felix Geisendörfer and contributors
4
- require,hdr-histogram-js,BSD-2-Clause,Copyright 2016 Alexandre Victoor
5
5
  require,koalas,MIT,Copyright 2013-2017 Brian Woodward
6
6
  require,limiter,MIT,Copyright 2011 John Hurliman
7
7
  require,lodash.kebabcase,MIT,Copyright JS Foundation and other contributors
@@ -10,18 +10,16 @@ require,lodash.sortby,MIT,Copyright JS Foundation and other contributors
10
10
  require,lodash.uniq,MIT,Copyright JS Foundation and other contributors
11
11
  require,methods,MIT,Copyright 2013-2014 TJ Holowaychuk
12
12
  require,module-details-from-path,MIT,Copyright 2016 Thomas Watson Steen
13
- require,msgpack-lite,MIT,Copyright 2015 Yusuke Kawasaki
14
- require,multer,MIT,Copyright 2014 Hage Yaapa
15
13
  require,nan,MIT,Copyright 2018 NAN contributors
16
14
  require,node-gyp-build,MIT,Copyright 2017 Mathias Buus
17
15
  require,opentracing,MIT,Copyright 2016 Resonance Labs Inc
18
16
  require,path-to-regexp,MIT,Copyright 2014 Blake Embrey
19
17
  require,performance-now,MIT,Copyright 2013 Braveg1rl
20
18
  require,protobufjs,BSD-3-Clause,Copyright 2016 Daniel Wirtz
19
+ require,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
21
20
  require,shimmer,BSD-2-Clause,Copyright Forrest L Norvell
22
21
  require,source-map,BSD-3-Clause,Copyright 2009-2011 Mozilla Foundation and contributors
23
22
  require,source-map-resolve,MIT,Copyright 2014-2020 Simon Lydell 2019 Jinxiang
24
- require,tar,ISC,Copyright Isaac Z. Schlueter and Contributors
25
23
  dev,autocannon,MIT,Copyright 2016 Matteo Collina
26
24
  dev,axios,MIT,Copyright 2014-present Matt Zabriskie
27
25
  dev,benchmark,MIT,Copyright 2010-2016 Mathias Bynens Robert Kieffer John-David Dalton
@@ -48,16 +46,17 @@ dev,int64-buffer,MIT,Copyright 2015-2016 Yusuke Kawasaki
48
46
  dev,jszip,MIT,Copyright 2015-2016 Stuart Knightley and contributors
49
47
  dev,mkdirp,MIT,Copyright 2010 James Halliday
50
48
  dev,mocha,MIT,Copyright 2011-2018 JS Foundation and contributors https://js.foundation
49
+ dev,multer,MIT,Copyright 2014 Hage Yaapa
50
+ dev,msgpack-lite,MIT,Copyright 2015 Yusuke Kawasaki
51
51
  dev,nock,MIT,Copyright 2017 Pedro Teixeira and other contributors
52
52
  dev,nyc,ISC,Copyright 2015 Contributors
53
53
  dev,proxyquire,MIT,Copyright 2013 Thorsten Lorenz
54
- dev,resolve,MIT,Copyright 2012 James Halliday
55
54
  dev,retry,MIT,Copyright 2011 Tim Koschützki Felix Geisendörfer
56
55
  dev,rimraf,ISC,Copyright Isaac Z. Schlueter and Contributors
57
- dev,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
58
56
  dev,sinon,BSD-3-Clause,Copyright 2010-2017 Christian Johansen
59
57
  dev,sinon-chai,WTFPL and BSD-2-Clause,Copyright 2004 Sam Hocevar 2012–2017 Domenic Denicola
60
58
  dev,tape,MIT,Copyright James Halliday
59
+ dev,tar,ISC,Copyright Isaac Z. Schlueter and Contributors
61
60
  dev,wait-on,MIT,Copyright 2015 Jeff Barczewski
62
61
  file,profile.proto,Apache license 2.0,Copyright 2016 Google Inc.
63
62
  file,TDigest.h,Apache license 2.0,Copyright Derrick R. Burns
package/index.d.ts CHANGED
@@ -886,6 +886,16 @@ declare namespace plugins {
886
886
  */
887
887
  depth?: number;
888
888
 
889
+ /**
890
+ * Whether to include the source of the operation within the query as a tag
891
+ * on every span. This may contain sensitive information and sould only be
892
+ * enabled if sensitive data is always sent as variables and not in the
893
+ * query text.
894
+ *
895
+ * @default false
896
+ */
897
+ source?: boolean;
898
+
889
899
  /**
890
900
  * An array of variable names to record. Can also be a callback that returns
891
901
  * the key/value pairs to record. For example, using
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "0.36.1",
3
+ "version": "0.36.5",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "bench:e2e": "SERVICES=mongo yarn services && cd benchmark/e2e && node benchmark-run.js --duration=30",
18
18
  "type:doc": "cd docs && yarn && yarn build",
19
19
  "type:test": "cd docs && yarn && yarn test",
20
- "lint": "node scripts/check_licenses.js && eslint .",
20
+ "lint": "node scripts/check_licenses.js && eslint . && yarn audit --groups dependencies",
21
21
  "services": "node ./scripts/install_plugin_modules && node packages/dd-trace/test/setup/services",
22
22
  "tdd": "node scripts/tdd.js",
23
23
  "test": "SERVICES=* yarn services && mocha --exit --expose-gc 'packages/dd-trace/test/setup/node.js' 'packages/*/test/**/*.spec.js'",
@@ -55,9 +55,9 @@
55
55
  "node": ">=8"
56
56
  },
57
57
  "dependencies": {
58
+ "@datadog/sketches-js": "^1.0.4",
58
59
  "@types/node": "^10.12.18",
59
60
  "form-data": "^3.0.0",
60
- "hdr-histogram-js": "^2.0.1",
61
61
  "koalas": "^1.0.2",
62
62
  "limiter": "^1.1.4",
63
63
  "lodash.kebabcase": "^4.1.1",
@@ -66,14 +66,12 @@
66
66
  "lodash.uniq": "^4.5.0",
67
67
  "methods": "^1.1.2",
68
68
  "module-details-from-path": "^1.0.3",
69
- "multer": "^1.4.2",
70
69
  "nan": "^2.12.1",
71
70
  "node-gyp-build": "^3.8.0",
72
71
  "opentracing": ">=0.12.1",
73
72
  "path-to-regexp": "^0.1.2",
74
73
  "performance-now": "^2.1.0",
75
74
  "protobufjs": "^6.9.0",
76
- "resolve": "^1.20.0",
77
75
  "semver": "^5.5.0",
78
76
  "shimmer": "1.2.1",
79
77
  "source-map": "^0.7.3",
@@ -106,6 +104,7 @@
106
104
  "mocha": "^5.2.0",
107
105
  "mocha-junit-reporter": "^2.0.0",
108
106
  "mocha-multi-reporters": "^1.5.1",
107
+ "multer": "^1.4.2",
109
108
  "msgpack-lite": "^0.1.26",
110
109
  "nock": "^11.3.3",
111
110
  "nyc": "^14.1.1",
@@ -89,11 +89,9 @@ function getHooks (config) {
89
89
 
90
90
  // TODO: test splitByAwsService when the test suite is fixed
91
91
  function getServiceName (serviceIdentifier, tracer, config) {
92
- const service = config.service || tracer._service
93
-
94
- return config.splitByAwsService
95
- ? `${service}-aws-${serviceIdentifier}`
96
- : service
92
+ return config.service
93
+ ? config.service
94
+ : `${tracer._service}-aws-${serviceIdentifier}`
97
95
  }
98
96
 
99
97
  // <2.1.35 has breaking changes for instrumentation
@@ -1,5 +1,4 @@
1
1
  const { relative } = require('path')
2
- const resolve = require('resolve')
3
2
 
4
3
  const { SAMPLING_RULE_DECISION } = require('../../dd-trace/src/constants')
5
4
 
@@ -132,7 +131,7 @@ module.exports = [
132
131
  const testEnvironmentMetadata = getTestEnvironmentMetadata('cucumber')
133
132
  const sourceRoot = process.cwd()
134
133
  const getTestSuiteName = (pickleUri) => {
135
- return relative(sourceRoot, resolve.sync(pickleUri, { basedir: __dirname }))
134
+ return relative(sourceRoot, pickleUri)
136
135
  }
137
136
  const pl = TestCaseRunner.default
138
137
  this.wrap(
@@ -9,6 +9,8 @@ function createWrapRequest (tracer, config) {
9
9
  return function requestWithTrace (params, options, cb) {
10
10
  if (!params) return request.apply(this, arguments)
11
11
 
12
+ const lastIndex = arguments.length - 1
13
+ const body = getBody(params.body || params.bulkBody)
12
14
  const childOf = tracer.scope().active()
13
15
  const span = tracer.startSpan('elasticsearch.query', {
14
16
  childOf,
@@ -20,48 +22,39 @@ function createWrapRequest (tracer, config) {
20
22
  'span.type': 'elasticsearch',
21
23
  'elasticsearch.url': params.path,
22
24
  'elasticsearch.method': params.method,
25
+ 'elasticsearch.body': body,
23
26
  'elasticsearch.params': JSON.stringify(params.querystring || params.query)
24
27
  }
25
28
  })
26
29
 
27
- if (params.body || params.bulkBody) {
28
- span.setTag('elasticsearch.body', JSON.stringify(params.body || params.bulkBody))
29
- }
30
-
31
30
  analyticsSampler.sample(span, config.analytics)
32
31
 
33
- cb = request.length === 2 || typeof options === 'function'
34
- ? tracer.scope().bind(options, childOf)
35
- : tracer.scope().bind(cb, childOf)
36
-
37
- return tracer.scope().activate(span, () => {
38
- if (typeof cb === 'function') {
39
- if (request.length === 2) {
40
- return request.call(this, params, wrapCallback(tracer, span, params, config, cb))
41
- } else {
42
- return request.call(this, params, options, wrapCallback(tracer, span, params, config, cb))
43
- }
44
- } else {
45
- const promise = request.apply(this, arguments)
32
+ cb = arguments[lastIndex]
46
33
 
47
- if (promise && typeof promise.then === 'function') {
48
- promise.then(() => finish(span, params, config), e => finish(span, params, config, e))
49
- } else {
50
- finish(span, params, config)
51
- }
34
+ if (typeof cb === 'function') {
35
+ arguments[lastIndex] = wrapCallback(tracer, span, params, config, cb)
52
36
 
53
- return promise
37
+ return tracer.scope().activate(span, () => request.apply(this, arguments))
38
+ } else {
39
+ const promise = request.apply(this, arguments)
40
+
41
+ if (promise && typeof promise.then === 'function') {
42
+ promise.then(() => finish(span, params, config), e => finish(span, params, config, e))
43
+ } else {
44
+ finish(span, params, config)
54
45
  }
55
- })
46
+
47
+ return promise
48
+ }
56
49
  }
57
50
  }
58
51
  }
59
52
 
60
53
  function wrapCallback (tracer, span, params, config, done) {
61
- return function (err) {
54
+ return tracer.scope().bind(function (err) {
62
55
  finish(span, params, config, err)
63
56
  done.apply(null, arguments)
64
- }
57
+ })
65
58
  }
66
59
 
67
60
  function finish (span, params, config, err) {
@@ -82,6 +75,10 @@ function quantizePath (path) {
82
75
  return path && path.replace(/[0-9]+/g, '?')
83
76
  }
84
77
 
78
+ function getBody (body) {
79
+ return body && JSON.stringify(body)
80
+ }
81
+
85
82
  function normalizeConfig (config) {
86
83
  const hooks = getHooks(config)
87
84
 
@@ -17,6 +17,7 @@ function createWrapFastify (tracer, config) {
17
17
  if (typeof app.addHook === 'function') {
18
18
  app.addHook('onRequest', createOnRequest(tracer, config))
19
19
  app.addHook('preHandler', preHandler)
20
+ app.addHook = createWrapAddHook(tracer, config)(app.addHook)
20
21
  }
21
22
 
22
23
  methods.forEach(method => {
@@ -30,6 +31,51 @@ function createWrapFastify (tracer, config) {
30
31
  }
31
32
  }
32
33
 
34
+ function createWrapAddHook (tracer, config) {
35
+ return function wrapAddHook (addHook) {
36
+ return function addHookWithTrace (name, fn) {
37
+ fn = arguments[arguments.length - 1]
38
+
39
+ if (typeof fn !== 'function') return addHook.apply(this, arguments)
40
+
41
+ arguments[arguments.length - 1] = safeWrap(fn, function (request, reply, done) {
42
+ const req = getReq(request)
43
+
44
+ if (!req) return fn.apply(this, arguments)
45
+
46
+ done = arguments[arguments.length - 1]
47
+
48
+ try {
49
+ if (typeof done === 'function') {
50
+ arguments[arguments.length - 1] = function (err) {
51
+ web.addError(req, err)
52
+ return done.apply(this, arguments)
53
+ }
54
+
55
+ return fn.apply(this, arguments)
56
+ } else {
57
+ const promise = fn.apply(this, arguments)
58
+
59
+ if (promise && typeof promise.catch === 'function') {
60
+ return promise.catch(err => {
61
+ web.addError(req, err)
62
+ throw err
63
+ })
64
+ }
65
+
66
+ return promise
67
+ }
68
+ } catch (e) {
69
+ web.addError(req, e)
70
+ throw e
71
+ }
72
+ })
73
+
74
+ return addHook.apply(this, arguments)
75
+ }
76
+ }
77
+ }
78
+
33
79
  function createOnRequest (tracer, config) {
34
80
  return function onRequest (request, reply, next) {
35
81
  if (typeof next !== 'function') return
@@ -101,6 +147,13 @@ function wrapHandler (handler) {
101
147
  }
102
148
  }
103
149
 
150
+ // TODO: move this to a common util
151
+ function safeWrap (fn, wrapper) {
152
+ Object.defineProperty(wrapper, 'length', Object.getOwnPropertyDescriptor(fn, 'length'))
153
+
154
+ return wrapper
155
+ }
156
+
104
157
  function getReq (request) {
105
158
  return request && (request.raw || request.req || request)
106
159
  }
@@ -60,7 +60,7 @@ function createWrapParse (tracer, config) {
60
60
  document._datadog_source = source.body || source
61
61
  }
62
62
 
63
- addDocumentTags(span, document)
63
+ addDocumentTags(span, document, config)
64
64
 
65
65
  return document
66
66
  } catch (e) {
@@ -82,7 +82,7 @@ function createWrapValidate (tracer, config) {
82
82
 
83
83
  // skip for schema stitching nested validation
84
84
  if (document && document.loc) {
85
- addDocumentTags(span, document)
85
+ addDocumentTags(span, document, config)
86
86
  }
87
87
 
88
88
  try {
@@ -228,7 +228,7 @@ function startExecutionSpan (tracer, config, operation, args) {
228
228
  const span = startSpan(tracer, config, 'execute')
229
229
 
230
230
  addExecutionTags(span, config, operation, args.document, args.operationName)
231
- addDocumentTags(span, args.document)
231
+ addDocumentTags(span, args.document, config)
232
232
  addVariableTags(tracer, config, span, args.variableValues)
233
233
 
234
234
  analyticsSampler.sample(span, config.analytics)
@@ -255,10 +255,10 @@ function addExecutionTags (span, config, operation, document, operationName) {
255
255
  span.addTags(tags)
256
256
  }
257
257
 
258
- function addDocumentTags (span, document) {
258
+ function addDocumentTags (span, document, config) {
259
259
  const tags = {}
260
260
 
261
- if (document && document._datadog_source) {
261
+ if (config.source && document && document._datadog_source) {
262
262
  tags['graphql.source'] = document._datadog_source
263
263
  }
264
264
 
@@ -304,7 +304,7 @@ function startResolveSpan (tracer, config, childOf, path, info, contextValue) {
304
304
  })
305
305
 
306
306
  if (fieldNode) {
307
- if (document && fieldNode.loc) {
307
+ if (config.source && document && fieldNode.loc) {
308
308
  span.setTag('graphql.source', document.substring(fieldNode.loc.start, fieldNode.loc.end))
309
309
  }
310
310
 
@@ -84,14 +84,6 @@ function patch (http, methodName, tracer, config) {
84
84
 
85
85
  scope.bind(res)
86
86
 
87
- span.setTag(HTTP_STATUS_CODE, res.statusCode)
88
-
89
- addResponseHeaders(res, span, config)
90
-
91
- if (!config.validateStatus(res.statusCode)) {
92
- span.setTag('error', 1)
93
- }
94
-
95
87
  res.on('end', () => finish(req, res, span, config))
96
88
 
97
89
  break
@@ -99,7 +91,7 @@ function patch (http, methodName, tracer, config) {
99
91
  case 'error':
100
92
  addError(span, arg)
101
93
  case 'abort': // eslint-disable-line no-fallthrough
102
- case 'close': // eslint-disable-line no-fallthrough
94
+ case 'timeout': // eslint-disable-line no-fallthrough
103
95
  finish(req, null, span, config)
104
96
  }
105
97
 
@@ -113,6 +105,18 @@ function patch (http, methodName, tracer, config) {
113
105
  }
114
106
 
115
107
  function finish (req, res, span, config) {
108
+ if (res) {
109
+ span.setTag(HTTP_STATUS_CODE, res.statusCode)
110
+
111
+ if (!config.validateStatus(res.statusCode)) {
112
+ span.setTag('error', 1)
113
+ }
114
+
115
+ addResponseHeaders(res, span, config)
116
+ } else {
117
+ span.setTag('error', 1)
118
+ }
119
+
116
120
  addRequestHeaders(req, span, config)
117
121
 
118
122
  config.hooks.request(span, req, res)
@@ -19,6 +19,13 @@ const {
19
19
  } = require('../../dd-trace/src/plugins/util/test')
20
20
  const { getFormattedJestTestParameters } = require('./util')
21
21
 
22
+ function getVmContext (environment) {
23
+ if (typeof environment.getVmContext === 'function') {
24
+ return environment.getVmContext()
25
+ }
26
+ return null
27
+ }
28
+
22
29
  function wrapEnvironment (BaseEnvironment) {
23
30
  return class DatadogJestEnvironment extends BaseEnvironment {
24
31
  constructor (config, context) {
@@ -54,11 +61,15 @@ const isTimeout = (event) => {
54
61
  function createHandleTestEvent (tracer, testEnvironmentMetadata, instrumenter) {
55
62
  return async function handleTestEventWithTrace (event) {
56
63
  if (event.name === 'test_retry') {
57
- const context = this.getVmContext()
58
- const { currentTestName } = context.expect.getState()
64
+ let testName = event.test && event.test.name
65
+ const context = getVmContext(this)
66
+ if (context) {
67
+ const { currentTestName } = context.expect.getState()
68
+ testName = currentTestName
69
+ }
59
70
  // If it's a retry, we restore the original test function so that it is not wrapped again
60
- if (this.originalTestFnByTestName[currentTestName]) {
61
- event.test.fn = this.originalTestFnByTestName[currentTestName]
71
+ if (this.originalTestFnByTestName[testName]) {
72
+ event.test.fn = this.originalTestFnByTestName[testName]
62
73
  }
63
74
  return
64
75
  }
@@ -66,7 +77,7 @@ function createHandleTestEvent (tracer, testEnvironmentMetadata, instrumenter) {
66
77
  if (!isTimeout(event)) {
67
78
  return
68
79
  }
69
- const context = this.getVmContext()
80
+ const context = getVmContext(this)
70
81
  if (context) {
71
82
  const { currentTestName } = context.expect.getState()
72
83
  const testSpan = this.testSpansByTestName[`${currentTestName}_${event.test.invocations}`]
@@ -99,17 +110,25 @@ function createHandleTestEvent (tracer, testEnvironmentMetadata, instrumenter) {
99
110
  event.name !== 'hook_failure') {
100
111
  return
101
112
  }
113
+ // for hook_failure events the test entry might not be defined, because the hook
114
+ // is not necessarily associated to a test:
115
+ if (!event.test) {
116
+ return
117
+ }
118
+
102
119
  const childOf = tracer.extract('text_map', {
103
120
  'x-datadog-trace-id': id().toString(10),
104
121
  'x-datadog-parent-id': '0000000000000000',
105
122
  'x-datadog-sampled': 1
106
123
  })
107
124
  let testName = event.test.name
108
- const context = this.getVmContext()
125
+ const context = getVmContext(this)
126
+
109
127
  if (context) {
110
128
  const { currentTestName } = context.expect.getState()
111
129
  testName = currentTestName
112
130
  }
131
+
113
132
  const commonSpanTags = {
114
133
  [TEST_TYPE]: 'test',
115
134
  [TEST_NAME]: testName,
@@ -188,7 +207,7 @@ function createHandleTestEvent (tracer, testEnvironmentMetadata, instrumenter) {
188
207
  result = await specFunction()
189
208
  // it may have been set already if the test timed out
190
209
  let suppressedErrors = []
191
- const context = environment.getVmContext()
210
+ const context = getVmContext(environment)
192
211
  if (context) {
193
212
  suppressedErrors = context.expect.getState().suppressedErrors
194
213
  }
@@ -79,8 +79,13 @@ function createWrapRunTest (tracer, testEnvironmentMetadata, sourceRoot) {
79
79
  activeSpan.setTag(TEST_STATUS, 'fail')
80
80
  }
81
81
  } catch (error) {
82
- activeSpan.setTag(TEST_STATUS, 'fail')
83
- activeSpan.setTag('error', error)
82
+ // this.skip has been called
83
+ if (error.constructor.name === 'Pending' && !this.forbidPending) {
84
+ activeSpan.setTag(TEST_STATUS, 'skip')
85
+ } else {
86
+ activeSpan.setTag(TEST_STATUS, 'fail')
87
+ activeSpan.setTag('error', error)
88
+ }
84
89
  throw error
85
90
  } finally {
86
91
  finishAllTraceSpans(activeSpan)
@@ -2,6 +2,22 @@
2
2
 
3
3
  const { instrument } = require('./util')
4
4
 
5
+ function createWrapConnectionCommand (tracer, config, name) {
6
+ return function wrapCommand (command) {
7
+ return function commandWithTrace (ns, ops) {
8
+ const hostParts = typeof this.address === 'string' ? this.address.split(':') : ''
9
+ const options = hostParts.length === 2
10
+ ? { host: hostParts[0], port: hostParts[1] }
11
+ : {} // no port means the address is a random UUID so no host either
12
+ const topology = { s: { options } }
13
+
14
+ ns = `${ns.db}.${ns.collection}`
15
+
16
+ return instrument(command, this, arguments, topology, ns, ops, tracer, config, { name })
17
+ }
18
+ }
19
+ }
20
+
5
21
  function createWrapCommand (tracer, config, name) {
6
22
  return function wrapCommand (command) {
7
23
  return function commandWithTrace (server, ns, ops) {
@@ -30,6 +46,24 @@ function unpatch (wp) {
30
46
  this.unwrap(wp, 'killCursors')
31
47
  }
32
48
 
49
+ function patchConnection ({ Connection }, tracer, config) {
50
+ const proto = Connection.prototype
51
+
52
+ this.wrap(proto, 'command', createWrapConnectionCommand(tracer, config))
53
+ this.wrap(proto, 'query', createWrapConnectionCommand(tracer, config))
54
+ this.wrap(proto, 'getMore', createWrapConnectionCommand(tracer, config, 'getMore'))
55
+ this.wrap(proto, 'killCursors', createWrapConnectionCommand(tracer, config, 'killCursors'))
56
+ }
57
+
58
+ function unpatchConnection ({ Connection }) {
59
+ const proto = Connection.prototype
60
+
61
+ this.unwrap(proto, 'command')
62
+ this.unwrap(proto, 'query')
63
+ this.unwrap(proto, 'getMore')
64
+ this.unwrap(proto, 'killCursors')
65
+ }
66
+
33
67
  function patchClass (WireProtocol, tracer, config) {
34
68
  this.wrap(WireProtocol.prototype, 'command', createWrapCommand(tracer, config))
35
69
  }
@@ -41,7 +75,14 @@ function unpatchClass (WireProtocol) {
41
75
  module.exports = [
42
76
  {
43
77
  name: 'mongodb',
44
- versions: ['>=3.3'],
78
+ versions: ['>=4'],
79
+ file: 'lib/cmap/connection.js',
80
+ patch: patchConnection,
81
+ unpatch: unpatchConnection
82
+ },
83
+ {
84
+ name: 'mongodb',
85
+ versions: ['>=3.3 <4'],
45
86
  file: 'lib/core/wireprotocol/index.js',
46
87
  patch,
47
88
  unpatch