dd-trace 5.80.0 → 5.81.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 (213) hide show
  1. package/LICENSE-3rdparty.csv +79 -88
  2. package/ext/tags.d.ts +1 -0
  3. package/ext/tags.js +1 -0
  4. package/index.d.ts +35 -35
  5. package/loader-hook.mjs +10 -3
  6. package/package.json +22 -40
  7. package/packages/datadog-esbuild/index.js +36 -19
  8. package/packages/datadog-instrumentations/index.js +1 -0
  9. package/packages/datadog-instrumentations/src/anthropic.js +12 -0
  10. package/packages/datadog-instrumentations/src/aws-sdk.js +5 -1
  11. package/packages/datadog-instrumentations/src/cucumber.js +2 -2
  12. package/packages/datadog-instrumentations/src/find-my-way.js +6 -5
  13. package/packages/datadog-instrumentations/src/google-genai.js +120 -0
  14. package/packages/datadog-instrumentations/src/graphql.js +20 -0
  15. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  16. package/packages/datadog-instrumentations/src/helpers/instrument.js +10 -0
  17. package/packages/datadog-instrumentations/src/helpers/register.js +6 -1
  18. package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +27 -0
  19. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +152 -0
  20. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +5 -0
  21. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langchain.js +237 -0
  22. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.js +9 -0
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +11 -0
  24. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +139 -0
  25. package/packages/datadog-instrumentations/src/langchain.js +3 -109
  26. package/packages/datadog-instrumentations/src/mocha/main.js +1 -1
  27. package/packages/datadog-instrumentations/src/mysql2.js +1 -1
  28. package/packages/datadog-instrumentations/src/playwright.js +45 -16
  29. package/packages/datadog-instrumentations/src/router.js +1 -1
  30. package/packages/datadog-instrumentations/src/selenium.js +3 -1
  31. package/packages/datadog-instrumentations/src/ws.js +35 -17
  32. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -1
  33. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +23 -2
  34. package/packages/datadog-plugin-cypress/src/plugin.js +1 -1
  35. package/packages/datadog-plugin-cypress/src/support.js +73 -31
  36. package/packages/datadog-plugin-google-genai/src/index.js +17 -0
  37. package/packages/datadog-plugin-google-genai/src/tracing.js +41 -0
  38. package/packages/datadog-plugin-graphql/src/tools/transforms.js +5 -4
  39. package/packages/datadog-plugin-jest/src/util.js +1 -1
  40. package/packages/datadog-plugin-langchain/src/tracing.js +7 -3
  41. package/packages/datadog-plugin-next/src/index.js +11 -3
  42. package/packages/dd-trace/src/aiguard/sdk.js +18 -10
  43. package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
  44. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
  45. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
  46. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -2
  47. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
  48. package/packages/dd-trace/src/appsec/reporter.js +0 -4
  49. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +4 -8
  50. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +4 -2
  51. package/packages/dd-trace/src/config.js +81 -7
  52. package/packages/dd-trace/src/config_defaults.js +14 -2
  53. package/packages/dd-trace/src/datastreams/encoding.js +23 -6
  54. package/packages/dd-trace/src/datastreams/pathway.js +40 -1
  55. package/packages/dd-trace/src/datastreams/processor.js +1 -1
  56. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -1
  57. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +15 -5
  58. package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
  59. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
  60. package/packages/dd-trace/src/debugger/devtools_client/index.js +30 -15
  61. package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +2 -0
  62. package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +24 -18
  63. package/packages/dd-trace/src/debugger/devtools_client/send.js +18 -8
  64. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +103 -15
  65. package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +25 -0
  66. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +56 -25
  67. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +64 -23
  68. package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +3 -1
  69. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +404 -0
  70. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
  71. package/packages/dd-trace/src/debugger/devtools_client/state.js +7 -2
  72. package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
  73. package/packages/dd-trace/src/debugger/index.js +1 -1
  74. package/packages/dd-trace/src/encode/span-stats.js +7 -1
  75. package/packages/dd-trace/src/histogram.js +1 -1
  76. package/packages/dd-trace/src/id.js +60 -0
  77. package/packages/dd-trace/src/lambda/runtime/ritm.js +1 -1
  78. package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
  79. package/packages/dd-trace/src/llmobs/plugins/genai/index.js +104 -0
  80. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +486 -0
  81. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +2 -2
  82. package/packages/dd-trace/src/llmobs/plugins/{openai.js → openai/index.js} +48 -6
  83. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +114 -0
  84. package/packages/dd-trace/src/llmobs/sdk.js +5 -0
  85. package/packages/dd-trace/src/llmobs/span_processor.js +6 -1
  86. package/packages/dd-trace/src/llmobs/tagger.js +4 -0
  87. package/packages/dd-trace/src/opentelemetry/logs/index.js +2 -2
  88. package/packages/dd-trace/src/opentelemetry/logs/logger.js +3 -2
  89. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +5 -3
  90. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +8 -8
  91. package/packages/dd-trace/src/opentelemetry/metrics/constants.js +34 -0
  92. package/packages/dd-trace/src/opentelemetry/metrics/index.js +81 -0
  93. package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +225 -0
  94. package/packages/dd-trace/src/opentelemetry/metrics/meter.js +171 -0
  95. package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +54 -0
  96. package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +62 -0
  97. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +251 -0
  98. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +532 -0
  99. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +10 -18
  100. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +36 -22
  101. package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +1 -1
  102. package/packages/dd-trace/src/opentelemetry/span.js +1 -1
  103. package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
  104. package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
  105. package/packages/dd-trace/src/payload-tagging/index.js +2 -2
  106. package/packages/dd-trace/src/plugin_manager.js +4 -2
  107. package/packages/dd-trace/src/plugins/index.js +1 -0
  108. package/packages/dd-trace/src/plugins/util/test.js +3 -3
  109. package/packages/dd-trace/src/plugins/util/url.js +119 -1
  110. package/packages/dd-trace/src/plugins/util/web.js +10 -41
  111. package/packages/dd-trace/src/process-tags/index.js +81 -0
  112. package/packages/dd-trace/src/profiling/config.js +1 -1
  113. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  114. package/packages/dd-trace/src/profiling/profilers/events.js +10 -1
  115. package/packages/dd-trace/src/proxy.js +5 -0
  116. package/packages/dd-trace/src/rate_limiter.js +1 -1
  117. package/packages/dd-trace/src/remote_config/manager.js +1 -1
  118. package/packages/dd-trace/src/ritm.js +1 -1
  119. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
  120. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
  121. package/packages/dd-trace/src/span_format.js +9 -4
  122. package/packages/dd-trace/src/span_processor.js +8 -3
  123. package/packages/dd-trace/src/span_stats.js +15 -4
  124. package/packages/dd-trace/src/spanleak.js +1 -1
  125. package/packages/dd-trace/src/supported-configurations.json +13 -0
  126. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  127. package/packages/dd-trace/src/telemetry/telemetry.js +11 -2
  128. package/vendor/dist/@datadog/sketches-js/LICENSE +39 -0
  129. package/vendor/dist/@datadog/sketches-js/index.js +1 -0
  130. package/vendor/dist/@datadog/source-map/LICENSE +28 -0
  131. package/vendor/dist/@datadog/source-map/index.js +1 -0
  132. package/vendor/dist/@isaacs/ttlcache/LICENSE +55 -0
  133. package/vendor/dist/@isaacs/ttlcache/index.js +1 -0
  134. package/vendor/dist/@opentelemetry/core/LICENSE +201 -0
  135. package/vendor/dist/@opentelemetry/core/index.js +1 -0
  136. package/vendor/dist/@opentelemetry/resources/LICENSE +201 -0
  137. package/vendor/dist/@opentelemetry/resources/index.js +1 -0
  138. package/vendor/dist/astring/LICENSE +19 -0
  139. package/vendor/dist/astring/index.js +1 -0
  140. package/vendor/dist/crypto-randomuuid/index.js +1 -0
  141. package/vendor/dist/escape-string-regexp/LICENSE +9 -0
  142. package/vendor/dist/escape-string-regexp/index.js +1 -0
  143. package/vendor/dist/esquery/LICENSE +24 -0
  144. package/vendor/dist/esquery/index.js +1 -0
  145. package/vendor/dist/ignore/LICENSE +21 -0
  146. package/vendor/dist/ignore/index.js +1 -0
  147. package/vendor/dist/istanbul-lib-coverage/LICENSE +24 -0
  148. package/vendor/dist/istanbul-lib-coverage/index.js +1 -0
  149. package/vendor/dist/jest-docblock/LICENSE +21 -0
  150. package/vendor/dist/jest-docblock/index.js +1 -0
  151. package/vendor/dist/jsonpath-plus/LICENSE +22 -0
  152. package/vendor/dist/jsonpath-plus/index.js +1 -0
  153. package/vendor/dist/limiter/LICENSE +19 -0
  154. package/vendor/dist/limiter/index.js +1 -0
  155. package/vendor/dist/lodash.sortby/LICENSE +47 -0
  156. package/vendor/dist/lodash.sortby/index.js +1 -0
  157. package/vendor/dist/lru-cache/LICENSE +15 -0
  158. package/vendor/dist/lru-cache/index.js +1 -0
  159. package/vendor/dist/meriyah/LICENSE +7 -0
  160. package/vendor/dist/meriyah/index.js +1 -0
  161. package/vendor/dist/module-details-from-path/LICENSE +21 -0
  162. package/vendor/dist/module-details-from-path/index.js +1 -0
  163. package/vendor/dist/mutexify/promise/LICENSE +21 -0
  164. package/vendor/dist/mutexify/promise/index.js +1 -0
  165. package/vendor/dist/opentracing/LICENSE +201 -0
  166. package/vendor/dist/opentracing/binary_carrier.d.ts +11 -0
  167. package/vendor/dist/opentracing/constants.d.ts +61 -0
  168. package/vendor/dist/opentracing/examples/demo/demo.d.ts +2 -0
  169. package/vendor/dist/opentracing/ext/tags.d.ts +90 -0
  170. package/vendor/dist/opentracing/functions.d.ts +20 -0
  171. package/vendor/dist/opentracing/global_tracer.d.ts +14 -0
  172. package/vendor/dist/opentracing/index.d.ts +12 -0
  173. package/vendor/dist/opentracing/index.js +1 -0
  174. package/vendor/dist/opentracing/mock_tracer/index.d.ts +5 -0
  175. package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +13 -0
  176. package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +16 -0
  177. package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +50 -0
  178. package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +26 -0
  179. package/vendor/dist/opentracing/noop.d.ts +8 -0
  180. package/vendor/dist/opentracing/reference.d.ts +33 -0
  181. package/vendor/dist/opentracing/span.d.ts +147 -0
  182. package/vendor/dist/opentracing/span_context.d.ts +26 -0
  183. package/vendor/dist/opentracing/test/api_compatibility.d.ts +16 -0
  184. package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +3 -0
  185. package/vendor/dist/opentracing/test/noop_implementation.d.ts +4 -0
  186. package/vendor/dist/opentracing/test/opentracing_api.d.ts +3 -0
  187. package/vendor/dist/opentracing/test/unittest.d.ts +2 -0
  188. package/vendor/dist/opentracing/tracer.d.ts +127 -0
  189. package/vendor/dist/path-to-regexp/LICENSE +21 -0
  190. package/vendor/dist/path-to-regexp/index.js +1 -0
  191. package/vendor/dist/pprof-format/LICENSE +8 -0
  192. package/vendor/dist/pprof-format/index.js +1 -0
  193. package/vendor/dist/protobufjs/LICENSE +39 -0
  194. package/vendor/dist/protobufjs/index.js +1 -0
  195. package/vendor/dist/protobufjs/minimal/LICENSE +39 -0
  196. package/vendor/dist/protobufjs/minimal/index.js +1 -0
  197. package/vendor/dist/retry/LICENSE +21 -0
  198. package/vendor/dist/retry/index.js +1 -0
  199. package/vendor/dist/rfdc/LICENSE +15 -0
  200. package/vendor/dist/rfdc/index.js +1 -0
  201. package/vendor/dist/semifies/LICENSE +201 -0
  202. package/vendor/dist/semifies/index.js +1 -0
  203. package/vendor/dist/shell-quote/LICENSE +24 -0
  204. package/vendor/dist/shell-quote/index.js +1 -0
  205. package/vendor/dist/source-map/LICENSE +28 -0
  206. package/vendor/dist/source-map/index.js +1 -0
  207. package/vendor/dist/source-map/lib/util/LICENSE +28 -0
  208. package/vendor/dist/source-map/lib/util/index.js +1 -0
  209. package/vendor/dist/source-map/mappings.wasm +0 -0
  210. package/vendor/dist/tlhunter-sorted-set/LICENSE +21 -0
  211. package/vendor/dist/tlhunter-sorted-set/index.js +1 -0
  212. package/vendor/dist/ttl-set/LICENSE +21 -0
  213. package/vendor/dist/ttl-set/index.js +1 -0
