dd-trace 6.13.0 → 6.14.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 (201) hide show
  1. package/LICENSE-3rdparty.csv +3 -1
  2. package/ci/init.js +8 -3
  3. package/ci/test-optimization-validation/ci-package-scripts.js +2 -2
  4. package/ci/test-optimization-validation/ci-remediation.js +6 -6
  5. package/ci/test-optimization-validation/command-blocker.js +7 -5
  6. package/ci/test-optimization-validation/framework-adapters/cucumber.js +1 -1
  7. package/ci/test-optimization-validation/framework-adapters/vitest.js +3 -3
  8. package/ci/test-optimization-validation/package-check.js +1 -1
  9. package/ci/test-optimization-validation/report-writer.js +7 -5
  10. package/ci/vitest-no-worker-init-runner-setup.mjs +8 -0
  11. package/ci/vitest-no-worker-init-setup.mjs +13 -13
  12. package/ci/vitest-no-worker-init-v5-setup.mjs +4 -0
  13. package/package.json +13 -10
  14. package/packages/datadog-esbuild/index.js +3 -1
  15. package/packages/datadog-instrumentations/src/cypress-config.js +19 -17
  16. package/packages/datadog-instrumentations/src/fs.js +24 -20
  17. package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +2 -2
  18. package/packages/datadog-instrumentations/src/graphql.js +16 -16
  19. package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +504 -0
  20. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
  21. package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +265 -0
  22. package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +1 -2
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +95 -30
  24. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/ai.js +0 -25
  25. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql-jit.js +83 -0
  26. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql.js +85 -1
  27. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
  28. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/mercurius.js +30 -12
  29. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +13 -0
  30. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +251 -0
  31. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +11 -1
  32. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +562 -27
  33. package/packages/datadog-instrumentations/src/jest.js +25 -20
  34. package/packages/datadog-instrumentations/src/knex.js +76 -0
  35. package/packages/datadog-instrumentations/src/mariadb.js +6 -0
  36. package/packages/datadog-instrumentations/src/mocha/common.js +59 -2
  37. package/packages/datadog-instrumentations/src/mocha/main.js +25 -15
  38. package/packages/datadog-instrumentations/src/mocha/utils.js +2 -1
  39. package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +98 -0
  40. package/packages/datadog-instrumentations/src/mocha/worker.js +12 -8
  41. package/packages/datadog-instrumentations/src/net.js +14 -17
  42. package/packages/datadog-instrumentations/src/next.js +212 -62
  43. package/packages/datadog-instrumentations/src/openai.js +42 -40
  44. package/packages/datadog-instrumentations/src/pg.js +15 -0
  45. package/packages/datadog-instrumentations/src/playwright.js +109 -13
  46. package/packages/datadog-instrumentations/src/rum-browser-scripts.js +40 -0
  47. package/packages/datadog-instrumentations/src/sequelize.js +94 -2
  48. package/packages/datadog-instrumentations/src/undici.js +53 -4
  49. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +37 -3
  50. package/packages/datadog-instrumentations/src/vitest-main.js +92 -9
  51. package/packages/datadog-instrumentations/src/vitest-worker.js +71 -14
  52. package/packages/datadog-instrumentations/src/webdriverio.js +965 -6
  53. package/packages/datadog-plugin-amqp10/src/consumer.js +3 -1
  54. package/packages/datadog-plugin-amqp10/src/producer.js +3 -1
  55. package/packages/datadog-plugin-amqp10/src/util.js +2 -1
  56. package/packages/datadog-plugin-avsc/src/schema_iterator.js +6 -1
  57. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +16 -5
  58. package/packages/datadog-plugin-cassandra-driver/src/index.js +8 -3
  59. package/packages/datadog-plugin-cucumber/src/index.js +0 -2
  60. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +262 -48
  61. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +4 -1
  62. package/packages/datadog-plugin-graphql/src/execute.js +998 -196
  63. package/packages/datadog-plugin-graphql/src/index.js +27 -7
  64. package/packages/datadog-plugin-graphql/src/jit.js +136 -0
  65. package/packages/datadog-plugin-graphql/src/request.js +18 -27
  66. package/packages/datadog-plugin-graphql/src/resolve-error.js +108 -0
  67. package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -2
  68. package/packages/datadog-plugin-graphql/src/tools/transforms.js +45 -3
  69. package/packages/datadog-plugin-graphql/src/utils.js +208 -120
  70. package/packages/datadog-plugin-graphql/src/validate.js +10 -23
  71. package/packages/datadog-plugin-jest/src/index.js +0 -6
  72. package/packages/datadog-plugin-langchain/src/tracing.js +7 -0
  73. package/packages/datadog-plugin-mocha/src/index.js +403 -75
  74. package/packages/datadog-plugin-mongodb-core/src/query.js +6 -0
  75. package/packages/datadog-plugin-mysql/src/index.js +41 -15
  76. package/packages/datadog-plugin-net/src/tcp.js +3 -1
  77. package/packages/datadog-plugin-next/src/index.js +63 -29
  78. package/packages/datadog-plugin-playwright/src/index.js +167 -27
  79. package/packages/datadog-plugin-undici/src/index.js +27 -41
  80. package/packages/datadog-plugin-vitest/src/index.js +6 -12
  81. package/packages/dd-trace/src/aiguard/evaluation.js +2 -1
  82. package/packages/dd-trace/src/aiguard/messages/anthropic.js +8 -1
  83. package/packages/dd-trace/src/aiguard/messages/openai.js +8 -1
  84. package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +20 -6
  85. package/packages/dd-trace/src/appsec/api_security/index.js +23 -6
  86. package/packages/dd-trace/src/appsec/api_security/sampler.js +99 -40
  87. package/packages/dd-trace/src/appsec/graphql.js +6 -2
  88. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +3 -3
  89. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -1
  90. package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +8 -2
  91. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +11 -36
  92. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +1 -1
  93. package/packages/dd-trace/src/appsec/lambda.js +44 -26
  94. package/packages/dd-trace/src/ci-visibility/encode/json-encoder.js +32 -2
  95. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +8 -8
  96. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +6 -4
  97. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +20 -4
  98. package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +5 -173
  99. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +7 -6
  100. package/packages/dd-trace/src/ci-visibility/exporters/agents.js +54 -0
  101. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/writer.js +1 -2
  102. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +394 -225
  103. package/packages/dd-trace/src/ci-visibility/exporters/limits.js +9 -0
  104. package/packages/dd-trace/src/ci-visibility/exporters/request.js +323 -31
  105. package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +42 -0
  106. package/packages/dd-trace/src/ci-visibility/final-flush.js +2 -1
  107. package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +57 -18
  108. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +0 -3
  109. package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +164 -71
  110. package/packages/dd-trace/src/ci-visibility/requests/video-request.js +176 -0
  111. package/packages/dd-trace/src/ci-visibility/telemetry.js +10 -7
  112. package/packages/dd-trace/src/ci-visibility/test-video.js +61 -0
  113. package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -0
  114. package/packages/dd-trace/src/config/index.js +73 -13
  115. package/packages/dd-trace/src/config/parsers.js +11 -1
  116. package/packages/dd-trace/src/config/stable.js +3 -3
  117. package/packages/dd-trace/src/config/supported-configurations.json +20 -2
  118. package/packages/dd-trace/src/crashtracking/crashtracker.js +82 -18
  119. package/packages/dd-trace/src/debugger/config.js +12 -1
  120. package/packages/dd-trace/src/debugger/constants.js +1 -0
  121. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +2 -1
  122. package/packages/dd-trace/src/debugger/devtools_client/request-options.js +33 -0
  123. package/packages/dd-trace/src/debugger/devtools_client/send.js +7 -40
  124. package/packages/dd-trace/src/debugger/devtools_client/status.js +11 -6
  125. package/packages/dd-trace/src/debugger/devtools_client/tags.js +41 -0
  126. package/packages/dd-trace/src/debugger/index.js +23 -3
  127. package/packages/dd-trace/src/dogstatsd.js +510 -76
  128. package/packages/dd-trace/src/encode/0.4-cross-payload.js +170 -0
  129. package/packages/dd-trace/src/encode/0.4.js +5 -5
  130. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +9 -8
  131. package/packages/dd-trace/src/evp_proxy/direct.js +27 -23
  132. package/packages/dd-trace/src/exporters/agent/index.js +2 -1
  133. package/packages/dd-trace/src/exporters/agent/writer.js +24 -7
  134. package/packages/dd-trace/src/exporters/agentless/index.js +7 -9
  135. package/packages/dd-trace/src/exporters/agentless/writer.js +100 -118
  136. package/packages/dd-trace/src/exporters/common/agents.js +28 -6
  137. package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -2
  138. package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +191 -0
  139. package/packages/dd-trace/src/exporters/common/request.js +31 -11
  140. package/packages/dd-trace/src/exporters/common/url.js +40 -1
  141. package/packages/dd-trace/src/exporters/common/writer.js +9 -7
  142. package/packages/dd-trace/src/flush.js +6 -3
  143. package/packages/dd-trace/src/id.js +14 -0
  144. package/packages/dd-trace/src/index.js +5 -2
  145. package/packages/dd-trace/src/llmobs/experiments/dataset.js +2 -1
  146. package/packages/dd-trace/src/llmobs/index.js +32 -32
  147. package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +22 -71
  148. package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +23 -13
  149. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +7 -0
  150. package/packages/dd-trace/src/llmobs/util.js +0 -33
  151. package/packages/dd-trace/src/llmobs/writers/base.js +49 -32
  152. package/packages/dd-trace/src/log/index.js +7 -1
  153. package/packages/dd-trace/src/{ci-visibility/log-submission → log-submission}/log-submission-plugin.js +48 -19
  154. package/packages/dd-trace/src/openfeature/writers/base.js +14 -12
  155. package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
  156. package/packages/dd-trace/src/opentelemetry/logs/index.js +5 -24
  157. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +14 -4
  158. package/packages/dd-trace/src/opentelemetry/metrics/index.js +15 -22
  159. package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +14 -4
  160. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +10 -0
  161. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +19 -4
  162. package/packages/dd-trace/src/opentelemetry/resource-attributes.js +55 -0
  163. package/packages/dd-trace/src/opentelemetry/trace/index.js +6 -1
  164. package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +10 -0
  165. package/packages/dd-trace/src/opentracing/propagation/text_map.js +93 -18
  166. package/packages/dd-trace/src/payload-tagging/index.js +2 -1
  167. package/packages/dd-trace/src/plugins/ci_plugin.js +1 -6
  168. package/packages/dd-trace/src/plugins/tracing.js +12 -10
  169. package/packages/dd-trace/src/plugins/util/ci.js +3 -1
  170. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +16 -15
  171. package/packages/dd-trace/src/plugins/util/test.js +83 -20
  172. package/packages/dd-trace/src/plugins/util/url.js +2 -2
  173. package/packages/dd-trace/src/plugins/util/web.js +4 -9
  174. package/packages/dd-trace/src/profiling/config.js +1 -0
  175. package/packages/dd-trace/src/profiling/oom.js +7 -2
  176. package/packages/dd-trace/src/profiling/profiler.js +23 -13
  177. package/packages/dd-trace/src/profiling/profilers/space.js +38 -11
  178. package/packages/dd-trace/src/profiling/webspan-utils.js +7 -4
  179. package/packages/dd-trace/src/proxy.js +75 -5
  180. package/packages/dd-trace/src/remote_config/index.js +319 -101
  181. package/packages/dd-trace/src/remote_config/scheduler.js +37 -12
  182. package/packages/dd-trace/src/runtime_metrics/client.js +37 -8
  183. package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +5 -1
  184. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -1
  185. package/packages/dd-trace/src/sampling_rule.js +36 -9
  186. package/packages/dd-trace/src/serverless/telemetry-delivery-tracker.js +4 -8
  187. package/packages/dd-trace/src/serverless/vercel.js +53 -20
  188. package/packages/dd-trace/src/serverless.js +10 -3
  189. package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
  190. package/packages/dd-trace/src/span_stats.js +24 -28
  191. package/packages/dd-trace/src/startup-log.js +3 -2
  192. package/packages/dd-trace/src/telemetry/agentless-url.js +28 -0
  193. package/packages/dd-trace/src/telemetry/send-data.js +18 -16
  194. package/packages/dd-trace/src/telemetry/session-propagation.js +3 -2
  195. package/packages/dd-trace/src/tracer.js +4 -5
  196. package/packages/dd-trace/src/tracer_metadata.js +11 -3
  197. package/vendor/dist/@datadog/sketches-js/index.js +1 -1
  198. package/vendor/dist/protobufjs/index.js +1 -1
  199. package/vendor/dist/protobufjs/minimal/index.js +1 -1
  200. package/packages/datadog-instrumentations/src/playwright-browser-scripts.js +0 -27
  201. package/packages/dd-trace/src/encode/agentless-json.js +0 -210
