dd-trace 6.0.0-pre-ac0fc13 → 6.0.0-pre-2d874ad

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 (75) hide show
  1. package/index.d.ts +20 -0
  2. package/package.json +3 -3
  3. package/packages/datadog-instrumentations/src/apollo.js +101 -0
  4. package/packages/datadog-instrumentations/src/cucumber.js +2 -1
  5. package/packages/datadog-instrumentations/src/grpc/server.js +3 -1
  6. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  7. package/packages/datadog-instrumentations/src/jest.js +7 -5
  8. package/packages/datadog-instrumentations/src/mocha.js +4 -1
  9. package/packages/datadog-instrumentations/src/playwright.js +151 -6
  10. package/packages/datadog-plugin-amqplib/src/consumer.js +5 -4
  11. package/packages/datadog-plugin-amqplib/src/producer.js +3 -4
  12. package/packages/datadog-plugin-apollo/src/gateway/execute.js +12 -0
  13. package/packages/datadog-plugin-apollo/src/gateway/fetch.js +36 -0
  14. package/packages/datadog-plugin-apollo/src/gateway/index.js +36 -0
  15. package/packages/datadog-plugin-apollo/src/gateway/plan.js +13 -0
  16. package/packages/datadog-plugin-apollo/src/gateway/postprocessing.js +12 -0
  17. package/packages/datadog-plugin-apollo/src/gateway/request.js +139 -0
  18. package/packages/datadog-plugin-apollo/src/gateway/validate.js +21 -0
  19. package/packages/datadog-plugin-apollo/src/index.js +15 -0
  20. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -11
  21. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +3 -6
  22. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +5 -7
  23. package/packages/datadog-plugin-cucumber/src/index.js +2 -2
  24. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -2
  25. package/packages/datadog-plugin-jest/src/index.js +2 -2
  26. package/packages/datadog-plugin-kafkajs/src/consumer.js +4 -3
  27. package/packages/datadog-plugin-kafkajs/src/producer.js +3 -5
  28. package/packages/datadog-plugin-mocha/src/index.js +2 -2
  29. package/packages/datadog-plugin-playwright/src/index.js +10 -2
  30. package/packages/datadog-plugin-rhea/src/consumer.js +5 -3
  31. package/packages/datadog-plugin-rhea/src/producer.js +3 -4
  32. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +23 -12
  33. package/packages/dd-trace/src/appsec/iast/index.js +10 -0
  34. package/packages/dd-trace/src/appsec/iast/path-line.js +9 -6
  35. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +1 -1
  36. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +6 -2
  37. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-telemetry.js +1 -1
  38. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +14 -2
  39. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -1
  40. package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +34 -27
  41. package/packages/dd-trace/src/appsec/iast/telemetry/namespaces.js +39 -11
  42. package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +7 -6
  43. package/packages/dd-trace/src/appsec/remote_config/index.js +1 -1
  44. package/packages/dd-trace/src/appsec/reporter.js +24 -11
  45. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +0 -2
  46. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +6 -1
  47. package/packages/dd-trace/src/config.js +0 -3
  48. package/packages/dd-trace/src/data_streams_context.js +1 -1
  49. package/packages/dd-trace/src/datastreams/pathway.js +58 -1
  50. package/packages/dd-trace/src/datastreams/processor.js +3 -5
  51. package/packages/dd-trace/src/lambda/runtime/ritm.js +1 -1
  52. package/packages/dd-trace/src/opentracing/propagation/text_map.js +21 -2
  53. package/packages/dd-trace/src/opentracing/span.js +2 -0
  54. package/packages/dd-trace/src/opentracing/span_context.js +1 -0
  55. package/packages/dd-trace/src/plugins/apollo.js +50 -0
  56. package/packages/dd-trace/src/plugins/composite.js +1 -0
  57. package/packages/dd-trace/src/plugins/index.js +1 -0
  58. package/packages/dd-trace/src/plugins/tracing.js +6 -2
  59. package/packages/dd-trace/src/plugins/util/test.js +2 -2
  60. package/packages/dd-trace/src/priority_sampler.js +11 -6
  61. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +24 -0
  62. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +24 -0
  63. package/packages/dd-trace/src/telemetry/index.js +15 -4
  64. package/packages/dd-trace/src/tracer.js +3 -3
  65. package/CONTRIBUTING.md +0 -171
  66. package/MIGRATING.md +0 -224
  67. package/packages/dd-trace/src/external-logger/test/index.spec.js +0 -147
  68. package/scripts/check-proposal-labels.js +0 -71
  69. package/scripts/check_licenses.js +0 -69
  70. package/scripts/helpers/color.js +0 -8
  71. package/scripts/helpers/exec.js +0 -22
  72. package/scripts/helpers/title.js +0 -15
  73. package/scripts/install_plugin_modules.js +0 -248
  74. package/scripts/publish_docs.js +0 -21
  75. package/scripts/st.js +0 -105