@@ -0,0 +1,11 @@
1
+ import { rewrite } from './index.js'
2
+
3
+ async function load (url, context, nextLoad) {
4
+ const result = await nextLoad(url, context)
5
+
6
+ result.source = rewrite(result.source, url, context.format)
7
+
8
+ return result
9
+ }
10
+
11
+ export { load }
@@ -0,0 +1,139 @@
1
+ 'use strict'
2
+
3
+ const { parse } = require('./compiler')
4
+
5
+ const tracingChannelPredicate = (node) => (
6
+ node.specifiers?.[0]?.local?.name === 'tr_ch_apm_tracingChannel' ||
7
+ node.declarations?.[0]?.id?.properties?.[0]?.value?.name === 'tr_ch_apm_tracingChannel'
8
+ )
9
+
10
+ const transforms = module.exports = {
11
+ tracingChannelImport ({ format }, node) {
12
+ if (node.body.some(tracingChannelPredicate)) return
13
+
14
+ const index = node.body.findIndex(child => child.directive === 'use strict')
15
+ const code = format === 'module'
16
+ ? 'import { tracingChannel as tr_ch_apm_tracingChannel } from "diagnostics_channel"'
17
+ : 'const {tracingChannel: tr_ch_apm_tracingChannel} = require("diagnostics_channel")'
18
+
19
+ node.body.splice(index + 1, 0, parse(code, { module: format === 'module' }).body[0])
20
+ },
21
+
22
+ tracingChannelDeclaration (state, node) {
23
+ const { channelName, module: { name } } = state
24
+ const channelVariable = 'tr_ch_apm$' + channelName.replaceAll(':', '_')
25
+
26
+ if (node.body.some(child => child.declarations?.[0]?.id?.name === channelVariable)) return
27
+
28
+ transforms.tracingChannelImport(state, node)
29
+
30
+ const index = node.body.findIndex(tracingChannelPredicate)
31
+ const code = `
32
+ const ${channelVariable} = tr_ch_apm_tracingChannel("orchestrion:${name}:${channelName}")
33
+ `
34
+
35
+ node.body.splice(index + 1, 0, parse(code).body[0])
36
+ },
37
+
38
+ traceCallback: traceAny,
39
+ tracePromise: traceAny,
40
+ traceSync: traceAny,
41
+ }
42
+
43
+ function traceAny (state, node, _parent, ancestry) {
44
+ const program = ancestry[ancestry.length - 1]
45
+
46
+ if (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') {
47
+ traceInstanceMethod(state, node, program)
48
+ } else {
49
+ traceFunction(state, node, program)
50
+ }
51
+ }
52
+
53
+ function traceFunction (state, node, program) {
54
+ const { operator } = state
55
+
56
+ transforms.tracingChannelDeclaration(state, program)
57
+
58
+ node.body = wrap(state, {
59
+ type: 'ArrowFunctionExpression',
60
+ params: node.params,
61
+ body: node.body,
62
+ async: operator === 'tracePromise',
63
+ expression: false,
64
+ generator: false
65
+ })
66
+ }
67
+
68
+ function traceInstanceMethod (state, node, program) {
69
+ const { functionQuery, operator } = state
70
+ const { methodName } = functionQuery
71
+
72
+ const classBody = node.body
73
+
74
+ // If the method exists on the class, we return as it will be patched later
75
+ // while traversing child nodes later on.
76
+ if (classBody.body.some(({ key }) => key.name === methodName)) return
77
+
78
+ // Method doesn't exist on the class so we assume an instance method and
79
+ // wrap it in the constructor instead.
80
+ let ctor = classBody.body.find(({ kind }) => kind === 'constructor')
81
+
82
+ transforms.tracingChannelDeclaration(state, program)
83
+
84
+ if (!ctor) {
85
+ ctor = parse(
86
+ node.superClass
87
+ ? 'class A { constructor (...args) { super(...args) } }'
88
+ : 'class A { constructor () {} }'
89
+ ).body[0].body.body[0] // Extract constructor from dummy class body.
90
+
91
+ classBody.body.unshift(ctor)
92
+ }
93
+
94
+ const ctorBody = parse(`
95
+ const __apm$${methodName} = this["${methodName}"]
96
+ this["${methodName}"] = function () {}
97
+ `).body
98
+
99
+ // Extract only right-hand side function of line 2.
100
+ const fn = ctorBody[1].expression.right
101
+
102
+ fn.async = operator === 'tracePromise'
103
+ fn.body = wrap(state, { type: 'Identifier', name: `__apm$${methodName}` })
104
+
105
+ ctor.value.body.body.push(...ctorBody)
106
+ }
107
+
108
+ function wrap (state, node) {
109
+ const { channelName, operator, functionQuery: { index = -1 } } = state
110
+ const async = operator === 'tracePromise' ? 'async' : ''
111
+ const channelVariable = 'tr_ch_apm$' + channelName.replaceAll(':', '_')
112
+ const tracedArgs = operator === 'traceCallback'
113
+ ? `__apm$original_args.splice(${index}, 1, arguments[${index >= 0 ? index : `arguments.length + ${index}`}])`
114
+ : '__apm$original_args'
115
+ const traceParams = operator === 'traceCallback'
116
+ ? `__apm$traced, ${index}`
117
+ : '__apm$traced'
118
+ const wrapper = parse(`
119
+ function wrapper () {
120
+ const __apm$original_args = arguments;
121
+ const __apm$traced = ${async} function () {
122
+ const __apm$wrapped = () => {};
123
+ const __apm$traced_args = ${tracedArgs};
124
+ return __apm$wrapped.apply(this, __apm$traced_args);
125
+ };
126
+ if (!${channelVariable}.hasSubscribers) return __apm$traced.apply(this, arguments);
127
+ return ${channelVariable}.${operator}(${traceParams}, {
128
+ arguments,
129
+ self: this,
130
+ moduleVersion: "1.0.0"
131
+ }, this, ...arguments);
132
+ }
133
+ `).body[0].body // Extract only block statement of function body.
134
+
135
+ // Replace the right-hand side assignment of `const __apm$wrapped = () => {}`.
136
+ wrapper.body[1].declarations[0].init.body.body[0].declarations[0].init = node
137
+
138
+ return wrapper
139
+ }
@@ -1,113 +1,7 @@
1
1
  'use strict'
