dd-trace 5.67.0 → 5.68.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 (104) hide show
  1. package/LICENSE-3rdparty.csv +0 -3
  2. package/README.md +0 -2
  3. package/ci/init.js +52 -54
  4. package/ext/exporters.d.ts +2 -1
  5. package/ext/exporters.js +2 -1
  6. package/index.d.ts +47 -2
  7. package/initialize.mjs +1 -1
  8. package/package.json +8 -11
  9. package/packages/datadog-esbuild/index.js +56 -0
  10. package/packages/datadog-instrumentations/src/aws-sdk.js +42 -4
  11. package/packages/datadog-instrumentations/src/azure-functions.js +1 -1
  12. package/packages/datadog-instrumentations/src/azure-service-bus.js +1 -1
  13. package/packages/datadog-instrumentations/src/cassandra-driver.js +2 -2
  14. package/packages/datadog-instrumentations/src/connect.js +6 -2
  15. package/packages/datadog-instrumentations/src/cucumber.js +31 -6
  16. package/packages/datadog-instrumentations/src/express.js +5 -6
  17. package/packages/datadog-instrumentations/src/fastify.js +3 -3
  18. package/packages/datadog-instrumentations/src/helpers/hook.js +28 -15
  19. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
  20. package/packages/datadog-instrumentations/src/helpers/instrument.js +11 -2
  21. package/packages/datadog-instrumentations/src/helpers/register.js +10 -3
  22. package/packages/datadog-instrumentations/src/http2/client.js +1 -0
  23. package/packages/datadog-instrumentations/src/http2/server.js +0 -1
  24. package/packages/datadog-instrumentations/src/ioredis.js +12 -1
  25. package/packages/datadog-instrumentations/src/jest.js +48 -36
  26. package/packages/datadog-instrumentations/src/limitd-client.js +2 -1
  27. package/packages/datadog-instrumentations/src/mocha/main.js +15 -7
  28. package/packages/datadog-instrumentations/src/mocha/utils.js +3 -0
  29. package/packages/datadog-instrumentations/src/mongoose.js +2 -1
  30. package/packages/datadog-instrumentations/src/oracledb.js +19 -13
  31. package/packages/datadog-instrumentations/src/pg.js +9 -5
  32. package/packages/datadog-instrumentations/src/pino.js +18 -6
  33. package/packages/datadog-instrumentations/src/playwright.js +15 -1
  34. package/packages/datadog-instrumentations/src/sequelize.js +1 -1
  35. package/packages/datadog-instrumentations/src/vitest.js +155 -62
  36. package/packages/datadog-plugin-ai/src/tracing.js +3 -3
  37. package/packages/datadog-plugin-aws-sdk/src/base.js +23 -8
  38. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +2 -2
  39. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +101 -2
  40. package/packages/datadog-plugin-aws-sdk/src/util.js +1 -1
  41. package/packages/datadog-plugin-cucumber/src/index.js +4 -56
  42. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +6 -2
  43. package/packages/datadog-plugin-cypress/src/support.js +4 -0
  44. package/packages/datadog-plugin-express/src/code_origin.js +2 -2
  45. package/packages/datadog-plugin-fastify/src/code_origin.js +1 -2
  46. package/packages/datadog-plugin-jest/src/index.js +0 -21
  47. package/packages/datadog-plugin-mocha/src/index.js +3 -57
  48. package/packages/datadog-plugin-mongodb-core/src/index.js +20 -7
  49. package/packages/datadog-plugin-playwright/src/index.js +11 -5
  50. package/packages/datadog-plugin-vitest/src/index.js +5 -1
  51. package/packages/datadog-plugin-ws/src/close.js +1 -1
  52. package/packages/datadog-plugin-ws/src/producer.js +6 -1
  53. package/packages/datadog-plugin-ws/src/receiver.js +6 -1
  54. package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +1 -1
  55. package/packages/dd-trace/src/appsec/telemetry/waf.js +2 -2
  56. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -4
  57. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +11 -3
  58. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +10 -1
  59. package/packages/dd-trace/src/config.js +69 -304
  60. package/packages/dd-trace/src/config_defaults.js +186 -0
  61. package/packages/dd-trace/src/crashtracking/crashtracker.js +2 -1
  62. package/packages/dd-trace/src/datastreams/fnv.js +2 -2
  63. package/packages/dd-trace/src/datastreams/writer.js +3 -2
  64. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -1
  65. package/packages/dd-trace/src/dogstatsd.js +4 -3
  66. package/packages/dd-trace/src/encode/0.4.js +1 -5
  67. package/packages/dd-trace/src/exporter.js +1 -0
  68. package/packages/dd-trace/src/exporters/agent/index.js +3 -2
  69. package/packages/dd-trace/src/exporters/agent/writer.js +1 -1
  70. package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +3 -2
  71. package/packages/dd-trace/src/exporters/common/request.js +2 -1
  72. package/packages/dd-trace/src/exporters/span-stats/index.js +3 -2
  73. package/packages/dd-trace/src/llmobs/constants/tags.js +2 -0
  74. package/packages/dd-trace/src/llmobs/plugins/ai/index.js +4 -3
  75. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -1
  76. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +40 -13
  77. package/packages/dd-trace/src/llmobs/plugins/openai.js +7 -1
  78. package/packages/dd-trace/src/llmobs/tagger.js +8 -0
  79. package/packages/dd-trace/src/llmobs/telemetry.js +2 -1
  80. package/packages/dd-trace/src/log/index.js +28 -17
  81. package/packages/dd-trace/src/log/log.js +29 -5
  82. package/packages/dd-trace/src/log/writer.js +5 -5
  83. package/packages/dd-trace/src/noop/span.js +1 -0
  84. package/packages/dd-trace/src/opentelemetry/span.js +14 -3
  85. package/packages/dd-trace/src/opentracing/span.js +18 -4
  86. package/packages/dd-trace/src/plugin_manager.js +20 -2
  87. package/packages/dd-trace/src/plugins/ci_plugin.js +97 -3
  88. package/packages/dd-trace/src/plugins/index.js +2 -0
  89. package/packages/dd-trace/src/plugins/util/git-cache.js +129 -0
  90. package/packages/dd-trace/src/plugins/util/git.js +40 -26
  91. package/packages/dd-trace/src/plugins/util/test.js +37 -27
  92. package/packages/dd-trace/src/plugins/util/web.js +1 -1
  93. package/packages/dd-trace/src/profiler.js +4 -1
  94. package/packages/dd-trace/src/profiling/config.js +73 -42
  95. package/packages/dd-trace/src/profiling/profiler.js +3 -1
  96. package/packages/dd-trace/src/profiling/profilers/events.js +3 -8
  97. package/packages/dd-trace/src/profiling/profilers/space.js +1 -0
  98. package/packages/dd-trace/src/profiling/profilers/wall.js +196 -117
  99. package/packages/dd-trace/src/remote_config/capabilities.js +5 -0
  100. package/packages/dd-trace/src/remote_config/manager.js +3 -2
  101. package/packages/dd-trace/src/startup-log.js +2 -1
  102. package/packages/dd-trace/src/supported-configurations.json +3 -0
  103. package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
  104. package/register.js +1 -1