package/index.d.ts CHANGED
@@ -137,8 +137,10 @@ interface Tracer extends opentracing.Tracer {
137
137
  // is doesn't need to be exported for Tracer
138
138
  /** @hidden */
139
139
  interface Plugins {
140
+ "aerospike": tracer.plugins.aerospike;
140
141
  "amqp10": tracer.plugins.amqp10;
141
142
  "amqplib": tracer.plugins.amqplib;
143
+ "apollo": tracer.plugins.apollo;
142
144
  "aws-sdk": tracer.plugins.aws_sdk;
143
145
  "bunyan": tracer.plugins.bunyan;
144
146
  "cassandra-driver": tracer.plugins.cassandra_driver;
@@ -1098,6 +1100,12 @@ declare namespace tracer {
1098
1100
  meta?: boolean;
1099
1101
  }
1100
1102
 
1103
+ /**
1104
+ * This plugin automatically instruments the
1105
+ * [aerospike](https://github.com/aerospike/aerospike-client-nodejs) for module versions >= v3.16.2.
1106
+ */
1107
+ interface aerospike extends Instrumentation {}
1108
+
1101
1109
  /**
1102
1110
  * This plugin automatically instruments the
1103
1111
  * [amqp10](https://github.com/noodlefrenzy/node-amqp10) module.
@@ -1110,6 +1118,14 @@ declare namespace tracer {
1110
1118
  */
1111
1119
  interface amqplib extends Instrumentation {}
1112
1120
 
1121
+ /**
1122
+ * Currently this plugin automatically instruments
1123
+ * [@apollo/gateway](https://github.com/apollographql/federation) for module versions >= v2.3.0.
1124
+ * This module uses graphql operations to service requests & thus generates graphql spans.
1125
+ * We recommend disabling the graphql plugin if you only want to trace @apollo/gateway
1126
+ */
1127
+ interface apollo extends Instrumentation {}
1128
+
1113
1129
  /**
1114
1130
  * This plugin automatically instruments the
1115
1131
  * [aws-sdk](https://github.com/aws/aws-sdk-js) module.
@@ -1624,6 +1640,10 @@ declare namespace tracer {
1624
1640
  * The service name to be used for this plugin. If a function is used, it will be passed the connection parameters and its return value will be used as the service name.
1625
1641
  */
1626
1642
  service?: string | ((params: any) => string);
1643
+ /**
1644
+ * The database monitoring propagation mode to be used for this plugin.
1645
+ */
1646
+ dbmPropagationMode?: string;
1627
1647
  }
1628
1648
 
1629
1649
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "6.0.0-pre-ac0fc13",
3
+ "version": "6.0.0-pre-2d874ad",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -70,10 +70,10 @@
70
70
  },
