dd-trace 5.54.0 → 5.56.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 (191) hide show
  1. package/LICENSE-3rdparty.csv +1 -0
  2. package/ci/cypress/plugin.js +8 -0
  3. package/ci/cypress/polyfills.js +23 -0
  4. package/ci/init.js +8 -7
  5. package/initialize.mjs +2 -2
  6. package/package.json +10 -9
  7. package/packages/datadog-code-origin/index.js +22 -4
  8. package/packages/datadog-core/src/utils/src/kebabcase.js +3 -3
  9. package/packages/datadog-core/src/utils/src/set.js +8 -10
  10. package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -6
  11. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +2 -3
  12. package/packages/datadog-instrumentations/src/cookie-parser.js +1 -1
  13. package/packages/datadog-instrumentations/src/couchbase.js +3 -6
  14. package/packages/datadog-instrumentations/src/cucumber.js +21 -28
  15. package/packages/datadog-instrumentations/src/dns.js +4 -4
  16. package/packages/datadog-instrumentations/src/elasticsearch.js +9 -10
  17. package/packages/datadog-instrumentations/src/fastify.js +7 -9
  18. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +14 -16
  19. package/packages/datadog-instrumentations/src/hapi.js +10 -11
  20. package/packages/datadog-instrumentations/src/helpers/fetch.js +4 -5
  21. package/packages/datadog-instrumentations/src/helpers/hook.js +1 -2
  22. package/packages/datadog-instrumentations/src/helpers/register.js +6 -5
  23. package/packages/datadog-instrumentations/src/jest.js +421 -376
  24. package/packages/datadog-instrumentations/src/koa.js +2 -3
  25. package/packages/datadog-instrumentations/src/mariadb.js +11 -4
  26. package/packages/datadog-instrumentations/src/mocha/main.js +79 -75
  27. package/packages/datadog-instrumentations/src/mocha.js +3 -1
  28. package/packages/datadog-instrumentations/src/mysql.js +11 -2
  29. package/packages/datadog-instrumentations/src/nyc.js +2 -1
  30. package/packages/datadog-instrumentations/src/openai.js +2 -2
  31. package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -3
  32. package/packages/datadog-instrumentations/src/pg.js +2 -3
  33. package/packages/datadog-instrumentations/src/playwright.js +19 -22
  34. package/packages/datadog-instrumentations/src/protobufjs.js +3 -4
  35. package/packages/datadog-instrumentations/src/redis.js +1 -1
  36. package/packages/datadog-instrumentations/src/restify.js +9 -13
  37. package/packages/datadog-instrumentations/src/router.js +12 -11
  38. package/packages/datadog-instrumentations/src/tedious.js +1 -2
  39. package/packages/datadog-instrumentations/src/vitest.js +15 -29
  40. package/packages/datadog-plugin-avsc/src/schema_iterator.js +12 -12
  41. package/packages/datadog-plugin-aws-sdk/src/base.js +12 -8
  42. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +3 -5
  43. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +12 -20
  44. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -5
  45. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +3 -5
  46. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +3 -5
  47. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +3 -5
  48. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -2
  49. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +7 -10
  50. package/packages/datadog-plugin-azure-functions/src/index.js +5 -4
  51. package/packages/datadog-plugin-cucumber/src/index.js +3 -2
  52. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -1
  53. package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -1
  54. package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
  55. package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +1 -1
  56. package/packages/datadog-plugin-graphql/src/index.js +3 -2
  57. package/packages/datadog-plugin-graphql/src/resolve.js +17 -10
  58. package/packages/datadog-plugin-http/src/client.js +5 -6
  59. package/packages/datadog-plugin-http2/src/client.js +7 -8
  60. package/packages/datadog-plugin-jest/src/index.js +3 -2
  61. package/packages/datadog-plugin-mocha/src/index.js +6 -1
  62. package/packages/datadog-plugin-mongodb-core/src/index.js +2 -1
  63. package/packages/datadog-plugin-mysql/src/index.js +11 -0
  64. package/packages/datadog-plugin-next/src/index.js +1 -1
  65. package/packages/datadog-plugin-openai/src/tracing.js +2 -4
  66. package/packages/datadog-plugin-oracledb/src/index.js +2 -1
  67. package/packages/datadog-plugin-playwright/src/index.js +3 -2
  68. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +8 -9
  69. package/packages/datadog-plugin-redis/src/index.js +1 -3
  70. package/packages/datadog-plugin-vitest/src/index.js +5 -4
  71. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +0 -1
  72. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +0 -1
  73. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +0 -1
  74. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +0 -1
  75. package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +1 -2
  76. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
  77. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +12 -13
  78. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +44 -1
  79. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +2 -1
  80. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +8 -3
  81. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -1
  82. package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +1 -1
  83. package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +1 -2
  84. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +10 -11
  85. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +0 -4
  86. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +0 -1
  87. package/packages/dd-trace/src/appsec/index.js +16 -5
  88. package/packages/dd-trace/src/appsec/reporter.js +11 -11
  89. package/packages/dd-trace/src/appsec/sdk/set_user.js +2 -2
  90. package/packages/dd-trace/src/appsec/sdk/track_event.js +3 -3
  91. package/packages/dd-trace/src/appsec/telemetry/index.js +31 -1
  92. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +6 -2
  93. package/packages/dd-trace/src/azure_metadata.js +8 -3
  94. package/packages/dd-trace/src/baggage.js +2 -2
  95. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +8 -7
  96. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -1
  97. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -1
  98. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -1
  99. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -1
  100. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +4 -3
  101. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +7 -6
  102. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -1
  103. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -3
  104. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -3
  105. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -1
  106. package/packages/dd-trace/src/config-helper.js +89 -0
  107. package/packages/dd-trace/src/config.js +120 -115
  108. package/packages/dd-trace/src/config_stable.js +7 -4
  109. package/packages/dd-trace/src/datastreams/fnv.js +1 -1
  110. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +6 -6
  111. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +1 -2
  112. package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -2
  113. package/packages/dd-trace/src/debugger/devtools_client/index.js +2 -1
  114. package/packages/dd-trace/src/debugger/devtools_client/send.js +8 -3
  115. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +1 -2
  116. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +3 -4
  117. package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +1 -1
  118. package/packages/dd-trace/src/debugger/devtools_client/status.js +5 -1
  119. package/packages/dd-trace/src/debugger/index.js +1 -0
  120. package/packages/dd-trace/src/dogstatsd.js +2 -2
  121. package/packages/dd-trace/src/encode/0.4.js +5 -2
  122. package/packages/dd-trace/src/encode/0.5.js +3 -5
  123. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +5 -5
  124. package/packages/dd-trace/src/exporter.js +2 -1
  125. package/packages/dd-trace/src/exporters/agent/writer.js +3 -1
  126. package/packages/dd-trace/src/exporters/common/docker.js +3 -2
  127. package/packages/dd-trace/src/exporters/common/request.js +4 -1
  128. package/packages/dd-trace/src/exporters/common/util.js +3 -1
  129. package/packages/dd-trace/src/id.js +3 -3
  130. package/packages/dd-trace/src/index.js +4 -3
  131. package/packages/dd-trace/src/lambda/handler.js +2 -1
  132. package/packages/dd-trace/src/lambda/index.js +2 -1
  133. package/packages/dd-trace/src/lambda/runtime/patch.js +3 -2
  134. package/packages/dd-trace/src/lambda/runtime/ritm.js +3 -2
  135. package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
  136. package/packages/dd-trace/src/llmobs/index.js +21 -5
  137. package/packages/dd-trace/src/llmobs/noop.js +18 -20
  138. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +11 -13
  139. package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -2
  140. package/packages/dd-trace/src/llmobs/sdk.js +2 -1
  141. package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
  142. package/packages/dd-trace/src/llmobs/tagger.js +19 -6
  143. package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
  144. package/packages/dd-trace/src/log/index.js +5 -4
  145. package/packages/dd-trace/src/log/writer.js +1 -2
  146. package/packages/dd-trace/src/msgpack/encoder.js +3 -3
  147. package/packages/dd-trace/src/noop/span.js +1 -1
  148. package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
  149. package/packages/dd-trace/src/opentracing/propagation/log.js +4 -5
  150. package/packages/dd-trace/src/opentracing/propagation/text_map.js +35 -42
  151. package/packages/dd-trace/src/opentracing/span.js +7 -6
  152. package/packages/dd-trace/src/payload-tagging/config/index.js +17 -21
  153. package/packages/dd-trace/src/plugin_manager.js +4 -3
  154. package/packages/dd-trace/src/plugins/ci_plugin.js +25 -1
  155. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  156. package/packages/dd-trace/src/plugins/util/ci.js +7 -7
  157. package/packages/dd-trace/src/plugins/util/git.js +1 -1
  158. package/packages/dd-trace/src/plugins/util/llm.js +2 -2
  159. package/packages/dd-trace/src/plugins/util/stacktrace.js +8 -1
  160. package/packages/dd-trace/src/plugins/util/test.js +4 -3
  161. package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -1
  162. package/packages/dd-trace/src/plugins/util/web.js +3 -4
  163. package/packages/dd-trace/src/priority_sampler.js +46 -35
  164. package/packages/dd-trace/src/profiling/config.js +12 -32
  165. package/packages/dd-trace/src/profiling/exporter_cli.js +20 -20
  166. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  167. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +2 -1
  168. package/packages/dd-trace/src/profiling/index.js +2 -1
  169. package/packages/dd-trace/src/profiling/profiler.js +7 -4
  170. package/packages/dd-trace/src/profiling/profilers/events.js +10 -2
  171. package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +3 -1
  172. package/packages/dd-trace/src/profiling/tagger.js +22 -12
  173. package/packages/dd-trace/src/proxy.js +2 -1
  174. package/packages/dd-trace/src/ritm.js +4 -4
  175. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +3 -2
  176. package/packages/dd-trace/src/sampler.js +10 -2
  177. package/packages/dd-trace/src/serverless.js +11 -4
  178. package/packages/dd-trace/src/span_processor.js +2 -1
  179. package/packages/dd-trace/src/standalone/tracesource.js +1 -2
  180. package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +1 -2
  181. package/packages/dd-trace/src/startup-log.js +5 -17
  182. package/packages/dd-trace/src/supported-configurations.json +440 -0
  183. package/packages/dd-trace/src/telemetry/dependencies.js +62 -57
  184. package/packages/dd-trace/src/telemetry/send-data.js +7 -6
  185. package/packages/dd-trace/src/telemetry/telemetry.js +16 -26
  186. package/packages/dd-trace/src/tracer.js +3 -7
  187. package/packages/dd-trace/src/util.js +0 -5
  188. package/packages/datadog-core/src/utils/src/get.js +0 -11
  189. package/packages/datadog-core/src/utils/src/has.js +0 -14
  190. package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +0 -120
  191. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +0 -20
