dd-trace 5.55.0 → 5.57.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 (150) hide show
  1. package/LICENSE-3rdparty.csv +1 -0
  2. package/index.d.ts +44 -2
  3. package/init.js +4 -1
  4. package/package.json +24 -23
  5. package/packages/datadog-core/src/utils/src/set.js +8 -10
  6. package/packages/datadog-esbuild/index.js +22 -0
  7. package/packages/datadog-instrumentations/src/cassandra-driver.js +43 -60
  8. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +12 -12
  9. package/packages/datadog-instrumentations/src/cucumber.js +4 -6
  10. package/packages/datadog-instrumentations/src/elasticsearch.js +16 -19
  11. package/packages/datadog-instrumentations/src/fastify.js +91 -9
  12. package/packages/datadog-instrumentations/src/helpers/bundler-register.js +20 -5
  13. package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +2 -2
  14. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  15. package/packages/datadog-instrumentations/src/helpers/register.js +17 -5
  16. package/packages/datadog-instrumentations/src/ioredis.js +8 -13
  17. package/packages/datadog-instrumentations/src/iovalkey.js +10 -14
  18. package/packages/datadog-instrumentations/src/jest.js +423 -325
  19. package/packages/datadog-instrumentations/src/memcached.js +17 -24
  20. package/packages/datadog-instrumentations/src/mocha/main.js +7 -6
  21. package/packages/datadog-instrumentations/src/moleculer/client.js +9 -10
  22. package/packages/datadog-instrumentations/src/moleculer/server.js +12 -13
  23. package/packages/datadog-instrumentations/src/openai.js +30 -2
  24. package/packages/datadog-instrumentations/src/playwright.js +4 -1
  25. package/packages/datadog-instrumentations/src/prisma.js +116 -0
  26. package/packages/datadog-instrumentations/src/redis.js +32 -43
  27. package/packages/datadog-instrumentations/src/router.js +1 -1
  28. package/packages/datadog-instrumentations/src/sharedb.js +10 -16
  29. package/packages/datadog-instrumentations/src/vitest.js +4 -4
  30. package/packages/datadog-plugin-aws-sdk/src/base.js +6 -1
  31. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +9 -4
  32. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +3 -2
  33. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -1
  34. package/packages/datadog-plugin-aws-sdk/src/util.js +2 -2
  35. package/packages/datadog-plugin-azure-functions/src/index.js +5 -4
  36. package/packages/datadog-plugin-bunyan/src/index.js +2 -2
  37. package/packages/datadog-plugin-cassandra-driver/src/index.js +6 -2
  38. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/batch-consumer.js +1 -1
  39. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/consumer.js +1 -1
  40. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/index.js +1 -1
  41. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/producer.js +1 -1
  42. package/packages/datadog-plugin-cucumber/src/index.js +4 -2
  43. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +9 -5
  44. package/packages/datadog-plugin-elasticsearch/src/index.js +12 -4
  45. package/packages/datadog-plugin-http/src/client.js +1 -0
  46. package/packages/datadog-plugin-http/src/server.js +2 -1
  47. package/packages/datadog-plugin-http2/src/client.js +1 -0
  48. package/packages/datadog-plugin-http2/src/server.js +1 -0
  49. package/packages/datadog-plugin-jest/src/index.js +4 -3
  50. package/packages/datadog-plugin-memcached/src/index.js +6 -2
  51. package/packages/datadog-plugin-mocha/src/index.js +3 -2
  52. package/packages/datadog-plugin-moleculer/src/client.js +15 -9
  53. package/packages/datadog-plugin-moleculer/src/server.js +9 -5
  54. package/packages/datadog-plugin-next/src/index.js +2 -1
  55. package/packages/datadog-plugin-openai/src/tracing.js +127 -80
  56. package/packages/datadog-plugin-oracledb/src/index.js +2 -1
  57. package/packages/datadog-plugin-pino/src/index.js +2 -2
  58. package/packages/datadog-plugin-prisma/src/client.js +62 -0
  59. package/packages/datadog-plugin-prisma/src/engine.js +81 -0
  60. package/packages/datadog-plugin-prisma/src/index.js +22 -0
  61. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -1
  62. package/packages/datadog-plugin-redis/src/index.js +9 -3
  63. package/packages/datadog-plugin-router/src/index.js +1 -0
  64. package/packages/datadog-plugin-sharedb/src/index.js +13 -5
  65. package/packages/datadog-plugin-winston/src/index.js +2 -2
  66. package/packages/dd-trace/src/appsec/channels.js +26 -21
  67. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
  68. package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +13 -20
  69. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +1 -1
  70. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +44 -1
  71. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +2 -1
  72. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +7 -2
  73. package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +0 -1
  74. package/packages/dd-trace/src/appsec/index.js +28 -2
  75. package/packages/dd-trace/src/appsec/rasp/utils.js +0 -5
  76. package/packages/dd-trace/src/appsec/reporter.js +6 -4
  77. package/packages/dd-trace/src/baggage.js +2 -2
  78. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +3 -3
  79. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
  80. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
  81. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
  82. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
  83. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -6
  84. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -3
  85. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +3 -3
  86. package/packages/dd-trace/src/config.js +334 -312
  87. package/packages/dd-trace/src/constants.js +2 -1
  88. package/packages/dd-trace/src/crashtracking/crashtracker.js +12 -14
  89. package/packages/dd-trace/src/datastreams/context.js +1 -1
  90. package/packages/dd-trace/src/datastreams/processor.js +1 -1
  91. package/packages/dd-trace/src/datastreams/writer.js +3 -3
  92. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +6 -3
  93. package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
  94. package/packages/dd-trace/src/debugger/devtools_client/index.js +2 -3
  95. package/packages/dd-trace/src/debugger/devtools_client/send.js +5 -1
  96. package/packages/dd-trace/src/debugger/devtools_client/state.js +7 -4
  97. package/packages/dd-trace/src/debugger/devtools_client/status.js +5 -1
  98. package/packages/dd-trace/src/dogstatsd.js +3 -3
  99. package/packages/dd-trace/src/exporters/agent/index.js +10 -5
  100. package/packages/dd-trace/src/exporters/agent/writer.js +4 -2
  101. package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +2 -2
  102. package/packages/dd-trace/src/exporters/log/index.js +1 -1
  103. package/packages/dd-trace/src/exporters/span-stats/writer.js +2 -2
  104. package/packages/dd-trace/src/guardrails/index.js +3 -1
  105. package/packages/dd-trace/src/guardrails/telemetry.js +1 -1
  106. package/packages/dd-trace/src/llmobs/index.js +11 -5
  107. package/packages/dd-trace/src/llmobs/plugins/base.js +2 -2
  108. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +1 -1
  109. package/packages/dd-trace/src/llmobs/tagger.js +13 -13
  110. package/packages/dd-trace/src/llmobs/writers/base.js +2 -2
  111. package/packages/dd-trace/src/llmobs/writers/spans.js +2 -2
  112. package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
  113. package/packages/dd-trace/src/opentracing/propagation/text_map.js +22 -28
  114. package/packages/dd-trace/src/opentracing/span.js +1 -0
  115. package/packages/dd-trace/src/plugin_manager.js +3 -3
  116. package/packages/dd-trace/src/plugins/cache.js +2 -2
  117. package/packages/dd-trace/src/plugins/ci_plugin.js +11 -7
  118. package/packages/dd-trace/src/plugins/database.js +3 -1
  119. package/packages/dd-trace/src/plugins/index.js +1 -0
  120. package/packages/dd-trace/src/plugins/log_plugin.js +5 -1
  121. package/packages/dd-trace/src/plugins/outbound.js +8 -6
  122. package/packages/dd-trace/src/plugins/structured_log_plugin.js +9 -0
  123. package/packages/dd-trace/src/plugins/tracing.js +1 -1
  124. package/packages/dd-trace/src/plugins/util/ci.js +83 -30
  125. package/packages/dd-trace/src/plugins/util/git.js +1 -0
  126. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +3 -2
  127. package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -0
  128. package/packages/dd-trace/src/plugins/util/tags.js +4 -1
  129. package/packages/dd-trace/src/plugins/util/test.js +80 -10
  130. package/packages/dd-trace/src/plugins/util/web.js +1 -0
  131. package/packages/dd-trace/src/profiler.js +0 -2
  132. package/packages/dd-trace/src/profiling/exporter_cli.js +1 -3
  133. package/packages/dd-trace/src/profiling/profilers/events.js +10 -2
  134. package/packages/dd-trace/src/profiling/ssi-heuristics.js +18 -126
  135. package/packages/dd-trace/src/proxy.js +12 -27
  136. package/packages/dd-trace/src/runtime_metrics/index.js +1 -1
  137. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +14 -45
  138. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +2 -2
  139. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +4 -0
  140. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +2 -2
  141. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +4 -0
  142. package/packages/dd-trace/src/supported-configurations.json +13 -3
  143. package/packages/dd-trace/src/telemetry/telemetry.js +11 -4
  144. package/packages/dd-trace/src/tracer.js +11 -0
  145. package/packages/dd-trace/src/tracer_metadata.js +25 -0
  146. package/packages/dd-trace/src/util.js +11 -4
  147. package/version.js +3 -1
  148. package/packages/datadog-core/src/utils/src/get.js +0 -11
  149. package/packages/datadog-core/src/utils/src/has.js +0 -14
  150. package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +0 -30
