dd-trace 6.21.0 → 6.22.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 (204) hide show
  1. package/ci/diagnose.js +9 -14
  2. package/ci/init.js +1 -2
  3. package/ci/test-optimization-validation/ci-discovery.js +9 -4
  4. package/ci/test-optimization-validation/executable.js +1 -5
  5. package/ci/test-optimization-validation/framework-adapters/cypress.js +1 -4
  6. package/ci/test-optimization-validation/framework-adapters/vitest.js +1 -1
  7. package/ci/test-optimization-validation/generated-files.js +6 -4
  8. package/ci/test-optimization-validation/generated-test-contract.js +7 -3
  9. package/ci/test-optimization-validation/manifest-scaffold.js +7 -2
  10. package/ci/test-optimization-validation/manifest-schema.js +6 -7
  11. package/ci/test-optimization-validation/report-writer.js +6 -2
  12. package/ci/test-optimization-validation/runner-command.js +2 -4
  13. package/ci/test-optimization-validation/runner-contract.js +1 -2
  14. package/ci/test-optimization-validation/scenarios/auto-test-retries.js +1 -15
  15. package/ci/vitest-no-worker-init-setup.mjs +10 -7
  16. package/index.d.ts +25 -14
  17. package/initialize.mjs +1 -3
  18. package/openfeature/rules-based.d.ts +11 -0
  19. package/openfeature/rules-based.js +7 -0
  20. package/package.json +12 -10
  21. package/packages/datadog-core/src/storage.js +16 -0
  22. package/packages/datadog-esbuild/index.js +18 -12
  23. package/packages/datadog-instrumentations/src/aerospike.js +3 -3
  24. package/packages/datadog-instrumentations/src/ai.js +3 -3
  25. package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -6
  26. package/packages/datadog-instrumentations/src/aws-sdk.js +21 -13
  27. package/packages/datadog-instrumentations/src/cassandra-driver.js +25 -20
  28. package/packages/datadog-instrumentations/src/claude-agent-sdk.js +9 -23
  29. package/packages/datadog-instrumentations/src/cucumber.js +48 -33
  30. package/packages/datadog-instrumentations/src/elasticsearch.js +1 -5
  31. package/packages/datadog-instrumentations/src/electron.js +6 -6
  32. package/packages/datadog-instrumentations/src/fastify.js +13 -4
  33. package/packages/datadog-instrumentations/src/fs.js +2 -2
  34. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +9 -5
  35. package/packages/datadog-instrumentations/src/grpc/client.js +2 -0
  36. package/packages/datadog-instrumentations/src/helpers/bundler-register.js +2 -2
  37. package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +1 -2
  38. package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -1
  39. package/packages/datadog-instrumentations/src/helpers/register.js +36 -1
  40. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -0
  41. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +87 -6
  42. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql-jit.js +5 -6
  43. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +48 -31
  44. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +7 -7
  45. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +42 -4
  46. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +7 -10
  47. package/packages/datadog-instrumentations/src/ioredis.js +7 -5
  48. package/packages/datadog-instrumentations/src/iovalkey.js +7 -5
  49. package/packages/datadog-instrumentations/src/jest.js +3 -10
  50. package/packages/datadog-instrumentations/src/knex.js +9 -5
  51. package/packages/datadog-instrumentations/src/mariadb-bundle.js +3 -3
  52. package/packages/datadog-instrumentations/src/mocha/common.js +20 -8
  53. package/packages/datadog-instrumentations/src/mocha/main.js +140 -43
  54. package/packages/datadog-instrumentations/src/mocha/utils.js +3 -2
  55. package/packages/datadog-instrumentations/src/mocha/worker.js +1 -2
  56. package/packages/datadog-instrumentations/src/mongodb-core.js +3 -3
  57. package/packages/datadog-instrumentations/src/mongoose.js +3 -3
  58. package/packages/datadog-instrumentations/src/nova-sonic/audio.js +173 -0
  59. package/packages/datadog-instrumentations/src/nova-sonic/index.js +209 -0
  60. package/packages/datadog-instrumentations/src/nova-sonic/session.js +483 -0
  61. package/packages/datadog-instrumentations/src/openai-realtime/index.js +18 -6
  62. package/packages/datadog-instrumentations/src/openai-realtime/session.js +1 -1
  63. package/packages/datadog-instrumentations/src/openai.js +7 -0
  64. package/packages/datadog-instrumentations/src/pino.js +5 -6
  65. package/packages/datadog-instrumentations/src/redis.js +27 -13
  66. package/packages/datadog-instrumentations/src/router.js +30 -0
  67. package/packages/datadog-instrumentations/src/rum-browser-scripts.js +2 -6
  68. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +7 -5
  69. package/packages/datadog-instrumentations/src/vitest-main.js +9 -15
  70. package/packages/datadog-instrumentations/src/vitest-util.js +2 -2
  71. package/packages/datadog-instrumentations/src/vitest-worker.js +1 -2
  72. package/packages/datadog-instrumentations/src/vitest.js +2 -2
  73. package/packages/datadog-instrumentations/src/webdriverio.js +5 -8
  74. package/packages/datadog-instrumentations/src/ws.js +1 -4
  75. package/packages/datadog-plugin-amqplib/src/client.js +1 -2
  76. package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -5
  77. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/handler.js +1 -2
  78. package/packages/datadog-plugin-aws-sdk/src/base.js +5 -8
  79. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +18 -0
  80. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/sonic.js +45 -0
  81. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +9 -3
  82. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -5
  83. package/packages/datadog-plugin-azure-durable-functions/src/index.js +5 -4
  84. package/packages/datadog-plugin-azure-functions/src/index.js +5 -3
  85. package/packages/datadog-plugin-claude-agent-sdk/src/index.js +0 -2
  86. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +1 -5
  87. package/packages/datadog-plugin-cypress/src/index.js +6 -6
  88. package/packages/datadog-plugin-cypress/src/source-map-utils.js +1 -2
  89. package/packages/datadog-plugin-cypress/src/support.js +1 -4
  90. package/packages/datadog-plugin-express/src/code_origin.js +1 -2
  91. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -2
  92. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +1 -2
  93. package/packages/datadog-plugin-graphql/src/execute.js +5 -5
  94. package/packages/datadog-plugin-grpc/src/util.js +1 -2
  95. package/packages/datadog-plugin-kafkajs/src/producer.js +1 -2
  96. package/packages/datadog-plugin-mocha/src/index.js +7 -10
  97. package/packages/datadog-plugin-mocha/src/webdriverio-video.js +8 -4
  98. package/packages/datadog-plugin-mongodb-core/src/query.js +8 -5
  99. package/packages/datadog-plugin-next/src/index.js +1 -2
  100. package/packages/datadog-plugin-openai/src/tracing.js +5 -2
  101. package/packages/datadog-plugin-openai-agents/src/integration.js +6 -2
  102. package/packages/datadog-plugin-openai-agents/src/processor.js +2 -4
  103. package/packages/datadog-plugin-postgres/src/index.js +24 -0
  104. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -5
  105. package/packages/datadog-plugin-rhea/src/consumer.js +1 -4
  106. package/packages/datadog-plugin-vitest/src/index.js +5 -2
  107. package/packages/datadog-shimmer/src/shimmer.js +5 -4
  108. package/packages/datadog-webpack/index.js +55 -43
  109. package/packages/datadog-webpack/src/loader.js +56 -8
  110. package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +2 -4
  111. package/packages/dd-trace/src/aiguard/messages/utils.js +1 -2
  112. package/packages/dd-trace/src/aiguard/redaction.js +8 -2
  113. package/packages/dd-trace/src/appsec/api_security/normalized-route.js +3 -2
  114. package/packages/dd-trace/src/appsec/api_security/sampler.js +2 -6
  115. package/packages/dd-trace/src/appsec/downstream_requests.js +1 -9
  116. package/packages/dd-trace/src/appsec/handlers/http-request.js +3 -9
  117. package/packages/dd-trace/src/appsec/handlers/http-response.js +7 -2
  118. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +4 -3
  119. package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +1 -4
  120. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +7 -1
  121. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -3
  122. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -3
  123. package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +1 -6
  124. package/packages/dd-trace/src/appsec/lambda.js +1 -3
  125. package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +37 -27
  126. package/packages/dd-trace/src/appsec/rasp/lfi.js +9 -5
  127. package/packages/dd-trace/src/appsec/reporter.js +21 -1
  128. package/packages/dd-trace/src/appsec/stack_trace.js +1 -2
  129. package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +3 -6
  130. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +1 -1
  131. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +13 -7
  132. package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +1 -2
  133. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +2 -8
  134. package/packages/dd-trace/src/ci-visibility/resolve-runfile-path.js +54 -0
  135. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +5 -8
  136. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +2 -53
  137. package/packages/dd-trace/src/config/config-types.d.ts +2 -2
  138. package/packages/dd-trace/src/config/defaults.js +5 -5
  139. package/packages/dd-trace/src/config/generated-config-types.d.ts +8 -0
  140. package/packages/dd-trace/src/config/helper.js +34 -3
  141. package/packages/dd-trace/src/config/index.js +10 -9
  142. package/packages/dd-trace/src/config/normalize-service.js +1 -1
  143. package/packages/dd-trace/src/config/parsers.js +2 -2
  144. package/packages/dd-trace/src/config/supported-configurations.json +35 -0
  145. package/packages/dd-trace/src/datastreams/processor.js +3 -2
  146. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -4
  147. package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -0
  148. package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -0
  149. package/packages/dd-trace/src/debugger/guardrail-metrics.js +2 -2
  150. package/packages/dd-trace/src/dogstatsd.js +1 -1
  151. package/packages/dd-trace/src/encode/tags-processors.js +2 -2
  152. package/packages/dd-trace/src/exporters/common/request.js +1 -5
  153. package/packages/dd-trace/src/id.js +14 -1
  154. package/packages/dd-trace/src/lambda/handler.js +179 -19
  155. package/packages/dd-trace/src/lambda/index.js +15 -1
  156. package/packages/dd-trace/src/lambda/runtime/patch.js +34 -7
  157. package/packages/dd-trace/src/llmobs/audio-utils.js +3 -2
  158. package/packages/dd-trace/src/llmobs/constants/tags.js +12 -0
  159. package/packages/dd-trace/src/llmobs/experiments/experiment.js +1 -1
  160. package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +15 -0
  161. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +1 -2
  162. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +1 -3
  163. package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
  164. package/packages/dd-trace/src/llmobs/plugins/nova-sonic.js +92 -0
  165. package/packages/dd-trace/src/llmobs/plugins/openai/index.js +56 -2
  166. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +38 -0
  167. package/packages/dd-trace/src/llmobs/prompts/manager.js +5 -7
  168. package/packages/dd-trace/src/llmobs/prompts/prompt.js +1 -1
  169. package/packages/dd-trace/src/llmobs/span_processor.js +1 -2
  170. package/packages/dd-trace/src/llmobs/tagger.js +2 -2
  171. package/packages/dd-trace/src/llmobs/util.js +1 -2
  172. package/packages/dd-trace/src/llmobs/writers/base.js +4 -5
  173. package/packages/dd-trace/src/log/log.js +1 -5
  174. package/packages/dd-trace/src/openfeature/evaluation-telemetry-opt-out-hook.js +51 -0
  175. package/packages/dd-trace/src/openfeature/flagging_provider.js +48 -21
  176. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +1 -1
  177. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +1 -1
  178. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -2
  179. package/packages/dd-trace/src/opentelemetry/otlp/common.proto +1 -1
  180. package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +6 -23
  181. package/packages/dd-trace/src/opentracing/propagation/text_map.js +53 -13
  182. package/packages/dd-trace/src/otel-sampling.js +4 -5
  183. package/packages/dd-trace/src/otel-thread-ctx.js +79 -13
  184. package/packages/dd-trace/src/plugins/database.js +7 -16
  185. package/packages/dd-trace/src/plugins/util/git.js +9 -25
  186. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -5
  187. package/packages/dd-trace/src/plugins/util/test.js +48 -4
  188. package/packages/dd-trace/src/priority_sampler.js +1 -2
  189. package/packages/dd-trace/src/profiling/profiler.js +4 -6
  190. package/packages/dd-trace/src/proxy.js +1 -2
  191. package/packages/dd-trace/src/ritm.js +4 -2
  192. package/packages/dd-trace/src/serverless.js +5 -0
  193. package/packages/dd-trace/src/span_processor.js +13 -17
  194. package/packages/dd-trace/src/telemetry/endpoints.js +1 -3
  195. package/packages/dd-trace/src/util.js +29 -0
  196. package/packages/dd-trace/src/web-tags-cache.js +6 -2
  197. package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
  198. package/vendor/dist/@datadog/openfeature-node-server/rules-based/LICENSE +201 -0
  199. package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.d.ts +925 -0
  200. package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.js +1 -0
  201. package/vendor/dist/@datadog/sketches-js/index.js +1 -1
  202. package/vendor/dist/protobufjs/index.js +1 -1
  203. package/vendor/dist/protobufjs/minimal/index.js +1 -1
  204. package/vendor/dist/shell-quote/index.js +1 -1