@@ -24,7 +24,8 @@ const {
24
24
  OUTPUT_TOKENS_METRIC_KEY,
25
25
  TOTAL_TOKENS_METRIC_KEY,
26
26
  INTEGRATION,
27
- DECORATOR
27
+ DECORATOR,
28
+ PROPAGATED_ML_APP_KEY
28
29
  } = require('./constants/tags')
29
30
 
30
31
  // global registry of LLMObs spans
@@ -73,12 +74,24 @@ class LLMObsTagger {
73
74
  if (integration) this._setTag(span, INTEGRATION, integration)
74
75
  if (_decorator) this._setTag(span, DECORATOR, _decorator)
75
76
 
76
- if (!mlApp) mlApp = registry.get(parent)?.[ML_APP] || this._config.llmobs.mlApp
77
- this._setTag(span, ML_APP, mlApp)
77
+ const spanMlApp =
78
+ mlApp ||
79
+ registry.get(parent)?.[ML_APP] ||
80
+ span.context()._trace.tags[PROPAGATED_ML_APP_KEY] ||
81
+ this._config.llmobs.mlApp
82
+
83
+ if (!spanMlApp) {
84
+ throw new Error(
85
+ '[LLMObs] Cannot start an LLMObs span without an mlApp configured.' +
86
+ 'Ensure this configuration is set before running your application.'
87
+ )
88
+ }
89
+
90
+ this._setTag(span, ML_APP, spanMlApp)
78
91
 
79
92
  const parentId =
80
- parent?.context().toSpanId() ||
81
- span.context()._trace.tags[PROPAGATED_PARENT_ID_KEY] ||
93
+ parent?.context().toSpanId() ??
94
+ span.context()._trace.tags[PROPAGATED_PARENT_ID_KEY] ??
82
95
  ROOT_PARENT_ID
83
96
  this._setTag(span, PARENT_ID_KEY, parentId)
84
97
  }
