dd-trace 5.98.0 → 5.99.1

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 (139) hide show
  1. package/LICENSE-3rdparty.csv +0 -1
  2. package/ext/tags.js +1 -0
  3. package/index.d.ts +9 -1
  4. package/package.json +68 -47
  5. package/packages/datadog-instrumentations/src/crypto.js +45 -0
  6. package/packages/datadog-instrumentations/src/cypress-config.js +122 -16
  7. package/packages/datadog-instrumentations/src/dns.js +24 -56
  8. package/packages/datadog-instrumentations/src/graphql.js +1 -1
  9. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +74 -0
  10. package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +4 -1
  11. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
  12. package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +10 -3
  13. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
  14. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/modelcontextprotocol-sdk.js +59 -0
  15. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +11 -2
  16. package/packages/datadog-instrumentations/src/jest.js +5 -5
  17. package/packages/datadog-instrumentations/src/modelcontextprotocol-sdk.js +7 -0
  18. package/packages/datadog-instrumentations/src/pino.js +4 -28
  19. package/packages/datadog-instrumentations/src/playwright-browser-scripts.js +27 -0
  20. package/packages/datadog-instrumentations/src/playwright.js +5 -17
  21. package/packages/datadog-instrumentations/src/stripe.js +38 -24
  22. package/packages/datadog-instrumentations/src/vitest.js +32 -4
  23. package/packages/datadog-instrumentations/src/zlib.js +29 -0
  24. package/packages/datadog-plugin-aws-sdk/src/base.js +1 -2
  25. package/packages/datadog-plugin-azure-event-hubs/src/producer.js +8 -15
  26. package/packages/datadog-plugin-azure-service-bus/src/producer.js +4 -9
  27. package/packages/datadog-plugin-cucumber/src/index.js +2 -2
  28. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +5 -5
  29. package/packages/datadog-plugin-cypress/src/source-map-utils.js +48 -1
  30. package/packages/datadog-plugin-dd-trace-api/src/index.js +1 -1
  31. package/packages/datadog-plugin-graphql/src/utils.js +2 -2
  32. package/packages/datadog-plugin-http/src/server.js +11 -11
  33. package/packages/datadog-plugin-jest/src/index.js +2 -2
  34. package/packages/datadog-plugin-memcached/src/index.js +1 -1
  35. package/packages/datadog-plugin-mocha/src/index.js +1 -2
  36. package/packages/datadog-plugin-modelcontextprotocol-sdk/src/index.js +24 -0
  37. package/packages/datadog-plugin-modelcontextprotocol-sdk/src/tracing.js +55 -0
  38. package/packages/datadog-plugin-mongodb-core/src/index.js +1 -6
  39. package/packages/datadog-plugin-playwright/src/index.js +2 -3
  40. package/packages/datadog-plugin-vitest/src/index.js +14 -6
  41. package/packages/datadog-plugin-ws/src/close.js +2 -0
  42. package/packages/datadog-plugin-ws/src/producer.js +2 -0
  43. package/packages/datadog-plugin-ws/src/receiver.js +1 -0
  44. package/packages/dd-trace/src/aiguard/channels.js +8 -0
  45. package/packages/dd-trace/src/aiguard/index.js +7 -3
  46. package/packages/dd-trace/src/aiguard/sdk.js +44 -0
  47. package/packages/dd-trace/src/aiguard/tags.js +1 -0
  48. package/packages/dd-trace/src/appsec/blocking.js +18 -6
  49. package/packages/dd-trace/src/appsec/graphql.js +7 -7
  50. package/packages/dd-trace/src/appsec/index.js +9 -11
  51. package/packages/dd-trace/src/appsec/rasp/command_injection.js +4 -5
  52. package/packages/dd-trace/src/appsec/rasp/lfi.js +8 -4
  53. package/packages/dd-trace/src/appsec/rasp/sql_injection.js +5 -10
  54. package/packages/dd-trace/src/appsec/rasp/ssrf.js +5 -6
  55. package/packages/dd-trace/src/appsec/recommended.json +2438 -13
  56. package/packages/dd-trace/src/appsec/reporter.js +6 -5
  57. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +4 -8
  58. package/packages/dd-trace/src/appsec/store.js +50 -0
  59. package/packages/dd-trace/src/appsec/waf/index.js +3 -5
  60. package/packages/dd-trace/src/baggage.js +16 -13
  61. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -2
  62. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -2
  63. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -2
  64. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
  65. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +1 -1
  66. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -4
  67. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -2
  68. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -5
  69. package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +3 -4
  70. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +6 -6
  71. package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +2 -2
  72. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -2
  73. package/packages/dd-trace/src/config/config-types.d.ts +0 -4
  74. package/packages/dd-trace/src/config/defaults.js +10 -10
  75. package/packages/dd-trace/src/config/generated-config-types.d.ts +39 -38
  76. package/packages/dd-trace/src/config/index.js +29 -39
  77. package/packages/dd-trace/src/config/parsers.js +26 -9
  78. package/packages/dd-trace/src/config/supported-configurations.json +46 -78
  79. package/packages/dd-trace/src/debugger/config.js +2 -0
  80. package/packages/dd-trace/src/debugger/devtools_client/send.js +25 -5
  81. package/packages/dd-trace/src/dogstatsd.js +5 -8
  82. package/packages/dd-trace/src/encode/0.4.js +4 -5
  83. package/packages/dd-trace/src/exporter.js +1 -1
  84. package/packages/dd-trace/src/exporters/agent/index.js +0 -1
  85. package/packages/dd-trace/src/exporters/agent/writer.js +1 -2
  86. package/packages/dd-trace/src/exporters/agentless/writer.js +3 -3
  87. package/packages/dd-trace/src/exporters/common/util.js +2 -2
  88. package/packages/dd-trace/src/git_metadata_tagger.js +1 -1
  89. package/packages/dd-trace/src/id.js +2 -0
  90. package/packages/dd-trace/src/index.js +2 -5
  91. package/packages/dd-trace/src/lambda/handler.js +1 -3
  92. package/packages/dd-trace/src/llmobs/constants/tags.js +3 -0
  93. package/packages/dd-trace/src/llmobs/plugins/{anthropic.js → anthropic/index.js} +5 -63
  94. package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +106 -0
  95. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +3 -2
  96. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -2
  97. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/embedding.js +2 -1
  98. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +0 -49
  99. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/vectorstore.js +2 -1
  100. package/packages/dd-trace/src/llmobs/plugins/langchain/messages.js +76 -0
  101. package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -26
  102. package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/index.js +68 -0
  103. package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +57 -0
  104. package/packages/dd-trace/src/llmobs/sdk.js +23 -3
  105. package/packages/dd-trace/src/llmobs/span_processor.js +14 -1
  106. package/packages/dd-trace/src/llmobs/writers/base.js +7 -1
  107. package/packages/dd-trace/src/llmobs/writers/spans.js +1 -1
  108. package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +103 -0
  109. package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -0
  110. package/packages/dd-trace/src/opentelemetry/logs/index.js +6 -6
  111. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +3 -2
  112. package/packages/dd-trace/src/opentelemetry/metrics/index.js +7 -7
  113. package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +3 -2
  114. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +19 -66
  115. package/packages/dd-trace/src/opentelemetry/trace/index.js +11 -16
  116. package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +11 -3
  117. package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +51 -41
  118. package/packages/dd-trace/src/opentelemetry/tracer.js +9 -11
  119. package/packages/dd-trace/src/opentracing/propagation/text_map.js +30 -23
  120. package/packages/dd-trace/src/opentracing/span.js +2 -2
  121. package/packages/dd-trace/src/opentracing/tracer.js +12 -5
  122. package/packages/dd-trace/src/plugin_manager.js +6 -6
  123. package/packages/dd-trace/src/plugins/index.js +1 -0
  124. package/packages/dd-trace/src/plugins/log_plugin.js +1 -1
  125. package/packages/dd-trace/src/plugins/util/test.js +128 -7
  126. package/packages/dd-trace/src/plugins/util/url.js +2 -1
  127. package/packages/dd-trace/src/profiling/profilers/event_plugins/crypto.js +32 -0
  128. package/packages/dd-trace/src/profiling/profilers/event_plugins/zlib.js +19 -0
  129. package/packages/dd-trace/src/profiling/profilers/events.js +35 -0
  130. package/packages/dd-trace/src/proxy.js +8 -14
  131. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +2 -2
  132. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
  133. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
  134. package/packages/dd-trace/src/span_processor.js +1 -2
  135. package/packages/dd-trace/src/tagger.js +2 -2
  136. package/packages/dd-trace/src/telemetry/send-data.js +5 -7
  137. package/packages/dd-trace/src/tracer.js +2 -2
  138. package/vendor/dist/ignore/LICENSE +0 -21
  139. package/vendor/dist/ignore/index.js +0 -1