@@ -4,7 +4,7 @@ const { EventEmitter } = require('events')
4
4
  const dc = require('dc-polyfill')
5
5
  const crashtracker = require('../crashtracking')
6
6
  const log = require('../log')
7
- const { buildProfilingRuntime } = require('./config')
7
+ const { buildProfilingRuntime, getProfilingTags } = require('./config')
8
8
  const { snapshotKinds } = require('./constants')
9
9
  const { threadNamePrefix } = require('./profilers/shared')
10
10
  const { isWebServerSpan, endpointNameFromTags, getStartedSpans } = require('./webspan-utils')
@@ -54,6 +54,7 @@ class Profiler extends EventEmitter {
54
54
  #compressionFn
55
55
  #compressionFnInitialized = false
56
56
  #compressionOptions
57
+ #config
57
58
  #customLabelKeys = new Set()
58
59
  #enabled = false
59
60
  #endpointCounts = new Map()
@@ -64,7 +65,7 @@ class Profiler extends EventEmitter {
64
65
  #profilers
65
66
  #spanFinishListener
66
67
  #systemInfoReport
67
- #tags
68
+ #currentSnapshotTags
68
69
  #timer
69
70
  #uploadCompression
70
71
 
@@ -156,7 +157,7 @@ class Profiler extends EventEmitter {
156
157
  }
157
158
  }
158
159
  } else {
159
- const zstdCompress = require('@datadog/libdatadog').load('datadog-js-zstd').zstd_compress
160
+ const { zstd_compress: zstdCompress } = require('@datadog/libdatadog')
160
161
  const level = clevel ?? 0 // 0 is zstd default compression level
161
162
  this.#compressionFn = (buffer) => Promise.resolve(Buffer.from(zstdCompress(buffer, level)))
162
163
  }