@@ -0,0 +1,45 @@
1
+ 'use strict'
2
+
3
+ const { storage } = require('../../../../datadog-core')
4
+ const TracingPlugin = require('../../../../dd-trace/src/plugins/tracing')
5
+
6
+ const legacyStorage = storage('legacy')
7
+
8
+ class SonicTracingPlugin extends TracingPlugin {
9
+ static id = 'bedrockruntime_sonic'
10
+ static component = 'aws-sdk'
11
+ static operation = 'sonic'
12
+ static prefix = 'tracing:apm:aws:bedrockruntime:sonic:span'
13
+
14
+ constructor (...args) {
15
+ super(...args)
16
+ this.addSub('dd-trace:aws:bedrockruntime:sonic:capture-context', context => {
17
+ const store = legacyStorage.getStore()
18
+ const previous = context.runInContext ?? (fn => fn())
19
+ context.runInContext = fn => previous(() => legacyStorage.run(store, fn))
20
+ })
21
+ }
22
+
23
+ /** @param {object} ctx */
24
+ bindStart (ctx) {
25
+ this.startSpan('aws.bedrockruntime.sonic', {
26
+ service: this.config.service,
27
+ resource: ctx.name,
28
+ type: 'bedrockruntime',
29
+ kind: 'client',
30
+ startTime: ctx.startTime,
31
+ meta: { 'aws.bedrock.request.model': ctx.model },
32
+ }, ctx)
33
+ return ctx.currentStore
34
+ }
35
+
36
+ /** @param {object} ctx */
37
+ end (ctx) {
38
+ const span = ctx.currentStore?.span
39
+ if (!span) return
40
+ if (ctx.descriptor.error) span.setTag('error', ctx.descriptor.error)
41
+ span.finish(ctx.finishTime)
42
+ }
43
+ }
44
+
45
+ module.exports = SonicTracingPlugin
@@ -174,9 +174,15 @@ class Kinesis extends BaseAwsSdkPlugin {
174
174
 
175
175
  responseExtractDSMContext (operation, params, response, span, kwargs = {}) {
176
176
  const { streamName } = kwargs
177
- if (!this.config.dsmEnabled) return
178
- if (operation !== 'getRecords') return
179
- if (!response || !response.Records || !response.Records[0]) return
177
+ if (
178
+ !this.config.dsmEnabled ||
179
+ operation !== 'getRecords' ||
180
+ !response ||
181
+ !response.Records ||
182
+ !response.Records[0]
183
+ ) {
184
+ return
185
+ }
180
186
 
181
187
  // Only attribute payloadSize to the span when there is a single record.
182
188
  span = response.Records.length > 1 ? null : span
@@ -202,8 +202,7 @@ class Sqs extends BaseAwsSdkPlugin {
202
202
  * @returns {Array<Record<string, string> | undefined> | undefined}
203
203
  */
204
204
  responseExtract (params, operation, response) {
205
- if (operation !== 'receiveMessage') return
206
- if (!response?.Messages?.length) return
205
+ if (operation !== 'receiveMessage' || !response?.Messages?.length) return
207
206
 
208
207
  return response.Messages.map(message => this.parseMessageCarrier(message))
209
208
  }
@@ -261,9 +260,7 @@ class Sqs extends BaseAwsSdkPlugin {
261
260
  * carriers are parsed here.
262
261
  */
263
262
  responseExtractDSMContext (operation, params, response, span, carriers) {
264
- if (!this.config.dsmEnabled) return
265
- if (operation !== 'receiveMessage') return
266
- if (!response?.Messages?.length) return
263
+ if (!this.config.dsmEnabled || operation !== 'receiveMessage' || !response?.Messages?.length) return
267
264
 
268
265
  const messages = response.Messages
269
266
  // Only attribute payloadSize to the span when there is a single message.
@@ -2,6 +2,7 @@
2
2
 
3
3
  const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
4
4
  const { AUTO_KEEP } = require('../../../ext/priority')
5
+ const { getIsAzureContainerApp } = require('../../dd-trace/src/serverless')
5
6
  const { writeTraceparent, writeTracestate } = require('../../dd-trace/src/carrier')
6
7
 
7
8
  const ORCHESTRATION_FAILURE_END_CHANNEL =
@@ -39,7 +40,7 @@ class AzureDurableFunctionsPlugin extends TracingPlugin {
39
40
  childOf = this.tracer.extract('text_map', carrier) ?? undefined
40
41
  }
41
42
  const extractedAsDrop = childOf?._sampling.priority < AUTO_KEEP
42
-
43
+ const prefix = getIsAzureContainerApp() ? 'aca' : 'aas'
43
44
  const span = this.startSpan(this.operationName(), {
44
45
  startTime: ctx.startTime,
45
46
  childOf,
@@ -48,15 +49,15 @@ class AzureDurableFunctionsPlugin extends TracingPlugin {
48
49
 
49
50
  meta: {
50
51
  component: 'azure-functions',
51
- 'aas.function.name': ctx.functionName,
52
- 'aas.function.trigger': ctx.trigger,
52
+ [`${prefix}.function.name`]: ctx.functionName,
53
+ [`${prefix}.function.trigger`]: ctx.trigger,
53
54
  'resource.name': `${ctx.trigger} ${ctx.functionName}`,
54
55
  },
55
56
  }, ctx)
56
57
 
57
58
  // in the case of entity functions, operationName should be available
58
59
  if (ctx.operationName) {
59
- span.setTag('aas.function.operation', ctx.operationName)
60
+ span.setTag(`${prefix}.function.operation`, ctx.operationName)
60
61
  span.setTag('resource.name', `${ctx.trigger} ${ctx.functionName} ${ctx.operationName}`
61
62
  )
62
63
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
4
4
  const web = require('../../dd-trace/src/plugins/util/web')
5
+ const { getIsAzureContainerApp } = require('../../dd-trace/src/serverless')
5
6
 
6
7
  const triggerMap = {
7
8
  deleteRequest: 'Http',
@@ -52,7 +53,6 @@ class AzureFunctionsPlugin extends TracingPlugin {
52
53
  req,
53
54
  ctx
54
55
  )
55
-
56
56
  span._integrationName = 'azure-functions'
57
57
  span.context().setTag('component', 'azure-functions')
58
58
  span.addTags(meta)
@@ -102,9 +102,11 @@ class AzureFunctionsPlugin extends TracingPlugin {
102
102
  }
103
103
 
104
104
  function getMetaForTrigger ({ functionName, methodName, invocationContext }) {
105
+ const prefix = getIsAzureContainerApp() ? 'aca' : 'aas'
106
+
105
107
  let meta = {
106
- 'aas.function.name': functionName,
107
- 'aas.function.trigger': mapTriggerTag(methodName),
108
+ [`${prefix}.function.name`]: functionName,
109
+ [`${prefix}.function.trigger`]: mapTriggerTag(methodName),
108
110
  'span.type': 'serverless',
109
111
  }
110
112
 
@@ -1,7 +1,5 @@
1
1
  'use strict'
2
2
 
3
- require('../../datadog-instrumentations/src/claude-agent-sdk')
4
-
5
3
  const CompositePlugin = require('../../dd-trace/src/plugins/composite')
6
4
  const ClaudeAgentSdkLLMObsPlugins = require('../../dd-trace/src/llmobs/plugins/claude-agent-sdk')
7
5
  const ClaudeAgentSdkTracingPlugins = require('./tracing')
@@ -1526,11 +1526,7 @@ class CypressPlugin {
1526
1526
  : undefined
1527
1527
  const testSpan = this.activeTestSpan || lastFailedTestSpan
1528
1528
 
1529
- if (!testSpan) {
1530
- return
1531
- }
1532
-
1533
- if (!isFailureScreenshotForUpload(details)) {
1529
+ if (!testSpan || !isFailureScreenshotForUpload(details)) {
1534
1530
  return
1535
1531
  }
1536
1532
 
@@ -53,12 +53,12 @@ class CypressPlugin extends Plugin {
53
53
  // downstream steps — then run the plugin's afterScreenshot on those
54
54
  // details and propagate the value back to Cypress. The user handler runs
55
55
  // regardless of whether screenshot upload is enabled.
56
- const registerAfterScreenshot = (afterScreenshotHandler) => {
56
+ const registerAfterScreenshot = () => {
57
57
  const filteredUserAfterScreenshotHandlers = userAfterScreenshotHandlers.filter(
58
- handler => handler !== afterScreenshotHandler
58
+ handler => handler !== datadogAfterScreenshotHandler
59
59
  )
60
60
  if (filteredUserAfterScreenshotHandlers.length === 0) {
61
- if (afterScreenshotHandler) on('after:screenshot', afterScreenshotHandler)
61
+ if (datadogAfterScreenshotHandler) on('after:screenshot', datadogAfterScreenshotHandler)
62
62
  return
63
63
  }
64
64
 
@@ -73,7 +73,7 @@ class CypressPlugin extends Plugin {
73
73
  Promise.resolve(details)
74
74
  )
75
75
  return chain.then((finalDetails) => {
76
- if (afterScreenshotHandler) afterScreenshotHandler(finalDetails)
76
+ if (datadogAfterScreenshotHandler) datadogAfterScreenshotHandler(finalDetails)
77
77
  return finalDetails
78
78
  })
79
79
  })
@@ -90,14 +90,14 @@ class CypressPlugin extends Plugin {
90
90
  Promise.resolve()
91
91
  ))
92
92
  }
93
- registerAfterScreenshot(datadogAfterScreenshotHandler)
93
+ registerAfterScreenshot()
94
94
  registerAfterRunWithCleanup()
95
95
  payload.registered = true
96
96
  return
97
97
  }
98
98
 
99
99
  registerBeforeRun(cypressPlugin.beforeRun.bind(cypressPlugin))
100
- registerAfterScreenshot(datadogAfterScreenshotHandler)
100
+ registerAfterScreenshot()
101
101
 
102
102
  on('after:spec', (spec, results) => {
103
103
  const chain = userAfterSpecHandlers.reduce(
@@ -26,8 +26,7 @@ function isJavaScriptFile (absoluteFilePath) {
26
26
  * @param {number} testSourceLine
27
27
  */
28
28
  function shouldTrustInvocationDetailsLine (absoluteFilePath, testSourceLine) {
29
- if (!Number.isInteger(testSourceLine) || testSourceLine < 1) return false
30
- if (!isJavaScriptFile(absoluteFilePath)) return false
29
+ if (!Number.isInteger(testSourceLine) || testSourceLine < 1 || !isJavaScriptFile(absoluteFilePath)) return false
31
30
 
32
31
  return getCachedSourceMap(absoluteFilePath) === null
33
32
  }
@@ -52,10 +52,7 @@ Cypress.on('command:end', (command) => {
52
52
  if (name === 'task' && args && typeof args[0] === 'string' && args[0].startsWith('dd:')) {
53
53
  return
54
54
  }
55
- if (INTERNAL_CYPRESS_COMMANDS.has(name)) {
56
- return
57
- }
58
- if (entry == null) {
55
+ if (INTERNAL_CYPRESS_COMMANDS.has(name) || entry == null) {
59
56
  return
60
57
  }
61
58
  const err = command.get('err')
@@ -26,8 +26,7 @@ class ExpressCodeOriginForSpansPlugin extends Plugin {
26
26
 
27
27
  // Route added handling: compute and cache tags
28
28
  const handleRouteAdded = ({ topOfStackFunc, layer }) => {
29
- if (!layer) return
30
- if (layerTags.has(layer)) return
29
+ if (!layer || layerTags.has(layer)) return
31
30
  layerTags.set(layer, entryTags(topOfStackFunc))
32
31
  }
33
32
 
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { getMessageSize } = require('../../dd-trace/src/datastreams')
3
+ const { getHeadersSize, getSizeOrZero } = require('../../dd-trace/src/datastreams')
4
4
  const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
5
5
  const { storage } = require('../../datadog-core')
6
6
  const reconstructPubSubRequestContext = require('./pubsub-request-context')
@@ -82,7 +82,7 @@ class GoogleCloudPubsubConsumerPlugin extends ConsumerPlugin {
82
82
  const { span } = ctx.currentStore
83
83
  const subscription = message._subscriber._subscription
84
84
  const topic = subscription?.metadata?.topic || message.attributes?.['pubsub.topic']
85
- const payloadSize = getMessageSize(message)
85
+ const payloadSize = getSizeOrZero(message.data) + getHeadersSize(message.attributes)
86
86
  this.tracer.decodeDataStreamsContext(message.attributes)
87
87
  this.tracer
88
88
  .setCheckpoint(['direction:in', `topic:${topic}`, 'type:google-pubsub'], span, payloadSize)
@@ -46,8 +46,7 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
46
46
  }
47
47
 
48
48
  start (ctx) {
49
- if (!this.config.dsmEnabled) return
50
- if (ctx.api !== 'publish' || !ctx.currentStore) return
49
+ if (!this.config.dsmEnabled || ctx.api !== 'publish' || !ctx.currentStore) return
51
50
  const { request } = ctx
52
51
  const messages = request.messages || []
53
52
  const topic = request.topic
@@ -78,8 +78,8 @@ if (asyncDisposeSymbol === undefined) {
78
78
  }
79
79
 
80
80
  class AbortError extends Error {
81
- constructor (message) {
82
- super(message)
81
+ constructor () {
82
+ super('Aborted')
83
83
  this.name = 'AbortError'
84
84
  }
85
85
  }
@@ -599,7 +599,7 @@ function wrapResolve (resolve, isJit = false) {
599
599
  }
600
600
 
601
601
  if (rootCtx.abortController?.signal.aborted) {
602
- throw new AbortError('Aborted')
602
+ throw new AbortError()
603
603
  }
604
604
 
605
605
  if (!traceResolver) {
@@ -736,7 +736,7 @@ function resolveCompiledJitField (rootCtx, descriptorId, resolve, self, source,
736
736
  }
737
737
 
738
738
  if (rootCtx.abortController?.signal.aborted) {
739
- throw new AbortError('Aborted')
739
+ throw new AbortError()
740
740
  }
741
741
 
742
742
  const depth = config.countListIndices ? descriptor.pathDepth : descriptor.selectionDepth
@@ -930,7 +930,7 @@ function resolveJitDefaultInvocation (rootCtx, descriptorId, source, path, argum
930
930
  }
931
931
  }
932
932
  if (rootCtx.abortController?.signal.aborted) {
933
- throw new AbortError('Aborted')
933
+ throw new AbortError()
934
934
  }
935
935
 
936
936
  const depth = rootCtx.config.countListIndices ? descriptor.pathDepth : descriptor.selectionDepth
@@ -71,9 +71,8 @@ module.exports = {
71
71
  },
72
72
 
73
73
  addMetadataTags (span, metadata, filter, type) {
74
- if (!metadata || typeof metadata.getMap !== 'function') return
75
74
  // Default no-op filter: skip the full metadata clone via `getMap()`.
76
- if (filter === getEmptyObject) return
75
+ if (!metadata || typeof metadata.getMap !== 'function' || filter === getEmptyObject) return
77
76
 
78
77
  const values = filter(metadata.getMap())
79
78
 
@@ -63,8 +63,7 @@ class KafkajsProducerPlugin extends ProducerPlugin {
63
63
  const commitList = ctx.result
64
64
  const clusterId = ctx.clusterId
65
65
 
66
- if (!this.config.dsmEnabled) return
67
- if (!commitList || !Array.isArray(commitList)) return
66
+ if (!this.config.dsmEnabled || !commitList || !Array.isArray(commitList)) return
68
67
  for (const rawCommit of commitList) {
69
68
  const commit = this.transformProduceResponse(rawCommit, clusterId)
70
69
  this.tracer.setOffset(commit)
@@ -651,9 +651,9 @@ class MochaPlugin extends CiPlugin {
651
651
  testSuiteMetadata[TEST_ITR_FORCED_RUN] = 'true'
652
652
  this.telemetry.count(TELEMETRY_ITR_FORCED_TO_RUN, { testLevel: 'suite' })
653
653
  }
654
- testSuiteMetadata[TEST_SOURCE_FILE] = this.repositoryRoot !== this.sourceRoot && !!this.repositoryRoot
655
- ? getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
656
- : testSuite
654
+ testSuiteMetadata[TEST_SOURCE_FILE] = this.repositoryRoot === this.sourceRoot || !this.repositoryRoot
655
+ ? testSuite
656
+ : getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
657
657
  if (testSuiteMetadata[TEST_SOURCE_FILE]) {
658
658
  testSuiteMetadata[TEST_SOURCE_START] = 1
659
659
  }
@@ -1113,10 +1113,7 @@ class MochaPlugin extends CiPlugin {
1113
1113
  #startWebdriverioJasmineTest (result, specs, currentSuite) {
1114
1114
  const state = this._webdriverioJasmineState
1115
1115
  const currentStore = storage('legacy').getStore()
1116
- if (!state || !result?.id) {
1117
- return currentStore
1118
- }
1119
- if (state.completedTestStatuses.has(result.id)) {
1116
+ if (!state || !result?.id || state.completedTestStatuses.has(result.id)) {
1120
1117
  return currentStore
1121
1118
  }
1122
1119
 
@@ -1962,9 +1959,9 @@ class MochaPlugin extends CiPlugin {
1962
1959
  const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.sourceRoot)
1963
1960
  const testSuiteSpan = this._testSuiteSpansByTestSuite.get(testSuite)
1964
1961
 
1965
- extraTags[TEST_SOURCE_FILE] = this.repositoryRoot !== this.sourceRoot && !!this.repositoryRoot
1966
- ? getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
1967
- : testSuite
1962
+ extraTags[TEST_SOURCE_FILE] = this.repositoryRoot === this.sourceRoot || !this.repositoryRoot
1963
+ ? testSuite
1964
+ : getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
1968
1965
 
1969
1966
  if (isNew) {
1970
1967
  extraTags[TEST_IS_NEW] = 'true'
@@ -141,9 +141,13 @@ class WebdriverioVideo {
141
141
  captureOwners.set(browser, this)
142
142
  this.#onResult = /** @param {{command?: string, endpoint?: string}} event */ (event) => {
143
143
  const { command, endpoint } = event
144
- if (command === 'takeScreenshot' || endpoint?.endsWith('/screenshot')) return
145
- // WDIO looks up the context before BiDi navigation. Capturing in that gap can block navigation.
146
- if (command === 'getWindowHandle' || command === 'getWindowHandles') return
144
+ if (
145
+ command === 'takeScreenshot' || endpoint?.endsWith('/screenshot') ||
146
+ // WDIO looks up the context before BiDi navigation. Capturing in that gap can block navigation.
147
+ command === 'getWindowHandle' || command === 'getWindowHandles'
148
+ ) {
149
+ return
150
+ }
147
151
  this.capture()
148
152
  }
149
153
  browser.on?.('result', this.#onResult)
@@ -252,7 +256,7 @@ class WebdriverioVideo {
252
256
  const frames = Array.isArray(screenshots) ? screenshots : [screenshots]
253
257
  if (!frames.length) throw new Error('WebdriverIO returned no video frames')
254
258
  for (let index = 0; index < frames.length; index++) {
255
- if (typeof frames[index] !== 'string') throw new Error('WebdriverIO returned an invalid video frame')
259
+ if (typeof frames[index] !== 'string') throw new TypeError('WebdriverIO returned an invalid video frame')
256
260
  if (Buffer.byteLength(frames[index], 'base64') > MAX_FRAME_BYTES - frameBytes) {
257
261
  throw new Error('WebdriverIO video frames exceeded the 200 MiB worker limit')
258
262
  }
@@ -181,10 +181,9 @@ function canStringifyDirectWalk (value, depth) {
181
181
  child._bsontype !== undefined ||
182
182
  isRegExp(child) ||
183
183
  isMap(child) ||
184
- typeof child.toJSON === 'function') {
184
+ typeof child.toJSON === 'function' || !canStringifyDirectWalk(child, depth + 1)) {
185
185
  return false
186
186
  }
187
- if (!canStringifyDirectWalk(child, depth + 1)) return false
188
187
  }
189
188
  return true
190
189
  }
@@ -322,9 +321,13 @@ function buildRedact (value, ancestors) {
322
321
  // `value === original` short-circuit.
323
322
  if (typeof value.toJSON === 'function') {
324
323
  const json = value.toJSON()
325
- if (typeof json !== 'object' || json === null || json === value) return REDACT_LEAF
326
- // Re-screen: toJSON can return a TypedArray or Binary BSON wrapper.
327
- if (ArrayBuffer.isView(json) || json._bsontype === 'Binary') return REDACT_LEAF
324
+ if (
325
+ typeof json !== 'object' || json === null || json === value ||
326
+ // Re-screen: toJSON can return a TypedArray or Binary BSON wrapper.
327
+ ArrayBuffer.isView(json) || json._bsontype === 'Binary'
328
+ ) {
329
+ return REDACT_LEAF
330
+ }
328
331
  value = json
329
332
  } else if (bsontype !== undefined) {
330
333
  return REDACT_LEAF
@@ -107,8 +107,7 @@ class NextPlugin extends ServerPlugin {
107
107
  const { req, res, nextRequest = {} } = ctx
108
108
  const store = ctx.currentStore ?? storage('legacy').getStore()
109
109
 
110
- if (!store) return
111
- if (reusedNextRequestStores.has(store)) return
110
+ if (!store || reusedNextRequestStores.has(store)) return
112
111
 
113
112
  const span = store.span
114
113
  const error = ctx.error ?? span.context().getTag('error')
@@ -295,8 +295,7 @@ class OpenAiTracingPlugin extends TracingPlugin {
295
295
  }
296
296
 
297
297
  sendLog (methodName, span, tags, openaiStore, error) {
298
- if (!openaiStore) return
299
- if (!this.sampler.isSampled(span)) return
298
+ if (!openaiStore || !this.sampler.isSampled(span)) return
300
299
 
301
300
  const log = {
302
301
  status: error ? 'error' : 'info',
@@ -334,6 +333,10 @@ function normalizeMethodName (methodName) {
334
333
  case 'responses.create':
335
334
  return 'createResponse'
336
335
 
336
+ // decisions
337
+ case 'decisions.create':
338
+ return 'createDecision'
339
+
337
340
  // files
338
341
  case 'files.create':
339
342
  return 'createFile'
@@ -460,8 +460,12 @@ class OpenAIAgentsIntegration {
460
460
  */
461
461
  #llmSpanParentAgentName (oaiSpan) {
462
462
  const traceInfo = this.#traceInfo.get(oaiSpan.traceId)
463
- if (!traceInfo?.currentTopLevelAgentSpanId) return
464
- if (!this.#hasUntracedPathToAncestor(oaiSpan.parentId, traceInfo.currentTopLevelAgentSpanId)) return
463
+ if (
464
+ !traceInfo?.currentTopLevelAgentSpanId ||
465
+ !this.#hasUntracedPathToAncestor(oaiSpan.parentId, traceInfo.currentTopLevelAgentSpanId)
466
+ ) {
467
+ return
468
+ }
465
469
  return traceInfo.currentTopLevelAgentName
466
470
  }
467
471
 
@@ -64,8 +64,7 @@ class DDOpenAIAgentsProcessor {
64
64
 
65
65
  onSpanStart (oaiSpan) {
66
66
  const integration = this._getIntegration()
67
- if (!integration?.enabled) return RESOLVED
68
- if (!oaiSpan?.spanData) return RESOLVED // guard NoopSpan
67
+ if (!integration?.enabled || !oaiSpan?.spanData) return RESOLVED // guard NoopSpan
69
68
  const type = oaiSpan.spanData.type
70
69
  const kind = SPAN_KIND_BY_TYPE[type]
71
70
  try {
@@ -84,8 +83,7 @@ class DDOpenAIAgentsProcessor {
84
83
 
85
84
  onSpanEnd (oaiSpan) {
86
85
  const integration = this._getIntegration()
87
- if (!integration?.enabled) return RESOLVED
88
- if (!oaiSpan?.spanData) return RESOLVED
86
+ if (!integration?.enabled || !oaiSpan?.spanData) return RESOLVED
89
87
  const type = oaiSpan.spanData.type
90
88
  const kind = SPAN_KIND_BY_TYPE[type]
91
89
  try {
@@ -1,9 +1,12 @@
1
1
  'use strict'
2
2
 
3
+ const { performance } = require('node:perf_hooks')
4
+
3
5
  const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
4
6
  const DatabasePlugin = require('../../dd-trace/src/plugins/database')
5
7
  const Plugin = require('../../dd-trace/src/plugins/plugin')
6
8
 
9
+ const ACQUIRE_START_CHANNEL = 'tracing:orchestrion:postgres:query:acquire:start'
7
10
  const PREPARE_START_CHANNEL = 'tracing:orchestrion:postgres:query:prepare:start'
8
11
 
9
12
  /**
@@ -14,6 +17,8 @@ const PREPARE_START_CHANNEL = 'tracing:orchestrion:postgres:query:prepare:start'
14
17
  * @property {string} [host]
15
18
  * @property {number} [pid]
16
19
  * @property {number} [port]
20
+ * @property {boolean} [poolWaitFinished]
21
+ * @property {number} [poolWaitStartMs]
17
22
  * @property {PostgresQuery} query
18
23
  * @property {string} [statement]
19
24
  * @property {string} user
@@ -63,12 +68,16 @@ class PostgresPlugin extends DatabasePlugin {
63
68
  /** @type {WeakMap<PostgresQuery, import('../../..').Span>} */
64
69
  #spans = new WeakMap()
65
70
 
71
+ /** @type {WeakMap<PostgresQuery, PostgresContext>} */
72
+ #waitContexts = new WeakMap()
73
+
66
74
  /**
67
75
  * @param {object} tracer
68
76
  * @param {import('../../dd-trace/src/config/config-base')} tracerConfig
69
77
  */
70
78
  constructor (tracer, tracerConfig) {
71
79
  super(tracer, tracerConfig)
80
+ this.addSub(ACQUIRE_START_CHANNEL, ctx => this.#finishPoolWait(ctx.query))
72
81
  this.#preparation = new PostgresPreparationPlugin(this.#prepare.bind(this), tracer, tracerConfig)
73
82
  }
74
83
 
@@ -112,12 +121,26 @@ class PostgresPlugin extends DatabasePlugin {
112
121
  }
113
122
 
114
123
  this.#spans.set(query, span)
124
+ this.#waitContexts.set(query, ctx)
115
125
  if (this.#dbmEnabled) {
116
126
  this.#dbmQueries.set(query, { service: service.name })
117
127
  }
118
128
  return ctx.currentStore
119
129
  }
120
130
 
131
+ /**
132
+ * @param {PostgresQuery} query
133
+ */
134
+ #finishPoolWait (query) {
135
+ const ctx = this.#waitContexts.get(query)
136
+ if (ctx === undefined) return
137
+
138
+ this.#waitContexts.delete(query)
139
+ ctx.poolWaitFinished = true
140
+ const waitTime = ctx.poolWaitStartMs === undefined ? 0 : performance.now() - ctx.poolWaitStartMs
141
+ ctx.currentStore.span.setTag('db.pool.wait_time_ms', waitTime)
142
+ }
143
+
121
144
  /**
122
145
  * @param {PostgresPreparationContext} ctx
123
146
  */
@@ -152,6 +175,7 @@ class PostgresPlugin extends DatabasePlugin {
152
175
  this.#dbmQueries.delete(query)
153
176
  if (span === undefined) return
154
177
 
178
+ this.#finishPoolWait(query)
155
179
  this.#spans.delete(query)
156
180
 
157
181
  const statement = dbmState?.statement ?? result.statement
@@ -144,12 +144,8 @@ class SchemaExtractor {
144
144
  span.setTag(SCHEMA_NAME, removeLeadingPeriod(descriptor.fullName))
145
145
  span.setTag(SCHEMA_OPERATION, operation)
146
146
 
147
- if (!tracer._dataStreamsProcessor.canSampleSchema(operation)) {
148
- return
149
- }
150
-
151
147
  // if the span is unsampled, do not sample the schema
152
- if (!tracer._prioritySampler.isSampled(span)) {
148
+ if (!tracer._dataStreamsProcessor.canSampleSchema(operation) || !tracer._prioritySampler.isSampled(span)) {
153
149
  return
154
150
  }
155
151
 
@@ -52,10 +52,7 @@ class RheaConsumerPlugin extends ConsumerPlugin {
52
52
 
53
53
  function getResourceNameFromMessage (msgObj) {
54
54
  let resourceName = 'amq.topic'
55
- let options = {}
56
- if (msgObj.receiver && msgObj.receiver.options) {
57
- options = msgObj.receiver.options
58
- }
55
+ const options = msgObj.receiver && msgObj.receiver.options ? msgObj.receiver.options : {}
59
56
  if (options.source && options.source.address) {
60
57
  resourceName = options.source.address
61
58
  }
@@ -354,6 +354,8 @@ class VitestPlugin extends CiPlugin {
354
354
  browserProjectName,
355
355
  testExecutionId,
356
356
  testStartLine,
357
+ startTime,
358
+ duration,
357
359
  }) => {
358
360
  const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
359
361
  const extraTags = {
@@ -380,10 +382,11 @@ class VitestPlugin extends CiPlugin {
380
382
  testSuite,
381
383
  testSuiteSpan || this.testSuiteSpan,
382
384
  extraTags,
383
- testExecutionId
385
+ testExecutionId,
386
+ startTime
384
387
  )
385
388
  this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'test', this.getTestTelemetryTags(testSpan))
386
- testSpan.finish()
389
+ testSpan.finish(Number.isFinite(duration) && duration >= 0 ? testSpan._startTime + duration : undefined)
387
390
  })
388
391
 
389
392
  this.addBind('ci:vitest:test-suite:start', (ctx) => {