@@ -3,11 +3,12 @@
3
3
  const zlib = require('zlib')
4
4
  const dc = require('dc-polyfill')
5
5
 
6
- const { storage } = require('../../../datadog-core')
6
+ const { NETWORK_CLIENT_IP } = require('../../../../ext/tags')
7
7
  const web = require('../plugins/util/web')
8
8
  const { ipHeaderList } = require('../plugins/util/ip_extractor')
9
9
  const { keepTrace } = require('../priority_sampler')
10
10
  const { ASM } = require('../standalone/product')
11
+ const { getActiveRequest } = require('./store')
11
12
  const {
12
13
  incrementWafInitMetric,
13
14
  incrementWafUpdatesMetric,
@@ -302,7 +303,7 @@ function reportWafConfigUpdate (product, rcConfigId, diagnostics, wafVersion) {
302
303
 
303
304
  function reportMetrics (metrics, raspRule, req) {
304
305
  if (!req) {
305
- req = storage('legacy').getStore()?.req
306
+ req = getActiveRequest()
306
307
  }
307
308
  const rootSpan = req && web.root(req)
308
309
 
@@ -337,7 +338,7 @@ function reportTruncationMetrics (rootSpan, metrics) {
337
338
 
338
339
  function reportAttack ({ events: attackData, actions }, req) {
339
340
  if (!req) {
340
- req = storage('legacy').getStore()?.req
341
+ req = getActiveRequest()
341
342
  }
342
343
 
343
344
  const rootSpan = web.root(req)
@@ -363,7 +364,7 @@ function reportAttack ({ events: attackData, actions }, req) {
363
364
  : '{"triggers":' + attackDataStr + '}'
364
365
 
365
366
  if (req.socket) {
366
- newTags['network.client.ip'] = req.socket.remoteAddress
367
+ newTags[NETWORK_CLIENT_IP] = req.socket.remoteAddress
367
368
  }
368
369
 
369
370
  rootSpan.addTags(newTags)
@@ -481,7 +482,7 @@ function reportAttributes (attributes, req) {
481
482
  if (!attributes) return
482
483
 
483
484
  if (!req) {
484
- req = storage('legacy').getStore()?.req
485
+ req = getActiveRequest()
485
486
  }
486
487
 
487
488
  const rootSpan = web.root(req)
@@ -3,8 +3,9 @@
3
3
  const { USER_ID } = require('../addresses')
4
4
  const waf = require('../waf')
5
5
  const { block, getBlockingAction } = require('../blocking')
6
- const { storage } = require('../../../../datadog-core')
7
6
  const log = require('../../log')
7
+ const web = require('../../plugins/util/web')
8
+ const { getActiveRequest } = require('../store')
8
9
  const { setUserTags } = require('./set_user')
9
10
  const { getRootSpan } = require('./utils')
10
11
 
@@ -32,13 +33,8 @@ function checkUserAndSetUser (tracer, user) {
32
33
  }
33
34
 
34
35
  function blockRequest (tracer, req, res) {
35
- if (!req || !res) {
36
- const store = storage('legacy').getStore()
37
- if (store) {
38
- req = req || store.req
39
- res = res || store.res
40
- }
41
- }
36
+ req ||= getActiveRequest()
37
+ res ||= req && web.getContext(req)?.res
42
38
 
43
39
  if (!req || !res) {
44
40
  log.warn('[ASM] Requests or response object not available in blockRequest')
@@ -0,0 +1,50 @@
1
+ 'use strict'
2
+
3
+ const { storage } = require('../../../datadog-core')
4
+
5
+ const legacyStorage = storage('legacy')
6
+
7
+ const kReq = Symbol('dd-trace.appsec.req')
8
+
9
+ /**
10
+ * Return a new legacy-storage clone that weakly references `req`.
11
+ *
12
+ * The ref lives on an enumerable symbol key so it survives the
13
+ * `{ ...store, span }` spreads performed by plugin scope handling,
14
+ * while still allowing `req` (and therefore `res`) to be garbage
15
+ * collected once the request is done.
16
+ *
17
+ * @param {object|undefined} store
18
+ * @param {object} req
19
+ * @returns {object}
20
+ */
21
+ function withRequest (store, req) {
22
+ return { ...store, [kReq]: new WeakRef(req) }
23
+ }
24
+
25
+ /**
26
+ * Resolve the inbound request attached to a specific legacy store.
27
+ * Prefer {@link getActiveRequest} unless you already have a store in hand.
28
+ *
29
+ * @param {object|undefined} store
30
+ * @returns {object|undefined}
31
+ */
32
+ function getRequest (store) {
33
+ return store?.[kReq]?.deref()
34
+ }
35
+
36
+ /**
37
+ * Resolve the inbound request attached to the currently active legacy store.
38
+ * Shortcut for `getRequest(storage('legacy').getStore())`.
39
+ *
40
+ * @returns {object|undefined}
41
+ */
42
+ function getActiveRequest () {
43
+ return legacyStorage.getStore()?.[kReq]?.deref()
44
+ }
45
+
46
+ module.exports = {
47
+ withRequest,
48
+ getRequest,
49
+ getActiveRequest,
50
+ }
@@ -1,12 +1,12 @@
1
1
  'use strict'
2
2
 
3
- const { storage } = require('../../../../datadog-core')
4
3
  const log = require('../../log')
5
4
  const Reporter = require('../reporter')
6
5
  const Limiter = require('../../rate_limiter')
7
6
  const { keepTrace } = require('../../priority_sampler')
8
7
  const { ASM } = require('../../standalone/product')
9
8
  const web = require('../../plugins/util/web')
9
+ const { getActiveRequest } = require('../store')
10
10
  const { updateRateLimitedMetric } = require('../telemetry')
11
11
 
12
12
  class WafUpdateError extends Error {
@@ -112,13 +112,11 @@ function removeConfig (configPath) {
112
112
 
113
113
  function run (data, req, raspRule) {
114
114
  if (!req) {
115
- const store = storage('legacy').getStore()
116
- if (!store || !store.req) {
115
+ req = getActiveRequest()
116
+ if (!req) {
117
117
  log.warn('[ASM] Request object not available in waf.run')
118
118
  return
119
119
  }
120
-
121
- req = store.req
122
120
  }
123
121
 
124
122
  const wafContext = waf.wafManager.getWAFContext(req)
@@ -3,10 +3,9 @@
3
3
  const { storage } = require('../../datadog-core')
4
4
 
5
5
  /**
6
- * Spec (API semantics):
7
- * - OpenTelemetry Baggage API: https://opentelemetry.io/docs/specs/otel/baggage/api/
6
+ * In-process baggage map stored in async local storage. Frozen on every write.
8
7
  *
9
- * In-process baggage is a string->string map stored in async local storage.
8
+ * @see https://opentelemetry.io/docs/specs/otel/baggage/api/
10
9
  * @typedef {import('../../datadog-core/src/storage').Store<string>} BaggageStore
11
10
  */
12
11
 
@@ -18,6 +17,8 @@ const baggageStorage =
18
17
  /** @type {unknown} */ (storage('baggage'))
19
18
  )
20
19
 
20
+ const EMPTY_STORE = Object.freeze(/** @type {BaggageStore} */ ({}))
21
+
21
22
  // TODO: Implement metadata https://opentelemetry.io/docs/specs/otel/baggage/api/#set-value
22
23
  /**
23
24
  * @param {string} key
@@ -25,12 +26,11 @@ const baggageStorage =
25
26
  * @param {object} [metadata] Not used yet
26
27
  */
27
28
  function setBaggageItem (key, value, metadata) {
29
+ const store = baggageStorage.getStore()
28
30
  if (typeof key !== 'string' || typeof value !== 'string' || key === '') {
29
- return baggageStorage.getStore() ?? {}
31
+ return store ?? EMPTY_STORE
30
32
  }
31
-
32
- const store = baggageStorage.getStore()
33
- const newStore = { ...store, [key]: value }
33
+ const newStore = Object.freeze({ ...store, [key]: value })
34
34
  baggageStorage.enterWith(newStore)
35
35
  return newStore
36
36
  }
@@ -44,23 +44,26 @@ function getBaggageItem (key) {
44
44
  }
45
45
 
46
46
  function getAllBaggageItems () {
47
- return baggageStorage.getStore() ?? {}
47
+ return baggageStorage.getStore() ?? EMPTY_STORE
48
48
  }
49
49
 
50
50
  /**
51
- * @param {string} keyToRemove
51
+ * @param {string} keyToRemove No-op for non-string or empty keys.
52
52
  */
53
53
  function removeBaggageItem (keyToRemove) {
54
- const store = baggageStorage.getStore() ?? {}
54
+ const store = baggageStorage.getStore() ?? EMPTY_STORE
55
+ if (typeof keyToRemove !== 'string' || keyToRemove === '') {
56
+ return store
57
+ }
55
58
  const { [keyToRemove]: _, ...newBaggage } = store
59
+ Object.freeze(newBaggage)
56
60
  baggageStorage.enterWith(newBaggage)
57
61
  return newBaggage
58
62
  }
59
63
 
60
64
  function removeAllBaggageItems () {
61
- const newContext = /** @type {BaggageStore} */ ({})
62
- baggageStorage.enterWith(newContext)
63
- return newContext
65
+ baggageStorage.enterWith(EMPTY_STORE)
66
+ return EMPTY_STORE
64
67
  }
65
68
 
66
69
  module.exports = {
@@ -1,9 +1,9 @@
1
1
  'use strict'
2
2
 
3
+ const getConfig = require('../../config')
3
4
  const request = require('../requests/request')
4
5
  const id = require('../../id')
5
6
  const log = require('../../log')
6
- const { getValueFromEnvSources } = require('../../config/helper')
7
7
 
8
8
  const {
9
9
  incrementCountMetric,
@@ -151,7 +151,7 @@ function fetchFromApi ({
151
151
  options.path = `${evpProxyPrefix}/api/v2/ci/libraries/tests`
152
152
  options.headers['X-Datadog-EVP-Subdomain'] = 'api'
153
153
  } else {
154
- const apiKey = getValueFromEnvSources('DD_API_KEY')
154
+ const { apiKey } = getConfig()
155
155
  if (!apiKey) {
156
156
  return done(new Error('Known tests were not fetched because Datadog API key is not defined.'))
157
157
  }
@@ -1,8 +1,8 @@
1
1
  'use strict'
2
+ const getConfig = require('../../../config')
2
3
  const request = require('../../../exporters/common/request')
3
4
  const log = require('../../../log')
4
5
  const { safeJSONStringify } = require('../../../exporters/common/util')
5
- const { getValueFromEnvSources } = require('../../../config/helper')
6
6
 
7
7
  const { CoverageCIVisibilityEncoder } = require('../../../encode/coverage-ci-visibility')
8
8
  const BaseWriter = require('../../../exporters/common/writer')
@@ -29,7 +29,7 @@ class Writer extends BaseWriter {
29
29
  path: '/api/v2/citestcov',
30
30
  method: 'POST',
31
31
  headers: {
32
- 'dd-api-key': getValueFromEnvSources('DD_API_KEY'),
32
+ 'dd-api-key': getConfig().apiKey,
33
33
  ...form.getHeaders(),
34
34
  },
35
35
  timeout: 15_000,
@@ -1,9 +1,9 @@
1
1
  'use strict'
2
+ const getConfig = require('../../../config')
2
3
  const request = require('../../../exporters/common/request')
3
4
  const log = require('../../../log')
4
5
  const { safeJSONStringify } = require('../../../exporters/common/util')
5
6
  const { JSONEncoder } = require('../../encode/json-encoder')
6
- const { getValueFromEnvSources } = require('../../../config/helper')
7
7
  const { DEBUGGER_INPUT_V1 } = require('../../../debugger/constants')
8
8
 
9
9
  const BaseWriter = require('../../../exporters/common/writer')
@@ -26,7 +26,7 @@ class DynamicInstrumentationLogsWriter extends BaseWriter {
26
26
  path: '/api/v2/logs',
27
27
  method: 'POST',
28
28
  headers: {
29
- 'dd-api-key': getValueFromEnvSources('DD_API_KEY'),
29
+ 'dd-api-key': getConfig().apiKey,
30
30
  'Content-Type': 'application/json',
31
31
  },
32
32
  timeout: this.timeout,
@@ -1,8 +1,8 @@
1
1
  'use strict'
2
+ const getConfig = require('../../../config')
2
3
  const request = require('../../../exporters/common/request')
3
4
  const { safeJSONStringify } = require('../../../exporters/common/util')
4
5
  const log = require('../../../log')
5
- const { getValueFromEnvSources } = require('../../../config/helper')
6
6
 
7
7
  const { AgentlessCiVisibilityEncoder } = require('../../../encode/agentless-ci-visibility')
8
8
  const BaseWriter = require('../../../exporters/common/writer')
@@ -30,7 +30,7 @@ class Writer extends BaseWriter {
30
30
  path: '/api/v2/citestcycle',
31
31
  method: 'POST',
32
32
  headers: {
33
- 'dd-api-key': getValueFromEnvSources('DD_API_KEY'),
33
+ 'dd-api-key': getConfig().apiKey,
34
34
  'Content-Type': 'application/msgpack',
35
35
  },
36
36
  timeout: 15_000,
@@ -234,7 +234,7 @@ class CiVisibilityExporter extends BufferingExporter {
234
234
  testManagementAttemptToFixRetries ?? this._config.testManagementAttemptToFixRetries,
235
235
  isImpactedTestsEnabled: isImpactedTestsEnabled && this._config.isImpactedTestsEnabled,
236
236
  isCoverageReportUploadEnabled,
237
- isKeepingCoverageConfiguration: this._config.isKeepingCoverageConfiguration,
237
+ DD_TEST_TIA_KEEP_COV_CONFIG: this._config.DD_TEST_TIA_KEEP_COV_CONFIG,
238
238
  }
239
239
  }
240
240
 
@@ -3,12 +3,11 @@
3
3
  const fs = require('fs')
4
4
  const path = require('path')
5
5
 
6
+ const getConfig = require('../../../config')
6
7
  const FormData = require('../../../exporters/common/form-data')
7
8
  const request = require('../../../exporters/common/request')
8
- const { getValueFromEnvSources } = require('../../../config/helper')
9
9
 
10
10
  const log = require('../../../log')
11
- const { isFalse } = require('../../../util')
12
11
  const {
13
12
  getLatestCommits,
14
13
  getRepositoryUrl,
@@ -51,7 +50,7 @@ function getCommonRequestOptions (url) {
51
50
  return {
52
51
  method: 'POST',
53
52
  headers: {
54
- 'dd-api-key': getValueFromEnvSources('DD_API_KEY'),
53
+ 'dd-api-key': getConfig().apiKey,
55
54
  },
56
55
  timeout: 15_000,
57
56
  url,
@@ -288,7 +287,7 @@ function sendGitMetadata (url, { isEvpProxy, evpProxyPrefix }, configRepositoryU
288
287
  }
289
288
  // Otherwise we unshallow and get commits to upload again
290
289
  log.debug('It is shallow clone, unshallowing...')
291
- if (!isFalse(getValueFromEnvSources('DD_CIVISIBILITY_GIT_UNSHALLOW_ENABLED'))) {
290
+ if (getConfig().DD_CIVISIBILITY_GIT_UNSHALLOW_ENABLED) {
292
291
  unshallowRepository(false)
293
292
  }
294
293
 
@@ -1,8 +1,8 @@
1
1
  'use strict'
2
2
 
3
+ const getConfig = require('../../config')
3
4
  const request = require('../requests/request')
4
5
  const log = require('../../log')
5
- const { getValueFromEnvSources } = require('../../config/helper')
6
6
  const {
7
7
  incrementCountMetric,
8
8
  distributionMetric,
@@ -120,7 +120,7 @@ function fetchFromApi ({
120
120
  options.path = `${evpProxyPrefix}/api/v2/ci/tests/skippable`
121
121
  options.headers['X-Datadog-EVP-Subdomain'] = 'api'
122
122
  } else {
123
- const apiKey = getValueFromEnvSources('DD_API_KEY')
123
+ const { apiKey } = getConfig()
124
124
  if (!apiKey) {
125
125
  return done(new Error('Skippable suites were not fetched because Datadog API key is not defined.'))
126
126
  }
@@ -2,26 +2,25 @@
2
2
 
3
3
  const Plugin = require('../../plugins/plugin')
4
4
  const log = require('../../log')
5
- const { getValueFromEnvSources } = require('../../config/helper')
6
5
 
7
6
  function getWinstonLogSubmissionParameters (config) {
8
- const { site, service } = config
7
+ const { site, service, apiKey, DD_AGENTLESS_LOG_SUBMISSION_URL } = config
9
8
 
10
9
  const defaultParameters = {
11
10
  host: `http-intake.logs.${site}`,
12
11
  path: `/api/v2/logs?ddsource=winston&service=${service}`,
13
12
  ssl: true,
14
13
  headers: {
15
- 'DD-API-KEY': getValueFromEnvSources('DD_API_KEY'),
14
+ 'DD-API-KEY': apiKey,
16
15
  },
17
16
  }
18
17
 
19
- if (!getValueFromEnvSources('DD_AGENTLESS_LOG_SUBMISSION_URL')) {
18
+ if (!DD_AGENTLESS_LOG_SUBMISSION_URL) {
20
19
  return defaultParameters
21
20
  }
22
21
 
23
22
  try {
24
- const url = new URL(getValueFromEnvSources('DD_AGENTLESS_LOG_SUBMISSION_URL'))
23
+ const url = new URL(DD_AGENTLESS_LOG_SUBMISSION_URL)
25
24
  return {
26
25
  host: url.hostname,
27
26
  port: url.port,
@@ -5,8 +5,8 @@ const path = require('node:path')
5
5
  const { createHash } = require('node:crypto')
6
6
  const { tmpdir } = require('node:os')
7
7
 
8
+ const getConfig = require('../../config')
8
9
  const log = require('../../log')
9
- const { getValueFromEnvSources } = require('../../config/helper')
10
10
 
11
11
  const CACHE_TTL_MS = 30 * 60 * 1000 // 30 minutes
12
12
  const CACHE_LOCK_POLL_MS = 500
@@ -14,13 +14,12 @@ const CACHE_LOCK_TIMEOUT_MS = 120_000 // 2 minutes
14
14
  const CACHE_LOCK_HEARTBEAT_MS = 30_000 // 30 seconds
15
15
 
16
16
  /**
17
- * Returns whether the filesystem cache is enabled via the env var.
17
+ * Returns whether the filesystem cache is enabled via config.
18
18
  *
19
19
  * @returns {boolean}
20
20
  */
21
21
  function isCacheEnabled () {
22
- const { isTrue } = require('../../util')
23
- return isTrue(getValueFromEnvSources('DD_EXPERIMENTAL_TEST_REQUESTS_FS_CACHE'))
22
+ return getConfig().DD_EXPERIMENTAL_TEST_REQUESTS_FS_CACHE
24
23
  }
25
24
 
26
25
  /**
@@ -1,8 +1,8 @@
1
1
  'use strict'
2
2
 
3
+ const getConfig = require('../../config')
3
4
  const id = require('../../id')
4
5
  const log = require('../../log')
5
- const { getValueFromEnvSources } = require('../../config/helper')
6
6
  const {
7
7
  incrementCountMetric,
8
8
  distributionMetric,
@@ -36,6 +36,7 @@ function getLibraryConfiguration ({
36
36
  custom,
37
37
  tag,
38
38
  }, done) {
39
+ const config = getConfig()
39
40
  const options = {
40
41
  path: '/api/v2/libraries/tests/services/setting',
41
42
  method: 'POST',
@@ -50,11 +51,10 @@ function getLibraryConfiguration ({
50
51
  options.path = `${evpProxyPrefix}/api/v2/libraries/tests/services/setting`
51
52
  options.headers['X-Datadog-EVP-Subdomain'] = 'api'
52
53
  } else {
53
- const apiKey = getValueFromEnvSources('DD_API_KEY')
54
- if (!apiKey) {
54
+ if (!config.apiKey) {
55
55
  return done(new Error('Request to settings endpoint was not done because Datadog API key is not defined.'))
56
56
  }
57
- options.headers['dd-api-key'] = apiKey
57
+ options.headers['dd-api-key'] = config.apiKey
58
58
  }
59
59
 
60
60
  const data = JSON.stringify({
@@ -132,11 +132,11 @@ function getLibraryConfiguration ({
132
132
 
133
133
  log.debug('Remote settings: %j', settings)
134
134
 
135
- if (getValueFromEnvSources('DD_CIVISIBILITY_DANGEROUSLY_FORCE_COVERAGE')) {
135
+ if (config.DD_CIVISIBILITY_DANGEROUSLY_FORCE_COVERAGE) {
136
136
  settings.isCodeCoverageEnabled = true
137
137
  log.debug('Dangerously set code coverage to true')
138
138
  }
139
- if (getValueFromEnvSources('DD_CIVISIBILITY_DANGEROUSLY_FORCE_TEST_SKIPPING')) {
139
+ if (config.DD_CIVISIBILITY_DANGEROUSLY_FORCE_TEST_SKIPPING) {
140
140
  settings.isSuitesSkippingEnabled = true
141
141
  log.debug('Dangerously set test skipping to true')
142
142
  }
@@ -3,10 +3,10 @@
3
3
  const { readFileSync } = require('node:fs')
4
4
  const { gzipSync } = require('node:zlib')
5
5
 
6
+ const getConfig = require('../../config')
6
7
  const FormData = require('../../exporters/common/form-data')
7
8
  const request = require('../../exporters/common/request')
8
9
  const log = require('../../log')
9
- const { getValueFromEnvSources } = require('../../config/helper')
10
10
  const {
11
11
  incrementCountMetric,
12
12
  distributionMetric,
@@ -34,7 +34,7 @@ function uploadCoverageReport (
34
34
  { filePath, format, testEnvironmentMetadata, url, isEvpProxy, evpProxyPrefix },
35
35
  callback
36
36
  ) {
37
- const apiKey = getValueFromEnvSources('DD_API_KEY')
37
+ const apiKey = getConfig().apiKey
38
38
 
39
39
  if (!apiKey && !isEvpProxy) {
40
40
  return callback(new Error('DD_API_KEY is required for coverage report upload'))
@@ -1,8 +1,8 @@
1
1
  'use strict'
2
2
 
3
+ const getConfig = require('../../config')
3
4
  const request = require('../requests/request')
4
5
  const id = require('../../id')
5
- const { getValueFromEnvSources } = require('../../config/helper')
6
6
  const log = require('../../log')
7
7
 
8
8
  const {
@@ -121,7 +121,7 @@ function fetchFromApi ({
121
121
  options.path = `${evpProxyPrefix}/api/v2/test/libraries/test-management/tests`
122
122
  options.headers['X-Datadog-EVP-Subdomain'] = 'api'
123
123
  } else {
124
- const apiKey = getValueFromEnvSources('DD_API_KEY')
124
+ const { apiKey } = getConfig()
125
125
  if (!apiKey) {
126
126
  return done(new Error('Test management tests were not fetched because Datadog API key is not defined.'))
127
127
  }
@@ -10,11 +10,8 @@ export interface ConfigProperties extends GeneratedConfig {
10
10
  }
11
11
  commitSHA: string | undefined
12
12
  debug: boolean
13
- gcpPubSubPushSubscriptionEnabled: boolean
14
13
  instrumentationSource: 'manual' | 'ssi'
15
- isAzureFunction: boolean
16
14
  isCiVisibility: boolean
17
- isGCPFunction: boolean
18
15
  isServiceNameInferred: boolean
19
16
  isServiceUserProvided: boolean
20
17
  logger: import('../../../../index').TracerOptions['logger'] | undefined
@@ -22,7 +19,6 @@ export interface ConfigProperties extends GeneratedConfig {
22
19
  readonly parsedDdTags: Record<string, string>
23
20
  plugins: boolean
24
21
  repositoryUrl: string | undefined
25
- rules: import('../../../../index').SamplingRule[]
26
22
  sampler: {
27
23
  rateLimit: number
28
24
  rules: import('../../../../index').SamplingRule[]
@@ -81,11 +81,8 @@ for (const [name, value] of Object.entries(defaults)) {
81
81
  * @param {string} optionName
82
82
  */
83
83
  function generateTelemetry (value = null, origin, optionName) {
84
- const { type, canonicalName = optionName } = configurationsTable[optionName] ?? { type: typeof value }
85
- // TODO: Consider adding a preParser hook to the parsers object.
86
- if (canonicalName === 'OTEL_RESOURCE_ATTRIBUTES') {
87
- value = telemetryTransformers.MAP(value)
88
- }
84
+ const tableEntry = configurationsTable[optionName]
85
+ const { type, canonicalName = optionName } = tableEntry ?? { type: typeof value }
89
86
  // TODO: Should we not send defaults to telemetry to reduce size?
90
87
  // TODO: How to handle aliases/actual names in the future? Optional fields? Normalize the name at intake?
91
88
  // TODO: Validate that space separated tags are parsed by the backend. Optimizations would be possible with that.
@@ -94,9 +91,12 @@ function generateTelemetry (value = null, origin, optionName) {
94
91
  if (telemetryTransformers[type]) {
95
92
  value = telemetryTransformers[type](value)
96
93
  } else if (typeof value === 'object' && value !== null) {
97
- value = value instanceof URL
98
- ? String(value)
99
- : JSON.stringify(value)
94
+ // Custom optionsTable entries (no `configurationsTable` row, e.g. `logger`)
95
+ // hold opaque user-supplied references that may carry cycles, so avoid
96
+ // traversing them via JSON.stringify.
97
+ value = tableEntry === undefined
98
+ ? util.inspect(value, { depth: -1 })
99
+ : value instanceof URL ? String(value) : JSON.stringify(value)
100
100
  } else if (typeof value === 'function') {
101
101
  value = value.name || 'function'
102
102
  }
@@ -250,7 +250,7 @@ for (const [canonicalName, entries] of Object.entries(supportedConfigurations))
250
250
  option.transformer = transformer
251
251
  }
252
252
  if (entry.configurationNames) {
253
- addOption(option, type, entry.configurationNames)
253
+ addOption(option, entry.configurationNames)
254
254
  }
255
255
  configurationsTable[canonicalName] = option
256
256
 
@@ -287,7 +287,7 @@ for (const [fullPropertyName, alias] of fallbackConfigurations) {
287
287
  }
288
288
  }
289
289
 
290
- function addOption (option, type, configurationNames) {
290
+ function addOption (option, configurationNames) {
291
291
  for (const name of configurationNames) {
292
292
  let index = -1
293
293
  let lastNestedProperties