dd-trace 2.40.0 → 2.42.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 (89) hide show
  1. package/README.md +2 -2
  2. package/package.json +4 -4
  3. package/packages/datadog-core/src/storage/async_resource.js +4 -0
  4. package/packages/datadog-instrumentations/src/cucumber.js +5 -2
  5. package/packages/datadog-instrumentations/src/grpc/client.js +44 -42
  6. package/packages/datadog-instrumentations/src/grpc/server.js +69 -60
  7. package/packages/datadog-instrumentations/src/http2/client.js +25 -26
  8. package/packages/datadog-instrumentations/src/jest.js +9 -5
  9. package/packages/datadog-instrumentations/src/mocha.js +5 -3
  10. package/packages/datadog-plugin-cypress/src/plugin.js +4 -2
  11. package/packages/datadog-plugin-graphql/src/execute.js +6 -4
  12. package/packages/datadog-plugin-grpc/src/client.js +29 -11
  13. package/packages/datadog-plugin-grpc/src/server.js +22 -6
  14. package/packages/datadog-plugin-http2/src/client.js +46 -29
  15. package/packages/datadog-plugin-jest/src/index.js +8 -3
  16. package/packages/datadog-plugin-openai/src/index.js +39 -16
  17. package/packages/datadog-plugin-openai/src/services.js +13 -9
  18. package/packages/datadog-plugin-router/src/index.js +1 -1
  19. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +3 -1
  20. package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +3 -0
  21. package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +7 -1
  22. package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +45 -0
  23. package/packages/dd-trace/src/appsec/iast/analyzers/index.js +3 -3
  24. package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +3 -0
  25. package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +66 -0
  26. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +19 -15
  27. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +5 -2
  28. package/packages/dd-trace/src/appsec/iast/analyzers/ssrf-analyzer.js +2 -0
  29. package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +27 -8
  30. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +18 -19
  31. package/packages/dd-trace/src/appsec/iast/analyzers/weak-cipher-analyzer.js +3 -0
  32. package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +3 -0
  33. package/packages/dd-trace/src/appsec/iast/analyzers/xcontenttype-header-missing-analyzer.js +19 -0
  34. package/packages/dd-trace/src/appsec/iast/iast-log.js +1 -1
  35. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +205 -0
  36. package/packages/dd-trace/src/appsec/iast/index.js +11 -7
  37. package/packages/dd-trace/src/appsec/iast/tags.js +2 -1
  38. package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +6 -6
  39. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +7 -5
  40. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +23 -4
  41. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +49 -17
  42. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-telemetry.js +33 -0
  43. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +23 -16
  44. package/packages/dd-trace/src/appsec/iast/taint-tracking/{origin-types.js → source-types.js} +1 -0
  45. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +76 -37
  46. package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +101 -0
  47. package/packages/dd-trace/src/appsec/iast/telemetry/index.js +45 -0
  48. package/packages/dd-trace/src/appsec/iast/telemetry/{logs.js → log/index.js} +5 -5
  49. package/packages/dd-trace/src/appsec/iast/telemetry/{log_collector.js → log/log-collector.js} +1 -1
  50. package/packages/dd-trace/src/appsec/iast/telemetry/namespaces.js +76 -0
  51. package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +53 -0
  52. package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +42 -0
  53. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +5 -1
  54. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +3 -1
  55. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
  56. package/packages/dd-trace/src/config.js +47 -12
  57. package/packages/dd-trace/src/constants.js +1 -0
  58. package/packages/dd-trace/src/external-logger/src/index.js +9 -1
  59. package/packages/dd-trace/src/external-logger/test/index.spec.js +1 -1
  60. package/packages/dd-trace/src/format.js +1 -1
  61. package/packages/dd-trace/src/lambda/handler.js +8 -1
  62. package/packages/dd-trace/src/opentelemetry/span.js +3 -1
  63. package/packages/dd-trace/src/opentracing/span_context.js +2 -1
  64. package/packages/dd-trace/src/opentracing/tracer.js +1 -0
  65. package/packages/dd-trace/src/plugins/ci_plugin.js +6 -1
  66. package/packages/dd-trace/src/plugins/outbound.js +29 -12
  67. package/packages/dd-trace/src/plugins/plugin.js +28 -0
  68. package/packages/dd-trace/src/plugins/tracing.js +33 -16
  69. package/packages/dd-trace/src/plugins/util/ci.js +3 -2
  70. package/packages/dd-trace/src/plugins/util/test.js +55 -11
  71. package/packages/dd-trace/src/plugins/util/user-provided-git.js +1 -22
  72. package/packages/dd-trace/src/plugins/util/web.js +1 -0
  73. package/packages/dd-trace/src/profiling/config.js +8 -8
  74. package/packages/dd-trace/src/profiling/exporters/agent.js +4 -1
  75. package/packages/dd-trace/src/profiling/index.js +0 -2
  76. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  77. package/packages/dd-trace/src/profiling/profilers/wall.js +162 -10
  78. package/packages/dd-trace/src/service-naming/index.js +2 -2
  79. package/packages/dd-trace/src/service-naming/schemas/v0/graphql.js +12 -0
  80. package/packages/dd-trace/src/service-naming/schemas/v0/index.js +2 -1
  81. package/packages/dd-trace/src/service-naming/schemas/v1/graphql.js +12 -0
  82. package/packages/dd-trace/src/service-naming/schemas/v1/index.js +2 -1
  83. package/packages/dd-trace/src/span_processor.js +0 -4
  84. package/packages/dd-trace/src/span_sampler.js +1 -1
  85. package/packages/dd-trace/src/telemetry/dependencies.js +24 -12
  86. package/packages/dd-trace/src/telemetry/metrics.js +11 -1
  87. package/packages/diagnostics_channel/src/index.js +64 -0
  88. package/packages/dd-trace/src/profiling/profilers/cpu.js +0 -126
  89. package/scripts/version.js +0 -66