@@ -2,8 +2,7 @@
2
2
 
3
3
  const {
4
4
  channel,
5
- addHook,
6
- AsyncResource
5
+ addHook
7
6
  } = require('./helpers/instrument')
8
7
  const shimmer = require('../../datadog-shimmer')
9
8
 
@@ -17,35 +16,29 @@ addHook({ name: 'memcached', versions: ['>=2.2'] }, Memcached => {
17
16
  return command.apply(this, arguments)
18
17
  }
19
18
 
20
- const callbackResource = new AsyncResource('bound-anonymous-fn')
21
- const asyncResource = new AsyncResource('bound-anonymous-fn')
22
-
23
19
  const client = this
24
20
 
25
- const wrappedQueryCompiler = asyncResource.bind(function () {
21
+ const wrappedQueryCompiler = function () {
26
22
  const query = queryCompiler.apply(this, arguments)
27
- const callback = callbackResource.bind(query.callback)
28
-
29
- query.callback = shimmer.wrapFunction(callback, callback => asyncResource.bind(function (err) {
30
- if (err) {
31
- errorCh.publish(err)
32
- }
33
- finishCh.publish()
34
-
35
- return callback.apply(this, arguments)
36
- }))
37
- startCh.publish({ client, server, query })
38
23
 
24
+ const ctx = { client, server, query }
25
+ startCh.runStores(ctx, () => {
26
+ query.callback = shimmer.wrapFunction(query.callback, callback => function (err) {
27
+ if (err) {
28
+ ctx.error = err
29
+ errorCh.publish(ctx)
30
+ }
31
+ finishCh.publish(ctx)
32
+
33
+ return finishCh.runStores(ctx, callback, this, ...arguments)
34
+ })
35
+ })
39
36
  return query
40
- })
41
-
42
- return asyncResource.runInAsyncScope(() => {
43
- arguments[0] = wrappedQueryCompiler
37
+ }
44
38
 
45
- const result = command.apply(this, arguments)
39
+ arguments[0] = wrappedQueryCompiler
46
40
 
47
- return result
48
- })
41
+ return command.apply(this, arguments)
49
42
  })
