dd-trace 5.102.0 → 5.103.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 (133) hide show
  1. package/ext/exporters.js +1 -0
  2. package/package.json +12 -11
  3. package/packages/datadog-esbuild/src/utils.js +2 -2
  4. package/packages/datadog-instrumentations/src/ai.js +1 -1
  5. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +32 -15
  6. package/packages/datadog-instrumentations/src/couchbase.js +69 -220
  7. package/packages/datadog-instrumentations/src/cucumber.js +1 -1
  8. package/packages/datadog-instrumentations/src/electron/preload.js +42 -0
  9. package/packages/datadog-instrumentations/src/electron.js +240 -0
  10. package/packages/datadog-instrumentations/src/fetch.js +5 -5
  11. package/packages/datadog-instrumentations/src/graphql.js +13 -12
  12. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +1 -1
  13. package/packages/datadog-instrumentations/src/helpers/hook.js +4 -1
  14. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  15. package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -2
  16. package/packages/datadog-instrumentations/src/helpers/kafka.js +41 -0
  17. package/packages/datadog-instrumentations/src/ioredis.js +16 -12
  18. package/packages/datadog-instrumentations/src/jest.js +351 -50
  19. package/packages/datadog-instrumentations/src/kafkajs.js +164 -173
  20. package/packages/datadog-instrumentations/src/mocha/main.js +73 -1
  21. package/packages/datadog-instrumentations/src/mongodb-core.js +33 -8
  22. package/packages/datadog-instrumentations/src/pg.js +24 -10
  23. package/packages/datadog-instrumentations/src/playwright.js +427 -55
  24. package/packages/datadog-instrumentations/src/redis.js +19 -10
  25. package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -21
  26. package/packages/datadog-plugin-aws-sdk/src/base.js +18 -24
  27. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
  28. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -1
  29. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
  30. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
  31. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
  32. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
  33. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -2
  34. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -1
  35. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
  36. package/packages/datadog-plugin-couchbase/src/index.js +58 -52
  37. package/packages/datadog-plugin-cucumber/src/index.js +1 -0
  38. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +214 -22
  39. package/packages/datadog-plugin-cypress/src/support.js +13 -1
  40. package/packages/datadog-plugin-electron/src/index.js +17 -0
  41. package/packages/datadog-plugin-electron/src/ipc.js +143 -0
  42. package/packages/datadog-plugin-electron/src/net.js +82 -0
  43. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +27 -18
  44. package/packages/datadog-plugin-graphql/src/execute.js +6 -28
  45. package/packages/datadog-plugin-graphql/src/resolve.js +30 -35
  46. package/packages/datadog-plugin-graphql/src/tools/signature.js +32 -7
  47. package/packages/datadog-plugin-graphql/src/tools/transforms.js +118 -100
  48. package/packages/datadog-plugin-graphql/src/utils.js +29 -0
  49. package/packages/datadog-plugin-grpc/src/client.js +6 -7
  50. package/packages/datadog-plugin-grpc/src/util.js +57 -22
  51. package/packages/datadog-plugin-http/src/client.js +2 -2
  52. package/packages/datadog-plugin-jest/src/index.js +92 -50
  53. package/packages/datadog-plugin-mocha/src/index.js +1 -0
  54. package/packages/datadog-plugin-mongodb-core/src/index.js +36 -70
  55. package/packages/datadog-plugin-mysql/src/index.js +1 -1
  56. package/packages/datadog-plugin-openai/src/services.js +2 -1
  57. package/packages/datadog-plugin-pg/src/index.js +3 -3
  58. package/packages/datadog-plugin-playwright/src/index.js +4 -0
  59. package/packages/datadog-plugin-redis/src/index.js +18 -23
  60. package/packages/dd-trace/src/aiguard/index.js +3 -1
  61. package/packages/dd-trace/src/aiguard/sdk.js +36 -30
  62. package/packages/dd-trace/src/aiguard/tags.js +20 -11
  63. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -2
  64. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
  65. package/packages/dd-trace/src/azure_metadata.js +17 -6
  66. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +4 -4
  67. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -2
  68. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +6 -4
  69. package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +1 -1
  70. package/packages/dd-trace/src/config/defaults.js +3 -14
  71. package/packages/dd-trace/src/config/generated-config-types.d.ts +3 -1
  72. package/packages/dd-trace/src/config/helper.js +4 -0
  73. package/packages/dd-trace/src/config/index.js +2 -2
  74. package/packages/dd-trace/src/config/major-overrides.js +98 -0
  75. package/packages/dd-trace/src/config/parsers.js +7 -1
  76. package/packages/dd-trace/src/config/supported-configurations.json +51 -38
  77. package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
  78. package/packages/dd-trace/src/datastreams/manager.js +1 -1
  79. package/packages/dd-trace/src/datastreams/processor.js +2 -2
  80. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +2 -2
  81. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
  82. package/packages/dd-trace/src/debugger/devtools_client/state.js +2 -1
  83. package/packages/dd-trace/src/debugger/index.js +7 -7
  84. package/packages/dd-trace/src/dogstatsd.js +2 -2
  85. package/packages/dd-trace/src/encode/0.4.js +45 -54
  86. package/packages/dd-trace/src/encode/0.5.js +34 -3
  87. package/packages/dd-trace/src/encode/agentless-json.js +1 -1
  88. package/packages/dd-trace/src/exporter.js +2 -0
  89. package/packages/dd-trace/src/exporters/agent/index.js +2 -1
  90. package/packages/dd-trace/src/exporters/agentless/index.js +3 -2
  91. package/packages/dd-trace/src/exporters/agentless/writer.js +2 -2
  92. package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -1
  93. package/packages/dd-trace/src/exporters/common/request.js +1 -1
  94. package/packages/dd-trace/src/exporters/electron/index.js +49 -0
  95. package/packages/dd-trace/src/external-logger/src/index.js +2 -1
  96. package/packages/dd-trace/src/git_metadata.js +10 -8
  97. package/packages/dd-trace/src/lambda/handler-paths.js +52 -0
  98. package/packages/dd-trace/src/lambda/index.js +62 -14
  99. package/packages/dd-trace/src/lambda/runtime/patch.js +21 -46
  100. package/packages/dd-trace/src/llmobs/index.js +13 -2
  101. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +45 -15
  102. package/packages/dd-trace/src/llmobs/writers/base.js +2 -1
  103. package/packages/dd-trace/src/openfeature/writers/base.js +2 -1
  104. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +2 -1
  105. package/packages/dd-trace/src/opentracing/propagation/text_map.js +20 -9
  106. package/packages/dd-trace/src/payload-tagging/config/index.js +2 -2
  107. package/packages/dd-trace/src/plugins/ci_plugin.js +49 -4
  108. package/packages/dd-trace/src/plugins/database.js +54 -12
  109. package/packages/dd-trace/src/plugins/index.js +1 -0
  110. package/packages/dd-trace/src/plugins/plugin.js +2 -4
  111. package/packages/dd-trace/src/plugins/util/ci.js +8 -8
  112. package/packages/dd-trace/src/plugins/util/git-cache.js +20 -18
  113. package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -2
  114. package/packages/dd-trace/src/plugins/util/test.js +37 -5
  115. package/packages/dd-trace/src/plugins/util/user-provided-git.js +17 -15
  116. package/packages/dd-trace/src/priority_sampler.js +1 -1
  117. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  118. package/packages/dd-trace/src/profiling/profilers/wall.js +1 -1
  119. package/packages/dd-trace/src/profiling/ssi-heuristics.js +1 -1
  120. package/packages/dd-trace/src/rate_limiter.js +1 -1
  121. package/packages/dd-trace/src/remote_config/scheduler.js +1 -1
  122. package/packages/dd-trace/src/ritm.js +2 -1
  123. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -8
  124. package/packages/dd-trace/src/serverless.js +5 -2
  125. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +20 -0
  126. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
  127. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +20 -0
  128. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
  129. package/packages/dd-trace/src/span_stats.js +1 -1
  130. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  131. package/packages/dd-trace/src/telemetry/endpoints.js +1 -1
  132. package/packages/dd-trace/src/telemetry/telemetry.js +2 -2
  133. package/packages/dd-trace/src/lambda/runtime/ritm.js +0 -133