@@ -16,7 +16,6 @@ require,import-in-the-middle,Apache license 2.0,Copyright 2021 Datadog Inc.
16
16
  require,istanbul-lib-coverage,BSD-3-Clause,Copyright 2012-2015 Yahoo! Inc.
17
17
  require,jest-docblock,MIT,Copyright Meta Platforms, Inc. and affiliates.
18
18
  require,jsonpath-plus,MIT,Copyright (c) 2011-2019 Stefan Goessner, Subbu Allamaraju, Mike Brevoort, Robert Krahn, Brett Zamir, Richard Schneider
19
- require,koalas,MIT,Copyright 2013-2017 Brian Woodward
20
19
  require,limiter,MIT,Copyright 2011 John Hurliman
21
20
  require,lodash.sortby,MIT,Copyright JS Foundation and other contributors
22
21
  require,lru-cache,ISC,Copyright (c) 2010-2022 Isaac Z. Schlueter and Contributors
@@ -51,7 +50,6 @@ dev,eslint-plugin-n,MIT,Copyright 2015 Toru Nagashima
51
50
  dev,eslint-plugin-promise,ISC,jden and other contributors
52
51
  dev,eslint-plugin-unicorn,MIT,Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
53
52
  dev,express,MIT,Copyright 2009-2014 TJ Holowaychuk 2013-2014 Roman Shtylman 2014-2015 Douglas Christopher Wilson
54
- dev,get-port,MIT,Copyright Sindre Sorhus
55
53
  dev,glob,ISC,Copyright Isaac Z. Schlueter and Contributors
56
54
  dev,globals,MIT,Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
57
55
  dev,graphql,MIT,Copyright 2015 Facebook Inc.
@@ -62,7 +60,6 @@ dev,nock,MIT,Copyright 2017 Pedro Teixeira and other contributors
62
60
  dev,nyc,ISC,Copyright 2015 Contributors
63
61
  dev,octokit,MIT,Copyright 2023 Octokit contributors
64
62
  dev,proxyquire,MIT,Copyright 2013 Thorsten Lorenz
65
- dev,rimraf,ISC,Copyright Isaac Z. Schlueter and Contributors
66
63
  dev,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
67
64
  dev,sinon,BSD-3-Clause,Copyright 2010-2017 Christian Johansen
68
65
  dev,sinon-chai,WTFPL and BSD-2-Clause,Copyright 2004 Sam Hocevar 2012–2017 Domenic Denicola