@@ -357,7 +370,7 @@ class LLMObsTagger {
357
370
  }
358
371
 
359
372
  const tagsCarrier = registry.get(span)
360
- Object.assign(tagsCarrier, { [key]: value })
373
+ tagsCarrier[key] = value
361
374
  }
362
375
  }
363
376
 
@@ -157,7 +157,7 @@ class BaseLLMObsWriter {
157
157
  return encodeUnicode(value) // serialize unicode characters
158
158
  }
159
159
  return value
160
- }).replace(/\\\\u/g, String.raw`\u`) // remove double escaping
160
+ }).replaceAll(String.raw`\\u`, String.raw`\u`) // remove double escaping
161
161
  }
162
162
  }
163
163
 
@@ -7,6 +7,7 @@ const { traceChannel, debugChannel, infoChannel, warnChannel, errorChannel } = r
7
7
  const logWriter = require('./writer')
8
8
  const { Log } = require('./log')
9
9
  const { memoize } = require('./utils')
10
+ const { getEnvironmentVariable } = require('../config-helper')
10
11
 
11
12
  const config = {
12
13
  enabled: false,
@@ -98,8 +99,8 @@ const log = {
98
99
  isEnabled (fleetStableConfigValue, localStableConfigValue) {
99
100
  return isTrue(coalesce(
100
101
  fleetStableConfigValue,
101
- process.env?.DD_TRACE_DEBUG,
102
- process.env?.OTEL_LOG_LEVEL === 'debug' || undefined,
102
+ getEnvironmentVariable('DD_TRACE_DEBUG'),
103
+ getEnvironmentVariable('OTEL_LOG_LEVEL') === 'debug' || undefined,
103
104
  localStableConfigValue,
104
105
  config.enabled
105
106
  ))
@@ -113,8 +114,8 @@ const log = {
113
114
  return coalesce(
114
115
  optionsValue,
115
116
  fleetStableConfigValue,
116
- process.env?.DD_TRACE_LOG_LEVEL,
117
- process.env?.OTEL_LOG_LEVEL,
117
+ getEnvironmentVariable('DD_TRACE_LOG_LEVEL'),
118
+ getEnvironmentVariable('OTEL_LOG_LEVEL'),
118
119
  localStableConfigValue,
119
120
  config.logLevel
120
121
  )
@@ -57,9 +57,8 @@ function getErrorLog (err) {
57
57
  if (typeof err?.delegate === 'function') {
58
58
  const result = err.delegate()
59
59
  return Array.isArray(result) ? Log.parse(...result) : Log.parse(result)
60
- } else {
61
- return err
62
60
  }
61
+ return err
63
62
  }
64
63
 
65
64
  function setStackTraceLimitFunction (fn) {
@@ -163,7 +163,7 @@ class MsgpackEncoder {
163
163
 
164
164
  encodeLong (bytes, value) {
165
165
  const offset = bytes.length
166
- const hi = (value / Math.pow(2, 32)) >> 0
166
+ const hi = (value / 2 ** 32) >> 0
167
167
  const lo = value >>> 0
168
168
 
169
169
  bytes.reserve(9)
@@ -216,7 +216,7 @@ class MsgpackEncoder {
216
216
  bytes.buffer[offset + 3] = value >> 8
217
217
  bytes.buffer[offset + 4] = value
218
218
  } else {
219
- const hi = Math.floor(value / Math.pow(2, 32))
219
+ const hi = Math.floor(value / 2 ** 32)
220
220
  const lo = value >>> 0
221
221
 
222
222
  bytes.reserve(9)
@@ -255,7 +255,7 @@ class MsgpackEncoder {
255
255
  bytes.buffer[offset + 3] = value >> 8
256
256
  bytes.buffer[offset + 4] = value
257
257
  } else {
258
- const hi = (value / Math.pow(2, 32)) >> 0
258
+ const hi = (value / 2 ** 32) >> 0
259
259
  const lo = value >>> 0
260
260
 
261
261
  bytes.reserve(9)
@@ -36,7 +36,7 @@ class NoopSpan {
36
36
  traceId: parent._traceId,
37
37
  spanId,
38
38
  parentId: parent._spanId,
39
- baggageItems: Object.assign({}, parent._baggageItems)
39
+ baggageItems: { ...parent._baggageItems }
40
40
  })
41
41
  : new NoopSpanContext({
42
42
  noop: this,
@@ -32,7 +32,7 @@ class Tracer {
32
32
  spanId: id(),
33
33
  parentId: parentSpanContext._spanId,
34
34
  sampling: parentSpanContext._sampling,
35
- baggageItems: Object.assign({}, parentSpanContext._baggageItems),
35
+ baggageItems: { ...parentSpanContext._baggageItems },
36
36
  trace: parentSpanContext._trace,
37
37
  tracestate: parentSpanContext._tracestate
38
38
  })
@@ -43,12 +43,11 @@ class LogPropagator {
43
43
  spanContext._trace.tags['_dd.p.tid'] = hi
44
44
 
45
45
  return spanContext
46
- } else {
47
- return new DatadogSpanContext({
48
- traceId: id(carrier.dd.trace_id, 10),
49
- spanId: id(carrier.dd.span_id, 10)
50
- })
51
46
  }
47
+ return new DatadogSpanContext({
48
+ traceId: id(carrier.dd.trace_id, 10),
49
+ spanId: id(carrier.dd.span_id, 10)
50
+ })
52
51
  }
53
52
  }
54
53
 
@@ -136,7 +136,7 @@ class TextMapPropagator {
136
136
  let itemCounter = 0
137
137
  let byteCounter = 0
138
138
 
139
- const baggageItems = spanContext ? spanContext._baggageItems : getAllBaggageItems()
139
+ const baggageItems = getAllBaggageItems()
140
140
  if (!baggageItems) return
141
141
  for (const [key, value] of Object.entries(baggageItems)) {
142
142
  const item = `${this._encodeOtelBaggageKey(String(key).trim())}=${encodeURIComponent(String(value).trim())},`
@@ -239,8 +239,8 @@ class TextMapPropagator {
239
239
 
240
240
  if (typeof origin === 'string') {
241
241
  const originValue = origin
242
- .replace(tracestateOriginFilter, '_')
243
- .replace(/[\x3D]/g, '~')
242
+ .replaceAll(tracestateOriginFilter, '_')
243
+ .replaceAll(/[\x3D]/g, '~')
244
244
 
245
245
  state.set('o', originValue)
246
246
  }
@@ -249,12 +249,12 @@ class TextMapPropagator {
249
249
  if (!tags[key] || !key.startsWith('_dd.p.')) continue
250
250
 
251
251
  const tagKey = 't.' + key.slice(6)
252
- .replace(tracestateTagKeyFilter, '_')
252
+ .replaceAll(tracestateTagKeyFilter, '_')
253
253
 
254
254
  const tagValue = tags[key]
255
255
  .toString()
256
- .replace(tracestateTagValueFilter, '_')
257
- .replace(/[\x3D]/g, '~')
256
+ .replaceAll(tracestateTagValueFilter, '_')
257
+ .replaceAll(/[\x3D]/g, '~')
258
258
 
259
259
  state.set(tagKey, tagValue)
260
260
  }
@@ -355,19 +355,20 @@ class TextMapPropagator {
355
355
  }
356
356
  }
357
357
 
358
- this._extractBaggageItems(carrier, context)
359
-
360
358
  if (this._config.tracePropagationBehaviorExtract === 'ignore') {
361
359
  context._links = []
362
- } else if (this._config.tracePropagationBehaviorExtract === 'restart') {
363
- context._links = []
364
- context._links.push({
365
- context,
366
- attributes:
367
- {
368
- reason: 'propagation_behavior_extract', context_headers: style
369
- }
370
- })
360
+ } else {
361
+ if (this._config.tracePropagationBehaviorExtract === 'restart') {
362
+ context._links = []
363
+ context._links.push({
364
+ context,
365
+ attributes:
366
+ {
367
+ reason: 'propagation_behavior_extract', context_headers: style
368
+ }
369
+ })
370
+ }
371
+ this._extractBaggageItems(carrier, context)
371
372
  }
372
373
 
373
374
  return context || this._extractSqsdContext(carrier)
@@ -508,7 +509,7 @@ class TextMapPropagator {
508
509
  default: {
509
510
  if (!key.startsWith('t.')) continue
510
511
  const subKey = key.slice(2) // e.g. t.tid -> tid
511
- const transformedValue = value.replace(/[\x7E]/gm, '=')
512
+ const transformedValue = value.replaceAll(/[\x7E]/gm, '=')
512
513
 
513
514
  // If subkey is tid then do nothing because trace header tid should always be preserved
514
515
  if (subKey === 'tid') {
@@ -581,22 +582,21 @@ class TextMapPropagator {
581
582
  return {
582
583
  [b3SampledKey]: parts[0]
583
584
  }
584
- } else {
585
- const b3 = {
586
- [b3TraceKey]: parts[0],
587
- [b3SpanKey]: parts[1]
588
- }
585
+ }
586
+ const b3 = {
587
+ [b3TraceKey]: parts[0],
588
+ [b3SpanKey]: parts[1]
589
+ }
589
590
 
590
- if (parts[2]) {
591
- b3[b3SampledKey] = parts[2] === '0' ? '0' : '1'
591
+ if (parts[2]) {
592
+ b3[b3SampledKey] = parts[2] === '0' ? '0' : '1'
592
593
 
593
- if (parts[2] === 'd') {
594
- b3[b3FlagsKey] = '1'
595
- }
594
+ if (parts[2] === 'd') {
595
+ b3[b3FlagsKey] = '1'
596
596
  }
597
-
598
- return b3
599
597
  }
598
+
599
+ return b3
600
600
  }
601
601
 
602
602
  _extractOrigin (carrier, spanContext) {
@@ -629,33 +629,26 @@ class TextMapPropagator {
629
629
  _extractBaggageItems (carrier, spanContext) {
630
630
  if (!this._hasPropagationStyle('extract', 'baggage')) return
631
631
  if (!carrier || !carrier.baggage) return
632
- if (!spanContext) removeAllBaggageItems()
633
632
  const baggages = carrier.baggage.split(',')
634
633
  const keysToSpanTag = this._config.baggageTagKeys === '*'
635
634
  ? undefined
636
635
  : new Set(this._config.baggageTagKeys.split(','))
637
636
  for (const keyValue of baggages) {
638
637
  if (!keyValue.includes('=')) {
639
- if (spanContext) spanContext._baggageItems = {}
638
+ removeAllBaggageItems()
640
639
  return
641
640
  }
642
641
  let [key, value] = keyValue.split('=')
643
642
  key = this._decodeOtelBaggageKey(key.trim())
644
643
  value = decodeURIComponent(value.trim())
645
644
  if (!key || !value) {
646
- if (spanContext) spanContext._baggageItems = {}
645
+ removeAllBaggageItems()
647
646
  return
648
647
  }
649
- // the current code assumes precedence of ot-baggage- (legacy opentracing baggage) over baggage
650
- if (spanContext) {
651
- if (Object.hasOwn(spanContext._baggageItems, key)) continue
652
- spanContext._baggageItems[key] = value
653
- if (this._config.baggageTagKeys === '*' || keysToSpanTag.has(key)) {
654
- spanContext._trace.tags['baggage.' + key] = value
655
- }
656
- } else {
657
- setBaggageItem(key, value)
648
+ if (spanContext && (this._config.baggageTagKeys === '*' || keysToSpanTag.has(key))) {
649
+ spanContext._trace.tags['baggage.' + key] = value
658
650
  }
651
+ setBaggageItem(key, value)
659
652
  }
660
653
  }
661
654
 
@@ -13,18 +13,17 @@ const { storage } = require('../../../datadog-core')
13
13
  const telemetryMetrics = require('../telemetry/metrics')
14
14
  const { channel } = require('dc-polyfill')
15
15
  const util = require('util')
16
+ const { getEnvironmentVariable } = require('../config-helper')
16
17
 
17
18
  const tracerMetrics = telemetryMetrics.manager.namespace('tracers')
18
19
 
19
- const {
20
- DD_TRACE_EXPERIMENTAL_STATE_TRACKING,
21
- DD_TRACE_EXPERIMENTAL_SPAN_COUNTS
22
- } = process.env
20
+ const DD_TRACE_EXPERIMENTAL_STATE_TRACKING = getEnvironmentVariable('DD_TRACE_EXPERIMENTAL_STATE_TRACKING')
21
+ const DD_TRACE_EXPERIMENTAL_SPAN_COUNTS = getEnvironmentVariable('DD_TRACE_EXPERIMENTAL_SPAN_COUNTS')
23
22
 
24
23
  const unfinishedRegistry = createRegistry('unfinished')
25
24
  const finishedRegistry = createRegistry('finished')
26
25
 
27
- const OTEL_ENABLED = !!process.env.DD_TRACE_OTEL_ENABLED
26
+ const OTEL_ENABLED = !!getEnvironmentVariable('DD_TRACE_OTEL_ENABLED')
28
27
  const ALLOWED = new Set(['string', 'number', 'boolean'])
29
28
 
30
29
  const integrationCounters = {
@@ -56,6 +55,8 @@ class DatadogSpan {
56
55
  constructor (tracer, processor, prioritySampler, fields, debug) {
57
56
  const operationName = fields.operationName
58
57
  const parent = fields.parent || null
58
+ // TODO(BridgeAR): Investigate why this is causing a performance regression
59
+ // eslint-disable-next-line prefer-object-spread
59
60
  const tags = Object.assign({}, fields.tags)
60
61
  const hostname = fields.hostname
61
62
 
@@ -333,7 +334,7 @@ class DatadogSpan {
333
334
  spanId: id(),
334
335
  parentId: parent._spanId,
335
336
  sampling: parent._sampling,
336
- baggageItems: Object.assign({}, parent._baggageItems),
337
+ baggageItems: { ...parent._baggageItems },
337
338
  trace: parent._trace,
338
339
  tracestate: parent._tracestate
339
340
  })
@@ -2,29 +2,25 @@ const aws = require('./aws.json')
2
2
  const sdks = { aws }
3
3
 
4
4
  function getSDKRules (sdk, requestInput, responseInput) {
5
- return Object.fromEntries(
6
- Object.entries(sdk).map(([service, serviceRules]) => {
7
- return [
8
- service,
9
- {
10
- request: serviceRules.request.concat(requestInput || []),
11
- response: serviceRules.response.concat(responseInput || []),
12
- expand: serviceRules.expand || []
13
- }
14
- ]
15
- })
16
- )
5
+ const sdkServiceRules = {}
6
+ for (const [service, serviceRules] of Object.entries(sdk)) {
7
+ sdkServiceRules[service] = {
8
+ // Make a copy. Otherwise calling the function multiple times would append
9
+ // the rules to the same object.
10
+ request: [...serviceRules.request, ...requestInput],
11
+ response: [...serviceRules.response, ...responseInput],
12
+ expand: serviceRules.expand
13
+ }
14
+ }
15
+ return sdkServiceRules
17
16
  }
18
17
 
19
- function appendRules (requestInput, responseInput) {
20
- return Object.fromEntries(
21
- Object.entries(sdks).map(([name, sdk]) => {
22
- return [
23
- name,
24
- getSDKRules(sdk, requestInput, responseInput)
25
- ]
26
- })
27
- )
18
+ function appendRules (requestInput = [], responseInput = []) {
19
+ const sdkRules = {}
20
+ for (const [name, sdk] of Object.entries(sdks)) {
21
+ sdkRules[name] = getSDKRules(sdk, requestInput, responseInput)
22
+ }
23
+ return sdkRules
28
24
  }
29
25
 
30
26
  module.exports = { appendRules }
@@ -4,17 +4,18 @@ const { channel } = require('dc-polyfill')
4
4
  const { isFalse } = require('./util')
5
5
  const plugins = require('./plugins')
6
6
  const log = require('./log')
7
+ const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
7
8
 
8
9
  const loadChannel = channel('dd-trace:instrumentation:load')
9
10
 
10
11
  // instrument everything that needs Plugin System V2 instrumentation
11
12
  require('../../datadog-instrumentations')
12
- if (process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined) {
13
+ if (getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') !== undefined) {
13
14
  // instrument lambda environment
14
15
  require('./lambda')
15
16
  }
16
17
 
17
- const { DD_TRACE_DISABLED_PLUGINS } = process.env
18
+ const DD_TRACE_DISABLED_PLUGINS = getEnvironmentVariable('DD_TRACE_DISABLED_PLUGINS')
18
19
 
19
20
  const disabledPlugins = new Set(
20
21
  DD_TRACE_DISABLED_PLUGINS && DD_TRACE_DISABLED_PLUGINS.split(',').map(plugin => plugin.trim())
@@ -32,7 +33,7 @@ function maybeEnable (Plugin) {
32
33
  if (!Plugin || typeof Plugin !== 'function') return
33
34
  if (!pluginClasses[Plugin.id]) {
34
35
  const envName = `DD_TRACE_${Plugin.id.toUpperCase()}_ENABLED`
35
- const enabled = process.env[envName.replace(/[^a-z0-9_]/ig, '_')]
36
+ const enabled = getEnvironmentVariable(envName.replaceAll(/[^a-z0-9_]/ig, '_'))
36
37
 
37
38
  // TODO: remove the need to load the plugin class in order to disable the plugin
38
39
  if (isFalse(enabled) || disabledPlugins.has(Plugin.id)) {
@@ -1,3 +1,4 @@
1
+ const { storage } = require('../../../datadog-core')
1
2
  const {
2
3
  getTestEnvironmentMetadata,
3
4
  getTestSessionName,
@@ -73,7 +74,10 @@ module.exports = class CiPlugin extends Plugin {
73
74
  this.fileLineToProbeId = new Map()
74
75
  this.rootDir = process.cwd() // fallback in case :session:start events are not emitted
75
76
 
76
- this.addSub(`ci:${this.constructor.id}:library-configuration`, ({ onDone, isParallel }) => {
77
+ this.addSub(`ci:${this.constructor.id}:library-configuration`, (ctx) => {
78
+ const { onDone, isParallel } = ctx
79
+ ctx.currentStore = storage('legacy').getStore()
80
+
77
81
  if (!this.tracer._exporter || !this.tracer._exporter.getLibraryConfiguration) {
78
82
  return onDone({ err: new Error('Test optimization was not initialized correctly') })
79
83
  }
@@ -95,6 +99,10 @@ module.exports = class CiPlugin extends Plugin {
95
99
  })
96
100
  })
97
101
 
102
+ this.addBind(`ci:${this.constructor.id}:test-suite:skippable`, (ctx) => {
103
+ return ctx.currentStore
104
+ })
105
+
98
106
  this.addSub(`ci:${this.constructor.id}:test-suite:skippable`, ({ onDone }) => {
99
107
  if (!this.tracer._exporter?.getSkippableSuites) {
100
108
  return onDone({ err: new Error('Test optimization was not initialized correctly') })
@@ -158,8 +166,12 @@ module.exports = class CiPlugin extends Plugin {
158
166
  // only for vitest
159
167
  // These are added for the worker threads to use
160
168
  if (this.constructor.id === 'vitest') {
169
+ // TODO: Figure out alternative ways to pass this information to the worker threads
170
+ // eslint-disable-next-line eslint-rules/eslint-process-env
161
171
  process.env.DD_CIVISIBILITY_TEST_SESSION_ID = this.testSessionSpan.context().toTraceId()
172
+ // eslint-disable-next-line eslint-rules/eslint-process-env
162
173
  process.env.DD_CIVISIBILITY_TEST_MODULE_ID = this.testModuleSpan.context().toSpanId()
174
+ // eslint-disable-next-line eslint-rules/eslint-process-env
163
175
  process.env.DD_CIVISIBILITY_TEST_COMMAND = this.command
164
176
  }
165
177
 
@@ -188,6 +200,10 @@ module.exports = class CiPlugin extends Plugin {
188
200
  this.telemetry.count(TELEMETRY_ITR_SKIPPED, { testLevel: 'suite' }, skippedSuites.length)
189
201
  })
190
202
 
203
+ this.addBind(`ci:${this.constructor.id}:known-tests`, (ctx) => {
204
+ return ctx.currentStore
205
+ })
206
+
191
207
  this.addSub(`ci:${this.constructor.id}:known-tests`, ({ onDone }) => {
192
208
  if (!this.tracer._exporter?.getKnownTests) {
193
209
  return onDone({ err: new Error('Test optimization was not initialized correctly') })
@@ -202,6 +218,10 @@ module.exports = class CiPlugin extends Plugin {
202
218
  })
203
219
  })
204
220
 
221
+ this.addBind(`ci:${this.constructor.id}:test-management-tests`, (ctx) => {
222
+ return ctx.currentStore
223
+ })
224
+
205
225
  this.addSub(`ci:${this.constructor.id}:test-management-tests`, ({ onDone }) => {
206
226
  if (!this.tracer._exporter?.getTestManagementTests) {
207
227
  return onDone({ err: new Error('Test optimization was not initialized correctly') })
@@ -215,6 +235,10 @@ module.exports = class CiPlugin extends Plugin {
215
235
  })
216
236
  })
217
237
 
238
+ this.addBind(`ci:${this.constructor.id}:modified-tests`, (ctx) => {
239
+ return ctx.currentStore
240
+ })
241
+
218
242
  this.addSub(`ci:${this.constructor.id}:modified-tests`, ({ onDone }) => {
219
243
  const {
220
244
  [GIT_PULL_REQUEST_BASE_BRANCH]: pullRequestBaseBranch,
@@ -34,7 +34,7 @@ class StoreBinding {
34
34
  this._transform = data => {
35
35
  const store = storage('legacy').getStore()
36
36
 
37
- return !store || !store.noop || data?.currentStore
37
+ return !store || !store.noop || (data && Object.hasOwn(data, 'currentStore'))
38
38
  ? transform(data)
39
39
  : store
40
40
  }
@@ -27,6 +27,7 @@ const {
27
27
  CI_NODE_NAME
28
28
  } = require('./tags')
29
29
  const { filterSensitiveInfoFromRepository } = require('./url')
30
+ const { getEnvironmentVariable } = require('../../config-helper')
30
31
 
31
32
  // Receives a string with the form 'John Doe <john.doe@gmail.com>'
32
33
  // and returns { name: 'John Doe', email: 'john.doe@gmail.com' }
@@ -67,7 +68,7 @@ function normalizeRef (ref) {
67
68
  if (!ref) {
68
69
  return ref
69
70
  }
70
- return ref.replace(/origin\/|refs\/heads\/|tags\//gm, '')
71
+ return ref.replaceAll(/origin\/|refs\/heads\/|tags\//gm, '')
71
72
  }
72
73
 
73
74
  function resolveTilde (filePath) {
@@ -76,16 +77,16 @@ function resolveTilde (filePath) {
76
77
  }
77
78
  // '~/folder/path' or '~'
78
79
  if (filePath[0] === '~' && (filePath[1] === '/' || filePath.length === 1)) {
79
- return filePath.replace('~', process.env.HOME)
80
+ return filePath.replace('~', getEnvironmentVariable('HOME'))
80
81
  }
81
82
  return filePath
82
83
  }
83
84
 
84
85
  function getGitHubEventPayload () {
85
- if (!process.env.GITHUB_EVENT_PATH) {
86
+ if (!getEnvironmentVariable('GITHUB_EVENT_PATH')) {
86
87
  return
87
88
  }
88
- return JSON.parse(readFileSync(process.env.GITHUB_EVENT_PATH, 'utf8'))
89
+ return JSON.parse(readFileSync(getEnvironmentVariable('GITHUB_EVENT_PATH'), 'utf8'))
89
90
  }
90
91
 
91
92
  module.exports = {
@@ -139,11 +140,10 @@ module.exports = {
139
140
 
140
141
  tags[refKey] = ref
141
142
 
142
- let finalPipelineName = ''
143
143
  if (JOB_NAME) {
144
144
  // Job names can contain parameters, e.g. jobName/KEY1=VALUE1,KEY2=VALUE2/branchName
145
145
  const jobNameAndParams = JOB_NAME.split('/')
146
- finalPipelineName = jobNameAndParams.length > 1 && jobNameAndParams[1].includes('=')
146
+ const finalPipelineName = jobNameAndParams.length > 1 && jobNameAndParams[1].includes('=')
147
147
  ? jobNameAndParams[0]
148
148
  : JOB_NAME.replace(`/${ref}`, '')
149
149
  tags[CI_PIPELINE_NAME] = finalPipelineName
@@ -432,7 +432,7 @@ module.exports = {
432
432
  [GIT_TAG]: BITBUCKET_TAG,
433
433
  [GIT_REPOSITORY_URL]: BITBUCKET_GIT_SSH_ORIGIN || BITBUCKET_GIT_HTTP_ORIGIN,
434
434
  [CI_WORKSPACE_PATH]: BITBUCKET_CLONE_DIR,
435
- [CI_PIPELINE_ID]: BITBUCKET_PIPELINE_UUID && BITBUCKET_PIPELINE_UUID.replace(/{|}/gm, ''),
435
+ [CI_PIPELINE_ID]: BITBUCKET_PIPELINE_UUID && BITBUCKET_PIPELINE_UUID.replaceAll(/{|}/gm, ''),
436
436
  [GIT_PULL_REQUEST_BASE_BRANCH]: BITBUCKET_PR_DESTINATION_BRANCH
437
437
  }
438
438
  }
@@ -51,7 +51,7 @@ function sanitizedExec (
51
51
  try {
52
52
  let result = cp.execFileSync(cmd, flags, { stdio: 'pipe' }).toString()
53
53
  if (shouldTrim) {
54
- result = result.replace(/(\r\n|\n|\r)/gm, '')
54
+ result = result.replaceAll(/(\r\n|\n|\r)/gm, '')
55
55
  }
56
56
  if (durationMetric) {
57
57
  distributionMetric(durationMetric.name, durationMetric.tags, Date.now() - startTime)
@@ -11,8 +11,8 @@ function normalize (text, limit = 128) {
11
11
  }
12
12
 
13
13
  text = text
14
- .replace(RE_NEWLINE, String.raw`\n`)
15
- .replace(RE_TAB, String.raw`\t`)
14
+ .replaceAll(RE_NEWLINE, String.raw`\n`)
15
+ .replaceAll(RE_TAB, String.raw`\t`)
16
16
 
17
17
  // In case the replace above matched, more characters were added that must now be considered.
18
18
  if (text.length > limit) {
@@ -34,7 +34,14 @@ function getCallSites (constructorOpt) {
34
34
  *
35
35
  * @param {Function} constructorOpt - Function to pass along to Error.captureStackTrace
36
36
  * @param {number} [limit=Infinity] - The maximum number of frames to return
37
- * @returns {{ file: string, line: number, method: (string|undefined), type: (string|undefined) }[]} - A
37
+ * @returns {StackFrame[]} - A list of stack frames from user-land code
38
+ *
39
+ * @typedef {Object} StackFrame
40
+ * @property {string} file - The file path of the frame
41
+ * @property {number} line - The line number in the file
42
+ * @property {number} column - The column number in the file
43
+ * @property {string} [method] - The function name, if available
44
+ * @property {string} [type] - The type name, if available
38
45
  */
39
46
  function getUserLandFrames (constructorOpt, limit = Infinity) {
40
47
  const callsites = getCallSites(constructorOpt)
@@ -2,6 +2,7 @@ const path = require('path')
2
2
  const fs = require('fs')
3
3
  const { URL } = require('url')
4
4
  const log = require('../../log')
5
+ const { getEnvironmentVariable } = require('../../config-helper')
5
6
 
6
7
  const istanbul = require('istanbul-lib-coverage')
7
8
  const ignore = require('ignore')
@@ -284,7 +285,7 @@ module.exports = {
284
285
  // Returns pkg manager and its version, separated by '-', e.g. npm-8.15.0 or yarn-1.22.19
285
286
  function getPkgManager () {
286
287
  try {
287
- return process.env.npm_config_user_agent.split(' ')[0].replace('/', '-')
288
+ return getEnvironmentVariable('npm_config_user_agent').split(' ')[0].replace('/', '-')
288
289
  } catch {
289
290
  return ''
290
291
  }
@@ -789,11 +790,11 @@ function addAttemptToFixStringToTestName (testName, numAttempt) {
789
790
  }
790
791
 
791
792
  function removeEfdStringFromTestName (testName) {
792
- return testName.replace(EFD_TEST_NAME_REGEX, '')
793
+ return testName.replaceAll(EFD_TEST_NAME_REGEX, '')
793
794
  }
794
795
 
795
796
  function removeAttemptToFixStringFromTestName (testName) {
796
- return testName.replace(ATTEMPT_TEST_NAME_REGEX, '')
797
+ return testName.replaceAll(ATTEMPT_TEST_NAME_REGEX, '')
797
798
  }
798
799
 
799
800
  function getIsFaultyEarlyFlakeDetection (projectSuites, testsBySuiteName, faultyThresholdPercentage) {
@@ -17,6 +17,7 @@ const {
17
17
 
18
18
  const { normalizeRef } = require('./ci')
19
19
  const { filterSensitiveInfoFromRepository } = require('./url')
20
+ const { getEnvironmentVariables } = require('../../config-helper')
20
21
 
21
22
  function removeEmptyValues (tags) {
22
23
  return Object.keys(tags).reduce((filteredTags, tag) => {
@@ -59,7 +60,7 @@ function getUserProviderGitMetadata () {
59
60
  DD_GIT_PULL_REQUEST_BASE_BRANCH,
60
61
  DD_GIT_PULL_REQUEST_BASE_BRANCH_SHA,
61
62
  DD_GIT_COMMIT_HEAD_SHA
62
- } = process.env
63
+ } = getEnvironmentVariables()
63
64
 
64
65
  const branch = normalizeRef(DD_GIT_BRANCH)
65
66
  let tag = normalizeRef(DD_GIT_TAG)