2
- const { addHook } = require('./helpers/instrument')
3
2
 
4
- const shimmer = require('../../datadog-shimmer')
3
+ const { addHook, getHooks } = require('./helpers/instrument')
5
4
 
6
- const tracingChannel = require('dc-polyfill').tracingChannel
7
-
8
- function wrap (obj, name, channelName, namespace) {
9
- const channel = tracingChannel(channelName)
10
- shimmer.wrap(obj, name, function (original) {
11
- return function () {
12
- if (!channel.start.hasSubscribers) {
13
- return original.apply(this, arguments)
14
- }
15
- const ctx = { self: this, arguments }
16
- if (namespace) {
17
- ctx.namespace = namespace
18
- }
19
- return channel.tracePromise(original, ctx, this, ...arguments)
20
- }
21
- })
22
- }
23
-
24
- // langchain compiles into ESM and CommonJS, with ESM being the default and landing in the `.js` files
25
- // however, CommonJS ends up in `cjs` files, and are required under the hood with `.cjs` files
26
- // we patch each separately and explicitly to match against exports only once, and not rely on file regex matching
27
- const extensions = ['js', 'cjs']
28
-
29
- for (const extension of extensions) {
30
- addHook({ name: '@langchain/core', file: `dist/runnables/base.${extension}`, versions: ['>=0.1'] }, exports => {
31
- if (extension === 'cjs') {
32
- wrap(exports.RunnableSequence.prototype, 'invoke', 'orchestrion:@langchain/core:RunnableSequence_invoke')
33
- wrap(exports.RunnableSequence.prototype, 'batch', 'orchestrion:@langchain/core:RunnableSequence_batch')
34
- }
35
- return exports
36
- })
37
-
38
- addHook({
39
- name: '@langchain/core',
40
- file: `dist/language_models/chat_models.${extension}`,
41
- versions: ['>=0.1']
42
- }, exports => {
43
- if (extension === 'cjs') {
44
- wrap(exports.BaseChatModel.prototype, 'generate', 'orchestrion:@langchain/core:BaseChatModel_generate')
45
- }
46
- return exports
47
- })
48
-
49
- addHook({ name: '@langchain/core', file: `dist/language_models/llms.${extension}`, versions: ['>=0.1'] }, exports => {
50
- if (extension === 'cjs') {
51
- wrap(exports.BaseLLM.prototype, 'generate', 'orchestrion:@langchain/core:BaseLLM_generate')
52
- }
53
- return exports
54
- })
55
-
56
- addHook({ name: '@langchain/core', file: `dist/tools/index.${extension}`, versions: ['>=0.1'] }, exports => {
57
- if (extension === 'cjs') {
58
- wrap(exports.StructuredTool.prototype, 'invoke', 'orchestrion:@langchain/core:Tool_invoke')
59
- }
60
- return exports
61
- })
62
-
63
- addHook({ name: '@langchain/core', file: `dist/vectorstores.${extension}`, versions: ['>=0.1'] }, exports => {
64
- if (extension === 'cjs') {
65
- wrap(
66
- exports.VectorStore.prototype, 'similaritySearch', 'orchestrion:@langchain/core:VectorStore_similaritySearch'
67
- )
68
- wrap(
69
- exports.VectorStore.prototype, 'similaritySearchWithScore',
70
- 'orchestrion:@langchain/core:VectorStore_similaritySearchWithScore'
71
- )
72
- }
73
-
74
- return exports
75
- })
76
-
77
- addHook({ name: '@langchain/core', file: `dist/embeddings.${extension}`, versions: ['>=0.1'] }, exports => {
78
- if (extension === 'cjs') {
79
- shimmer.wrap(exports, 'Embeddings', Embeddings => {
80
- return class extends Embeddings {
81
- constructor (...args) {
82
- super(...args)
83
-
84
- const namespace = ['langchain', 'embeddings']
85
-
86
- if (this.constructor.name === 'OpenAIEmbeddings') {
87
- namespace.push('openai')
88
- }
89
-
90
- wrap(this, 'embedQuery', 'apm:@langchain/core:Embeddings_embedQuery', namespace)
91
- wrap(this, 'embedDocuments', 'apm:@langchain/core:Embeddings_embedDocuments', namespace)
92
- }
93
- }
94
- })
95
- } else {
96
- const channel = tracingChannel('orchestrion:@langchain/core:Embeddings_constructor')
97
- channel.subscribe({
98
- end (ctx) {
99
- const { self } = ctx
100
- const namespace = ['langchain', 'embeddings']
101
-
102
- if (self.constructor.name === 'OpenAIEmbeddings') {
103
- namespace.push('openai')
104
- }
105
-
106
- wrap(self, 'embedQuery', 'apm:@langchain/core:Embeddings_embedQuery', namespace)
107
- wrap(self, 'embedDocuments', 'apm:@langchain/core:Embeddings_embedDocuments', namespace)
108
- }
109
- })
110
- }
111
- return exports
112
- })
5
+ for (const hook of getHooks('@langchain/core')) {
6
+ addHook(hook, exports => exports)
113
7
  }
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { createCoverageMap } = require('istanbul-lib-coverage')
3
+ const { createCoverageMap } = require('../../../../vendor/dist/istanbul-lib-coverage')
4
4
  const { addHook, channel } = require('../helpers/instrument')
5
5
  const shimmer = require('../../../datadog-shimmer')
6
6
  const { isMarkedAsUnskippable } = require('../../../datadog-plugin-jest/src/util')
@@ -4,7 +4,7 @@ const { errorMonitor } = require('node:events')
4
4
 
5
5
  const { channel, addHook } = require('./helpers/instrument')
6
6
  const shimmer = require('../../datadog-shimmer')
7
- const satisfies = require('semifies')
7
+ const satisfies = require('../../../vendor/dist/semifies')
8
8
 
9
9
  function wrapConnection (Connection, version) {
10
10
  const startCh = channel('apm:mysql2:query:start')
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const satisfies = require('semifies')
3
+ const satisfies = require('../../../vendor/dist/semifies')
4
4
 
5
5
  const { addHook, channel } = require('./helpers/instrument')
6
6
  const shimmer = require('../../datadog-shimmer')
@@ -11,6 +11,9 @@ const {
11
11
  getIsFaultyEarlyFlakeDetection
12
12
  } = require('../../dd-trace/src/plugins/util/test')
13
13
  const log = require('../../dd-trace/src/log')
14
+ const {
15
+ getEnvironmentVariable
16
+ } = require('../../dd-trace/src/config-helper')
14
17
  const { DD_MAJOR } = require('../../../version')
15
18
 
16
19
  const testStartCh = channel('ci:playwright:test:start')
@@ -38,7 +41,7 @@ const testSuiteToTestStatuses = new Map()
38
41
  const testSuiteToErrors = new Map()
39
42
  const testsToTestStatuses = new Map()
40
43
 
41
- const RUM_FLUSH_WAIT_TIME = 1000
44
+ const RUM_FLUSH_WAIT_TIME = Number(getEnvironmentVariable('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')) || 1000
42
45
 
43
46
  let applyRepeatEachIndex = null
44
47
 
@@ -687,10 +690,11 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
687
690
 
688
691
  const projects = getProjectsFromRunner(this, config)
689
692
 
690
- const shouldSetRetries = isFlakyTestRetriesEnabled &&
691
- flakyTestRetriesCount > 0 &&
692
- !isTestManagementTestsEnabled
693
- if (shouldSetRetries) {
693
+ // ATR and `--retries` are now compatible with Test Management.
694
+ // Test Management tests have their retries set to 0 at the test level,
695
+ // preventing them from being retried by ATR or `--retries`.
696
+ const shouldSetATRRetries = isFlakyTestRetriesEnabled && flakyTestRetriesCount > 0
697
+ if (shouldSetATRRetries) {
694
698
  projects.forEach(project => {
695
699
  if (project.retries === 0) { // Only if it hasn't been set by the user
696
700
  project.retries = flakyTestRetriesCount
@@ -722,6 +726,8 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
722
726
  })
723
727
  })
724
728
 
729
+ let preventedToFail = false
730
+
725
731
  const sessionStatus = runAllTestsReturn.status || runAllTestsReturn
726
732
 
727
733
  if (isTestManagementTestsEnabled && sessionStatus === 'failed') {
@@ -730,23 +736,30 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
730
736
  let totalPureQuarantinedFailedTestCount = 0
731
737
 
732
738
  for (const [fqn, testStatuses] of testsToTestStatuses.entries()) {
733
- const failedCount = testStatuses.filter(status => status === 'fail').length
734
- totalFailedTestCount += failedCount
735
- if (quarantinedButNotAttemptToFixFqns.has(fqn)) {
736
- totalPureQuarantinedFailedTestCount += failedCount
739
+ // Only count as failed if the final status (after retries) is 'fail'
740
+ const lastStatus = testStatuses[testStatuses.length - 1]
741
+ if (lastStatus === 'fail') {
742
+ totalFailedTestCount += 1
743
+ if (quarantinedButNotAttemptToFixFqns.has(fqn)) {
744
+ totalPureQuarantinedFailedTestCount += 1
745
+ }
737
746
  }
738
747
  }
739
748
 
740
749
  for (const test of quarantinedOrDisabledTestsAttemptToFix) {
741
750
  const testFqn = getTestFullyQualifiedName(test)
742
751
  const testStatuses = testsToTestStatuses.get(testFqn)
743
- totalAttemptToFixFailedTestCount += testStatuses.filter(status => status === 'fail').length
752
+ // Only count as failed if the final status (after retries) is 'fail'
753
+ if (testStatuses && testStatuses[testStatuses.length - 1] === 'fail') {
754
+ totalAttemptToFixFailedTestCount += 1
755
+ }
744
756
  }
745
757
 
746
758
  const totalIgnorableFailures = totalAttemptToFixFailedTestCount + totalPureQuarantinedFailedTestCount
747
759
 
748
760
  if (totalFailedTestCount > 0 && totalFailedTestCount === totalIgnorableFailures) {
749
761
  runAllTestsReturn = 'passed'
762
+ preventedToFail = true
750
763
  }
751
764
  }
752
765
 
@@ -754,7 +767,7 @@ function runAllTestsWrapper (runAllTests, playwrightVersion) {
754
767
  onDone = resolve
755
768
  })
756
769
  testSessionFinishCh.publish({
757
- status: STATUS_TO_TEST_STATUS[sessionStatus],
770
+ status: preventedToFail ? 'pass' : STATUS_TO_TEST_STATUS[sessionStatus],
758
771
  isEarlyFlakeDetectionEnabled,
759
772
  isEarlyFlakeDetectionFaulty,
760
773
  isTestManagementTestsEnabled,
@@ -917,6 +930,8 @@ addHook({
917
930
  }
918
931
  if (testProperties.attemptToFix) {
919
932
  test._ddIsAttemptToFix = true
933
+ // Prevent ATR or `--retries` from retrying attemptToFix tests
934
+ test.retries = 0
920
935
  const fileSuite = getSuiteType(test, 'file')
921
936
 
922
937
  if (!fileSuitesWithManagedTestsToProjects.has(fileSuite)) {
@@ -991,6 +1006,8 @@ addHook({
991
1006
  newTests.forEach(newTest => {
992
1007
  newTest._ddIsNew = true
993
1008
  if (isEarlyFlakeDetectionEnabled && newTest.expectedStatus !== 'skipped' && !newTest._ddIsModified) {
1009
+ // Prevent ATR or `--retries` from retrying new tests if EFD is enabled
1010
+ newTest.retries = 0
994
1011
  const fileSuite = getSuiteType(newTest, 'file')
995
1012
  if (!fileSuitesWithNewTestsToProjects.has(fileSuite)) {
996
1013
  fileSuitesWithNewTestsToProjects.set(fileSuite, getSuiteType(newTest, 'project'))
@@ -1064,9 +1081,19 @@ addHook({
1064
1081
 
1065
1082
  try {
1066
1083
  if (page) {
1067
- const isRumActive = await page.evaluate(() => {
1068
- return window.DD_RUM && window.DD_RUM.getInternalContext ? !!window.DD_RUM.getInternalContext() : false
1084
+ const { isRumInstrumented, isRumActive, rumSamplingRate } = await page.evaluate(() => {
1085
+ const isRumInstrumented = !!window.DD_RUM
1086
+ const isRumActive = window.DD_RUM && window.DD_RUM.getInternalContext
1087
+ ? !!window.DD_RUM.getInternalContext()
1088
+ : false
1089
+ const rumSamplingRate = window.DD_RUM && window.DD_RUM.getInitConfiguration
1090
+ ? window.DD_RUM.getInitConfiguration().sessionSampleRate
1091
+ : null
1092
+ return { isRumInstrumented, isRumActive, rumSamplingRate }
1069
1093
  })
1094
+ if (isRumInstrumented && rumSamplingRate < 100 && !isRumActive) {
1095
+ log.debug("RUM was detected on the page, but it isn't active because the sampling rate is below 100%")
1096
+ }
1070
1097
 
1071
1098
  if (isRumActive) {
1072
1099
  testPageGotoCh.publish({
@@ -1075,8 +1102,9 @@ addHook({
1075
1102
  })
1076
1103
  }
1077
1104
  }
1078
- } catch {
1105
+ } catch (e) {
1079
1106
  // ignore errors such as redirects, context destroyed, etc
1107
+ log.error('goto hook error', e)
1080
1108
  }
1081
1109
 
1082
1110
  return response
@@ -1168,8 +1196,9 @@ addHook({
1168
1196
  }
1169
1197
  }
1170
1198
  }
1171
- } catch {
1199
+ } catch (e) {
1172
1200
  // ignore errors
1201
+ log.error('afterEach hook error', e)
1173
1202
  }
1174
1203
  },
1175
1204
  title: 'afterEach hook',
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const METHODS = [...require('http').METHODS.map(v => v.toLowerCase()), 'all']
4
- const pathToRegExp = require('path-to-regexp')
4
+ const pathToRegExp = require('../../../vendor/dist/path-to-regexp')
5
5
  const shimmer = require('../../datadog-shimmer')
6
6
  const { addHook, channel } = require('./helpers/instrument')
7
7
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  const { addHook, channel } = require('./helpers/instrument')
4
4
  const shimmer = require('../../datadog-shimmer')
5
+ const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
5
6
 
6
7
  const ciSeleniumDriverGetStartCh = channel('ci:selenium:driver:get')
7
8
 
@@ -15,7 +16,8 @@ if (window.DD_RUM && window.DD_RUM.stopSession) {
15
16
  `
16
17
  const IS_RUM_ACTIVE_SCRIPT = 'return !!window.DD_RUM'
17
18
 
18
- const DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS = 500
19
+ const DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS =
20
+ Number(getEnvironmentVariable('DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS')) || 500
19
21
  const DD_CIVISIBILITY_TEST_EXECUTION_ID_COOKIE_NAME = 'datadog-ci-visibility-test-execution-id'
20
22
 
21
23
  // TODO: can we increase the supported version range?
@@ -12,6 +12,9 @@ const producerCh = tracingChannel('ws:send')
12
12
  const receiverCh = tracingChannel('ws:receive')
13
13
  const closeCh = tracingChannel('ws:close')
14
14
  const emitCh = channel('tracing:ws:server:connect:emit')
15
+ // TODO: Add a error channel / handle error events properly.
16
+
17
+ const eventHandlerMap = new WeakMap()
15
18
 
16
19
  function wrapHandleUpgrade (handleUpgrade) {
17
20
  return function () {
@@ -67,24 +70,37 @@ function createWrapEmit (emit) {
67
70
  }
68
71
 
69
72
  function createWrappedHandler (handler) {
70
- return function wrappedMessageHandler (data, binary) {
73
+ return shimmer.wrapFunction(handler, originalHandler => function (data, binary) {
71
74
  const byteLength = dataLength(data)
72
75
 
73
76
  const ctx = { data, binary, socket: this._sender?._socket, byteLength }
74
77
 
75
- return receiverCh.traceSync(handler, ctx, this, data, binary)
76
- }
78
+ return receiverCh.traceSync(originalHandler, ctx, this, data, binary)
79
+ })
77
80
  }
78
81
 
79
82
  function wrapListener (originalOn) {
80
83
  return function (eventName, handler) {
81
84
  if (eventName === 'message') {
82
- return originalOn.call(this, eventName, createWrappedHandler(handler))
85
+ // Prevent multiple wrapping of the same handler in case the user adds the listener multiple times
86
+ const wrappedHandler = eventHandlerMap.get(handler) ?? createWrappedHandler(handler)
87
+ eventHandlerMap.set(handler, wrappedHandler)
88
+ return originalOn.call(this, eventName, wrappedHandler)
83
89
  }
84
90
  return originalOn.apply(this, arguments)
85
91
  }
86
92
  }
87
93
 
94
+ function removeListener (originalOff) {
95
+ return function (eventName, handler) {
96
+ if (eventName === 'message') {
97
+ const wrappedHandler = eventHandlerMap.get(handler)
98
+ return originalOff.call(this, eventName, wrappedHandler)
99
+ }
100
+ return originalOff.apply(this, arguments)
101
+ }
102
+ }
103
+
88
104
  function wrapClose (close) {
89
105
  return function (code, data) {
90
106
  // _closeFrameReceived is set to true when receiver receives a close frame from a peer
@@ -115,22 +131,24 @@ addHook({
115
131
  versions: ['>=8.0.0']
116
132
  }, ws => {
117
133
  shimmer.wrap(ws.prototype, 'send', wrapSend)
118
- shimmer.wrap(ws.prototype, 'on', wrapListener)
119
134
  shimmer.wrap(ws.prototype, 'close', wrapClose)
135
+
136
+ // TODO: Do not wrap these methods. Instead, add a listener to the websocket instance when one is created.
137
+ // That way it avoids producing too many spans for the same websocket instance and less user code is impacted.
138
+ shimmer.wrap(ws.prototype, 'on', wrapListener)
139
+ shimmer.wrap(ws.prototype, 'addListener', wrapListener)
140
+ shimmer.wrap(ws.prototype, 'off', removeListener)
141
+ shimmer.wrap(ws.prototype, 'removeListener', removeListener)
142
+
120
143
  return ws
121
144
  })
122
145
 
123
- function detectType (data) {
124
- if (typeof Blob !== 'undefined' && data instanceof Blob) return 'Blob'
125
- if (typeof Buffer !== 'undefined' && Buffer.isBuffer(data)) return 'Buffer'
126
- if (typeof data === 'string') return 'string'
127
- return 'Unknown'
128
- }
129
-
130
146
  function dataLength (data) {
131
- const type = detectType(data)
132
- if (type === 'Blob') return data.size
133
- if (type === 'Buffer') return data.length
134
- if (type === 'string') return Buffer.byteLength(data)
135
- return 0
147
+ if (typeof data === 'string') {
148
+ return Buffer.byteLength(data)
149
+ }
150
+ if (data instanceof Blob) {
151
+ return data.size
152
+ }
153
+ return data?.length ?? 0
136
154
  }
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const shellParser = require('shell-quote/parse')
3
+ const shellParser = require('../../../vendor/dist/shell-quote').parse
4
4
 
5
5
  const ALLOWED_ENV_VARIABLES = new Set(['LD_PRELOAD', 'LD_LIBRARY_PATH', 'PATH'])
6
6
  const PROCESS_DENYLIST = new Set(['md5'])
@@ -133,6 +133,14 @@ function getCypressCommand (details) {
133
133
  return `${TEST_FRAMEWORK_NAME} ${details.specPattern || ''}`
134
134
  }
135
135
 
136
+ function getIsTestIsolationEnabled (cypressConfig) {
137
+ if (!cypressConfig) {
138
+ // If we can't read testIsolation config parameter, we default to allowing retries
139
+ return true
140
+ }
141
+ return cypressConfig.testIsolation === undefined ? true : cypressConfig.testIsolation
142
+ }
143
+
136
144
  function getLibraryConfiguration (tracer, testConfiguration) {
137
145
  return new Promise(resolve => {
138
146
  if (!tracer._tracer._exporter?.getLibraryConfiguration) {
@@ -296,6 +304,12 @@ class CypressPlugin {
296
304
  this.tracer = tracer
297
305
  this.cypressConfig = cypressConfig
298
306
 
307
+ this.isTestIsolationEnabled = getIsTestIsolationEnabled(cypressConfig)
308
+
309
+ if (!this.isTestIsolationEnabled) {
310
+ log.warn('Test isolation is disabled, retries will not be enabled')
311
+ }
312
+
299
313
  // we have to do it here because the tracer is not initialized in the constructor
300
314
  this.testEnvironmentMetadata[DD_TEST_IS_USER_PROVIDED_SERVICE] =
301
315
  tracer._tracer._config.isServiceUserProvided ? 'true' : 'false'
@@ -324,7 +338,7 @@ class CypressPlugin {
324
338
  this.isEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
325
339
  this.earlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
326
340
  this.isKnownTestsEnabled = isKnownTestsEnabled
327
- if (isFlakyTestRetriesEnabled) {
341
+ if (isFlakyTestRetriesEnabled && this.isTestIsolationEnabled) {
328
342
  this.isFlakyTestRetriesEnabled = true
329
343
  this.cypressConfig.retries.runMode = flakyTestRetriesCount
330
344
  }
@@ -467,6 +481,7 @@ class CypressPlugin {
467
481
  // We need to make sure that the plugin is initialized before running the tests
468
482
  // This is for the case where the user has not returned the promise from the init function
469
483
  await this.libraryConfigurationPromise
484
+
470
485
  this.command = getCypressCommand(details)
471
486
  this.frameworkVersion = getCypressVersion(details)
472
487
  this.rootDir = getRootDir(details)
@@ -801,7 +816,8 @@ class CypressPlugin {
801
816
  testManagementTests: this.getTestSuiteProperties(testSuite),
802
817
  isImpactedTestsEnabled: this.isImpactedTestsEnabled,
803
818
  isModifiedTest: this.getIsTestModified(testSuiteAbsolutePath),
804
- repositoryRoot: this.repositoryRoot
819
+ repositoryRoot: this.repositoryRoot,
820
+ isTestIsolationEnabled: this.isTestIsolationEnabled
805
821
  }
806
822
 
807
823
  if (this.testSuiteSpan) {
@@ -962,6 +978,11 @@ class CypressPlugin {
962
978
  this.activeTestSpan.addTags(tags)
963
979
  }
964
980
  return null
981
+ },
982
+ 'dd:log': (message) => {
983
+ // eslint-disable-next-line no-console
984
+ console.log(`[datadog] ${message}`)
985
+ return null
965
986
  }
966
987
  }
967
988
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  const NoopTracer = require('../../dd-trace/src/noop/tracer')
4
4
  const cypressPlugin = require('./cypress-plugin')
5
- const satisfies = require('semifies')
5
+ const satisfies = require('../../../vendor/dist/semifies')
6
6
  const { DD_MAJOR } = require('../../../version')
7
7
 
8
8
  const noopTask = {