dd-trace 5.35.0 → 5.36.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 (84) hide show
  1. package/index.d.ts +3 -7
  2. package/package.json +4 -4
  3. package/packages/datadog-core/index.js +1 -1
  4. package/packages/datadog-core/src/storage.js +76 -31
  5. package/packages/datadog-instrumentations/src/jest.js +3 -7
  6. package/packages/datadog-plugin-aerospike/src/index.js +1 -1
  7. package/packages/datadog-plugin-apollo/src/gateway/fetch.js +1 -1
  8. package/packages/datadog-plugin-apollo/src/gateway/index.js +1 -1
  9. package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -1
  10. package/packages/datadog-plugin-aws-sdk/src/base.js +3 -3
  11. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -4
  12. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -2
  13. package/packages/datadog-plugin-azure-functions/src/index.js +1 -1
  14. package/packages/datadog-plugin-couchbase/src/index.js +2 -2
  15. package/packages/datadog-plugin-cucumber/src/index.js +11 -11
  16. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +6 -1
  17. package/packages/datadog-plugin-cypress/src/support.js +36 -29
  18. package/packages/datadog-plugin-grpc/src/client.js +1 -1
  19. package/packages/datadog-plugin-grpc/src/server.js +1 -1
  20. package/packages/datadog-plugin-hapi/src/index.js +1 -1
  21. package/packages/datadog-plugin-http/src/client.js +1 -1
  22. package/packages/datadog-plugin-http/src/server.js +1 -1
  23. package/packages/datadog-plugin-http2/src/client.js +3 -3
  24. package/packages/datadog-plugin-http2/src/server.js +1 -1
  25. package/packages/datadog-plugin-jest/src/index.js +6 -11
  26. package/packages/datadog-plugin-langchain/src/tracing.js +1 -1
  27. package/packages/datadog-plugin-mariadb/src/index.js +3 -3
  28. package/packages/datadog-plugin-mocha/src/index.js +13 -13
  29. package/packages/datadog-plugin-next/src/index.js +4 -4
  30. package/packages/datadog-plugin-openai/src/tracing.js +1 -1
  31. package/packages/datadog-plugin-playwright/src/index.js +4 -4
  32. package/packages/datadog-plugin-rhea/src/consumer.js +1 -1
  33. package/packages/datadog-plugin-router/src/index.js +2 -2
  34. package/packages/datadog-plugin-selenium/src/index.js +1 -1
  35. package/packages/datadog-plugin-vitest/src/index.js +11 -11
  36. package/packages/dd-trace/src/appsec/graphql.js +6 -6
  37. package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +1 -1
  38. package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +6 -6
  39. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +2 -2
  40. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +5 -5
  41. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +2 -2
  42. package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +2 -2
  43. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +2 -2
  44. package/packages/dd-trace/src/appsec/iast/index.js +2 -2
  45. package/packages/dd-trace/src/appsec/iast/taint-tracking/constants.js +6 -0
  46. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +8 -8
  47. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +1 -1
  48. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +65 -0
  49. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-telemetry.js +14 -5
  50. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +80 -2
  51. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -1
  52. package/packages/dd-trace/src/appsec/index.js +4 -4
  53. package/packages/dd-trace/src/appsec/rasp/command_injection.js +1 -1
  54. package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +5 -5
  55. package/packages/dd-trace/src/appsec/rasp/lfi.js +1 -1
  56. package/packages/dd-trace/src/appsec/rasp/sql_injection.js +2 -2
  57. package/packages/dd-trace/src/appsec/rasp/ssrf.js +1 -1
  58. package/packages/dd-trace/src/appsec/reporter.js +3 -3
  59. package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
  60. package/packages/dd-trace/src/appsec/waf/index.js +1 -1
  61. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +2 -0
  62. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +17 -10
  63. package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +3 -3
  64. package/packages/dd-trace/src/config.js +2 -0
  65. package/packages/dd-trace/src/data_streams_context.js +2 -2
  66. package/packages/dd-trace/src/exporters/common/agents.js +1 -1
  67. package/packages/dd-trace/src/exporters/common/request.js +3 -3
  68. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +1 -1
  69. package/packages/dd-trace/src/log/writer.js +3 -3
  70. package/packages/dd-trace/src/noop/span.js +1 -1
  71. package/packages/dd-trace/src/opentracing/propagation/text_map.js +5 -4
  72. package/packages/dd-trace/src/opentracing/span.js +1 -1
  73. package/packages/dd-trace/src/plugin_manager.js +3 -1
  74. package/packages/dd-trace/src/plugins/apollo.js +1 -1
  75. package/packages/dd-trace/src/plugins/ci_plugin.js +35 -1
  76. package/packages/dd-trace/src/plugins/log_plugin.js +1 -1
  77. package/packages/dd-trace/src/plugins/plugin.js +8 -8
  78. package/packages/dd-trace/src/plugins/tracing.js +3 -3
  79. package/packages/dd-trace/src/plugins/util/git.js +3 -3
  80. package/packages/dd-trace/src/plugins/util/test.js +5 -1
  81. package/packages/dd-trace/src/profiling/exporters/agent.js +3 -3
  82. package/packages/dd-trace/src/profiling/profilers/wall.js +1 -1
  83. package/packages/dd-trace/src/scope.js +5 -5
  84. package/packages/dd-trace/src/tracer.js +0 -14