50
43
 
51
44
  return Memcached
@@ -201,9 +201,10 @@ function getOnEndHandler (isParallel) {
201
201
  }
202
202
  }
203
203
 
204
- function getExecutionConfiguration (runner, isParallel, onFinishRequest) {
204
+ function getExecutionConfiguration (runner, isParallel, frameworkVersion, onFinishRequest) {
205
205
  const ctx = {
206
- isParallel
206
+ isParallel,
207
+ frameworkVersion
207
208
  }
208
209
 
209
210
  const onReceivedSkippableSuites = ({ err, skippableSuites, itrCorrelationId: responseItrCorrelationId }) => {
@@ -343,7 +344,7 @@ addHook({
343
344
  name: 'mocha',
344
345
  versions: ['>=5.2.0'],
345
346
  file: 'lib/mocha.js'
346
- }, (Mocha) => {
347
+ }, (Mocha, frameworkVersion) => {
347
348
  shimmer.wrap(Mocha.prototype, 'run', run => function () {
348
349
  // Workers do not need to request any data, just run the tests
349
350
  if (!testFinishCh.hasSubscribers || getEnvironmentVariable('MOCHA_WORKER_ID') || this.options.parallel) {
@@ -363,7 +364,7 @@ addHook({
363
364
  }
364
365
  })
365
366
 
366
- getExecutionConfiguration(runner, false, () => {
367
+ getExecutionConfiguration(runner, false, frameworkVersion, () => {
367
368
  if (config.isKnownTestsEnabled) {
368
369
  const testSuites = this.files.map(file => getTestSuitePath(file, process.cwd()))
369
370
  const isFaulty = getIsFaultyEarlyFlakeDetection(
@@ -521,7 +522,7 @@ addHook({
521
522
  if (ctx) {
522
523
  testSuiteFinishCh.publish({ status, ...ctx.currentStore }, () => {})
523
524
  } else {
524
- log.warn(() => `No ctx found for suite ${suite.file}`)
525
+ log.warn('No ctx found for suite', suite.file)
525
526
  }
526
527
  })
527
528
 
@@ -616,7 +617,7 @@ addHook({
616
617
  this.once('start', getOnStartHandler(true, frameworkVersion))
617
618
  this.once('end', getOnEndHandler(true))
618
619
 
619
- getExecutionConfiguration(this, true, () => {
620
+ getExecutionConfiguration(this, true, frameworkVersion, () => {
620
621
  if (config.isKnownTestsEnabled) {
621
622
  const testSuites = files.map(file => getTestSuitePath(file, process.cwd()))
622
623
  const isFaulty = getIsFaultyEarlyFlakeDetection(
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { channel, addHook, AsyncResource } = require('../helpers/instrument')
3
+ const { channel, addHook } = require('../helpers/instrument')
4
4
  const shimmer = require('../../../datadog-shimmer')
5
5
 
6
6
  const startChannel = channel('apm:moleculer:call:start')
@@ -9,29 +9,28 @@ const errorChannel = channel('apm:moleculer:call:error')
9
9
 
10
10
  function wrapCall (call) {
11
11
  return function (actionName, params, opts) {
12
- const callResource = new AsyncResource('bound-anonymous-fn')
13
-
14
12
  opts = arguments[2] = opts || {}
15
13
  opts.meta = opts.meta || {}
16
14
 
17
15
  arguments.length = Math.max(3, arguments.length)
18
16
 
19
- return callResource.runInAsyncScope(() => {
20
- startChannel.publish({ actionName, params, opts })
21
-
17
+ const ctx = { actionName, params, opts }
18
+ return startChannel.runStores(ctx, () => {
22
19
  const promise = call.apply(this, arguments)
23
20
  const broker = this
24
- const ctx = promise.ctx
21
+ ctx.promiseCtx = promise.ctx
22
+ ctx.broker = broker
25
23
 
26
24
  return promise
27
25
  .then(
28
26
  result => {
29
- finishChannel.publish({ broker, ctx })
27
+ finishChannel.publish(ctx)
30
28
  return result
31
29
  },
32
30
  error => {
33
- errorChannel.publish(error)
34
- finishChannel.publish({ broker, ctx })
31
+ ctx.error = error
32
+ errorChannel.publish(ctx)
33
+ finishChannel.publish(ctx)
35
34
  throw error
36
35
  }
37
36
  )
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { channel, addHook, AsyncResource } = require('../helpers/instrument')
3
+ const { channel, addHook } = require('../helpers/instrument')
4
4
  const shimmer = require('../../../datadog-shimmer')
5
5
 
6
6
  const startChannel = channel('apm:moleculer:action:start')
@@ -24,27 +24,26 @@ function createMiddleware () {
24
24
  localAction (next, action) {
25
25
  const broker = this
26
26
 
27
- return shimmer.wrapFunction(next, next => function datadogMiddleware (ctx) {
28
- const actionResource = new AsyncResource('bound-anonymous-fn')
29
-
30
- return actionResource.runInAsyncScope(() => {
31
- startChannel.publish({ action, ctx, broker })
32
-
27
+ return shimmer.wrapFunction(next, next => function datadogMiddleware (middlewareCtx) {
28
+ const ctx = { action, middlewareCtx, broker }
29
+ return startChannel.runStores(ctx, () => {
33
30
  try {
34
- return next(ctx).then(
31
+ return next(middlewareCtx).then(
35
32
  result => {
36
- finishChannel.publish()
33
+ finishChannel.publish(ctx)
37
34
  return result
38
35
  },
39
36
  error => {
40
- errorChannel.publish(error)
41
- finishChannel.publish()
37
+ ctx.error = error
38
+ errorChannel.publish(ctx)
39
+ finishChannel.publish(ctx)
42
40
  throw error
43
41
  }
44
42
  )
45
43
  } catch (e) {
46
- errorChannel.publish(e)
47
- finishChannel.publish()
44
+ ctx.error = e
45
+ errorChannel.publish(ctx)
46
+ finishChannel.publish(ctx)
48
47
  }
49
48
  })
50
49
  })
@@ -31,7 +31,21 @@ const V4_PACKAGE_SHIMS = [
31
31
  file: 'resources/files',
32
32
  targetClass: 'Files',
33
33
  baseResource: 'files',
34
- methods: ['create', 'del', 'list', 'retrieve']
34
+ methods: ['create', 'list', 'retrieve'],
35
+ },
36
+ {
37
+ file: 'resources/files',
38
+ targetClass: 'Files',
39
+ baseResource: 'files',
40
+ methods: ['del'],
41
+ versions: ['>=4.0.0 <5.0.0']
42
+ },
43
+ {
44
+ file: 'resources/files',
45
+ targetClass: 'Files',
46
+ baseResource: 'files',
47
+ methods: ['delete'],
48
+ versions: ['>=5']
35
49
  },
36
50
  {
37
51
  file: 'resources/files',
@@ -78,7 +92,21 @@ const V4_PACKAGE_SHIMS = [
78
92
  file: 'resources/models',
79
93
  targetClass: 'Models',
80
94
  baseResource: 'models',
81
- methods: ['del', 'list', 'retrieve']
95
+ methods: ['list', 'retrieve']
96
+ },
97
+ {
98
+ file: 'resources/models',
99
+ targetClass: 'Models',
100
+ baseResource: 'models',
101
+ methods: ['del'],
102
+ versions: ['>=4 <5']
103
+ },
104
+ {
105
+ file: 'resources/models',
106
+ targetClass: 'Models',
107
+ baseResource: 'models',
108
+ methods: ['delete'],
109
+ versions: ['>=5']
82
110
  },
83
111
  {
84
112
  file: 'resources/moderations',
@@ -516,7 +516,10 @@ function runnerHook (runnerExport, playwrightVersion) {
516
516
  testSessionStartCh.publish({ command, frameworkVersion: playwrightVersion, rootDir })
517
517
 
518
518
  try {
519
- const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh)
519
+ const { err, libraryConfig } = await getChannelPromise(
520
+ libraryConfigurationCh,
521
+ { frameworkVersion: playwrightVersion }
522
+ )
520
523
  if (!err) {
521
524
  isKnownTestsEnabled = libraryConfig.isKnownTestsEnabled
522
525
  isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
@@ -0,0 +1,116 @@
1
+ 'use strict'
2
+
3
+ const {
4
+ channel,
5
+ addHook
6
+ } = require('./helpers/instrument')
7
+
8
+ const prismaEngineStart = channel('apm:prisma:engine:start')
9
+ const tracingChannel = require('dc-polyfill').tracingChannel
10
+ const clientCH = tracingChannel('apm:prisma:client')
11
+
12
+ const allowedClientSpanOperations = new Set([
13
+ 'operation',
14
+ 'serialize',
15
+ 'transaction'
16
+ ])
17
+
18
+ class TracingHelper {
19
+ dbConfig = null
20
+ isEnabled () {
21
+ return true
22
+ }
23
+
24
+ // needs a sampled tracecontext to generate engine spans
25
+ getTraceParent (context) {
26
+ return '00-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-01' // valid sampled traceparent
27
+ }
28
+
29
+ dispatchEngineSpans (spans) {
30
+ for (const span of spans) {
31
+ if (span.parentId === null) {
32
+ prismaEngineStart.publish({ engineSpan: span, allEngineSpans: spans, dbConfig: this.dbConfig })
33
+ }
34
+ }
35
+ }
36
+
37
+ getActiveContext () {}
38
+
39
+ runInChildSpan (options, callback) {
40
+ if (typeof options === 'string') {
41
+ options = {
42
+ name: options
43
+ }
44
+ }
45
+
46
+ if (allowedClientSpanOperations.has(options.name)) {
47
+ const ctx = {
48
+ resourceName: options.name,
49
+ attributes: options.attributes || {}
50
+ }
51
+
52
+ if (options.name !== 'serialize') {
53
+ return clientCH.tracePromise(callback, ctx, this, ...arguments)
54
+ }
55
+
56
+ return clientCH.traceSync(callback, ctx, this, ...arguments)
57
+ }
58
+ return callback()
59
+ }
60
+
61
+ setDbString (dbConfig) {
62
+ this.dbConfig = dbConfig
63
+ }
64
+ }
65
+
66
+ addHook({ name: '@prisma/client', versions: ['>=6.1.0'] }, (prisma, version) => {
67
+ const tracingHelper = new TracingHelper()
68
+
69
+ /*
70
+ * This is a custom PrismaClient that extends the original PrismaClient
71
+ * This allows us to grab additional information from the PrismaClient such as DB connection strings
72
+ */
73
+ class PrismaClient extends prisma.PrismaClient {
74
+ constructor (...args) {
75
+ super(...args)
76
+
77
+ const datasources = this._engine?.config.inlineDatasources?.db.url?.value
78
+ if (datasources) {
79
+ const result = parseDBString(datasources)
80
+ tracingHelper.setDbString(result)
81
+ }
82
+ }
83
+ }
84
+
85
+ prisma.PrismaClient = PrismaClient
86
+ /*
87
+ * This is taking advantage of the built in tracing support from Prisma.
88
+ * The below variable is setting a global tracing helper that Prisma uses
89
+ * to enable OpenTelemetry.
90
+ */
91
+ // https://github.com/prisma/prisma/blob/478293bbfce91e41ceff02f2a0b03bb8acbca03e/packages/instrumentation/src/PrismaInstrumentation.ts#L42
92
+ const versions = version.split('.')
93
+ if (versions[0] === '6' && versions[1] < 4) {
94
+ global.PRISMA_INSTRUMENTATION = {
95
+ helper: tracingHelper
96
+ }
97
+ } else {
98
+ global[`V${versions[0]}_PRISMA_INSTRUMENTATION`] = {
99
+ helper: tracingHelper
100
+ }
101
+ }
102
+
103
+ return prisma
104
+ })
105
+
106
+ function parseDBString (dbString) {
107
+ const url = new URL(dbString)
108
+ const dbConfig = {
109
+ user: url.username,
110
+ password: url.password,
111
+ host: url.hostname,
112
+ port: url.port,
113
+ database: url.pathname.slice(1) // Remove leading slash
114
+ }
115
+ return dbConfig
116
+ }
@@ -2,8 +2,7 @@
2
2
 
3
3
  const {
4
4
  channel,
5
- addHook,
6
- AsyncResource
5
+ addHook
7
6
  } = require('./helpers/instrument')
8
7
  const shimmer = require('../../datadog-shimmer')
9
8
 
@@ -22,15 +21,11 @@ function wrapAddCommand (addCommand) {
22
21
  const name = command[0]
23
22
  const args = command.slice(1)
24
23
 
25
- const asyncResource = new AsyncResource('bound-anonymous-fn')
26
- return asyncResource.runInAsyncScope(() => {
27
- start(this, name, args, this._url)
28
-
24
+ const ctx = getStartCtx(this, name, args, this._url)
25
+ return startCh.runStores(ctx, () => {
29
26
  const res = addCommand.apply(this, arguments)
30
- const onResolve = asyncResource.bind(() => finish(finishCh, errorCh))
31
- const onReject = asyncResource.bind(err => finish(finishCh, errorCh, err))
32
27
 
33
- res.then(onResolve, onReject)
28
+ res.then(() => finish(finishCh, errorCh, ctx), err => finish(finishCh, errorCh, ctx, err))
34
29
 
35
30
  return res
36
31
  })
@@ -39,8 +34,8 @@ function wrapAddCommand (addCommand) {
39
34
 
40
35
  function wrapCommandQueueClass (cls) {
41
36
  const ret = class RedisCommandQueue extends cls {
42
- constructor () {
43
- super(arguments)
37
+ constructor (...args) {
38
+ super(...args)
44
39
  if (createClientUrl) {
45
40
  try {
46
41
  const parsed = new URL(createClientUrl)
@@ -94,14 +89,9 @@ addHook({ name: 'redis', versions: ['>=2.6 <4'] }, redis => {
94
89
 
95
90
  if (!options.callback) return internalSendCommand.apply(this, arguments)
96
91
 
97
- const callbackResource = new AsyncResource('bound-anonymous-fn')
98
- const asyncResource = new AsyncResource('bound-anonymous-fn')
99
- const cb = callbackResource.bind(options.callback)
100
-
101
- return asyncResource.runInAsyncScope(() => {
102
- start(this, options.command, options.args)
103
-
104
- options.callback = asyncResource.bind(wrapCallback(finishCh, errorCh, cb))
92
+ const ctx = getStartCtx(this, options.command, options.args)
93
+ return startCh.runStores(ctx, () => {
94
+ options.callback = wrapCallback(finishCh, errorCh, ctx, options.callback)
105
95
 
106
96
  try {
107
97
  return internalSendCommand.apply(this, arguments)
@@ -121,26 +111,21 @@ addHook({ name: 'redis', versions: ['>=0.12 <2.6'] }, redis => {
121
111
  return sendCommand.apply(this, arguments)
122
112
  }
123
113
 
124
- const callbackResource = new AsyncResource('bound-anonymous-fn')
125
- const asyncResource = new AsyncResource('bound-anonymous-fn')
126
-
127
- return asyncResource.runInAsyncScope(() => {
128
- start(this, command, args)
129
-
114
+ const ctx = getStartCtx(this, command, args)
115
+ return startCh.runStores(ctx, () => {
130
116
  if (typeof callback === 'function') {
131
- const cb = callbackResource.bind(callback)
132
- arguments[2] = asyncResource.bind(wrapCallback(finishCh, errorCh, cb))
117
+ arguments[2] = wrapCallback(finishCh, errorCh, ctx, callback)
133
118
  } else if (Array.isArray(args) && typeof args.at(-1) === 'function') {
134
- const cb = callbackResource.bind(args.at(-1))
135
- args[args.length - 1] = asyncResource.bind(wrapCallback(finishCh, errorCh, cb))
119
+ args[args.length - 1] = wrapCallback(finishCh, errorCh, ctx, args.at(-1))
136
120
  } else {
137
- arguments[2] = asyncResource.bind(wrapCallback(finishCh, errorCh))
121
+ arguments[2] = wrapCallback(finishCh, errorCh, ctx)
138
122
  }
139
123
 
140
124
  try {
141
125
  return sendCommand.apply(this, arguments)
142
126
  } catch (err) {
143
- errorCh.publish(err)
127
+ ctx.error = err
128
+ errorCh.publish(ctx)
144
129
 
145
130
  throw err
146
131
  }
@@ -149,24 +134,28 @@ addHook({ name: 'redis', versions: ['>=0.12 <2.6'] }, redis => {
149
134
  return redis
150
135
  })
151
136
 
152
- function start (client, command, args, url = {}) {
153
- const db = client.selected_db
154
- const connectionOptions = client.connection_options || client.connection_option || client.connectionOption || url
155
- startCh.publish({ db, command, args, connectionOptions })
137
+ function getStartCtx (client, command, args, url = {}) {
138
+ return {
139
+ db: client.selected_db,
140
+ command,
141
+ args,
142
+ connectionOptions: client.connection_options || client.connection_option || client.connectionOption || url
143
+ }
156
144
  }
157
145
 
158
- function wrapCallback (finishCh, errorCh, callback) {
146
+ function wrapCallback (finishCh, errorCh, ctx, callback) {
159
147
  return shimmer.wrapFunction(callback, callback => function (err) {
160
- finish(finishCh, errorCh, err)
161
- if (callback) {
162
- return callback.apply(this, arguments)
163
- }
148
+ return finish(finishCh, errorCh, ctx, err, callback, this, arguments)
164
149
  })
165
150
  }
166
151
 
167
- function finish (finishCh, errorCh, error) {
152
+ function finish (finishCh, errorCh, ctx, error, callback, thisArg, args) {
168
153
  if (error) {
169
- errorCh.publish(error)
154
+ ctx.error = error
155
+ errorCh.publish(ctx)
156
+ }
157
+ if (callback) {
158
+ return finishCh.runStores(ctx, callback, thisArg, ...args)
170
159
  }
171
- finishCh.publish()
160
+ finishCh.publish(ctx)
172
161
  }
@@ -106,7 +106,7 @@ function createWrapRouterMethod (name) {
106
106
  }
107
107
 
108
108
  function extractMatchers (fn) {
109
- const arg = Array.isArray(fn) ? fn : [fn]
109
+ const arg = Array.isArray(fn) ? fn.flat(Infinity) : [fn]
110
110
 
111
111
  if (typeof arg[0] === 'function') {
112
112
  return []
@@ -2,8 +2,7 @@
2
2
 
3
3
  const {
4
4
  channel,
5
- addHook,
6
- AsyncResource
5
+ addHook
7
6
  } = require('./helpers/instrument')
8
7
  const shimmer = require('../../datadog-shimmer')
9
8
 
@@ -37,30 +36,25 @@ addHook({ name: 'sharedb', versions: ['>=1'], file: 'lib/agent.js' }, Agent => {
37
36
  const errorCh = channel('apm:sharedb:request:error')
38
37
 
39
38
  shimmer.wrap(Agent.prototype, '_handleMessage', origHandleMessageFn => function (request, callback) {
40
- const callbackResource = new AsyncResource('bound-anonymous-fn')
41
- const asyncResource = new AsyncResource('bound-anonymous-fn')
42
-
43
39
  const action = request.a
44
40
  const actionName = getReadableActionName(action)
45
41
 
46
- return asyncResource.runInAsyncScope(() => {
47
- startCh.publish({ actionName, request })
48
-
49
- callback = callbackResource.bind(callback)
50
-
51
- arguments[1] = shimmer.wrapFunction(callback, callback => asyncResource.bind(function (error, res) {
42
+ const ctx = { actionName, request }
43
+ return startCh.runStores(ctx, () => {
44
+ arguments[1] = shimmer.wrapFunction(callback, callback => function (error, res) {
52
45
  if (error) {
46
+ ctx.error = error
53
47
  errorCh.publish(error)
54
48
  }
55
- finishCh.publish({ request, res })
56
-
57
- return callback.apply(this, arguments)
58
- }))
49
+ ctx.res = res
50
+ return finishCh.runStores(ctx, callback, this, ...arguments)
51
+ })
59
52
 
60
53
  try {
61
54
  return origHandleMessageFn.apply(this, arguments)
62
55
  } catch (error) {
63
- errorCh.publish(error)
56
+ ctx.error = error
57
+ errorCh.publish(ctx)
64
58
 
65
59
  throw error
66
60
  }
@@ -113,9 +113,9 @@ function isBaseSequencer (vitestPackage) {
113
113
  return vitestPackage.b?.name === 'BaseSequencer'
114
114
  }
115
115
 
116
- function getChannelPromise (channelToPublishTo) {
116
+ function getChannelPromise (channelToPublishTo, frameworkVersion) {
117
117
  return new Promise(resolve => {
118
- channelToPublishTo.publish({ onDone: resolve })
118
+ channelToPublishTo.publish({ onDone: resolve, frameworkVersion })
119
119
  })
120
120
  }
121
121
 
@@ -173,7 +173,7 @@ function getTestName (task) {
173
173
  return testName
174
174
  }
175
175
 
176
- function getSortWrapper (sort) {
176
+ function getSortWrapper (sort, frameworkVersion) {
177
177
  return async function () {
178
178
  if (!testSessionFinishCh.hasSubscribers) {
179
179
  return sort.apply(this, arguments)
@@ -193,7 +193,7 @@ function getSortWrapper (sort) {
193
193
  let isDiEnabled = false
194
194
 
195
195
  try {
196
- const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh)
196
+ const { err, libraryConfig } = await getChannelPromise(libraryConfigurationCh, frameworkVersion)
197
197
  if (!err) {
198
198
  isFlakyTestRetriesEnabled = libraryConfig.isFlakyTestRetriesEnabled
199
199
  flakyTestRetriesCount = libraryConfig.flakyTestRetriesCount
@@ -56,7 +56,12 @@ class BaseAwsSdkPlugin extends ClientPlugin {
56
56
  }
57
57
  if (this.requestTags) this.requestTags.set(request, tags)
58
58
 
59
- const span = this.tracer.startSpan(this.operationFromRequest(request), { childOf, tags })
59
+ const span = this.tracer.startSpan(this.operationFromRequest(request),
60
+ {
61
+ childOf,
62
+ tags,
63
+ integrationName: 'aws-sdk'
64
+ })
60
65
 
61
66
  analyticsSampler.sample(span, this.config.measured)
62
67
 
@@ -119,8 +119,10 @@ class DynamoDb extends BaseAwsSdkPlugin {
119
119
 
120
120
  const configStr = this._tracerConfig?.trace?.dynamoDb?.tablePrimaryKeys
121
121
  if (!configStr) {
122
- log.warn('Missing DD_TRACE_DYNAMODB_TABLE_PRIMARY_KEYS env variable. ' +
123
- 'Please add your table\'s primary keys under this env variable.')
122
+ log.warn(
123
+ // eslint-disable-next-line @stylistic/max-len
124
+ 'Missing DD_TRACE_DYNAMODB_TABLE_PRIMARY_KEYS env variable. Please add your table\'s primary keys under this env variable.'
125
+ )
124
126
  return
125
127
  }
126
128
 
@@ -131,8 +133,11 @@ class DynamoDb extends BaseAwsSdkPlugin {
131
133
  if (Array.isArray(primaryKeys) && primaryKeys.length > 0 && primaryKeys.length <= 2) {
132
134
  config[tableName] = primaryKeys
133
135
  } else {
134
- log.warn(`Invalid primary key configuration for table: ${tableName}.` +
135
- 'Please fix the DD_TRACE_DYNAMODB_TABLE_PRIMARY_KEYS env var.')
136
+ log.warn(
137
+ // eslint-disable-next-line @stylistic/max-len
138
+ 'Invalid primary key configuration for table: %s. Please fix the DD_TRACE_DYNAMODB_TABLE_PRIMARY_KEYS env var.',
139
+ tableName
140
+ )
136
141
  }
137
142
  }
138
143
 
@@ -38,7 +38,8 @@ class Kinesis extends BaseAwsSdkPlugin {
38
38
  tags: {
39
39
  ...this.requestTags.get(request),
40
40
  'span.kind': 'server'
41
- }
41
+ },
42
+ integrationName: 'aws-sdk'
42
43
  }
43
44
  span = plugin.tracer.startSpan('aws.response', options)
44
45
  this.enter(span, store)
@@ -201,7 +202,7 @@ class Kinesis extends BaseAwsSdkPlugin {
201
202
 
202
203
  setDSMCheckpoint (span, parsedData, stream) {
203
204
  // get payload size of request data
204
- const payloadSize = Buffer.from(JSON.stringify(parsedData)).byteLength
205
+ const payloadSize = Buffer.byteLength(JSON.stringify(parsedData))
205
206
  const dataStreamsContext = this.tracer
206
207
  .setCheckpoint(['direction:out', `topic:${stream}`, 'type:kinesis'], span, payloadSize)
207
208
  return dataStreamsContext
@@ -30,7 +30,8 @@ class Sqs extends BaseAwsSdkPlugin {
30
30
  tags: {
31
31
  ...this.requestTags.get(request),
32
32
  'span.kind': 'server'
33
- }
33
+ },
34
+ integrationName: 'aws-sdk'
34
35
  }
35
36
  parsedMessageAttributes = contextExtraction.parsedAttributes
36
37
  span = this.tracer.startSpan('aws.response', options)