71
71
  "dependencies": {
72
72
  "@datadog/native-appsec": "7.1.0",
73
- "@datadog/native-iast-rewriter": "2.2.3",
73
+ "@datadog/native-iast-rewriter": "2.3.0",
74
74
  "@datadog/native-iast-taint-tracking": "1.7.0",
75
75
  "@datadog/native-metrics": "^2.0.0",
76
- "@datadog/pprof": "5.0.0",
76
+ "@datadog/pprof": "5.1.0",
77
77
  "@datadog/sketches-js": "^2.1.0",
78
78
  "@opentelemetry/api": "^1.0.0",
79
79
  "@opentelemetry/core": "^1.14.0",
@@ -0,0 +1,101 @@
1
+ const {
2
+ addHook,
3
+ channel
4
+ } = require('./helpers/instrument')
5
+ const shimmer = require('../../datadog-shimmer')
6
+ const tracingChannel = require('dc-polyfill').tracingChannel
7
+
8
+ const CHANNELS = {
9
+ 'gateway.request': tracingChannel('apm:apollo:gateway:request'),
10
+ 'gateway.plan': tracingChannel('apm:apollo:gateway:plan'),
11
+ 'gateway.validate': tracingChannel('apm:apollo:gateway:validate'),
12
+ 'gateway.execute': tracingChannel('apm:apollo:gateway:execute'),
13
+ 'gateway.fetch': tracingChannel('apm:apollo:gateway:fetch'),
14
+ 'gateway.postprocessing': tracingChannel('apm:apollo:gateway:postprocessing')
15
+ }
16
+
17
+ const executorCh = channel('apm:apollo:gateway:request:executor')
18
+ const generalErrorCh = channel('apm:apollo:gateway:general:error')
19
+
20
+ function wrapExecutor (executor) {
21
+ return function (...args) {
22
+ const ctx = { requestContext: args[0], gateway: this }
23
+ executorCh.publish(ctx)
24
+ return executor.apply(this, args)
25
+ }
26
+ }
27
+
28
+ function wrapApolloGateway (ApolloGateway) {
29
+ class ApolloGatewayWrapper extends ApolloGateway {
30
+ constructor (...args) {
31
+ super(...args)
32
+ shimmer.wrap(this, 'executor', wrapExecutor)
33
+ }
34
+ }
35
+ return ApolloGatewayWrapper
36
+ }
37
+
38
+ function wrapRecordExceptions (recordExceptions) {
39
+ return function wrappedRecordExceptions (...args) {
40
+ const errors = args[1]
41
+ // only the last exception in the array of exceptions will be reported on the span,
42
+ // this is mimicking apollo-gateways internal instrumentation
43
+ // TODO: should we consider a mechanism to report all exceptions? since this method aggregates all exceptions
44
+ // where as a span can only have one exception set on it at a time
45
+ generalErrorCh.publish({ error: errors[errors.length - 1] })
46
+ return recordExceptions.apply(this, args)
47
+ }
48
+ }
49
+
50
+ function wrapStartActiveSpan (startActiveSpan) {
51
+ return function (...args) {
52
+ const firstArg = args[0]
53
+ const cb = args[args.length - 1]
54
+ if (typeof firstArg !== 'string' || typeof cb !== 'function') return startActiveSpan.apply(this, args)
55
+
56
+ const method = CHANNELS[firstArg]
57
+ let ctx = {}
58
+ if (firstArg === 'gateway.fetch') {
59
+ ctx = { attributes: args[1].attributes }
60
+ }
61
+
62
+ switch (firstArg) {
63
+ case 'gateway.plan' :
64
+ case 'gateway.validate': {
65
+ args[args.length - 1] = function (...callbackArgs) {
66
+ return method.traceSync(cb, ctx, this, ...callbackArgs)
67
+ }
68
+ break
69
+ }
70
+ case 'gateway.request':
71
+ case 'gateway.execute':
72
+ case 'gateway.postprocessing' :
73
+ case 'gateway.fetch': {
74
+ args[args.length - 1] = function (...callbackArgs) {
75
+ return method.tracePromise(cb, ctx, this, ...callbackArgs)
76
+ }
77
+ break
78
+ }
79
+ }
80
+ return startActiveSpan.apply(this, args)
81
+ }
82
+ }
83
+
84
+ addHook({ name: '@apollo/gateway', file: 'dist/utilities/opentelemetry.js', versions: ['>=2.3.0'] },
85
+ (obj) => {
86
+ const newTracerObj = Object.create(obj.tracer)
87
+ shimmer.wrap(newTracerObj, 'startActiveSpan', wrapStartActiveSpan)
88
+ obj.tracer = newTracerObj
89
+ return obj
90
+ })
91
+
92
+ addHook({ name: '@apollo/gateway', file: 'dist/utilities/opentelemetry.js', versions: ['>=2.6.0'] },
93
+ (obj) => {
94
+ shimmer.wrap(obj, 'recordExceptions', wrapRecordExceptions)
95
+ return obj
96
+ })
97
+
98
+ addHook({ name: '@apollo/gateway', versions: ['>=2.3.0'] }, (gateway) => {
99
+ shimmer.wrap(gateway, 'ApolloGateway', wrapApolloGateway)
100
+ return gateway
101
+ })
@@ -92,7 +92,8 @@ function getStatusFromResultLatest (result) {
92
92
  }
93
93
 
94
94
  function isNewTest (testSuite, testName) {
95
- return !knownTests.includes(`cucumber.${testSuite}.${testName}`)
95
+ const testsForSuite = knownTests.cucumber?.[testSuite] || []
96
+ return !testsForSuite.includes(testName)
96
97
  }
97
98
 
98
99
  function getTestStatusFromRetries (testStatuses) {
@@ -92,7 +92,9 @@ function createWrapEmit (call, ctx, onCancel) {
92
92
  finishChannel.publish(ctx)
93
93
  call.removeListener('cancelled', onCancel)
94
94
  break
95
- case 'finish':
95
+ // Streams are always cancelled before `finish` since 1.10.0 so we have
96
+ // to use `prefinish` instead to avoid cancellation false positives.
97
+ case 'prefinish':
96
98
  if (call.status) {
97
99
  updateChannel.publish(call.status)
98
100
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  module.exports = {
4
4
  '@apollo/server': () => require('../apollo-server'),
5
+ '@apollo/gateway': () => require('../apollo'),
5
6
  'apollo-server-core': () => require('../apollo-server-core'),
6
7
  '@aws-sdk/smithy-client': () => require('../aws-sdk'),
7
8
  '@cucumber/cucumber': () => require('../cucumber'),
@@ -140,14 +140,16 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
140
140
  // Function that receives a list of known tests for a test service and
141
141
  // returns the ones that belong to the current suite
142
142
  getKnownTestsForSuite (knownTests) {
143
+ if (this.knownTestsForThisSuite) {
144
+ return this.knownTestsForThisSuite
145
+ }
143
146
  let knownTestsForSuite = knownTests
144
- // If jest runs in band, the known tests are not serialized, so they're an array.
145
- if (!Array.isArray(knownTests)) {
147
+ // If jest is using workers, known tests are serialized to json.
148
+ // If jest runs in band, they are not.
149
+ if (typeof knownTestsForSuite === 'string') {
146
150
  knownTestsForSuite = JSON.parse(knownTestsForSuite)
147
151
  }
148
- return knownTestsForSuite
149
- .filter(test => test.includes(this.testSuite))
150
- .map(test => test.replace(`jest.${this.testSuite}.`, '').trim())
152
+ return knownTestsForSuite.jest?.[this.testSuite] || []
151
153
  }
152
154
 
153
155
  // Add the `add_test` event we don't have the test object yet, so
@@ -106,7 +106,10 @@ function getTestFullName (test) {
106
106
  }
107
107
 
108
108
  function isNewTest (test) {
109
- return !knownTests.includes(getTestFullName(test))
109
+ const testSuite = getTestSuitePath(test.file, process.cwd())
110
+ const testName = removeEfdStringFromTestName(test.fullTitle())
111
+ const testsForSuite = knownTests.mocha?.[testSuite] || []
112
+ return !testsForSuite.includes(testName)
110
113
  }
111
114
 
112
115
  function retryTest (test) {
@@ -1,6 +1,9 @@
1
+ const semver = require('semver')
2
+
1
3
  const { addHook, channel, AsyncResource } = require('./helpers/instrument')
2
4
  const shimmer = require('../../datadog-shimmer')
3
- const { parseAnnotations } = require('../../dd-trace/src/plugins/util/test')
5
+ const { parseAnnotations, getTestSuitePath } = require('../../dd-trace/src/plugins/util/test')
6
+ const log = require('../../dd-trace/src/log')
4
7
 
5
8
  const testStartCh = channel('ci:playwright:test:start')
6
9
  const testFinishCh = channel('ci:playwright:test:finish')
@@ -8,6 +11,9 @@ const testFinishCh = channel('ci:playwright:test:finish')
8
11
  const testSessionStartCh = channel('ci:playwright:session:start')
9
12
  const testSessionFinishCh = channel('ci:playwright:session:finish')
10
13
 
14
+ const libraryConfigurationCh = channel('ci:playwright:library-configuration')
15
+ const knownTestsCh = channel('ci:playwright:known-tests')
16
+
11
17
  const testSuiteStartCh = channel('ci:playwright:test-suite:start')
12
18
  const testSuiteFinishCh = channel('ci:playwright:test-suite:finish')
13
19
 
@@ -16,6 +22,8 @@ const testSuiteToAr = new Map()
16
22
  const testSuiteToTestStatuses = new Map()
17
23
  const testSuiteToErrors = new Map()
18
24
 
25
+ let applyRepeatEachIndex = null
26
+
19
27
  let startedSuites = []
20
28
 
21
29
  const STATUS_TO_TEST_STATUS = {
@@ -26,6 +34,44 @@ const STATUS_TO_TEST_STATUS = {
26
34
  }
27
35
 
28
36
  let remainingTestsByFile = {}
37
+ let isEarlyFlakeDetectionEnabled = false
38
+ let earlyFlakeDetectionNumRetries = 0
39
+ let knownTests = []
40
+ let rootDir = ''
41
+ const MINIMUM_SUPPORTED_VERSION_EFD = '1.38.0'
42
+
43
+ function isNewTest (test) {
44
+ const testSuite = getTestSuitePath(test._requireFile, rootDir)
45
+ const testsForSuite = knownTests?.playwright?.[testSuite] || []
46
+
47
+ return !testsForSuite.includes(test.title)
48
+ }
49
+
50
+ function getSuiteType (test, type) {
51
+ let suite = test.parent
52
+ while (suite && suite._type !== type) {
53
+ suite = suite.parent
54
+ }
55
+ return suite
56
+ }
57
+
58
+ // Copy of Suite#_deepClone but with a function to filter tests
59
+ function deepCloneSuite (suite, filterTest) {
60
+ const copy = suite._clone()
61
+ for (const entry of suite._entries) {
62
+ if (entry.constructor.name === 'Suite') {
63
+ copy._addSuite(deepCloneSuite(entry, filterTest))
64
+ } else {
65
+ if (filterTest(entry)) {
66
+ const copiedTest = entry._clone()
67
+ copiedTest._ddIsNew = true
68
+ copiedTest._ddIsEfdRetry = true
69
+ copy._addTest(copiedTest)
70
+ }
71
+ }
72
+ }
73
+ return copy
74
+ }
29
75
 
30
76
  function getTestsBySuiteFromTestGroups (testGroups) {
31
77
  return testGroups.reduce((acc, { requireFile, tests }) => {
@@ -153,8 +199,11 @@ function getTestSuiteError (testSuiteAbsolutePath) {
153
199
  function testBeginHandler (test, browserName) {
154
200
  const {
155
201
  _requireFile: testSuiteAbsolutePath,
156
- title: testName, _type,
157
- location: { line: testSourceLine }
202
+ title: testName,
203
+ _type,
204
+ location: {
205
+ line: testSourceLine
206
+ }
158
207
  } = test
159
208
 
160
209
  if (_type === 'beforeAll' || _type === 'afterAll') {
@@ -198,7 +247,14 @@ function testEndHandler (test, annotations, testStatus, error, isTimeout) {
198
247
  const testResult = results[results.length - 1]
199
248
  const testAsyncResource = testToAr.get(test)
200
249
  testAsyncResource.runInAsyncScope(() => {
201
- testFinishCh.publish({ testStatus, steps: testResult.steps, error, extraTags: annotationTags })
250
+ testFinishCh.publish({
251
+ testStatus,
252
+ steps: testResult.steps,
253
+ error,
254
+ extraTags: annotationTags,
255
+ isNew: test._ddIsNew,
256
+ isEfdRetry: test._ddIsEfdRetry
257
+ })
202
258
  })
203
259
 
204
260
  if (testSuiteToTestStatuses.has(testSuiteAbsolutePath)) {
@@ -309,14 +365,54 @@ function dispatcherHookNew (dispatcherExport, runWrapper) {
309
365
 
310
366
  function runnerHook (runnerExport, playwrightVersion) {
311
367
  shimmer.wrap(runnerExport.Runner.prototype, 'runAllTests', runAllTests => async function () {
368
+ let onDone
369
+
312
370
  const testSessionAsyncResource = new AsyncResource('bound-anonymous-fn')
313
- const rootDir = getRootDir(this)
371
+
372
+ rootDir = getRootDir(this)
314
373
 
315
374
  const processArgv = process.argv.slice(2).join(' ')
316
375
  const command = `playwright ${processArgv}`
317
376
  testSessionAsyncResource.runInAsyncScope(() => {
318
377
  testSessionStartCh.publish({ command, frameworkVersion: playwrightVersion, rootDir })
319
378
  })
379
+
380
+ const configurationPromise = new Promise((resolve) => {
381
+ onDone = resolve
382
+ })
383
+
384
+ testSessionAsyncResource.runInAsyncScope(() => {
385
+ libraryConfigurationCh.publish({ onDone })
386
+ })
387
+
388
+ try {
389
+ const { err, libraryConfig } = await configurationPromise
390
+ if (!err) {
391
+ isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
392
+ earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
393
+ }
394
+ } catch (e) {
395
+ log.error(e)
396
+ }
397
+
398
+ if (isEarlyFlakeDetectionEnabled && semver.gte(playwrightVersion, MINIMUM_SUPPORTED_VERSION_EFD)) {
399
+ const knownTestsPromise = new Promise((resolve) => {
400
+ onDone = resolve
401
+ })
402
+ testSessionAsyncResource.runInAsyncScope(() => {
403
+ knownTestsCh.publish({ onDone })
404
+ })
405
+
406
+ try {
407
+ const { err, knownTests: receivedKnownTests } = await knownTestsPromise
408
+ if (!err) {
409
+ knownTests = receivedKnownTests
410
+ }
411
+ } catch (err) {
412
+ log.error(err)
413
+ }
414
+ }
415
+
320
416
  const projects = getProjectsFromRunner(this)
321
417
 
322
418
  const runAllTestsReturn = await runAllTests.apply(this, arguments)
@@ -334,7 +430,6 @@ function runnerHook (runnerExport, playwrightVersion) {
334
430
 
335
431
  const sessionStatus = runAllTestsReturn.status || runAllTestsReturn
336
432
 
337
- let onDone
338
433
  const flushWait = new Promise(resolve => {
339
434
  onDone = resolve
340
435
  })
@@ -394,3 +489,53 @@ addHook({
394
489
  file: 'lib/runner/dispatcher.js',
395
490
  versions: ['>=1.38.0']
396
491
  }, (dispatcher) => dispatcherHookNew(dispatcher, dispatcherRunWrapperNew))
492
+
493
+ // Hook used for early flake detection. EFD only works from >=1.38.0
494
+ addHook({
495
+ name: 'playwright',
496
+ file: 'lib/common/suiteUtils.js',
497
+ versions: [`>=${MINIMUM_SUPPORTED_VERSION_EFD}`]
498
+ }, suiteUtilsPackage => {
499
+ // We grab `applyRepeatEachIndex` to use it later
500
+ // `applyRepeatEachIndex` needs to be applied to a cloned suite
501
+ applyRepeatEachIndex = suiteUtilsPackage.applyRepeatEachIndex
502
+ return suiteUtilsPackage
503
+ })
504
+
505
+ // Hook used for early flake detection. EFD only works from >=1.38.0
506
+ addHook({
507
+ name: 'playwright',
508
+ file: 'lib/runner/loadUtils.js',
509
+ versions: [`>=${MINIMUM_SUPPORTED_VERSION_EFD}`]
510
+ }, (loadUtilsPackage) => {
511
+ const oldCreateRootSuite = loadUtilsPackage.createRootSuite
512
+
513
+ async function newCreateRootSuite () {
514
+ const rootSuite = await oldCreateRootSuite.apply(this, arguments)
515
+ if (!isEarlyFlakeDetectionEnabled) {
516
+ return rootSuite
517
+ }
518
+ const newTests = rootSuite
519
+ .allTests()
520
+ .filter(isNewTest)
521
+
522
+ newTests.forEach(newTest => {
523
+ newTest._ddIsNew = true
524
+ if (newTest.expectedStatus !== 'skipped') {
525
+ const fileSuite = getSuiteType(newTest, 'file')
526
+ const projectSuite = getSuiteType(newTest, 'project')
527
+ for (let repeatEachIndex = 0; repeatEachIndex < earlyFlakeDetectionNumRetries; repeatEachIndex++) {
528
+ const copyFileSuite = deepCloneSuite(fileSuite, isNewTest)
529
+ applyRepeatEachIndex(projectSuite._fullProject, copyFileSuite, repeatEachIndex + 1)
530
+ projectSuite._addSuite(copyFileSuite)
531
+ }
532
+ }
533
+ })
534
+
535
+ return rootSuite
536
+ }
537
+
538
+ loadUtilsPackage.createRootSuite = newCreateRootSuite
539
+
540
+ return loadUtilsPackage
541
+ })
@@ -2,7 +2,8 @@
2
2
 
3
3
  const { TEXT_MAP } = require('../../../ext/formats')
4
4
  const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
5
- const { getAmqpMessageSize, CONTEXT_PROPAGATION_KEY } = require('../../dd-trace/src/datastreams/processor')
5
+ const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
6
+ const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams/pathway')
6
7
  const { getResourceName } = require('./util')
7
8
 
8
9
  class AmqplibConsumerPlugin extends ConsumerPlugin {
@@ -29,12 +30,12 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
29
30
  })
30
31
 
31
32
  if (
32
- this.config.dsmEnabled &&
33
- message?.properties?.headers?.[CONTEXT_PROPAGATION_KEY]
33
+ this.config.dsmEnabled && message?.properties?.headers &&
34
+ DsmPathwayCodec.contextExists(message.properties.headers)
34
35
  ) {
35
36
  const payloadSize = getAmqpMessageSize({ headers: message.properties.headers, content: message.content })
36
37
  const queue = fields.queue ? fields.queue : fields.routingKey
37
- this.tracer.decodeDataStreamsContext(message.properties.headers[CONTEXT_PROPAGATION_KEY])
38
+ this.tracer.decodeDataStreamsContext(message.properties.headers)
38
39
  this.tracer
39
40
  .setCheckpoint(['direction:in', `topic:${queue}`, 'type:rabbitmq'], span, payloadSize)
40
41
  }
@@ -3,8 +3,8 @@
3
3
  const { TEXT_MAP } = require('../../../ext/formats')
4
4
  const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
5
5
  const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
6
- const { encodePathwayContext } = require('../../dd-trace/src/datastreams/pathway')
7
- const { getAmqpMessageSize, CONTEXT_PROPAGATION_KEY } = require('../../dd-trace/src/datastreams/processor')
6
+ const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams/pathway')
7
+ const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
8
8
  const { getResourceName } = require('./util')
9
9
 
10
10
  class AmqplibProducerPlugin extends ProducerPlugin {
@@ -40,8 +40,7 @@ class AmqplibProducerPlugin extends ProducerPlugin {
40
40
  .setCheckpoint(
41
41
  ['direction:out', `exchange:${fields.exchange}`, `has_routing_key:${hasRoutingKey}`, 'type:rabbitmq']
42
42
  , span, payloadSize)
43
- const pathwayCtx = encodePathwayContext(dataStreamsContext)
44
- fields.headers[CONTEXT_PROPAGATION_KEY] = pathwayCtx
43
+ DsmPathwayCodec.encode(dataStreamsContext, fields.headers)
45
44
  }
46
45
  }
47
46
  }
@@ -0,0 +1,12 @@
1
+ 'use strict'
2
+
3
+ const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
4
+
5
+ class ApolloGatewayExecutePlugin extends ApolloBasePlugin {
6
+ static get operation () { return 'execute' }
7
+ static get prefix () {
8
+ return 'tracing:apm:apollo:gateway:execute'
9
+ }
10
+ }
11
+
12
+ module.exports = ApolloGatewayExecutePlugin
@@ -0,0 +1,36 @@
1
+ 'use strict'
2
+
3
+ const { storage } = require('../../../datadog-core')
4
+ const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
5
+
6
+ class ApolloGatewayFetchPlugin extends ApolloBasePlugin {
7
+ static get operation () { return 'fetch' }
8
+ static get prefix () {
9
+ return 'tracing:apm:apollo:gateway:fetch'
10
+ }
11
+
12
+ bindStart (ctx) {
13
+ const store = storage.getStore()
14
+ const childOf = store ? store.span : null
15
+
16
+ const spanData = {
17
+ childOf,
18
+ service: this.getServiceName(),
19
+ type: this.constructor.type,
20
+ meta: {}
21
+ }
22
+
23
+ const serviceName = ctx?.attributes?.service
24
+
25
+ if (serviceName) { spanData.meta['serviceName'] = serviceName }
26
+
27
+ const span = this.startSpan(this.getOperationName(), spanData, false)
28
+
29
+ ctx.parentStore = store
30
+ ctx.currentStore = { ...store, span }
31
+
32
+ return ctx.currentStore
33
+ }
34
+ }
35
+
36
+ module.exports = ApolloGatewayFetchPlugin
@@ -0,0 +1,36 @@
1
+ 'use strict'
2
+
3
+ const { storage } = require('../../../datadog-core')
4
+ const CompositePlugin = require('../../../dd-trace/src/plugins/composite')
5
+ const ApolloGatewayExecutePlugin = require('./execute')
6
+ const ApolloGatewayPostProcessingPlugin = require('./postprocessing')
7
+ const ApolloGatewayRequestPlugin = require('./request')
8
+ const ApolloGatewayPlanPlugin = require('./plan')
9
+ const ApolloGatewayValidatePlugin = require('./validate')
10
+ const ApolloGatewayFetchPlugin = require('./fetch')
11
+
12
+ class ApolloGatewayPlugin extends CompositePlugin {
13
+ static get id () { return 'gateway' }
14
+ static get plugins () {
15
+ return {
16
+ execute: ApolloGatewayExecutePlugin,
17
+ postprocessing: ApolloGatewayPostProcessingPlugin,
18
+ request: ApolloGatewayRequestPlugin,
19
+ plan: ApolloGatewayPlanPlugin,
20
+ fetch: ApolloGatewayFetchPlugin,
21
+ validate: ApolloGatewayValidatePlugin
22
+ }
23
+ }
24
+
25
+ constructor (...args) {
26
+ super(...args)
27
+ this.addSub('apm:apollo:gateway:general:error', (ctx) => {
28
+ const store = storage.getStore()
29
+ const span = store?.span
30
+ if (!span) return
31
+ span.setTag('error', ctx.error)
32
+ })
33
+ }
34
+ }
35
+
36
+ module.exports = ApolloGatewayPlugin
@@ -0,0 +1,13 @@
1
+
2
+ 'use strict'
3
+
4
+ const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
5
+
6
+ class ApolloGatewayPlanPlugin extends ApolloBasePlugin {
7
+ static get operation () { return 'plan' }
8
+ static get prefix () {
9
+ return 'tracing:apm:apollo:gateway:plan'
10
+ }
11
+ }
12
+
13
+ module.exports = ApolloGatewayPlanPlugin
@@ -0,0 +1,12 @@
1
+ 'use strict'
2
+
3
+ const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
4
+
5
+ class ApolloGatewayPostProcessingPlugin extends ApolloBasePlugin {
6
+ static get operation () { return 'postprocessing' }
7
+ static get prefix () {
8
+ return 'tracing:apm:apollo:gateway:postprocessing'
9
+ }
10
+ }
11
+
12
+ module.exports = ApolloGatewayPostProcessingPlugin