@@ -176,12 +177,13 @@ class Profiler extends EventEmitter {
176
177
  if (this.enabled) return true
177
178
  this.#enabled = true
178
179
 
179
- const { tags, exporters, flushInterval, profilers, uploadCompression, systemInfoReport } =
180
+ const { tags: snapshotTags, exporters, flushInterval, profilers, uploadCompression, systemInfoReport } =
180
181
  buildProfilingRuntime(config)
181
- this.#tags = tags
182
+ this.#config = config
182
183
  this.#exporters = exporters
183
184
  this.#flushInterval = flushInterval
184
185
  this.#profilers = profilers
186
+ this.#currentSnapshotTags = snapshotTags
185
187
  this.#uploadCompression = uploadCompression
186
188
  this.#systemInfoReport = systemInfoReport
187
189
  if (this.#customLabelKeys.size > 0) {
@@ -248,7 +250,7 @@ class Profiler extends EventEmitter {
248
250
  processInfo(infos, info, profileType)
249
251
  this.#submit({
250
252
  [profileType]: encodedProfile,
251
- }, infos, start, end, snapshotKinds.ON_OUT_OF_MEMORY)
253
+ }, infos, start, end, this.#currentSnapshotTags, snapshotKinds.ON_OUT_OF_MEMORY)
252
254
  }