@@ -11,23 +11,23 @@ const { keepTrace } = require('../priority_sampler')
11
11
  const { AI_GUARD } = require('../standalone/product')
12
12
  const NoopAIGuard = require('./noop')
13
13
  const executeRequest = require('./client')
14
- const {
15
- AI_GUARD_RESOURCE,
16
- AI_GUARD_TARGET_TAG_KEY,
17
- AI_GUARD_REASON_TAG_KEY,
18
- AI_GUARD_ACTION_TAG_KEY,
19
- AI_GUARD_EVENT_TAG_KEY,
20
- AI_GUARD_BLOCKED_TAG_KEY,
21
- AI_GUARD_META_STRUCT_KEY,
22
- AI_GUARD_TOOL_NAME_TAG_KEY,
23
- AI_GUARD_TELEMETRY_REQUESTS,
24
- AI_GUARD_TELEMETRY_TRUNCATED,
25
- } = require('./tags')
14
+ const TAGS = require('./tags')
26
15
 
27
- const appsecMetrics = telemetryMetrics.manager.namespace('appsec')
16
+ const aiguardMetrics = telemetryMetrics.manager.namespace('ai_guard')
28
17
 
29
18
  const ALLOW = 'ALLOW'
30
19
 
20
+ /**
21
+ * Reports a telemetry error
22
+ *
23
+ * @param {string} errorType - The error type constant (client_error, bad_status, bad_response)
24
+ * @param {{ source: string, integration: string }} telemetryTags - Source and integration tags
25
+ */
26
+ function reportTelemetryError (errorType, telemetryTags) {
27
+ aiguardMetrics.count(TAGS.TELEMETRY_REQUESTS, { error: true, ...telemetryTags }).inc(1)
28
+ aiguardMetrics.count(TAGS.TELEMETRY_ERROR, { type: errorType, ...telemetryTags }).inc(1)
29
+ }
30
+
31
31
  class AIGuardAbortError extends Error {
32
32
  constructor (reason, tags, tagProbs, sds) {
33
33
  super(reason)
@@ -99,10 +99,10 @@ class AIGuard extends NoopAIGuard {
99
99
  * - Clones each message so callers cannot mutate the data set in the meta struct.
100
100
  * - Truncates the list of messages and `content` fields emitting metrics accordingly.
101
101
  */
102
- #buildMessagesForMetaStruct (messages) {
102
+ #buildMessagesForMetaStruct (messages, telemetryTags) {
103
103
  const size = Math.min(messages.length, this.#maxMessagesLength)
104
104
  if (messages.length > size) {
105
- appsecMetrics.count(AI_GUARD_TELEMETRY_TRUNCATED, { type: 'messages' }).inc(1)
105
+ aiguardMetrics.count(TAGS.TELEMETRY_TRUNCATED, { type: 'messages', ...telemetryTags }).inc(1)
106
106
  }
107
107
  const result = []
108
108
  let contentTruncated = false
@@ -115,7 +115,7 @@ class AIGuard extends NoopAIGuard {
115
115
  result.push(message)
116
116
  }
117
117
  if (contentTruncated) {
118
- appsecMetrics.count(AI_GUARD_TELEMETRY_TRUNCATED, { type: 'content' }).inc(1)
118
+ aiguardMetrics.count(TAGS.TELEMETRY_TRUNCATED, { type: 'content', ...telemetryTags }).inc(1)
119
119
  }
120
120
  return result
121
121
  }
@@ -185,22 +185,23 @@ class AIGuard extends NoopAIGuard {
185
185
  if (!this.#initialized) {
186
186
  return super.evaluate(messages, opts)
187
187
  }
188
- const { block = true } = opts ?? {}
189
- return this.#tracer.trace(AI_GUARD_RESOURCE, {}, async (span) => {
188
+ const { block = true, source = TAGS.SOURCE_SDK, integration = TAGS.INTEGRATION_NONE } = opts ?? {}
189
+ const telemetryTags = { source, integration }
190
+ return this.#tracer.trace(TAGS.RESOURCE, {}, async (span) => {
190
191
  const last = messages[messages.length - 1]
191
192
  const target = this.#isToolCall(last) ? 'tool' : 'prompt'
192
- span.setTag(AI_GUARD_TARGET_TAG_KEY, target)
193
+ span.setTag(TAGS.TARGET_TAG_KEY, target)
193
194
  if (target === 'tool') {
194
195
  const name = this.#getToolName(last, messages)
195
196
  if (name) {
196
- span.setTag(AI_GUARD_TOOL_NAME_TAG_KEY, name)
197
+ span.setTag(TAGS.TOOL_NAME_TAG_KEY, name)
197
198
  }
198
199
  }
199
200
  const metaStruct = {
200
- messages: this.#buildMessagesForMetaStruct(messages),
201
+ messages: this.#buildMessagesForMetaStruct(messages, telemetryTags),
201
202
  }
202
203
  span.meta_struct = {
203
- [AI_GUARD_META_STRUCT_KEY]: metaStruct,
204
+ [TAGS.META_STRUCT_KEY]: metaStruct,
204
205
  }
205
206
  const rootSpan = span.context()?._trace?.started?.[0]
206
207
  if (rootSpan) {
@@ -208,7 +209,7 @@ class AIGuard extends NoopAIGuard {
208
209
  // keepTrace must be called before executeRequest so the sampling decision
209
210
  // is propagated correctly to outgoing HTTP client calls.
210
211
  keepTrace(rootSpan, AI_GUARD)
211
- rootSpan.setTag(AI_GUARD_EVENT_TAG_KEY, 'true')
212
+ rootSpan.setTag(TAGS.EVENT_TAG_KEY, 'true')
212
213
  }
213
214
  let response
214
215
  try {
@@ -224,18 +225,18 @@ class AIGuard extends NoopAIGuard {
224
225
  payload,
225
226
  { url: this.#evaluateUrl, headers: this.#headers, timeout: this.#timeout })
226
227
  } catch (e) {
227
- appsecMetrics.count(AI_GUARD_TELEMETRY_REQUESTS, { error: true }).inc(1)
228
+ reportTelemetryError(TAGS.ERROR_TYPE_CLIENT, telemetryTags)
228
229
  throw new AIGuardClientError(`Unexpected error calling AI Guard service: ${e.message}`, { cause: e })
229
230
  }
230
231
  if (response.status !== 200) {
231
- appsecMetrics.count(AI_GUARD_TELEMETRY_REQUESTS, { error: true }).inc(1)
232
+ reportTelemetryError(TAGS.ERROR_TYPE_STATUS, telemetryTags)
232
233
  throw new AIGuardClientError(
233
234
  `AI Guard service call failed, status ${response.status}`,
234
235
  { errors: response.body?.errors })
235
236
  }
236
237
  const attr = response.body?.data?.attributes
237
238
  if (!attr?.action) {
238
- appsecMetrics.count(AI_GUARD_TELEMETRY_REQUESTS, { error: true }).inc(1)
239
+ reportTelemetryError(TAGS.ERROR_TYPE_RESPONSE, telemetryTags)
239
240
  throw new AIGuardClientError(`AI Guard service returned unexpected response : ${response.body}`)
240
241
  }
241
242
  const action = attr.action
@@ -254,13 +255,18 @@ class AIGuard extends NoopAIGuard {
254
255
  }
255
256
  const blockingEnabled = attr.is_blocking_enabled ?? false
256
257
  const shouldBlock = block && blockingEnabled && action !== ALLOW
257
- appsecMetrics.count(AI_GUARD_TELEMETRY_REQUESTS, { action, error: false, block: shouldBlock }).inc(1)
258
- span.setTag(AI_GUARD_ACTION_TAG_KEY, action)
258
+ aiguardMetrics.count(TAGS.TELEMETRY_REQUESTS, {
259
+ action,
260
+ error: false,
261
+ block: shouldBlock,
262
+ ...telemetryTags,
263
+ }).inc(1)
264
+ span.setTag(TAGS.ACTION_TAG_KEY, action)
259
265
  if (reason) {
260
- span.setTag(AI_GUARD_REASON_TAG_KEY, reason)
266
+ span.setTag(TAGS.REASON_TAG_KEY, reason)
261
267
  }
262
268
  if (shouldBlock) {
263
- span.setTag(AI_GUARD_BLOCKED_TAG_KEY, 'true')
269
+ span.setTag(TAGS.BLOCKED_TAG_KEY, 'true')
264
270
  throw new AIGuardAbortError(reason, tags, tagProbabilities, sdsFindings)
265
271
  }
266
272
  return { action, reason, tags, tagProbabilities, sds: sdsFindings }
@@ -1,15 +1,24 @@
1
1
  'use strict'
2
2
 
3
3
  module.exports = {
4
- AI_GUARD_RESOURCE: 'ai_guard',
5
- AI_GUARD_TARGET_TAG_KEY: 'ai_guard.target',
6
- AI_GUARD_TOOL_NAME_TAG_KEY: 'ai_guard.tool_name',
7
- AI_GUARD_ACTION_TAG_KEY: 'ai_guard.action',
8
- AI_GUARD_REASON_TAG_KEY: 'ai_guard.reason',
9
- AI_GUARD_BLOCKED_TAG_KEY: 'ai_guard.blocked',
10
- AI_GUARD_EVENT_TAG_KEY: 'ai_guard.event',
11
- AI_GUARD_META_STRUCT_KEY: 'ai_guard',
12
-
13
- AI_GUARD_TELEMETRY_REQUESTS: 'ai_guard.requests',
14
- AI_GUARD_TELEMETRY_TRUNCATED: 'ai_guard.truncated',
4
+ RESOURCE: 'ai_guard',
5
+ TARGET_TAG_KEY: 'ai_guard.target',
6
+ TOOL_NAME_TAG_KEY: 'ai_guard.tool_name',
7
+ ACTION_TAG_KEY: 'ai_guard.action',
8
+ REASON_TAG_KEY: 'ai_guard.reason',
9
+ BLOCKED_TAG_KEY: 'ai_guard.blocked',
10
+ EVENT_TAG_KEY: 'ai_guard.event',
11
+ META_STRUCT_KEY: 'ai_guard',
12
+
13
+ TELEMETRY_REQUESTS: 'requests',
14
+ TELEMETRY_TRUNCATED: 'truncated',
15
+ TELEMETRY_ERROR: 'error',
16
+
17
+ SOURCE_SDK: 'sdk',
18
+ SOURCE_AUTO: 'auto',
19
+ INTEGRATION_NONE: 'none',
20
+
21
+ ERROR_TYPE_CLIENT: 'client_error',
22
+ ERROR_TYPE_STATUS: 'bad_status',
23
+ ERROR_TYPE_RESPONSE: 'bad_response',
15
24
  }
@@ -208,8 +208,8 @@ let enableEsmRewriter = function (telemetryVerbosity) {
208
208
  }
209
209
  })
210
210
 
211
- port1.unref()
212
- port2.unref()
211
+ port1.unref?.()
212
+ port2.unref?.()
213
213
 
214
214
  try {
215
215
  Module.register('./rewriter-esm.mjs', {
@@ -100,7 +100,7 @@ function clearCache () { // only for test purposes
100
100
 
101
101
  function startClearCacheTimer () {
102
102
  resetVulnerabilityCacheTimer = setInterval(clearCache, RESET_VULNERABILITY_CACHE_INTERVAL)
103
- resetVulnerabilityCacheTimer.unref()
103
+ resetVulnerabilityCacheTimer.unref?.()
104
104
  }
105
105
 
106
106
  function stopClearCacheTimer () {
@@ -3,10 +3,8 @@
3
3
  // Modeled after https://github.com/DataDog/libdatadog/blob/f3994857a59bb5679a65967138c5a3aec418a65f/ddcommon/src/azure_app_services.rs
4
4
 
5
5
  const os = require('os')
6
- const {
7
- getEnvironmentVariable,
8
- getValueFromEnvSources,
9
- } = require('./config/helper')
6
+ const getConfig = require('./config')
7
+ const { getEnvironmentVariable } = require('./config/helper')
10
8
  const { getIsAzureFunction } = require('./serverless')
11
9
 
12
10
  function extractSubscriptionID (ownerName) {
@@ -19,7 +17,20 @@ function extractSubscriptionID (ownerName) {
19
17
  }
20
18
 
21
19
  function extractResourceGroup (ownerName) {
22
- return /.+\+(.+)-.+webspace(-Linux)?/.exec(ownerName)?.[1]
20
+ // WEBSITE_OWNER_NAME format: `<sub-id>+<rg>-<region>webspace[-Linux]`. Region
21
+ // names have no `-`; resource groups can. Plain string ops read more directly
22
+ // than `/.+\+(.+)-.+webspace(-Linux)?/` and avoid the engine backtracking
23
+ // through three `.+` quantifiers to land on the right `-`.
24
+ if (typeof ownerName !== 'string') return
25
+ const plusIdx = ownerName.indexOf('+')
26
+ if (plusIdx === -1) return
27
+ let rest = ownerName.slice(plusIdx + 1)
28
+ if (rest.endsWith('-Linux')) rest = rest.slice(0, -'-Linux'.length)
29
+ if (!rest.endsWith('webspace')) return
30
+ rest = rest.slice(0, -'webspace'.length)
31
+ const lastDash = rest.lastIndexOf('-')
32
+ if (lastDash === -1) return
33
+ return rest.slice(0, lastDash)
23
34
  }
24
35
 
25
36
  function buildResourceID (subscriptionID, siteName, resourceGroup) {
@@ -56,7 +67,7 @@ function buildMetadata () {
56
67
  const WEBSITE_SITE_NAME = getEnvironmentVariable('WEBSITE_SITE_NAME')
57
68
  const WEBSITE_SKU = getEnvironmentVariable('WEBSITE_SKU')
58
69
 
59
- const DD_AZURE_RESOURCE_GROUP = getValueFromEnvSources('DD_AZURE_RESOURCE_GROUP')
70
+ const { DD_AZURE_RESOURCE_GROUP } = getConfig()
60
71
  const isAzureFunction = FUNCTIONS_EXTENSION_VERSION !== undefined && FUNCTIONS_WORKER_RUNTIME !== undefined
61
72
  const isFlexConsumptionAzureFunction = isAzureFunction && WEBSITE_SKU === 'FlexConsumption'
62
73
 
@@ -120,7 +120,7 @@ class TestVisDynamicInstrumentation {
120
120
  })
121
121
 
122
122
  // Allow the parent to exit even if the worker is still running
123
- this.worker.unref()
123
+ this.worker.unref?.()
124
124
 
125
125
  this.breakpointSetChannel.port2.on('message', (probeId) => {
126
126
  const resolve = probeIdToResolveBreakpointSet.get(probeId)
@@ -128,7 +128,7 @@ class TestVisDynamicInstrumentation {
128
128
  resolve()
129
129
  probeIdToResolveBreakpointSet.delete(probeId)
130
130
  }
131
- }).unref()
131
+ }).unref?.()
132
132
 
133
133
  this.breakpointHitChannel.port2.on('message', ({ snapshot }) => {
134
134
  const { probe: { id: probeId } } = snapshot
@@ -138,7 +138,7 @@ class TestVisDynamicInstrumentation {
138
138
  } else {
139
139
  log.warn('Received a breakpoint hit for an unknown probe')
140
140
  }
141
- }).unref()
141
+ }).unref?.()
142
142
 
143
143
  this.breakpointRemoveChannel.port2.on('message', (probeId) => {
144
144
  const resolve = probeIdToResolveBreakpointRemove.get(probeId)
@@ -146,7 +146,7 @@ class TestVisDynamicInstrumentation {
146
146
  resolve()
147
147
  probeIdToResolveBreakpointRemove.delete(probeId)
148
148
  }
149
- }).unref()
149
+ }).unref?.()
150
150
  }
151
151
  }
152
152
 
@@ -48,11 +48,13 @@ class CiVisibilityExporter extends BufferingExporter {
48
48
 
49
49
  const gitUploadTimeoutId = setTimeout(() => {
50
50
  this._resolveGit(new Error('Timeout while uploading git metadata'))
51
- }, GIT_UPLOAD_TIMEOUT).unref()
51
+ }, GIT_UPLOAD_TIMEOUT)
52
+ gitUploadTimeoutId.unref?.()
52
53
 
53
54
  const canUseCiVisProtocolTimeoutId = setTimeout(() => {
54
55
  this._resolveCanUseCiVisProtocol(false)
55
- }, CAN_USE_CI_VIS_PROTOCOL_TIMEOUT).unref()
56
+ }, CAN_USE_CI_VIS_PROTOCOL_TIMEOUT)
57
+ canUseCiVisProtocolTimeoutId.unref?.()
56
58
 
57
59
  this._gitUploadPromise = new Promise(resolve => {
58
60
  this._resolveGit = (err) => {
@@ -11,10 +11,12 @@ const {
11
11
  VITEST_WORKER_TRACE_PAYLOAD_CODE,
12
12
  VITEST_WORKER_LOGS_PAYLOAD_CODE,
13
13
  } = require('../../../plugins/util/test')
14
- const { getEnvironmentVariable, getValueFromEnvSources } = require('../../../config/helper')
14
+ const getConfig = require('../../../config')
15
+ const { getEnvironmentVariable } = require('../../../config/helper')
15
16
  const Writer = require('./writer')
16
17
 
17
18
  function getInterprocessTraceCode () {
19
+ const { DD_PLAYWRIGHT_WORKER, DD_VITEST_WORKER } = getConfig()
18
20
  if (getEnvironmentVariable('JEST_WORKER_ID')) {
19
21
  return JEST_WORKER_TRACE_PAYLOAD_CODE
20
22
  }
@@ -24,13 +26,13 @@ function getInterprocessTraceCode () {
24
26
  if (getEnvironmentVariable('MOCHA_WORKER_ID')) {
25
27
  return MOCHA_WORKER_TRACE_PAYLOAD_CODE
26
28
  }
27
- if (getValueFromEnvSources('DD_PLAYWRIGHT_WORKER')) {
29
+ if (DD_PLAYWRIGHT_WORKER) {
28
30
  return PLAYWRIGHT_WORKER_TRACE_PAYLOAD_CODE
29
31
  }
30
32
  if (getEnvironmentVariable('TINYPOOL_WORKER_ID')) {
31
33
  return VITEST_WORKER_TRACE_PAYLOAD_CODE
32
34
  }
33
- if (getValueFromEnvSources('DD_VITEST_WORKER')) {
35
+ if (DD_VITEST_WORKER) {
34
36
  return VITEST_WORKER_TRACE_PAYLOAD_CODE
35
37
  }
36
38
  return null
@@ -51,7 +53,7 @@ function getInterprocessLogsCode () {
51
53
  if (getEnvironmentVariable('TINYPOOL_WORKER_ID')) {
52
54
  return VITEST_WORKER_LOGS_PAYLOAD_CODE
53
55
  }
54
- if (getValueFromEnvSources('DD_VITEST_WORKER')) {
56
+ if (getConfig().DD_VITEST_WORKER) {
55
57
  return VITEST_WORKER_LOGS_PAYLOAD_CODE
56
58
  }
57
59
  return null
@@ -149,7 +149,7 @@ function touchLock (cacheKey) {
149
149
  */
150
150
  function startLockHeartbeat (cacheKey) {
151
151
  const interval = setInterval(() => touchLock(cacheKey), CACHE_LOCK_HEARTBEAT_MS)
152
- interval.unref()
152
+ interval.unref?.()
153
153
  return () => {
154
154
  clearInterval(interval)
155
155
  try { fs.unlinkSync(getLockPath(cacheKey)) } catch { /* ignore */ }
@@ -5,29 +5,18 @@ const util = require('util')
5
5
 
6
6
  const { DD_MAJOR } = require('../../../../version')
7
7
  const { parsers, transformers, telemetryTransformers, setWarnInvalidValue } = require('./parsers')
8
+ const applyMajorOverrides = require('./major-overrides')
8
9
  const {
9
10
  supportedConfigurations,
10
11
  } = /** @type {import('./helper').SupportedConfigurationsJson} */ (require('./supported-configurations.json'))
11
12
 
13
+ applyMajorOverrides(supportedConfigurations, DD_MAJOR)
14
+
12
15
  let log
13
16
  let seqId = 0
14
17
  const configWithOrigin = new Map()
15
18
  const parseErrors = new Map()
16
19
 
17
- if (DD_MAJOR >= 6) {
18
- // Programmatic configuration of DD_IAST_SECURITY_CONTROLS_CONFIGURATION is not supported
19
- // in newer major versions. This is special handled here until a better solution is found.
20
- // TODO: Remove the programmatic configuration from supported-configurations.json once v5 is not supported anymore.
21
- supportedConfigurations.DD_IAST_SECURITY_CONTROLS_CONFIGURATION[0].internalPropertyName =
22
- supportedConfigurations.DD_IAST_SECURITY_CONTROLS_CONFIGURATION[0].configurationNames?.[0]
23
- delete supportedConfigurations.DD_IAST_SECURITY_CONTROLS_CONFIGURATION[0].configurationNames
24
- } else {
25
- // Default value for DD_TRACE_STARTUP_LOGS is 'false' in older major versions.
26
- // This is special handled here until a better solution is found.
27
- // TODO: Remove this here once v5 is not supported anymore.
28
- supportedConfigurations.DD_TRACE_STARTUP_LOGS[0].default = 'false'
29
- }
30
-
31
20
  /**
32
21
  * Warns about an invalid value for an option and adds the error to the last telemetry entry if it is not already set.
33
22
  * Logging happens only if the error is not already set or the option name is different from the last telemetry entry.
@@ -85,11 +85,12 @@ export interface GeneratedConfig {
85
85
  DD_CIVISIBILITY_TEST_MODULE_ID: string | undefined;
86
86
  DD_CIVISIBILITY_TEST_SESSION_ID: string | undefined;
87
87
  DD_CRASHTRACKING_ENABLED: boolean;
88
+ DD_CUSTOM_PARENT_ID: string | undefined;
88
89
  DD_CUSTOM_TRACE_ID: string | undefined;
89
90
  DD_ENABLE_LAGE_PACKAGE_NAME: boolean;
90
91
  DD_ENABLE_NX_SERVICE_NAME: boolean;
91
92
  DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED: boolean;
92
- DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_DIR: string;
93
+ DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_DIR: string | undefined;
93
94
  DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_ENABLED: boolean;
94
95
  DD_EXPERIMENTAL_TEST_OPT_SETTINGS_CACHE: string;
95
96
  DD_EXPERIMENTAL_TEST_REQUESTS_FS_CACHE: boolean;
@@ -243,6 +244,7 @@ export interface GeneratedConfig {
243
244
  DD_TRACE_ELASTIC_ELASTICSEARCH_ENABLED: boolean;
244
245
  DD_TRACE_ELASTIC_TRANSPORT_ENABLED: boolean;
245
246
  DD_TRACE_ELASTICSEARCH_ENABLED: boolean;
247
+ DD_TRACE_ELECTRON_ENABLED: boolean;
246
248
  DD_TRACE_ENCODING_DEBUG: boolean;
247
249
  DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED: boolean;
248
250
  DD_TRACE_EXPERIMENTAL_SPAN_COUNTS: boolean;
@@ -21,10 +21,14 @@
21
21
  */
22
22
 
23
23
  const { deprecate } = require('util')
24
+ const { DD_MAJOR } = require('../../../../version')
25
+ const applyMajorOverrides = require('./major-overrides')
24
26
  const {
25
27
  supportedConfigurations,
26
28
  } = /** @type {SupportedConfigurationsJson} */ (require('./supported-configurations.json'))
27
29
 
30
+ applyMajorOverrides(supportedConfigurations, DD_MAJOR)
31
+
28
32
  /**
29
33
  * Types for environment variable handling.
30
34
  *
@@ -165,7 +165,7 @@ class Config extends ConfigBase {
165
165
  }
166
166
 
167
167
  /**
168
- * @param {TracerOptions} [options={}]
168
+ * @param {TracerOptions} [options]
169
169
  */
170
170
  constructor (options = {}) {
171
171
  super()
@@ -357,7 +357,7 @@ class Config extends ConfigBase {
357
357
  setAndTrack(this, 'DD_METRICS_OTEL_ENABLED', false)
358
358
  }
359
359
 
360
- if (this.OTEL_TRACES_EXPORTER === 'otlp' && this.protocolVersion && this.protocolVersion !== '0.4') {
360
+ if (this.OTEL_TRACES_EXPORTER === 'otlp' && trackedConfigOrigins.has('protocolVersion')) {
361
361
  log.warn('DD_TRACE_AGENT_PROTOCOL_VERSION is set, disabling OTLP traces export')
362
362
  setAndTrack(this, 'OTEL_TRACES_EXPORTER', 'none')
363
363
  }
@@ -0,0 +1,98 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * @typedef {import('./helper').SupportedConfigurationsJson['supportedConfigurations']} SupportedConfigurations
5
+ */
6
+
7
+ const EXPERIMENTAL_APPSEC_PREFIX = 'experimental.appsec'
8
+ const EXPERIMENTAL_IAST_PREFIX = 'experimental.iast'
9
+ const INGESTION_PREFIX = 'ingestion.'
10
+
11
+ /**
12
+ * @param {SupportedConfigurations} supportedConfigurations Mutated in place.
13
+ * @param {number} majorVersion
14
+ */
15
+ function applyMajorOverrides (supportedConfigurations, majorVersion) {
16
+ if (majorVersion < 6) {
17
+ applyV5Overrides(supportedConfigurations)
18
+ return
19
+ }
20
+
21
+ for (const entries of Object.values(supportedConfigurations)) {
22
+ for (const entry of entries) {
23
+ if (Array.isArray(entry.configurationNames)) {
24
+ entry.configurationNames = entry.configurationNames.filter(
25
+ (name) =>
26
+ name !== EXPERIMENTAL_APPSEC_PREFIX &&
27
+ name !== EXPERIMENTAL_IAST_PREFIX &&
28
+ !name.startsWith(`${EXPERIMENTAL_APPSEC_PREFIX}.`) &&
29
+ !name.startsWith(`${EXPERIMENTAL_IAST_PREFIX}.`) &&
30
+ !name.startsWith(INGESTION_PREFIX)
31
+ )
32
+ if (entry.configurationNames.length === 0) delete entry.configurationNames
33
+ }
34
+ }
35
+ }
36
+ delete supportedConfigurations.DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED
37
+ delete supportedConfigurations.DD_TRACE_EXPERIMENTAL_B3_ENABLED
38
+
39
+ /* eslint-disable eslint-rules/eslint-env-aliases */
40
+ for (const name of [
41
+ 'DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED',
42
+ 'DD_PROFILING_EXPERIMENTAL_CPU_ENABLED',
43
+ 'DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED',
44
+ 'DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED',
45
+ ]) {
46
+ delete supportedConfigurations[name]
47
+ }
48
+ /* eslint-enable eslint-rules/eslint-env-aliases */
49
+ for (const canonical of [
50
+ 'DD_PROFILING_CODEHOTSPOTS_ENABLED',
51
+ 'DD_PROFILING_CPU_ENABLED',
52
+ 'DD_PROFILING_ENDPOINT_COLLECTION_ENABLED',
53
+ 'DD_PROFILING_TIMELINE_ENABLED',
54
+ ]) {
55
+ dropAlias(supportedConfigurations[canonical], (alias) => alias.startsWith('DD_PROFILING_EXPERIMENTAL_'))
56
+ }
57
+
58
+ delete supportedConfigurations.DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED
59
+ // eslint-disable-next-line eslint-rules/eslint-env-aliases
60
+ dropAlias(supportedConfigurations.DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED, 'DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED')
61
+ }
62
+
63
+ /**
64
+ * @param {SupportedConfigurations} supportedConfigurations Mutated in place.
65
+ */
66
+ function applyV5Overrides (supportedConfigurations) {
67
+ const startupLogsEntry = supportedConfigurations.DD_TRACE_STARTUP_LOGS?.[0]
68
+ if (startupLogsEntry) {
69
+ startupLogsEntry.default = 'false'
70
+ }
71
+
72
+ const iastEntry = supportedConfigurations.DD_IAST_SECURITY_CONTROLS_CONFIGURATION?.[0]
73
+ if (!iastEntry) return
74
+
75
+ iastEntry.configurationNames = [
76
+ iastEntry.internalPropertyName || iastEntry.configurationNames?.[0],
77
+ `${EXPERIMENTAL_IAST_PREFIX}.securityControlsConfiguration`,
78
+ ]
79
+ delete iastEntry.internalPropertyName
80
+ }
81
+
82
+ /**
83
+ * @param {import('./helper').SupportedConfigurationEntry[] | undefined} entries
84
+ * @param {string | ((alias: string) => boolean)} dropPredicate
85
+ */
86
+ function dropAlias (entries, dropPredicate) {
87
+ const entry = entries?.[0]
88
+ if (entry?.aliases === undefined) return
89
+ const matches = typeof dropPredicate === 'string'
90
+ ? (alias) => alias === dropPredicate
91
+ : dropPredicate
92
+ entry.aliases = entry.aliases.filter((alias) => !matches(alias))
93
+ if (entry.aliases.length === 0) {
94
+ delete entry.aliases
95
+ }
96
+ }
97
+
98
+ module.exports = applyMajorOverrides
@@ -2,6 +2,7 @@
2
2
 
3
3
  const fs = require('fs')
4
4
 
5
+ const { DD_MAJOR } = require('../../../../version')
5
6
  const tagger = require('../tagger')
6
7
 
7
8
  let warnInvalidValue
@@ -9,6 +10,7 @@ function setWarnInvalidValue (fn) {
9
10
  warnInvalidValue = fn
10
11
  }
11
12
 
13
+ // `'b3 single header'` is the legacy spelling of `'b3'`; on v6 it is normalised below.
12
14
  const VALID_PROPAGATION_STYLES = new Set([
13
15
  'datadog', 'tracecontext', 'b3', 'b3 single header', 'b3multi', 'baggage', 'none',
14
16
  ])
@@ -145,11 +147,15 @@ const transformers = {
145
147
  },
146
148
  validatePropagationStyles (value, optionName) {
147
149
  value = transformers.toLowerCase(value)
148
- for (const propagator of value) {
150
+ for (let index = 0; index < value.length; index++) {
151
+ const propagator = value[index]
149
152
  if (!VALID_PROPAGATION_STYLES.has(propagator)) {
150
153
  warnInvalidValue(propagator, optionName, optionName, 'Invalid propagator')
151
154
  return
152
155
  }
156
+ if (DD_MAJOR >= 6 && propagator === 'b3 single header') {
157
+ value[index] = 'b3'
158
+ }
153
159
  }
154
160
  return value
155
161
  },