package/README.md CHANGED
@@ -97,5 +97,3 @@ Please refer to the [SECURITY.md](https://github.com/DataDog/dd-trace-js/blob/ma
97
97
  ## Datadog With OpenTelemetery
98
98
 
99
99
  Please refer to the [Node.js Custom Instrumentation using OpenTelemetry API](https://docs.datadoghq.com/tracing/trace_collection/custom_instrumentation/nodejs/otel/) document. It includes information on how to use the OpenTelemetry API with dd-trace-js.
100
-
101
- Note that our internal implementation of the OpenTelemetry API is currently set within the version range `>=1.0.0 <1.9.0`. This range will be updated at a regular cadence therefore, we recommend updating your tracer to the latest release to ensure up to date support.
package/ci/init.js CHANGED
@@ -6,80 +6,78 @@ const { isTrue, isFalse } = require('../packages/dd-trace/src/util')
6
6
  const log = require('../packages/dd-trace/src/log')
7
7
  const { getEnvironmentVariable } = require('../packages/dd-trace/src/config-helper')
8
8
 
9
- const isJestWorker = !!getEnvironmentVariable('JEST_WORKER_ID')
10
- const isCucumberWorker = !!getEnvironmentVariable('CUCUMBER_WORKER_ID')
11
- const isMochaWorker = !!getEnvironmentVariable('MOCHA_WORKER_ID')
12
-
13
- const isPlaywrightWorker = !!getEnvironmentVariable('DD_PLAYWRIGHT_WORKER')
9
+ const PACKAGE_MANAGERS = ['npm', 'yarn', 'pnpm']
10
+ const DEFAULT_FLUSH_INTERVAL = 5000
11
+ const JEST_FLUSH_INTERVAL = 0
12
+ const EXPORTER_MAP = {
13
+ jest: 'jest_worker',
14
+ cucumber: 'cucumber_worker',
15
+ mocha: 'mocha_worker',
16
+ playwright: 'playwright_worker',
17
+ vitest: 'vitest_worker'
18
+ }
14
19
 
15
- const packageManagers = [
16
- 'npm',
17
- 'yarn',
18
- 'pnpm'
19
- ]
20
+ function isPackageManager () {
21
+ return PACKAGE_MANAGERS.some(packageManager =>
22
+ process.argv[1]?.includes(`bin/${packageManager}`)
23
+ )
24
+ }
20
25
 
21
- const isPackageManager = () => {
22
- return packageManagers.some(packageManager => process.argv[1]?.includes(`bin/${packageManager}`))
26
+ function detectTestWorkerType () {
27
+ if (getEnvironmentVariable('JEST_WORKER_ID')) return 'jest'
28
+ if (getEnvironmentVariable('CUCUMBER_WORKER_ID')) return 'cucumber'
29
+ if (getEnvironmentVariable('MOCHA_WORKER_ID')) return 'mocha'
30
+ if (getEnvironmentVariable('DD_PLAYWRIGHT_WORKER')) return 'playwright'
31
+ if (getEnvironmentVariable('TINYPOOL_WORKER_ID')) return 'vitest'
32
+ return null
23
33
  }
24
34
 
25
- const options = {
35
+ const testWorkerType = detectTestWorkerType()
36
+ const isTestWorker = testWorkerType !== null
37
+ const isJestWorker = testWorkerType === 'jest'
38
+
39
+ const baseOptions = {
26
40
  startupLogs: false,
27
41
  isCiVisibility: true,
28
- flushInterval: isJestWorker ? 0 : 5000
42
+ flushInterval: isJestWorker ? JEST_FLUSH_INTERVAL : DEFAULT_FLUSH_INTERVAL
29
43
  }
30
44
 
31
45
  let shouldInit = !isFalse(getEnvironmentVariable('DD_CIVISIBILITY_ENABLED'))
46
+ const isAgentlessEnabled = isTrue(getEnvironmentVariable('DD_CIVISIBILITY_AGENTLESS_ENABLED'))
32
47
 
33
- if (isPackageManager()) {
48
+ if (!isTestWorker && isPackageManager()) {
34
49
  log.debug('dd-trace is not initialized in a package manager.')
35
50
  shouldInit = false
36
51
  }
37
52
 
38
- const isAgentlessEnabled = isTrue(getEnvironmentVariable('DD_CIVISIBILITY_AGENTLESS_ENABLED'))
39
-
40
- if (isAgentlessEnabled) {
41
- if (getEnvironmentVariable('DD_API_KEY')) {
42
- options.experimental = {
43
- exporter: 'datadog'
44
- }
45
- } else {
46
- console.error('DD_CIVISIBILITY_AGENTLESS_ENABLED is set, but neither ' +
47
- 'DD_API_KEY nor DATADOG_API_KEY are set in your environment, so ' +
48
- 'dd-trace will not be initialized.')
49
- shouldInit = false
53
+ if (isTestWorker) {
54
+ baseOptions.telemetry = { enabled: false }
55
+ baseOptions.experimental = {
56
+ exporter: EXPORTER_MAP[testWorkerType]
50
57
  }
51
58
  } else {
52
- options.experimental = {
53
- exporter: 'agent_proxy'
54
- }
55
- }
56
-
57
- if (isJestWorker) {
58
- options.experimental = {
59
- exporter: 'jest_worker'
60
- }
61
- }
62
-
63
- if (isCucumberWorker) {
64
- options.experimental = {
65
- exporter: 'cucumber_worker'
66
- }
67
- }
68
-
69
- if (isMochaWorker) {
70
- options.experimental = {
71
- exporter: 'mocha_worker'
72
- }
73
- }
74
-
75
- if (isPlaywrightWorker) {
76
- options.experimental = {
77
- exporter: 'playwright_worker'
59
+ if (isAgentlessEnabled) {
60
+ if (getEnvironmentVariable('DD_API_KEY')) {
61
+ baseOptions.experimental = {
62
+ exporter: 'datadog'
63
+ }
64
+ } else {
65
+ console.error(
66
+ 'DD_CIVISIBILITY_AGENTLESS_ENABLED is set, but neither ' +
67
+ 'DD_API_KEY nor DATADOG_API_KEY are set in your environment, so ' +
68
+ 'dd-trace will not be initialized.'
69
+ )
70
+ shouldInit = false
71
+ }
72
+ } else {
73
+ baseOptions.experimental = {
74
+ exporter: 'agent_proxy'
75
+ }
78
76
  }
79
77
  }
80
78
 
81
79
  if (shouldInit) {
82
- tracer.init(options)
80
+ tracer.init(baseOptions)
83
81
  tracer.use('fs', false)
84
82
  tracer.use('child_process', false)
85
83
  }
@@ -6,7 +6,8 @@ declare const exporters: {
6
6
  JEST_WORKER: 'jest_worker',
7
7
  CUCUMBER_WORKER: 'cucumber_worker',
8
8
  MOCHA_WORKER: 'mocha_worker',
9
- PLAYWRIGHT_WORKER: 'playwright_worker'
9
+ PLAYWRIGHT_WORKER: 'playwright_worker',
10
+ VITEST_WORKER: 'vitest_worker'
10
11
  }
11
12
 
12
13
  export = exporters
package/ext/exporters.js CHANGED
@@ -7,5 +7,6 @@ module.exports = {
7
7
  JEST_WORKER: 'jest_worker',
8
8
  CUCUMBER_WORKER: 'cucumber_worker',
9
9
  MOCHA_WORKER: 'mocha_worker',
10
- PLAYWRIGHT_WORKER: 'playwright_worker'
10
+ PLAYWRIGHT_WORKER: 'playwright_worker',
11
+ VITEST_WORKER: 'vitest_worker'
11
12
  }
package/index.d.ts CHANGED
@@ -253,7 +253,7 @@ declare namespace tracer {
253
253
  /**
254
254
  * An array of span links
255
255
  */
256
- links?: Array<{ context: SpanContext, attributes?: Object }>
256
+ links?: { context: SpanContext, attributes?: Object }[]
257
257
  }
258
258
 
259
259
  /**
@@ -268,11 +268,34 @@ declare namespace tracer {
268
268
 
269
269
  /**
270
270
  * Causally links another span to the current span
271
+ *
272
+ * @deprecated In favor of addLink(link: { context: SpanContext, attributes?: Object }).
273
+ * This will be removed in the next major version.
271
274
  * @param {SpanContext} context The context of the span to link to.
272
275
  * @param {Object} attributes An optional key value pair of arbitrary values.
273
276
  * @returns {void}
274
277
  */
275
278
  addLink (context: SpanContext, attributes?: Object): void;
279
+
280
+ /**
281
+ * Adds a single link to the span.
282
+ *
283
+ * Links added after the creation will not affect the sampling decision.
284
+ * It is preferred span links be added at span creation.
285
+ *
286
+ * @param link the link to add.
287
+ */
288
+ addLink (link: { context: SpanContext, attributes?: Object }): void;
289
+
290
+ /**
291
+ * Adds multiple links to the span.
292
+ *
293
+ * Links added after the creation will not affect the sampling decision.
294
+ * It is preferred span links be added at span creation.
295
+ *
296
+ * @param links the links to add.
297
+ */
298
+ addLinks (links: { context: SpanContext, attributes?: Object }[]): void;
276
299
  }
277
300
 
278
301
  /**
@@ -404,7 +427,7 @@ declare namespace tracer {
404
427
 
405
428
  /**
406
429
  * The address of the trace agent that the tracer will submit to.
407
- * @default 'localhost'
430
+ * @default '127.0.0.1'
408
431
  */
409
432
  hostname?: string;
410
433
 
@@ -2311,11 +2334,33 @@ declare namespace tracer {
2311
2334
 
2312
2335
  /**
2313
2336
  * Causally links another span to the current span
2337
+ *
2338
+ * @deprecated In favor of addLink(link: otel.Link). This will be removed in the next major version.
2314
2339
  * @param {otel.SpanContext} context The context of the span to link to.
2315
2340
  * @param {SpanAttributes} attributes An optional key value pair of arbitrary values.
2316
2341
  * @returns {void}
2317
2342
  */
2318
2343
  addLink(context: otel.SpanContext, attributes?: SpanAttributes): void;
2344
+
2345
+ /**
2346
+ * Adds a single link to the span.
2347
+ *
2348
+ * Links added after the creation will not affect the sampling decision.
2349
+ * It is preferred span links be added at span creation.
2350
+ *
2351
+ * @param link the link to add.
2352
+ */
2353
+ addLink(link: otel.Link): this;
2354
+
2355
+ /**
2356
+ * Adds multiple links to the span.
2357
+ *
2358
+ * Links added after the creation will not affect the sampling decision.
2359
+ * It is preferred span links be added at span creation.
2360
+ *
2361
+ * @param links the links to add.
2362
+ */
2363
+ addLinks(links: otel.Link[]): this;
2319
2364
  }
2320
2365
 
2321
2366
  /**
package/initialize.mjs CHANGED
@@ -36,7 +36,7 @@ ${result.source}`
36
36
  const [NODE_MAJOR, NODE_MINOR] = process.versions.node.split('.').map(Number)
37
37
 
38
38
  const brokenLoaders = NODE_MAJOR === 18 && NODE_MINOR === 0
39
- const iitmExclusions = [/langsmith/, /openai\/_shims/, /openai\/resources\/chat\/completions\/messages/]
39
+ const iitmExclusions = [/langsmith/, /openai\/_shims/, /openai\/resources\/chat\/completions\/messages/, /openai\/agents-core\/dist\/shims/]
40
40
 
41
41
  export async function load (url, context, nextLoad) {
42
42
  const iitmExclusionsMatch = iitmExclusions.some((exclusion) => exclusion.test(url))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "5.67.0",
3
+ "version": "5.68.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -121,8 +121,8 @@
121
121
  "@datadog/sketches-js": "2.1.1",
122
122
  "@datadog/wasm-js-rewriter": "4.0.1",
123
123
  "@isaacs/ttlcache": "^1.4.1",
124
- "@opentelemetry/api": "1.8.0",
125
- "@opentelemetry/core": "^1.14.0",
124
+ "@opentelemetry/api": ">=1.0.0 <1.10.0",
125
+ "@opentelemetry/core": ">=1.14.0 <1.31.0",
126
126
  "crypto-randomuuid": "^1.0.0",
127
127
  "dc-polyfill": "^0.1.10",
128
128
  "ignore": "^7.0.5",
@@ -130,7 +130,6 @@
130
130
  "istanbul-lib-coverage": "^3.2.2",
131
131
  "jest-docblock": "^29.7.0",
132
132
  "jsonpath-plus": "^10.3.0",
133
- "koalas": "^1.0.2",
134
133
  "limiter": "^1.1.5",
135
134
  "lodash.sortby": "^4.7.0",
136
135
  "lru-cache": "^10.4.3",
@@ -155,20 +154,19 @@
155
154
  "@msgpack/msgpack": "^3.1.2",
156
155
  "@stylistic/eslint-plugin": "^5.0.0",
157
156
  "@types/node": "^18.19.106",
158
- "axios": "^1.11.0",
157
+ "axios": "^1.12.2",
159
158
  "benchmark": "^2.1.4",
160
159
  "body-parser": "^2.2.0",
161
160
  "chai": "^4.5.0",
162
161
  "eslint": "^9.29.0",
163
162
  "eslint-plugin-cypress": "^5.1.0",
164
163
  "eslint-plugin-import": "^2.32.0",
165
- "eslint-plugin-mocha": "^10.5.0",
164
+ "eslint-plugin-mocha": "^11.1.0",
166
165
  "eslint-plugin-n": "^17.20.0",
167
166
  "eslint-plugin-promise": "^7.2.1",
168
- "eslint-plugin-unicorn": "^60.0.0",
167
+ "eslint-plugin-unicorn": "^61.0.2",
169
168
  "express": "^5.1.0",
170
- "get-port": "^5.1.1",
171
- "glob": "^7.2.3",
169
+ "glob": "^10.4.5",
172
170
  "globals": "^16.3.0",
173
171
  "graphql": "*",
174
172
  "jszip": "^3.10.1",
@@ -178,9 +176,8 @@
178
176
  "nyc": "^15.1.0",
179
177
  "octokit": "^5.0.3",
180
178
  "proxyquire": "^2.1.3",
181
- "rimraf": "^3.0.2",
182
179
  "semver": "^7.7.2",
183
- "sinon": "^18.0.1",
180
+ "sinon": "^21.0.0",
184
181
  "sinon-chai": "^3.7.0",
185
182
  "tap": "^16.3.10",
186
183
  "tiktoken": "^1.0.21",
@@ -33,6 +33,7 @@ const RAW_BUILTINS = require('module').builtinModules
33
33
  const CHANNEL = 'dd-trace:bundler:load'
34
34
  const path = require('path')
35
35
  const fs = require('fs')
36
+ const { execSync } = require('child_process')
36
37
 
37
38
  const builtins = new Set()
38
39
 
@@ -61,6 +62,39 @@ function isESMBuild (build) {
61
62
  return format === 'esm' || outputFile?.endsWith('.mjs') || outExtension === '.mjs'
62
63
  }
63
64
 
65
+ function getGitMetadata () {
66
+ const gitMetadata = {
67
+ repositoryURL: null,
68
+ commitSHA: null
69
+ }
70
+
71
+ try {
72
+ gitMetadata.repositoryURL = execSync('git config --get remote.origin.url', {
73
+ encoding: 'utf8',
74
+ stdio: ['pipe', 'pipe', 'ignore'],
75
+ cwd: process.cwd()
76
+ }).trim()
77
+ } catch (e) {
78
+ if (DEBUG) {
79
+ console.warn('Warning: failed to get git repository URL:', e.message)
80
+ }
81
+ }
82
+
83
+ try {
84
+ gitMetadata.commitSHA = execSync('git rev-parse HEAD', {
85
+ encoding: 'utf8',
86
+ stdio: ['pipe', 'pipe', 'ignore'],
87
+ cwd: process.cwd()
88
+ }).trim()
89
+ } catch (e) {
90
+ if (DEBUG) {
91
+ console.warn('Warning: failed to get git commit SHA:', e.message)
92
+ }
93
+ }
94
+
95
+ return gitMetadata
96
+ }
97
+
64
98
  module.exports.setup = function (build) {
65
99
  const externalModules = new Set(build.initialOptions.external || [])
66
100
  if (isESMBuild(build)) {
@@ -77,6 +111,28 @@ ${build.initialOptions.banner.js}`
77
111
  }
78
112
  }
79
113
 
114
+ // Get git metadata at build time and add it to the banner for both ESM and CommonJS builds
115
+ const gitMetadata = getGitMetadata()
116
+ if (gitMetadata.repositoryURL || gitMetadata.commitSHA) {
117
+ build.initialOptions.banner ??= {}
118
+ build.initialOptions.banner.js ??= ''
119
+
120
+ build.initialOptions.banner.js = `if (typeof process === 'object' && process !== null &&
121
+ process.env !== null && typeof process.env === 'object') {
122
+ ${gitMetadata.repositoryURL ? `process.env.DD_GIT_REPOSITORY_URL = '${gitMetadata.repositoryURL}';` : ''}
123
+ ${gitMetadata.commitSHA ? `process.env.DD_GIT_COMMIT_SHA = '${gitMetadata.commitSHA}';` : ''}
124
+ }
125
+ ${build.initialOptions.banner.js}`
126
+
127
+ if (DEBUG) {
128
+ console.log('Info: automatically injected git metadata:')
129
+ console.log(`DD_GIT_REPOSITORY_URL: ${gitMetadata.repositoryURL || 'not available'}`)
130
+ console.log(`DD_GIT_COMMIT_SHA: ${gitMetadata.commitSHA || 'not available'}`)
131
+ }
132
+ } else if (DEBUG) {
133
+ console.warn('Warning: No git metadata available - skipping injection')
134
+ }
135
+
80
136
  build.onResolve({ filter: /.*/ }, args => {
81
137
  if (externalModules.has(args.path)) {
82
138
  // Internal Node.js packages will still be instrumented via require()
@@ -61,7 +61,6 @@ function wrapSmithySend (send) {
61
61
 
62
62
  const startCh = channel(`apm:aws:request:start:${channelSuffix}`)
63
63
  const regionCh = channel(`apm:aws:request:region:${channelSuffix}`)
64
- const completeChannel = channel(`apm:aws:request:complete:${channelSuffix}`)
65
64
  const responseStartChannel = channel(`apm:aws:response:start:${channelSuffix}`)
66
65
  const responseFinishChannel = channel(`apm:aws:response:finish:${channelSuffix}`)
67
66
 
@@ -87,7 +86,7 @@ function wrapSmithySend (send) {
87
86
  args[args.length - 1] = shimmer.wrapFunction(cb, cb => function (err, result) {
88
87
  addResponse(ctx, err, result)
89
88
 
90
- completeChannel.publish(ctx)
89
+ handleCompletion(result, ctx, channelSuffix)
91
90
 
92
91
  const responseCtx = { request, response: ctx.response }
93
92
 
@@ -102,12 +101,12 @@ function wrapSmithySend (send) {
102
101
  .then(
103
102
  result => {
104
103
  addResponse(ctx, null, result)
105
- completeChannel.publish(ctx)
104
+ handleCompletion(result, ctx, channelSuffix)
106
105
  return result
107
106
  },
108
107
  error => {
109
108
  addResponse(ctx, error)
110
- completeChannel.publish(ctx)
109
+ handleCompletion(null, ctx, channelSuffix)
111
110
  throw error
112
111
  }
113
112
  )
@@ -118,6 +117,45 @@ function wrapSmithySend (send) {
118
117
  }
119
118
  }
120
119
 
120
+ function handleCompletion (result, ctx, channelSuffix) {
121
+ const completeChannel = channel(`apm:aws:request:complete:${channelSuffix}`)
122
+ const streamedChunkChannel = channel(`apm:aws:response:streamed-chunk:${channelSuffix}`)
123
+
124
+ const iterator = result?.body?.[Symbol.asyncIterator]
125
+ if (!iterator) {
126
+ completeChannel.publish(ctx)
127
+ return
128
+ }
129
+
130
+ shimmer.wrap(result.body, Symbol.asyncIterator, function (asyncIterator) {
131
+ return function () {
132
+ const iterator = asyncIterator.apply(this, arguments)
133
+ shimmer.wrap(iterator, 'next', function (next) {
134
+ return function () {
135
+ return next.apply(this, arguments)
136
+ .then(result => {
137
+ const { done, value: chunk } = result
138
+ streamedChunkChannel.publish({ ctx, chunk, done })
139
+
140
+ if (done) {
141
+ completeChannel.publish(ctx)
142
+ }
143
+
144
+ return result
145
+ })
146
+ .catch(err => {
147
+ addResponse(ctx, err)
148
+ completeChannel.publish(ctx)
149
+ throw err
150
+ })
151
+ }
152
+ })
153
+
154
+ return iterator
155
+ }
156
+ })
157
+ }
158
+
121
159
  function wrapCb (cb, serviceName, ctx) {
122
160
  // eslint-disable-next-line n/handle-callback-err
123
161
  return shimmer.wrapFunction(cb, cb => function wrappedCb (err, response) {
@@ -8,7 +8,7 @@ const dc = require('dc-polyfill')
8
8
 
9
9
  const azureFunctionsChannel = dc.tracingChannel('datadog:azure:functions:invoke')
10
10
 
11
- addHook({ name: '@azure/functions', versions: ['>=4'] }, azureFunction => {
11
+ addHook({ name: '@azure/functions', versions: ['>=4'], patchDefault: false }, (azureFunction) => {
12
12
  const { app } = azureFunction
13
13
 
14
14
  // Http triggers
@@ -11,7 +11,7 @@ const producerStartCh = channel('apm:azure-service-bus:send:start')
11
11
  const producerErrorCh = channel('apm:azure-service-bus:send:error')
12
12
  const producerFinishCh = channel('apm:azure-service-bus:send:finish')
13
13
 
14
- addHook({ name: '@azure/service-bus', versions: ['>=7.9.2'] }, (obj) => {
14
+ addHook({ name: '@azure/service-bus', versions: ['>=7.9.2'], patchDefault: false }, (obj) => {
15
15
  const ServiceBusClient = obj.ServiceBusClient
16
16
  shimmer.wrap(ServiceBusClient.prototype, 'createSender', createSender => function (queueOrTopicName) {
17
17
  const sender = createSender.apply(this, arguments)
@@ -45,7 +45,7 @@ addHook({ name: 'cassandra-driver', versions: ['>=3.0.0'] }, cassandra => {
45
45
  return cassandra
46
46
  })
47
47
 
48
- addHook({ name: 'cassandra-driver', versions: ['>=4.4'] }, cassandra => {
48
+ addHook({ name: 'cassandra-driver', versions: ['>=4.4'], patchDefault: false }, (cassandra) => {
49
49
  shimmer.wrap(cassandra.Client.prototype, '_execute', _execute => function (query, params, execOptions, callback) {
50
50
  if (!startCh.hasSubscribers) {
51
51
  return _execute.apply(this, arguments)
@@ -68,7 +68,7 @@ const isValid = (args) => {
68
68
  return args.length === 4 || typeof args[3] === 'function'
69
69
  }
70
70
 
71
- addHook({ name: 'cassandra-driver', versions: ['3 - 4.3'] }, cassandra => {
71
+ addHook({ name: 'cassandra-driver', versions: ['3 - 4.3'], patchDefault: false }, (cassandra) => {
72
72
  shimmer.wrap(cassandra.Client.prototype, '_innerExecute', _innerExecute =>
73
73
  function (query, params, execOptions, callback) {
74
74
  if (!startCh.hasSubscribers) {
@@ -102,11 +102,15 @@ function wrapNext (req, next) {
102
102
  })
103
103
  }
104
104
 
105
- addHook({ name: 'connect', versions: ['>=3'] }, connect => {
105
+ addHook({ name: 'connect', versions: ['>=3.4.0'] }, (connect) => {
106
106
  return shimmer.wrapFunction(connect, connect => wrapConnect(connect))
107
107
  })
108
108
 
109
- addHook({ name: 'connect', versions: ['2.2.2'] }, connect => {
109
+ addHook({ name: 'connect', versions: ['>=3 <3.4.0'], file: 'lib/connect.js' }, (connect) => {
110
+ return shimmer.wrapFunction(connect, connect => wrapConnect(connect))
111
+ })
112
+
113
+ addHook({ name: 'connect', versions: ['2.2.2'], file: 'lib/connect.js' }, connect => {
110
114
  shimmer.wrap(connect.proto, 'use', wrapUse)
111
115
  shimmer.wrap(connect.proto, 'handle', wrapHandle)
112
116
 
@@ -82,10 +82,14 @@ let testManagementAttemptToFixRetries = 0
82
82
  let testManagementTests = {}
83
83
  let modifiedTests = {}
84
84
  let numTestRetries = 0
85
- let knownTests = []
85
+ let knownTests = {}
86
86
  let skippedSuites = []
87
87
  let isSuitesSkipped = false
88
88
 
89
+ function isValidKnownTests (receivedKnownTests) {
90
+ return !!receivedKnownTests.cucumber
91
+ }
92
+
89
93
  function getSuiteStatusFromTestStatuses (testStatuses) {
90
94
  if (testStatuses.includes('fail')) {
91
95
  return 'fail'
@@ -123,7 +127,10 @@ function getStatusFromResultLatest (result) {
123
127
  }
124
128
 
125
129
  function isNewTest (testSuite, testName) {
126
- const testsForSuite = knownTests.cucumber?.[testSuite] || []
130
+ if (!isValidKnownTests(knownTests)) {
131
+ return false
132
+ }
133
+ const testsForSuite = knownTests.cucumber[testSuite] || []
127
134
  return !testsForSuite.includes(testName)
128
135
  }
129
136
 
@@ -508,9 +515,9 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
508
515
  pickleByFile = isCoordinator ? getPickleByFileNew(this) : getPickleByFile(this)
509
516
 
510
517
  if (isKnownTestsEnabled) {
511
- const isFaulty = getIsFaultyEarlyFlakeDetection(
518
+ const isFaulty = !isValidKnownTests(knownTests) || getIsFaultyEarlyFlakeDetection(
512
519
  Object.keys(pickleByFile),
513
- knownTests.cucumber || {},
520
+ knownTests.cucumber,
514
521
  earlyFlakeDetectionFaultyThreshold
515
522
  )
516
523
  if (isFaulty) {
@@ -592,6 +599,9 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
592
599
  // Handles EFD in both the main process and the worker process.
593
600
  function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = false, isWorker = false) {
594
601
  return async function () {
602
+ if (!testSuiteFinishCh.hasSubscribers) {
603
+ return runTestCaseFunction.apply(this, arguments)
604
+ }
595
605
  const pickle = isNewerCucumberVersion
596
606
  ? arguments[0].pickle
597
607
  : this.eventDataCollector.getPickle(arguments[0])
@@ -747,6 +757,9 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
747
757
 
748
758
  function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion) {
749
759
  return function (worker, message) {
760
+ if (!testSuiteFinishCh.hasSubscribers) {
761
+ return parseWorkerMessageFunction.apply(this, arguments)
762
+ }
750
763
  // If the message is an array, it's a dd-trace message, so we need to stop cucumber processing,
751
764
  // or cucumber will throw an error
752
765
  // TODO: identify the message better
@@ -972,10 +985,17 @@ addHook({
972
985
  )
973
986
  // EFD in parallel mode only supported in >=11.0.0
974
987
  shimmer.wrap(adapterPackage.ChildProcessAdapter.prototype, 'startWorker', startWorker => function () {
975
- if (isKnownTestsEnabled) {
988
+ if (isKnownTestsEnabled && isValidKnownTests(knownTests)) {
989
+ this.options.worldParameters._ddIsKnownTestsEnabled = true
976
990
  this.options.worldParameters._ddIsEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
977
991
  this.options.worldParameters._ddKnownTests = knownTests
978
992
  this.options.worldParameters._ddEarlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
993
+ } else {
994
+ isEarlyFlakeDetectionEnabled = false
995
+ isKnownTestsEnabled = false
996
+ this.options.worldParameters._ddIsEarlyFlakeDetectionEnabled = false
997
+ this.options.worldParameters._ddIsKnownTestsEnabled = false
998
+ this.options.worldParameters._ddEarlyFlakeDetectionNumRetries = 0
979
999
  }
980
1000
 
981
1001
  if (isImpactedTestsEnabled) {
@@ -1001,9 +1021,14 @@ addHook({
1001
1021
  'initialize',
1002
1022
  initialize => async function () {
1003
1023
  await initialize.apply(this, arguments)
1004
- isKnownTestsEnabled = !!this.options.worldParameters._ddKnownTests
1024
+ isKnownTestsEnabled = !!this.options.worldParameters._ddIsKnownTestsEnabled
1005
1025
  if (isKnownTestsEnabled) {
1006
1026
  knownTests = this.options.worldParameters._ddKnownTests
1027
+ // if for whatever reason the worker does not receive valid known tests, we disable EFD and known tests
1028
+ if (!isValidKnownTests(knownTests)) {
1029
+ isKnownTestsEnabled = false
1030
+ knownTests = {}
1031
+ }
1007
1032
  }
1008
1033
  isEarlyFlakeDetectionEnabled = !!this.options.worldParameters._ddIsEarlyFlakeDetectionEnabled
1009
1034
  if (isEarlyFlakeDetectionEnabled) {