253
255
 
254
256
  _setInterval () {
@@ -332,6 +334,7 @@ class Profiler extends EventEmitter {
332
334
 
333
335
  const startDate = this.#lastStart
334
336
  const endDate = new Date()
337
+ const snapshotTags = this.#currentSnapshotTags
335
338
  const profiles = []
336
339
 
337
340
  crashtracker.withProfilerSerializing(() => {
@@ -348,6 +351,7 @@ class Profiler extends EventEmitter {
348
351
  })
349
352
 
350
353
  if (restart) {
354
+ this.#currentSnapshotTags = getProfilingTags(this.#config)
351
355
  this._capture(this._timeoutInterval, endDate)
352
356
  }
353
357
 
@@ -385,7 +389,7 @@ class Profiler extends EventEmitter {
385
389
  }))
386
390
 
387
391
  if (hasEncoded) {
388
- await this.#submit(encodedProfiles, infos, startDate, endDate, snapshotKind)
392
+ await this.#submit(encodedProfiles, infos, startDate, endDate, snapshotTags, snapshotKind)
389
393
  profileSubmittedChannel.publish()
390
394
  log.debug('Submitted profiles')
391
395
  }
@@ -395,9 +399,15 @@ class Profiler extends EventEmitter {
395
399
  }
396
400
  }
397
401
 