package/README.md CHANGED
@@ -143,8 +143,8 @@ $ yarn leak:plugins
143
143
 
144
144
  ### Linting
145
145
 
146
- We use [ESLint](https://eslint.org) to make sure that new code is
147
- conform to our coding standards.
146
+ We use [ESLint](https://eslint.org) to make sure that new code
147
+ conforms to our coding standards.
148
148
 
149
149
  To run the linter, use:
150
150
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "2.40.0",
3
+ "version": "2.42.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -68,9 +68,9 @@
68
68
  "dependencies": {
69
69
  "@datadog/native-appsec": "^3.2.0",
70
70
  "@datadog/native-iast-rewriter": "2.0.1",
71
- "@datadog/native-iast-taint-tracking": "^1.5.0",
71
+ "@datadog/native-iast-taint-tracking": "1.5.0",
72
72
  "@datadog/native-metrics": "^1.6.0",
73
- "@datadog/pprof": "2.2.3",
73
+ "@datadog/pprof": "3.1.0",
74
74
  "@datadog/sketches-js": "^2.1.0",
75
75
  "@types/node": "<18.13",
76
76
  "@opentelemetry/api": "^1.0.0",
@@ -95,7 +95,7 @@
95
95
  "node-abort-controller": "^3.0.1",
96
96
  "opentracing": ">=0.12.1",
97
97
  "path-to-regexp": "^0.1.2",
98
- "protobufjs": "^7.1.2",
98
+ "protobufjs": "^7.2.4",
99
99
  "retry": "^0.10.1",
100
100
  "semver": "^7.3.8"
101
101
  },
@@ -5,6 +5,7 @@ const { channel } = require('../../../diagnostics_channel')
5
5
 
6
6
  const beforeCh = channel('dd-trace:storage:before')
7
7
  const afterCh = channel('dd-trace:storage:after')
8
+ const enterCh = channel('dd-trace:storage:enter')
8
9
 
9
10
  let PrivateSymbol = Symbol
10
11
  function makePrivateSymbol () {
@@ -52,6 +53,7 @@ class AsyncResourceStorage {
52
53
  const resource = this._executionAsyncResource()
53
54
 
54
55
  resource[this._ddResourceStore] = store
56
+ enterCh.publish()
55
57
  }
56
58
 
57
59
  run (store, callback, ...args) {
@@ -61,11 +63,13 @@ class AsyncResourceStorage {
61
63
  const oldStore = resource[this._ddResourceStore]
62
64
 
63
65
  resource[this._ddResourceStore] = store
66
+ enterCh.publish()
64
67
 
65
68
  try {
66
69
  return callback(...args)
67
70
  } finally {
68
71
  resource[this._ddResourceStore] = oldStore
72
+ enterCh.publish()
69
73
  }
70
74
  }
71
75
 
@@ -37,6 +37,7 @@ const patched = new WeakSet()
37
37
 
38
38
  let pickleByFile = {}
39
39
  const pickleResultByFile = {}
40
+ let isSuitesSkipped = false
40
41
 
41
42
  function getSuiteStatusFromTestStatuses (testStatuses) {
42
43
  if (testStatuses.some(status => status === 'fail')) {
@@ -264,7 +265,9 @@ addHook({
264
265
  const { err, skippableSuites } = await skippableSuitesPromise
265
266
 
266
267
  if (!err) {
267
- this.pickleIds = getPicklesToRun(this, skippableSuites)
268
+ const newPickleIds = getPicklesToRun(this, skippableSuites)
269
+ isSuitesSkipped = newPickleIds.length !== this.pickleIds.length
270
+ this.pickleIds = newPickleIds
268
271
  }
269
272
 
270
273
  pickleByFile = getPickleByFile(this)
@@ -292,7 +295,7 @@ addHook({
292
295
  asyncResource.runInAsyncScope(() => {
293
296
  sessionFinishCh.publish({
294
297
  status: success ? 'pass' : 'fail',
295
- isSuitesSkipped: skippableSuites ? !!skippableSuites.length : false,
298
+ isSuitesSkipped,
296
299
  testCodeCoverageLinesTotal
297
300
  })
298
301
  })
@@ -1,15 +1,17 @@
1
1
  'use strict'
2
2
 
3
3
  const types = require('./types')
4
- const { addHook, channel, AsyncResource } = require('../helpers/instrument')
4
+ const { addHook, channel } = require('../helpers/instrument')
5
5
  const shimmer = require('../../../datadog-shimmer')
6
6
 
7
7
  const patched = new WeakSet()
8
8
  const instances = new WeakMap()
9
9
 
10
10
  const startChannel = channel('apm:grpc:client:request:start')
11
+ const asyncStartChannel = channel('apm:grpc:client:request:asyncStart')
11
12
  const errorChannel = channel('apm:grpc:client:request:error')
12
13
  const finishChannel = channel('apm:grpc:client:request:finish')
14
+ const emitChannel = channel('apm:grpc:client:request:emit')
13
15
 
14
16
  function createWrapMakeRequest (type) {
15
17
  return function wrapMakeRequest (makeRequest) {
@@ -99,45 +101,39 @@ function wrapMethod (method, path, type) {
99
101
  return wrapped
100
102
  }
101
103
 
102
- function wrapCallback (requestResource, parentResource, callback) {
104
+ function wrapCallback (ctx, callback = () => { }) {
103
105
  return function (err) {
104
106
  if (err) {
105
- requestResource.runInAsyncScope(() => {
106
- errorChannel.publish(err)
107
- })
107
+ ctx.error = err
108
+ errorChannel.publish(ctx)
108
109
  }
109
110
 
110
- if (callback) {
111
- return parentResource.runInAsyncScope(() => {
112
- return callback.apply(this, arguments)
113
- })
114
- }
111
+ return asyncStartChannel.runStores(ctx, () => {
112
+ return callback.apply(this, arguments)
113
+ // No async end channel needed
114
+ })
115
115
  }
116
116
  }
117
117
 
118
- function wrapStream (call, requestResource, parentResource) {
119
- if (!call || typeof call.emit !== 'function') return
120
-
121
- shimmer.wrap(call, 'emit', emit => {
122
- return function (eventName, ...args) {
123
- requestResource.runInAsyncScope(() => {
124
- switch (eventName) {
125
- case 'error':
126
- errorChannel.publish(args[0])
127
-
128
- break
129
- case 'status':
130
- finishChannel.publish(args[0])
131
-
132
- break
133
- }
134
- })
118
+ function createWrapEmit (ctx) {
119
+ return function wrapEmit (emit) {
120
+ return function (event, arg1) {
121
+ switch (event) {
122
+ case 'error':
123
+ ctx.error = arg1
124
+ errorChannel.publish(ctx)
125
+ break
126
+ case 'status':
127
+ ctx.result = arg1
128
+ finishChannel.publish(ctx)
129
+ break
130
+ }
135
131
 
136
- return parentResource.runInAsyncScope(() => {
132
+ return emitChannel.runStores(ctx, () => {
137
133
  return emit.apply(this, arguments)
138
134
  })
139
135
  }
140
- })
136
+ }
141
137
  }
142
138
 
143
139
  function callMethod (client, method, args, path, metadata, type) {
@@ -145,25 +141,31 @@ function callMethod (client, method, args, path, metadata, type) {
145
141
 
146
142
  const length = args.length
147
143
  const callback = args[length - 1]
148
- const parentResource = new AsyncResource('bound-anonymous-fn')
149
- const requestResource = new AsyncResource('bound-anonymous-fn')
150
144
 
151
- return requestResource.runInAsyncScope(() => {
152
- startChannel.publish({ metadata, path, type })
145
+ const ctx = { metadata, path, type }
153
146
 
154
- if (type === types.unary || type === types.client_stream) {
155
- if (typeof callback === 'function') {
156
- args[length - 1] = wrapCallback(requestResource, parentResource, callback)
157
- } else {
158
- args[length] = wrapCallback(requestResource, parentResource)
147
+ return startChannel.runStores(ctx, () => {
148
+ try {
149
+ if (type === types.unary || type === types.client_stream) {
150
+ if (typeof callback === 'function') {
151
+ args[length - 1] = wrapCallback(ctx, callback)
152
+ } else {
153
+ args[length] = wrapCallback(ctx)
154
+ }
159
155
  }
160
- }
161
156
 
162
- const call = method.apply(client, args)
157
+ const call = method.apply(client, args)
163
158
 
164
- wrapStream(call, requestResource, parentResource)
159
+ if (call && typeof call.emit === 'function') {
160
+ shimmer.wrap(call, 'emit', createWrapEmit(ctx))
161
+ }
165
162
 
166
- return call
163
+ return call
164
+ } catch (e) {
165
+ ctx.error = e
166
+ errorChannel.publish(ctx)
167
+ }
168
+ // No end channel needed
167
169
  })
168
170
  }
169
171
 
@@ -1,13 +1,15 @@
1
1
  'use strict'
2
2
 
3
3
  const types = require('./types')
4
- const { channel, addHook, AsyncResource } = require('../helpers/instrument')
4
+ const { channel, addHook } = require('../helpers/instrument')
5
5
  const shimmer = require('../../../datadog-shimmer')
6
6
 
7
7
  const startChannel = channel('apm:grpc:server:request:start')
8
+ const asyncStartChannel = channel('apm:grpc:server:request:asyncStart')
8
9
  const errorChannel = channel('apm:grpc:server:request:error')
9
10
  const updateChannel = channel('apm:grpc:server:request:update')
10
11
  const finishChannel = channel('apm:grpc:server:request:finish')
12
+ const emitChannel = channel('apm:grpc:server:request:emit')
11
13
 
12
14
  // https://github.com/grpc/grpc/blob/master/doc/statuscodes.md
13
15
  const OK = 0
@@ -31,28 +33,38 @@ function wrapHandler (func, name) {
31
33
  const type = types[this.type]
32
34
  const isStream = type !== 'unary'
33
35
 
34
- const parentResource = new AsyncResource('bound-anonymous-fn')
35
- const requestResource = new AsyncResource('bound-anonymous-fn')
36
-
37
- return requestResource.runInAsyncScope(() => {
38
- startChannel.publish({ name, metadata, type })
39
-
40
- const onCancel = requestResource.bind(() => {
41
- finishChannel.publish({ code: CANCELLED })
42
- })
43
-
44
- // Finish the span if the call was cancelled.
45
- call.once('cancelled', onCancel)
36
+ const ctx = { name, metadata, type }
37
+
38
+ return startChannel.runStores(ctx, () => {
39
+ try {
40
+ const onCancel = () => {
41
+ ctx.code = CANCELLED
42
+ finishChannel.publish(ctx)
43
+ }
44
+
45
+ // Finish the span if the call was cancelled.
46
+ call.once('cancelled', onCancel)
47
+
48
+ if (isStream) {
49
+ wrapStream(call, ctx, onCancel)
50
+ } else {
51
+ arguments[1] = wrapCallback(callback, call, ctx, onCancel)
52
+ }
53
+
54
+ shimmer.wrap(call, 'emit', emit => {
55
+ return function () {
56
+ return emitChannel.runStores(ctx, () => {
57
+ return emit.apply(this, arguments)
58
+ })
59
+ }
60
+ })
46
61
 
47
- if (isStream) {
48
- wrapStream(call, requestResource, onCancel)
49
- } else {
50
- arguments[1] = wrapCallback(callback, call, requestResource, parentResource, onCancel)
62
+ return func.apply(this, arguments)
63
+ } catch (e) {
64
+ ctx.error = e
65
+ errorChannel.publish(ctx)
51
66
  }
52
-
53
- shimmer.wrap(call, 'emit', emit => requestResource.bind(emit))
54
-
55
- return func.apply(this, arguments)
67
+ // No end channel needed
56
68
  })
57
69
  }
58
70
  }
@@ -67,69 +79,66 @@ function wrapRegister (register) {
67
79
  }
68
80
  }
69
81
 
70
- function wrapStream (call, requestResource, onCancel) {
71
- if (call.call && call.call.sendStatus) {
72
- call.call.sendStatus = wrapSendStatus(call.call.sendStatus, requestResource)
73
- }
74
-
75
- shimmer.wrap(call, 'emit', emit => {
76
- return function (eventName, ...args) {
77
- switch (eventName) {
82
+ function createWrapEmit (call, ctx, onCancel) {
83
+ return function wrapEmit (emit) {
84
+ return function (event, arg1) {
85
+ switch (event) {
78
86
  case 'error':
79
- errorChannel.publish(args[0])
80
- finishChannel.publish({ code: args[0].code })
81
-
87
+ ctx.error = arg1
88
+ errorChannel.publish(ctx)
89
+ ctx.code = arg1.code
90
+ finishChannel.publish(ctx)
82
91
  call.removeListener('cancelled', onCancel)
83
-
84
92
  break
85
-
86
- // Finish the span of the response only if it was successful.
87
- // Otherwise it'll be finished in the `error` listener.
88
93
  case 'finish':
89
94
  if (call.status) {
90
95
  updateChannel.publish(call.status)
91
96
  }
92
-
93
97
  if (!call.status || call.status.code === 0) {
94
- finishChannel.publish()
98
+ finishChannel.publish(ctx)
95
99
  }
96
-
97
100
  call.removeListener('cancelled', onCancel)
98
-
99
101
  break
100
102
  }
101
103
 
102
104
  return emit.apply(this, arguments)
103
105
  }
104
- })
106
+ }
105
107
  }
106
108
 
107
- function wrapCallback (callback, call, requestResource, parentResource, onCancel) {
108
- return function (err, value, trailer, flags) {
109
- requestResource.runInAsyncScope(() => {
110
- if (err) {
111
- errorChannel.publish(err)
112
- finishChannel.publish(err)
113
- } else {
114
- finishChannel.publish({ code: OK, trailer })
115
- }
109
+ function wrapStream (call, ctx, onCancel) {
110
+ if (call.call && call.call.sendStatus) {
111
+ call.call.sendStatus = wrapSendStatus(call.call.sendStatus, ctx)
112
+ }
116
113
 
117
- call.removeListener('cancelled', onCancel)
118
- })
114
+ shimmer.wrap(call, 'emit', createWrapEmit(call, ctx, onCancel))
115
+ }
119
116
 
120
- if (callback) {
121
- return parentResource.runInAsyncScope(() => {
122
- return callback.apply(this, arguments)
123
- })
117
+ function wrapCallback (callback = () => {}, call, ctx, onCancel) {
118
+ return function (err, value, trailer, flags) {
119
+ if (err) {
120
+ ctx.error = err
121
+ errorChannel.publish(ctx)
122
+ } else {
123
+ ctx.code = OK
124
+ ctx.trailer = trailer
124
125
  }
126
+
127
+ finishChannel.publish(ctx)
128
+
129
+ call.removeListener('cancelled', onCancel)
130
+
131
+ return asyncStartChannel.runStores(ctx, () => {
132
+ return callback.apply(this, arguments)
133
+ // No async end channel needed
134
+ })
125
135
  }
126
136
  }
127
137
 
128
- function wrapSendStatus (sendStatus, requestResource) {
138
+ function wrapSendStatus (sendStatus, ctx) {
129
139
  return function (status) {
130
- requestResource.runInAsyncScope(() => {
131
- updateChannel.publish(status)
132
- })
140
+ ctx.status = status
141
+ updateChannel.publish(ctx)
133
142
 
134
143
  return sendStatus.apply(this, arguments)
135
144
  }
@@ -1,32 +1,27 @@
1
1
  'use strict'
2
2
 
3
3
  const shimmer = require('../../../datadog-shimmer')
4
- const { addHook, channel, AsyncResource } = require('../helpers/instrument')
4
+ const { addHook, channel } = require('../helpers/instrument')
5
5
 
6
6
  const connectChannel = channel('apm:http2:client:connect:start')
7
7
  const startChannel = channel('apm:http2:client:request:start')
8
- const finishChannel = channel('apm:http2:client:request:finish')
8
+ const endChannel = channel('apm:http2:client:request:end')
9
+ const asyncStartChannel = channel('apm:http2:client:request:asyncStart')
10
+ const asyncEndChannel = channel('apm:http2:client:request:asyncEnd')
9
11
  const errorChannel = channel('apm:http2:client:request:error')
10
- const responseChannel = channel('apm:http2:client:response')
11
12
 
12
- function createWrapEmit (requestResource, parentResource) {
13
+ function createWrapEmit (ctx) {
13
14
  return function wrapEmit (emit) {
14
15
  return function (event, arg1) {
15
- requestResource.runInAsyncScope(() => {
16
- switch (event) {
17
- case 'response':
18
- responseChannel.publish(arg1)
19
- break
20
- case 'error':
21
- errorChannel.publish(arg1)
22
- case 'close': // eslint-disable-line no-fallthrough
23
- finishChannel.publish()
24
- break
25
- }
26
- })
16
+ ctx.eventName = event
17
+ ctx.eventData = arg1
27
18
 
28
- return parentResource.runInAsyncScope(() => {
29
- return emit.apply(this, arguments)
19
+ return asyncStartChannel.runStores(ctx, () => {
20
+ try {
21
+ return emit.apply(this, arguments)
22
+ } finally {
23
+ asyncEndChannel.publish(ctx)
24
+ }
30
25
  })
31
26
  }
32
27
  }
@@ -35,17 +30,21 @@ function createWrapEmit (requestResource, parentResource) {
35
30
  function createWrapRequest (authority, options) {
36
31
  return function wrapRequest (request) {
37
32
  return function (headers) {
38
- const parentResource = new AsyncResource('bound-anonymous-fn')
39
- const requestResource = new AsyncResource('bound-anonymous-fn')
33
+ const ctx = { headers, authority, options }
40
34
 
41
- return requestResource.runInAsyncScope(() => {
42
- startChannel.publish({ headers, authority, options })
35
+ return startChannel.runStores(ctx, () => {
36
+ try {
37
+ const req = request.apply(this, arguments)
43
38
 
44
- const req = request.apply(this, arguments)
39
+ shimmer.wrap(req, 'emit', createWrapEmit(ctx))
45
40
 
46
- shimmer.wrap(req, 'emit', createWrapEmit(requestResource, parentResource))
47
-
48
- return req
41
+ return req
42
+ } catch (e) {
43
+ ctx.error = e
44
+ errorChannel.publish(ctx)
45
+ } finally {
46
+ endChannel.publish(ctx)
47
+ }
49
48
  })
50
49
  }
51
50
  }
@@ -42,6 +42,7 @@ const jestItrConfigurationCh = channel('ci:jest:itr-configuration')
42
42
  let skippableSuites = []
43
43
  let isCodeCoverageEnabled = false
44
44
  let isSuitesSkippingEnabled = false
45
+ let isSuitesSkipped = false
45
46
 
46
47
  const sessionAsyncResource = new AsyncResource('bound-anonymous-fn')
47
48
 
@@ -128,8 +129,7 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
128
129
  suite: this.testSuite,
129
130
  runner: 'jest-circus',
130
131
  testParameters,
131
- frameworkVersion: jestVersion,
132
- testStartLine: getTestLineStart(event.test.asyncError, this.testSuite)
132
+ frameworkVersion: jestVersion
133
133
  })
134
134
  originalTestFns.set(event.test, event.test.fn)
135
135
  event.test.fn = asyncResource.bind(event.test.fn)
@@ -144,7 +144,10 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
144
144
  const formattedError = formatJestError(event.test.errors[0])
145
145
  testErrCh.publish(formattedError)
146
146
  }
147
- testRunFinishCh.publish(status)
147
+ testRunFinishCh.publish({
148
+ status,
149
+ testStartLine: getTestLineStart(event.test.asyncError, this.testSuite)
150
+ })
148
151
  // restore in case it is retried
149
152
  event.test.fn = originalTestFns.get(event.test)
150
153
  })
@@ -227,7 +230,6 @@ function cliWrapper (cli, jestVersion) {
227
230
  log.error(err)
228
231
  }
229
232
  }
230
- const isSuitesSkipped = !!skippableSuites.length
231
233
 
232
234
  const processArgv = process.argv.slice(2).join(' ')
233
235
  sessionAsyncResource.runInAsyncScope(() => {
@@ -430,6 +432,8 @@ addHook({
430
432
 
431
433
  const filteredTests = getJestSuitesToRun(skippableSuites, tests, rootDir)
432
434
 
435
+ isSuitesSkipped = filteredTests.length !== tests.length
436
+
433
437
  skippableSuites = []
434
438
 
435
439
  return { ...testPaths, tests: filteredTests }
@@ -469,7 +473,7 @@ function jasmineAsyncInstallWraper (jasmineAsyncInstallExport, jestVersion) {
469
473
  const formattedError = formatJestError(spec.result.failedExpectations[0].error)
470
474
  testErrCh.publish(formattedError)
471
475
  }
472
- testRunFinishCh.publish(specStatusToTestStatus[spec.result.status])
476
+ testRunFinishCh.publish({ status: specStatusToTestStatus[spec.result.status] })
473
477
  onComplete.apply(this, arguments)
474
478
  })
475
479
  arguments[0] = callback
@@ -46,6 +46,7 @@ const originalCoverageMap = createCoverageMap()
46
46
 
47
47
  let suitesToSkip = []
48
48
  let frameworkVersion
49
+ let isSuitesSkipped = false
49
50
 
50
51
  function getSuitesByTestFile (root) {
51
52
  const suitesByTestFile = {}
@@ -125,8 +126,6 @@ function mochaHook (Runner) {
125
126
  }
126
127
  testFileToSuiteAr.clear()
127
128
 
128
- const isSuitesSkipped = !!suitesToSkip.length
129
-
130
129
  let testCodeCoverageLinesTotal
131
130
  if (global.__coverage__) {
132
131
  try {
@@ -360,7 +359,10 @@ addHook({
360
359
  suitesToSkip = skippableSuites
361
360
  }
362
361
  // We remove the suites that we skip through ITR
363
- runner.suite.suites = getSuitesToRun(runner.suite.suites)
362
+ const newSuites = getSuitesToRun(runner.suite.suites)
363
+ isSuitesSkipped = newSuites.length !== runner.suite.suites.length
364
+ runner.suite.suites = newSuites
365
+
364
366
  global.run()
365
367
  }
366
368
 
@@ -37,7 +37,7 @@ const CYPRESS_STATUS_TO_TEST_STATUS = {
37
37
  function getTestSpanMetadata (tracer, testName, testSuite, cypressConfig) {
38
38
  const childOf = getTestParentSpan(tracer)
39
39
 
40
- const commonTags = getTestCommonTags(testName, testSuite, cypressConfig.version)
40
+ const commonTags = getTestCommonTags(testName, testSuite, cypressConfig.version, TEST_FRAMEWORK_NAME)
41
41
 
42
42
  return {
43
43
  childOf,
@@ -119,6 +119,7 @@ function getSkippableTests (isSuitesSkippingEnabled, tracer, testConfiguration)
119
119
  }
120
120
 
121
121
  module.exports = (on, config) => {
122
+ let isTestsSkipped = false
122
123
  const tracer = require('../../dd-trace')
123
124
  const testEnvironmentMetadata = getTestEnvironmentMetadata(TEST_FRAMEWORK_NAME)
124
125
 
@@ -306,7 +307,7 @@ module.exports = (on, config) => {
306
307
  testSessionSpan,
307
308
  testModuleSpan,
308
309
  {
309
- isSuitesSkipped: !!testsToSkip.length,
310
+ isSuitesSkipped: isTestsSkipped,
310
311
  isSuitesSkippingEnabled,
311
312
  isCodeCoverageEnabled
312
313
  }
@@ -352,6 +353,7 @@ module.exports = (on, config) => {
352
353
  if (testsToSkip.find(test => {
353
354
  return testName === test.name && testSuite === test.suite
354
355
  })) {
356
+ isTestsSkipped = true
355
357
  return { shouldSkip: true }
356
358
  }
357
359
 
@@ -7,6 +7,8 @@ let tools
7
7
  class GraphQLExecutePlugin extends TracingPlugin {
8
8
  static get id () { return 'graphql' }
9
9
  static get operation () { return 'execute' }
10
+ static get type () { return 'graphql' }
11
+ static get kind () { return 'server' }
10
12
 
11
13
  start ({ operation, args, docSource }) {
12
14
  const type = operation && operation.operation
@@ -14,11 +16,11 @@ class GraphQLExecutePlugin extends TracingPlugin {
14
16
  const document = args.document
15
17
  const source = this.config.source && document && docSource
16
18
 
17
- const span = this.startSpan('graphql.execute', {
18
- service: this.config.service,
19
+ const span = this.startSpan(this.operationName(), {
20
+ service: this.config.service || this.serviceName(),
19
21
  resource: getSignature(document, name, type, this.config.signature),
20
- kind: 'server',
21
- type: 'graphql',
22
+ kind: this.constructor.kind,
23
+ type: this.constructor.type,
22
24
  meta: {
23
25
  'graphql.operation.type': type,
24
26
  'graphql.operation.name': name,