@@ -39,7 +39,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
39
39
 
40
40
  onConfigure () {
41
41
  const onRequestBody = ({ req }) => {
42
- const iastContext = getIastContext(storage.getStore())
42
+ const iastContext = getIastContext(storage('legacy').getStore())
43
43
  if (iastContext && iastContext.body !== req.body) {
44
44
  this._taintTrackingHandler(HTTP_REQUEST_BODY, req, 'body', iastContext)
45
45
  iastContext.body = req.body
@@ -70,7 +70,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
70
70
  { channelName: 'apm:express:middleware:next', tag: HTTP_REQUEST_BODY },
71
71
  ({ req }) => {
72
72
  if (req && req.body !== null && typeof req.body === 'object') {
73
- const iastContext = getIastContext(storage.getStore())
73
+ const iastContext = getIastContext(storage('legacy').getStore())
74
74
  if (iastContext && iastContext.body !== req.body) {
75
75
  this._taintTrackingHandler(HTTP_REQUEST_BODY, req, 'body', iastContext)
76
76
  iastContext.body = req.body
@@ -115,7 +115,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
115
115
  this.addSub(
116
116
  { channelName: 'apm:graphql:resolve:start', tag: HTTP_REQUEST_BODY },
117
117
  (data) => {
118
- const iastContext = getIastContext(storage.getStore())
118
+ const iastContext = getIastContext(storage('legacy').getStore())
119
119
  const source = data.context?.source
120
120
  const ranges = source && getRanges(iastContext, source)
121
121
  if (ranges?.length) {
@@ -128,7 +128,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
128
128
  this.addSub(
129
129
  { channelName: 'datadog:url:parse:finish' },
130
130
  ({ input, base, parsed, isURL }) => {
131
- const iastContext = getIastContext(storage.getStore())
131
+ const iastContext = getIastContext(storage('legacy').getStore())
132
132
  let ranges
133
133
 
134
134
  if (base) {
@@ -157,7 +157,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
157
157
  const origRange = this._taintedURLs.get(context.urlObject)
158
158
  if (!origRange) return
159
159
 
160
- const iastContext = getIastContext(storage.getStore())
160
+ const iastContext = getIastContext(storage('legacy').getStore())
161
161
  if (!iastContext) return
162
162
 
163
163
  context.result =
@@ -168,7 +168,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
168
168
  this.addInstrumentedSource('http', [HTTP_REQUEST_HEADER_VALUE, HTTP_REQUEST_HEADER_NAME])
169
169
  }
170
170
 
171
- _taintTrackingHandler (type, target, property, iastContext = getIastContext(storage.getStore())) {
171
+ _taintTrackingHandler (type, target, property, iastContext = getIastContext(storage('legacy').getStore())) {
172
172
  if (!property) {
173
173
  taintObject(iastContext, target, type)
174
174
  } else if (target[property]) {
@@ -177,7 +177,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
177
177
  }
178
178
 
179
179
  _cookiesTaintTrackingHandler (target) {
180
- const iastContext = getIastContext(storage.getStore())
180
+ const iastContext = getIastContext(storage('legacy').getStore())
181
181
  // Prevent tainting cookie names since it leads to taint literal string with same value.
182
182
  taintObject(iastContext, target, HTTP_REQUEST_COOKIE_VALUE)
183
183
  }
@@ -206,7 +206,7 @@ class TaintTrackingPlugin extends SourceIastPlugin {
206
206
  this.taintUrl(req, iastContext)
207
207
  }
208
208
 
209
- _taintDatabaseResult (result, dbOrigin, iastContext = getIastContext(storage.getStore()), name) {
209
+ _taintDatabaseResult (result, dbOrigin, iastContext = getIastContext(storage('legacy').getStore()), name) {
210
210
  if (!iastContext) return result
211
211
 
212
212
  if (this._rowsToTaint === 0) return result
@@ -22,7 +22,7 @@ class KafkaConsumerIastPlugin extends SourceIastPlugin {
22
22
  }
23
23
 
24
24
  taintKafkaMessage (message) {
25
- const iastContext = getIastContext(storage.getStore())
25
+ const iastContext = getIastContext(storage('legacy').getStore())
26
26
 
27
27
  if (iastContext && message) {
28
28
  const { key, value } = message
@@ -0,0 +1,65 @@
1
+ 'use strict'
2
+
3
+ import path from 'path'
4
+ import { URL } from 'url'
5
+ import { getName } from '../telemetry/verbosity.js'
6
+ import { isNotLibraryFile, isPrivateModule } from './filter.js'
7
+ import constants from './constants.js'
8
+
9
+ const currentUrl = new URL(import.meta.url)
10
+ const ddTraceDir = path.join(currentUrl.pathname, '..', '..', '..', '..', '..', '..')
11
+
12
+ let port, rewriter
13
+
14
+ export async function initialize (data) {
15
+ if (rewriter) return Promise.reject(new Error('ALREADY INITIALIZED'))
16
+
17
+ const { csiMethods, telemetryVerbosity, chainSourceMap } = data
18
+ port = data.port
19
+
20
+ const iastRewriter = await import('@datadog/native-iast-rewriter')
21
+
22
+ const { NonCacheRewriter } = iastRewriter.default
23
+
24
+ rewriter = new NonCacheRewriter({
25
+ csiMethods,
26
+ telemetryVerbosity: getName(telemetryVerbosity),
27
+ chainSourceMap
28
+ })
29
+ }
30
+
31
+ export async function load (url, context, nextLoad) {
32
+ const result = await nextLoad(url, context)
33
+
34
+ if (!port) return result
35
+ if (!result.source) return result
36
+ if (url.includes(ddTraceDir) || url.includes('iitm=true')) return result
37
+
38
+ try {
39
+ if (isPrivateModule(url) && isNotLibraryFile(url)) {
40
+ const rewritten = rewriter.rewrite(result.source.toString(), url)
41
+
42
+ if (rewritten?.content) {
43
+ result.source = rewritten.content || result.source
44
+ const data = { url, rewritten }
45
+ port.postMessage({ type: constants.REWRITTEN_MESSAGE, data })
46
+ }
47
+ }
48
+ } catch (e) {
49
+ const newErrObject = {
50
+ message: e.message,
51
+ stack: e.stack
52
+ }
53
+
54
+ const data = {
55
+ level: 'error',
56
+ messages: ['[ASM] Error rewriting file %s', url, newErrObject]
57
+ }
58
+ port.postMessage({
59
+ type: constants.LOG_MESSAGE,
60
+ data
61
+ })
62
+ }
63
+
64
+ return result
65
+ }
@@ -12,10 +12,7 @@ const telemetryRewriter = {
12
12
  information (content, filename, rewriter) {
13
13
  const response = this.off(content, filename, rewriter)
14
14
 
15
- const metrics = response.metrics
16
- if (metrics && metrics.instrumentedPropagation) {
17
- INSTRUMENTED_PROPAGATION.inc(undefined, metrics.instrumentedPropagation)
18
- }
15
+ incrementTelemetry(response.metrics)
19
16
 
20
17
  return response
21
18
  }
@@ -30,4 +27,16 @@ function getRewriteFunction (rewriter) {
30
27
  }
31
28
  }
32
29
 
33
- module.exports = { getRewriteFunction }
30
+ function incrementTelemetry (metrics) {
31
+ if (metrics?.instrumentedPropagation) {
32
+ INSTRUMENTED_PROPAGATION.inc(undefined, metrics.instrumentedPropagation)
33
+ }
34
+ }
35
+
36
+ function incrementTelemetryIfNeeded (metrics) {
37
+ if (iastTelemetry.verbosity !== Verbosity.OFF) {
38
+ incrementTelemetry(metrics)
39
+ }
40
+ }
41
+
42
+ module.exports = { getRewriteFunction, incrementTelemetryIfNeeded }
@@ -1,18 +1,23 @@
1
1
  'use strict'
2
2
 
3
3
  const Module = require('module')
4
+ const { pathToFileURL } = require('url')
5
+ const { MessageChannel } = require('worker_threads')
4
6
  const shimmer = require('../../../../../datadog-shimmer')
5
7
  const { isPrivateModule, isNotLibraryFile } = require('./filter')
6
8
  const { csiMethods } = require('./csi-methods')
7
9
  const { getName } = require('../telemetry/verbosity')
8
- const { getRewriteFunction } = require('./rewriter-telemetry')
10
+ const { getRewriteFunction, incrementTelemetryIfNeeded } = require('./rewriter-telemetry')
9
11
  const dc = require('dc-polyfill')
10
12
  const log = require('../../../log')
13
+ const { isMainThread } = require('worker_threads')
14
+ const { LOG_MESSAGE, REWRITTEN_MESSAGE } = require('./constants')
11
15
 
12
16
  const hardcodedSecretCh = dc.channel('datadog:secrets:result')
13
17
  let rewriter
14
- let getPrepareStackTrace
18
+ let getPrepareStackTrace, cacheRewrittenSourceMap
15
19
  let kSymbolPrepareStackTrace
20
+ let esmRewriterEnabled = false
16
21
 
17
22
  let getRewriterOriginalPathAndLineFromSourceMap = function (path, line, column) {
18
23
  return { path, line, column }
@@ -46,6 +51,7 @@ function getRewriter (telemetryVerbosity) {
46
51
  const Rewriter = iastRewriter.Rewriter
47
52
  getPrepareStackTrace = iastRewriter.getPrepareStackTrace
48
53
  kSymbolPrepareStackTrace = iastRewriter.kSymbolPrepareStackTrace
54
+ cacheRewrittenSourceMap = iastRewriter.cacheRewrittenSourceMap
49
55
 
50
56
  const chainSourceMap = isFlagPresent('--enable-source-maps')
51
57
  const getOriginalPathAndLineFromSourceMap = iastRewriter.getOriginalPathAndLineFromSourceMap
@@ -104,6 +110,24 @@ function getCompileMethodFn (compileMethod) {
104
110
  }
105
111
  }
106
112
 
113
+ function esmRewritePostProcess (rewritten, filename) {
114
+ const { literalsResult, metrics } = rewritten
115
+
116
+ if (metrics?.status === 'modified') {
117
+ if (filename.startsWith('file://')) {
118
+ filename = filename.substring(7)
119
+ }
120
+
121
+ cacheRewrittenSourceMap(filename, rewritten.content)
122
+ }
123
+
124
+ incrementTelemetryIfNeeded(metrics)
125
+
126
+ if (literalsResult && hardcodedSecretCh.hasSubscribers) {
127
+ hardcodedSecretCh.publish(literalsResult)
128
+ }
129
+ }
130
+
107
131
  function enableRewriter (telemetryVerbosity) {
108
132
  try {
109
133
  const rewriter = getRewriter(telemetryVerbosity)
@@ -114,11 +138,65 @@ function enableRewriter (telemetryVerbosity) {
114
138
  }
115
139
  shimmer.wrap(Module.prototype, '_compile', compileMethod => getCompileMethodFn(compileMethod))
116
140
  }
141
+
142
+ enableEsmRewriter(telemetryVerbosity)
117
143
  } catch (e) {
118
144
  log.error('[ASM] Error enabling TaintTracking Rewriter', e)
119
145
  }
120
146
  }
121
147
 
148
+ function isEsmConfigured () {
149
+ const hasLoaderArg = isFlagPresent('--loader') || isFlagPresent('--experimental-loader')
150
+ if (hasLoaderArg) return true
151
+
152
+ const initializeLoaded = Object.keys(require.cache).find(file => file.includes('import-in-the-middle/hook.js'))
153
+ return !!initializeLoaded
154
+ }
155
+
156
+ function enableEsmRewriter (telemetryVerbosity) {
157
+ if (isMainThread && Module.register && !esmRewriterEnabled && isEsmConfigured()) {
158
+ esmRewriterEnabled = true
159
+
160
+ const { port1, port2 } = new MessageChannel()
161
+
162
+ port1.on('message', (message) => {
163
+ const { type, data } = message
164
+ switch (type) {
165
+ case LOG_MESSAGE:
166
+ log[data.level]?.(...data.messages)
167
+ break
168
+
169
+ case REWRITTEN_MESSAGE:
170
+ esmRewritePostProcess(data.rewritten, data.url)
171
+ break
172
+ }
173
+ })
174
+
175
+ port1.unref()
176
+ port2.unref()
177
+
178
+ const chainSourceMap = isFlagPresent('--enable-source-maps')
179
+ const data = {
180
+ port: port2,
181
+ csiMethods,
182
+ telemetryVerbosity,
183
+ chainSourceMap
184
+ }
185
+
186
+ try {
187
+ Module.register('./rewriter-esm.mjs', {
188
+ parentURL: pathToFileURL(__filename),
189
+ transferList: [port2],
190
+ data
191
+ })
192
+ } catch (e) {
193
+ log.error('[ASM] Error enabling ESM Rewriter', e)
194
+ port1.close()
195
+ port2.close()
196
+ }
197
+ }
198
+ }
199
+
122
200
  function disableRewriter () {
123
201
  shimmer.unwrap(Module.prototype, '_compile')
124
202
 
@@ -39,7 +39,7 @@ function getTransactionId (iastContext) {
39
39
  }
40
40
 
41
41
  function getContextDefault () {
42
- const store = storage.getStore()
42
+ const store = storage('legacy').getStore()
43
43
  return iastContextFunctions.getIastContext(store)
44
44
  }
45
45
 
@@ -91,7 +91,7 @@ function onRequestBodyParsed ({ req, res, body, abortController }) {
91
91
  if (body === undefined || body === null) return
92
92
 
93
93
  if (!req) {
94
- const store = storage.getStore()
94
+ const store = storage('legacy').getStore()
95
95
  req = store?.req
96
96
  }
97
97
 
@@ -186,7 +186,7 @@ function incomingHttpEndTranslator ({ req, res }) {
186
186
  }
187
187
 
188
188
  function onPassportVerify ({ framework, login, user, success, abortController }) {
189
- const store = storage.getStore()
189
+ const store = storage('legacy').getStore()
190
190
  const rootSpan = store?.req && web.root(store.req)
191
191
 
192
192
  if (!rootSpan) {
@@ -200,7 +200,7 @@ function onPassportVerify ({ framework, login, user, success, abortController })
200
200
  }
201
201
 
202
202
  function onPassportDeserializeUser ({ user, abortController }) {
203
- const store = storage.getStore()
203
+ const store = storage('legacy').getStore()
204
204
  const rootSpan = store?.req && web.root(store.req)
205
205
 
206
206
  if (!rootSpan) {
@@ -217,7 +217,7 @@ function onRequestQueryParsed ({ req, res, query, abortController }) {
217
217
  if (!query || typeof query !== 'object') return
218
218
 
219
219
  if (!req) {
220
- const store = storage.getStore()
220
+ const store = storage('legacy').getStore()
221
221
  req = store?.req
222
222
  }
223
223
 
@@ -27,7 +27,7 @@ function disable () {
27
27
  function analyzeCommandInjection ({ file, fileArgs, shell, abortController }) {
28
28
  if (!file) return
29
29
 
30
- const store = storage.getStore()
30
+ const store = storage('legacy').getStore()
31
31
  const req = store?.req
32
32
  if (!req) return
33
33
 
@@ -14,9 +14,9 @@ const enabledFor = {
14
14
 
15
15
  let fsPlugin
16
16
 
17
- function enterWith (fsProps, store = storage.getStore()) {
17
+ function enterWith (fsProps, store = storage('legacy').getStore()) {
18
18
  if (store && !store.fs?.opExcluded) {
19
- storage.enterWith({
19
+ storage('legacy').enterWith({
20
20
  ...store,
21
21
  fs: {
22
22
  ...store.fs,
@@ -42,7 +42,7 @@ class AppsecFsPlugin extends Plugin {
42
42
  }
43
43
 
44
44
  _onFsOperationStart () {
45
- const store = storage.getStore()
45
+ const store = storage('legacy').getStore()
46
46
  if (store) {
47
47
  enterWith({ root: store.fs?.root === undefined }, store)
48
48
  }
@@ -53,9 +53,9 @@ class AppsecFsPlugin extends Plugin {
53
53
  }
54
54
 
55
55
  _onFsOperationFinishOrRenderEnd () {
56
- const store = storage.getStore()
56
+ const store = storage('legacy').getStore()
57
57
  if (store?.fs?.parentStore) {
58
- storage.enterWith(store.fs.parentStore)
58
+ storage('legacy').enterWith(store.fs.parentStore)
59
59
  }
60
60
  }
61
61
  }
@@ -47,7 +47,7 @@ function onFirstReceivedRequest () {
47
47
  }
48
48
 
49
49
  function analyzeLfi (ctx) {
50
- const store = storage.getStore()
50
+ const store = storage('legacy').getStore()
51
51
  if (!store) return
52
52
 
53
53
  const { req, fs, res } = store
@@ -49,7 +49,7 @@ function analyzePgSqlInjection (ctx) {
49
49
  }
50
50
 
51
51
  function analyzeSqlInjection (query, dbSystem, abortController) {
52
- const store = storage.getStore()
52
+ const store = storage('legacy').getStore()
53
53
  if (!store) return
54
54
 
55
55
  const { req, res } = store
@@ -91,7 +91,7 @@ function hasAddressesObjectInputAddress (addressesObject) {
91
91
  function clearQuerySet ({ payload }) {
92
92
  if (!payload) return
93
93
 
94
- const store = storage.getStore()
94
+ const store = storage('legacy').getStore()
95
95
  if (!store) return
96
96
 
97
97
  const { req } = store
@@ -19,7 +19,7 @@ function disable () {
19
19
  }
20
20
 
21
21
  function analyzeSsrf (ctx) {
22
- const store = storage.getStore()
22
+ const store = storage('legacy').getStore()
23
23
  const req = store?.req
24
24
  const outgoingUrl = (ctx.args.options?.uri && format(ctx.args.options.uri)) ?? ctx.args.uri
25
25
 
@@ -102,7 +102,7 @@ function reportWafInit (wafVersion, rulesVersion, diagnosticsRules = {}) {
102
102
  }
103
103
 
104
104
  function reportMetrics (metrics, raspRule) {
105
- const store = storage.getStore()
105
+ const store = storage('legacy').getStore()
106
106
  const rootSpan = store?.req && web.root(store.req)
107
107
  if (!rootSpan) return
108
108
 
@@ -117,7 +117,7 @@ function reportMetrics (metrics, raspRule) {
117
117
  }
118
118
 
119
119
  function reportAttack (attackData) {
120
- const store = storage.getStore()
120
+ const store = storage('legacy').getStore()
121
121
  const req = store?.req
122
122
  const rootSpan = web.root(req)
123
123
  if (!rootSpan) return
@@ -162,7 +162,7 @@ function isFingerprintDerivative (derivative) {
162
162
  function reportDerivatives (derivatives) {
163
163
  if (!derivatives) return
164
164
 
165
- const req = storage.getStore()?.req
165
+ const req = storage('legacy').getStore()?.req
166
166
  const rootSpan = web.root(req)
167
167
 
168
168
  if (!rootSpan) return
@@ -34,7 +34,7 @@ function checkUserAndSetUser (tracer, user) {
34
34
 
35
35
  function blockRequest (tracer, req, res) {
36
36
  if (!req || !res) {
37
- const store = storage.getStore()
37
+ const store = storage('legacy').getStore()
38
38
  if (store) {
39
39
  req = req || store.req
40
40
  res = res || store.res
@@ -48,7 +48,7 @@ function update (newRules) {
48
48
 
49
49
  function run (data, req, raspRule) {
50
50
  if (!req) {
51
- const store = storage.getStore()
51
+ const store = storage('legacy').getStore()
52
52
  if (!store || !store.req) {
53
53
  log.warn('[ASM] Request object not available in waf.run')
54
54
  return
@@ -119,6 +119,8 @@ class TestVisDynamicInstrumentation {
119
119
  const onHit = this.onHitBreakpointByProbeId.get(probeId)
120
120
  if (onHit) {
121
121
  onHit({ snapshot })
122
+ } else {
123
+ log.warn('Received a breakpoint hit for an unknown probe')
122
124
  }
123
125
  }).unref()
124
126
 
@@ -93,11 +93,14 @@ async function addBreakpoint (probe) {
93
93
  probe.location = { file, lines: [String(line)] }
94
94
 
95
95
  const script = findScriptFromPartialPath(file)
96
- if (!script) throw new Error(`No loaded script found for ${file}`)
96
+ if (!script) {
97
+ log.error(`No loaded script found for ${file}`)
98
+ throw new Error(`No loaded script found for ${file}`)
99
+ }
97
100
 
98
101
  const [path, scriptId, sourceMapURL] = script
99
102
 
100
- log.debug(`Adding breakpoint at ${path}:${line}`)
103
+ log.warn(`Adding breakpoint at ${path}:${line}`)
101
104
 
102
105
  let lineNumber = line
103
106
 
@@ -109,15 +112,19 @@ async function addBreakpoint (probe) {
109
112
  }
110
113
  }
111
114
 
112
- const { breakpointId } = await session.post('Debugger.setBreakpoint', {
113
- location: {
114
- scriptId,
115
- lineNumber: lineNumber - 1
116
- }
117
- })
115
+ try {
116
+ const { breakpointId } = await session.post('Debugger.setBreakpoint', {
117
+ location: {
118
+ scriptId,
119
+ lineNumber: lineNumber - 1
120
+ }
121
+ })
118
122
 
119
- breakpointIdToProbe.set(breakpointId, probe)
120
- probeIdToBreakpointId.set(probe.id, breakpointId)
123
+ breakpointIdToProbe.set(breakpointId, probe)
124
+ probeIdToBreakpointId.set(probe.id, breakpointId)
125
+ } catch (e) {
126
+ log.error(`Error setting breakpoint at ${path}:${line}:`, e)
127
+ }
121
128
  }
122
129
 
123
130
  function start () {
@@ -17,13 +17,13 @@ class TestApiManualPlugin extends CiPlugin {
17
17
  this.sourceRoot = process.cwd()
18
18
 
19
19
  this.unconfiguredAddSub('dd-trace:ci:manual:test:start', ({ testName, testSuite }) => {
20
- const store = storage.getStore()
20
+ const store = storage('legacy').getStore()
21
21
  const testSuiteRelative = getTestSuitePath(testSuite, this.sourceRoot)
22
22
  const testSpan = this.startTestSpan(testName, testSuiteRelative)
23
23
  this.enter(testSpan, store)
24
24
  })
25
25
  this.unconfiguredAddSub('dd-trace:ci:manual:test:finish', ({ status, error }) => {
26
- const store = storage.getStore()
26
+ const store = storage('legacy').getStore()
27
27
  const testSpan = store && store.span
28
28
  if (testSpan) {
29
29
  testSpan.setTag(TEST_STATUS, status)
@@ -35,7 +35,7 @@ class TestApiManualPlugin extends CiPlugin {
35
35
  }
36
36
  })
37
37
  this.unconfiguredAddSub('dd-trace:ci:manual:test:addTags', (tags) => {
38
- const store = storage.getStore()
38
+ const store = storage('legacy').getStore()
39
39
  const testSpan = store && store.span
40
40
  if (testSpan) {
41
41
  testSpan.addTags(tags)
@@ -518,6 +518,7 @@ class Config {
518
518
  this._setValue(defaults, 'ciVisAgentlessLogSubmissionEnabled', false)
519
519
  this._setValue(defaults, 'legacyBaggageEnabled', true)
520
520
  this._setValue(defaults, 'isTestDynamicInstrumentationEnabled', false)
521
+ this._setValue(defaults, 'isServiceUserProvided', false)
521
522
  this._setValue(defaults, 'logInjection', false)
522
523
  this._setValue(defaults, 'lookup', undefined)
523
524
  this._setValue(defaults, 'inferredProxyServicesEnabled', false)
@@ -1156,6 +1157,7 @@ class Config {
1156
1157
  this._setString(calc, 'ciVisibilityTestSessionName', DD_TEST_SESSION_NAME)
1157
1158
  this._setBoolean(calc, 'ciVisAgentlessLogSubmissionEnabled', isTrue(DD_AGENTLESS_LOG_SUBMISSION_ENABLED))
1158
1159
  this._setBoolean(calc, 'isTestDynamicInstrumentationEnabled', isTrue(DD_TEST_DYNAMIC_INSTRUMENTATION_ENABLED))
1160
+ this._setBoolean(calc, 'isServiceUserProvided', !!this._env.service)
1159
1161
  }
1160
1162
  this._setString(calc, 'dogstatsd.hostname', this._getHostname())
1161
1163
  this._setBoolean(calc, 'isGitUploadEnabled',
@@ -2,14 +2,14 @@ const { storage } = require('../../datadog-core')
2
2
  const log = require('./log')
3
3
 
4
4
  function getDataStreamsContext () {
5
- const store = storage.getStore()
5
+ const store = storage('legacy').getStore()
6
6
  return (store && store.dataStreamsContext) || null
7
7
  }
8
8
 
9
9
  function setDataStreamsContext (dataStreamsContext) {
10
10
  log.debug(() => `Setting new DSM Context: ${JSON.stringify(dataStreamsContext)}.`)
11
11
 
12
- if (dataStreamsContext) storage.enterWith({ ...(storage.getStore()), dataStreamsContext })
12
+ if (dataStreamsContext) storage('legacy').enterWith({ ...(storage('legacy').getStore()), dataStreamsContext })
13
13
  }
14
14
 
15
15
  module.exports = {
@@ -26,7 +26,7 @@ function createAgentClass (BaseAgent) {
26
26
  }
27
27
 
28
28
  _noop (callback) {
29
- return storage.run({ noop: true }, callback)
29
+ return storage('legacy').run({ noop: true }, callback)
30
30
  }
31
31
  }
32
32
 
@@ -126,9 +126,9 @@ function request (data, options, callback) {
126
126
 
127
127
  activeRequests++
128
128
 
129
- const store = storage.getStore()
129
+ const store = storage('legacy').getStore()
130
130
 
131
- storage.enterWith({ noop: true })
131
+ storage('legacy').enterWith({ noop: true })
132
132
 
133
133
  const req = client.request(options, onResponse)
134
134
 
@@ -146,7 +146,7 @@ function request (data, options, callback) {
146
146
  req.end()
147
147
  }
148
148
 
149
- storage.enterWith(store)
149
+ storage('legacy').enterWith(store)
150
150
  }
151
151
 
152
152
  // TODO: Figure out why setTimeout is needed to avoid losing the async context
@@ -29,7 +29,7 @@ class BedrockRuntimeLLMObsPlugin extends BaseLLMObsPlugin {
29
29
  if (modelName.includes('embed')) {
30
30
  return
31
31
  }
32
- const span = storage.getStore()?.span
32
+ const span = storage('legacy').getStore()?.span
33
33
  this.setLLMObsTags({ request, span, response, modelProvider, modelName })
34
34
  })
35
35
 
@@ -15,11 +15,11 @@ let logger = defaultLogger
15
15
  let logChannel = new LogChannel()
16
16
 
17
17
  function withNoop (fn) {
18
- const store = storage.getStore()
18
+ const store = storage('legacy').getStore()
19
19
 
20
- storage.enterWith({ noop: true })
20
+ storage('legacy').enterWith({ noop: true })
21
21
  fn()
22
- storage.enterWith(store)
22
+ storage('legacy').enterWith(store)
23
23
  }
24
24
 
25
25
  function unsubscribeAll () {
@@ -6,7 +6,7 @@ const { storage } = require('../../../datadog-core') // TODO: noop storage?
6
6
 
7
7
  class NoopSpan {
8
8
  constructor (tracer, parent) {
9
- this._store = storage.getHandle()
9
+ this._store = storage('legacy').getHandle()
10
10
  this._noopTracer = tracer
11
11
  this._noopContext = this._createContext(parent)
12
12
  }