398
- #submit (profiles, infos, start, end, snapshotKind) {
399
- const tags = this.#tags
400
-
402
+ /**
403
+ * @param {Record<string, Buffer|string>} profiles
404
+ * @param {Record<string, unknown>} infos
405
+ * @param {Date} start
406
+ * @param {Date} end
407
+ * @param {Record<string, string|number|boolean|undefined>} snapshotTags
408
+ * @param {string} snapshotKind
409
+ */
410
+ #submit (profiles, infos, start, end, snapshotTags, snapshotKind) {
401
411
  // Flatten endpoint counts
402
412
  const endpointCounts = {}
403
413
  for (const [endpoint, { count }] of this.#endpointCounts) {
@@ -405,12 +415,12 @@ class Profiler extends EventEmitter {
405
415
  }
406
416
  this.#endpointCounts.clear()
407
417
 
408
- tags.snapshot = snapshotKind
409
- tags.profile_seq = this.#profileSeq++
418
+ snapshotTags.snapshot = snapshotKind
419
+ snapshotTags.profile_seq = this.#profileSeq++
410
420
  const customAttributes = this.#customLabelKeys.size > 0
411
421
  ? [...this.#customLabelKeys]
412
422
  : undefined
413
- const exportSpec = { profiles, infos, start, end, tags, endpointCounts, customAttributes }
423
+ const exportSpec = { profiles, infos, start, end, tags: snapshotTags, endpointCounts, customAttributes }
414
424
  const tasks = this.#exporters.map(exporter =>
415
425
  exporter.export(exportSpec).catch(error => {
416
426
  log.warn(error)
@@ -1,5 +1,8 @@
1
1
  'use strict'
2
2
 
3
+ const { channel } = require('dc-polyfill')
4
+
5
+ const log = require('../../log')
3
6
  const { oomExportStrategies, ensureOOMExportStrategies, strategiesToCallbackMode, buildExportCommand } =
4
7
  require('../oom')
5
8
  const { encodeProfileAsync, getThreadLabels } = require('./shared')
@@ -11,10 +14,12 @@ const { encodeProfileAsync, getThreadLabels } = require('./shared')
11
14
  */
12
15
 
13
16
  const STACK_DEPTH = 64
17
+ const identityRefreshChannel = channel('datadog:identity:refresh')
14
18
 
15
19
  class NativeSpaceProfiler {
16
20
  #config
17
21
  #exporters
22
+ #identityRefreshListener
18
23
  #mapper
19
24
  #pprof
20
25
  #samplingInterval
@@ -39,20 +44,36 @@ class NativeSpaceProfiler {
39
44
  start ({ mapper, nearOOMCallback } = {}) {
40
45
  if (this.#started) return
41
46
 
42
- const config = this.#config
43
47
  this.#mapper = mapper
44
48
  this.#pprof = require('@datadog/pprof')
45
- this.#pprof.heap.start(this.#samplingInterval, STACK_DEPTH, config.DD_PROFILING_ALLOCATION_ENABLED)
46
- if (config.DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED) {
49
+ this.#pprof.heap.start(this.#samplingInterval, STACK_DEPTH, this.#config.DD_PROFILING_ALLOCATION_ENABLED)
50
+
51
+ if (this.#config.DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED) {
52
+ const config = this.#config
47
53
  const strategies = ensureOOMExportStrategies(config.DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES)
48
- this.#pprof.heap.monitorOutOfMemory(
49
- config.DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE,
50
- config.DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT,
51
- strategies.includes(oomExportStrategies.LOGS),
52
- strategies.includes(oomExportStrategies.PROCESS) ? buildExportCommand(this.#exporters, this.#tags) : [],
53
- (profile) => nearOOMCallback(this.type, this.#pprof.encodeSync(profile), this.getInfo()),
54
- strategiesToCallbackMode(strategies, this.#pprof.heap.CallbackMode)
55
- )
54
+ const monitorOutOfMemory = () => {
55
+ this.#pprof.heap.monitorOutOfMemory(
56
+ config.DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE,
57
+ config.DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT,
58
+ strategies.includes(oomExportStrategies.LOGS),
59
+ strategies.includes(oomExportStrategies.PROCESS) ? buildExportCommand(this.#exporters, this.#tags) : [],
60
+ (profile) => nearOOMCallback(this.type, this.#pprof.encodeSync(profile), this.getInfo()),
61
+ strategiesToCallbackMode(strategies, this.#pprof.heap.CallbackMode)
62
+ )
63
+ }
64
+ monitorOutOfMemory()
65
+
66
+ if (strategies.includes(oomExportStrategies.PROCESS)) {
67
+ this.#identityRefreshListener = () => {
68
+ try {
69
+ Object.assign(this.#tags, config.tags)
70
+ monitorOutOfMemory()
71
+ } catch (error) {
72
+ log.error(error)
73
+ }
74
+ }
75
+ identityRefreshChannel.subscribe(this.#identityRefreshListener)
76
+ }
56
77
  }
57
78
 
58
79
  this.#started = true
@@ -74,6 +95,12 @@ class NativeSpaceProfiler {
74
95
 
75
96
  stop () {
76
97
  if (!this.#started) return
98
+
99
+ if (this.#identityRefreshListener !== undefined) {
100
+ identityRefreshChannel.unsubscribe(this.#identityRefreshListener)
101
+ this.#identityRefreshListener = undefined
102
+ }
103
+
77
104
  this.#pprof.heap.stop()
78
105
  this.#started = false
79
106
  }
@@ -8,10 +8,13 @@ function isWebServerSpan (tags) {
8
8
  }
9
9
 
10
10
  function endpointNameFromTags (tags) {
11
- return tags[RESOURCE_NAME] || [
12
- tags[HTTP_METHOD],
13
- tags[HTTP_ROUTE],
14
- ].filter(Boolean).join(' ')
11
+ const resource = tags[RESOURCE_NAME]
12
+ if (resource) return resource
13
+
14
+ let endpoint = tags[HTTP_METHOD] || ''
15
+ const route = tags[HTTP_ROUTE]
16
+ if (route) endpoint += endpoint ? ` ${route}` : route
17
+ return endpoint
15
18
  }
16
19
 
17
20
  // The endpoint name a web-server span's tag bag yields changes over the span's
@@ -1,5 +1,7 @@
1
1
  'use strict'
2
2
 
3
+ const { channel } = require('dc-polyfill')
4
+ const uuid = require('../../../vendor/dist/crypto-randomuuid')
3
5
  const NoopProxy = require('./noop/proxy')
4
6
  const DatadogTracer = require('./tracer')
5
7
  const getConfig = require('./config')
@@ -11,7 +13,13 @@ const telemetry = require('./telemetry')
11
13
  const nomenclature = require('./service-naming')
12
14
  const PluginManager = require('./plugin_manager')
13
15
  const NoopDogStatsDClient = require('./noop/dogstatsd')
14
- const { IS_SERVERLESS, initializeServerlessTelemetry, supportsServerlessTelemetryRetention } = require('./serverless')
16
+ const {
17
+ IS_AWS_LAMBDA_MICROVM,
18
+ IS_SERVERLESS,
19
+ NODE_BUNDLES_OPENSSL,
20
+ initializeServerlessTelemetry,
21
+ supportsServerlessTelemetryRetention,
22
+ } = require('./serverless')
15
23
  const { flushServerlessTelemetry, registerTelemetryFlusher } = require('./flush')
16
24
  const processTags = require('./process-tags')
17
25
  const { isTrue } = require('./util')
@@ -48,6 +56,13 @@ function getDynamicInstrumentation () {
48
56
  return dynamicInstrumentation
49
57
  }
50
58
 
59
+ const UUID_POOL_SIZE = 128
60
+
61
+ const BUNDLED_OPENSSL_WARNING = 'This Node.js build bundles its own OpenSSL, so its random number ' +
62
+ 'generator is not reseeded when a MicroVM clone resumes and trace IDs may repeat across clones. ' +
63
+ 'Install Node.js from the Amazon Linux 2023 repositories (for example `dnf install nodejs22`) so it ' +
64
+ 'links the base image\'s snapsafe OpenSSL.'
65
+
51
66
  class LazyModule {
52
67
  constructor (provider) {
53
68
  this.provider = provider
@@ -150,6 +165,10 @@ class Tracer extends NoopProxy {
150
165
  try {
151
166
  const config = getConfig(options) // TODO: support dynamic code config
152
167
 
168
+ if (IS_AWS_LAMBDA_MICROVM) {
169
+ this.#registerMicroVmRunHook(config)
170
+ }
171
+
153
172
  // Add config dependent process tags
154
173
  processTags.initialize(config)
155
174
 
@@ -171,7 +190,7 @@ class Tracer extends NoopProxy {
171
190
 
172
191
  telemetry.start(config, this._pluginManager)
173
192
 
174
- if (config.dogstatsd && !isOfflineTestOptimizationValidation()) {
193
+ if (config.dogstatsd && !config.DD_AGENTLESS_ENABLED && !isOfflineTestOptimizationValidation()) {
175
194
  // Custom Metrics
176
195
  lazyProxy(this, 'dogstatsd', () => require('./dogstatsd').CustomMetrics, config)
177
196
  }
@@ -292,10 +311,10 @@ class Tracer extends NoopProxy {
292
311
  // are lazily configured when the library is imported.
293
312
  this._testApiManualPlugin.configure({ ...config, enabled: true }, false)
294
313
  }
295
- if (config.isCiVisibility && config.DD_AGENTLESS_LOG_SUBMISSION_ENABLED) {
314
+ if (config.DD_AGENTLESS_LOG_SUBMISSION_ENABLED) {
296
315
  if (config.DD_API_KEY) {
297
- const LogSubmissionPlugin = require('./ci-visibility/log-submission/log-submission-plugin')
298
- const automaticLogPlugin = new LogSubmissionPlugin(this)
316
+ const LogSubmissionPlugin = require('./log-submission/log-submission-plugin')
317
+ const automaticLogPlugin = new LogSubmissionPlugin(this, config)
299
318
  automaticLogPlugin.configure({ ...config, enabled: true })
300
319
  } else {
301
320
  log.warn(
@@ -318,6 +337,42 @@ class Tracer extends NoopProxy {
318
337
  return this
319
338
  }
320
339
 
340
+ /**
341
+ * Listens for the MicroVM /run lifecycle event and triggers a one-time
342
+ * identity reset on first fire.
343
+ *
344
+ * @param {import('./config/config-base')} config
345
+ */
346
+ #registerMicroVmRunHook (config) {
347
+ // Node reseeds its CSPRNG from the kernel on clone resume only when it links the base image's
348
+ // snapsafe libcrypto; a bundled OpenSSL keeps the snapshot's DRBG state, so the refresh below
349
+ // cannot produce distinct IDs. Logged at registration, during the image build, where the
350
+ // Dockerfile can still be fixed — not once per clone.
351
+ if (NODE_BUNDLES_OPENSSL) {
352
+ log.error(BUNDLED_OPENSSL_WARNING)
353
+ }
354
+
355
+ const ch = channel('http.server.request.start')
356
+
357
+ const onHttpRequest = ({ request }) => {
358
+ if (request.method === 'POST' && request.url === '/aws/lambda-microvms/runtime/v1/run') {
359
+ ch.unsubscribe(onHttpRequest)
360
+ drainUuidPool()
361
+ channel('datadog:identity:update').publish(config)
362
+ if (this._tracingInitialized) {
363
+ const storeTracerMetadata = require('./tracer_metadata')
364
+ const metadata = storeTracerMetadata(config)
365
+ if (metadata === undefined) {
366
+ log.warn('Could not store tracer configuration for service discovery')
367
+ }
368
+ }
369
+ channel('datadog:identity:refresh').publish(config)
370
+ }
371
+ }
372
+
373
+ ch.subscribe(onHttpRequest)
374
+ }
375
+
321
376
  /**
322
377
  * @param {import('./config/config-base')} config - Tracer configuration
323
378
  */
@@ -515,4 +570,19 @@ function isOfflineValidationExporter (options) {
515
570
  return OFFLINE_VALIDATION_EXPORTERS.has(options?.experimental?.exporter)
516
571
  }
517
572
 
573
+ /**
574
+ * Discards Node's buffered UUID entropy, so the identity subscribers draw from bytes generated
575
+ * after the clone resumed.
576
+ *
577
+ * `crypto.randomUUID()` serves `kBatchSize` (128, see `lib/internal/crypto/random.js`) UUIDs from one
578
+ * process-wide pool and refills it only when its cursor wraps back to 0. A full cycle crosses the
579
+ * cursor exactly once from any starting position, and the position is not observable, so the count
580
+ * has to be the batch size rather than the number of UUIDs we need.
581
+ */
582
+ function drainUuidPool () {
583
+ for (let index = 0; index < UUID_POOL_SIZE; index++) {
584
+ uuid()
585
+ }
586
+ }
587
+
518
588
  module.exports = Tracer