dd-trace 5.85.0 → 5.87.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 (71) hide show
  1. package/index.d.ts +38 -4
  2. package/package.json +1 -1
  3. package/packages/datadog-core/src/storage.js +30 -12
  4. package/packages/datadog-instrumentations/src/cucumber.js +14 -0
  5. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  6. package/packages/datadog-instrumentations/src/http/client.js +119 -1
  7. package/packages/datadog-instrumentations/src/jest.js +135 -10
  8. package/packages/datadog-instrumentations/src/mocha/main.js +9 -0
  9. package/packages/datadog-instrumentations/src/mocha/utils.js +6 -0
  10. package/packages/datadog-instrumentations/src/mysql2.js +131 -64
  11. package/packages/datadog-instrumentations/src/playwright.js +8 -0
  12. package/packages/datadog-instrumentations/src/prisma.js +225 -30
  13. package/packages/datadog-instrumentations/src/stripe.js +92 -0
  14. package/packages/datadog-instrumentations/src/vitest.js +11 -0
  15. package/packages/datadog-instrumentations/src/ws.js +22 -0
  16. package/packages/datadog-plugin-azure-functions/src/index.js +53 -37
  17. package/packages/datadog-plugin-cucumber/src/index.js +4 -10
  18. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +12 -1
  19. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -4
  20. package/packages/datadog-plugin-http/src/server.js +23 -8
  21. package/packages/datadog-plugin-jest/src/index.js +29 -10
  22. package/packages/datadog-plugin-jest/src/util.js +7 -1
  23. package/packages/datadog-plugin-mocha/src/index.js +5 -17
  24. package/packages/datadog-plugin-playwright/src/index.js +3 -0
  25. package/packages/datadog-plugin-prisma/src/datadog-tracing-helper.js +37 -14
  26. package/packages/datadog-plugin-prisma/src/index.js +8 -5
  27. package/packages/datadog-plugin-router/src/index.js +28 -19
  28. package/packages/datadog-plugin-vitest/src/index.js +6 -10
  29. package/packages/datadog-plugin-ws/src/server.js +8 -0
  30. package/packages/dd-trace/src/appsec/addresses.js +11 -0
  31. package/packages/dd-trace/src/appsec/channels.js +5 -1
  32. package/packages/dd-trace/src/appsec/downstream_requests.js +302 -0
  33. package/packages/dd-trace/src/appsec/iast/path-line.js +1 -0
  34. package/packages/dd-trace/src/appsec/index.js +103 -0
  35. package/packages/dd-trace/src/appsec/rasp/ssrf.js +66 -4
  36. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +14 -1
  37. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
  38. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +19 -0
  39. package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +15 -0
  40. package/packages/dd-trace/src/ci-visibility/telemetry.js +36 -0
  41. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +44 -1
  42. package/packages/dd-trace/src/config/defaults.js +2 -0
  43. package/packages/dd-trace/src/config/index.js +6 -0
  44. package/packages/dd-trace/src/config/supported-configurations.json +2 -0
  45. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +47 -2
  46. package/packages/dd-trace/src/debugger/devtools_client/index.js +75 -23
  47. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +23 -1
  48. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +3 -3
  49. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +168 -36
  50. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +18 -0
  51. package/packages/dd-trace/src/exporters/common/agents.js +1 -1
  52. package/packages/dd-trace/src/exporters/common/request.js +35 -35
  53. package/packages/dd-trace/src/id.js +1 -1
  54. package/packages/dd-trace/src/lambda/context.js +27 -0
  55. package/packages/dd-trace/src/lambda/handler.js +5 -18
  56. package/packages/dd-trace/src/llmobs/constants/writers.js +1 -1
  57. package/packages/dd-trace/src/llmobs/sdk.js +34 -5
  58. package/packages/dd-trace/src/log/writer.js +1 -5
  59. package/packages/dd-trace/src/plugins/ci_plugin.js +63 -1
  60. package/packages/dd-trace/src/plugins/database.js +42 -43
  61. package/packages/dd-trace/src/plugins/outbound.js +27 -2
  62. package/packages/dd-trace/src/plugins/tracing.js +39 -4
  63. package/packages/dd-trace/src/plugins/util/git.js +27 -30
  64. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +7 -0
  65. package/packages/dd-trace/src/plugins/util/test.js +3 -1
  66. package/packages/dd-trace/src/plugins/util/web.js +9 -7
  67. package/packages/dd-trace/src/profiling/config.js +6 -14
  68. package/packages/dd-trace/src/profiling/exporters/agent.js +23 -24
  69. package/packages/dd-trace/src/profiling/profiler.js +2 -0
  70. package/packages/dd-trace/src/startup-log.js +3 -2
  71. package/packages/dd-trace/src/plugins/util/serverless.js +0 -8
@@ -54,6 +54,7 @@ function startSpanHelper (tracer, name, options, traceCtx, config = {}) {
54
54
 
55
55
  const web = {
56
56
  TYPE: WEB,
57
+ /** @type {TracingPlugin | null} */
57
58
  plugin: null,
58
59
 
59
60
  // Ensure the configuration has the correct structure and defaults.
@@ -118,7 +119,7 @@ const web = {
118
119
  context.span.context()._name = name
119
120
  span = context.span
120
121
  } else {
121
- span = web.startChildSpan(tracer, config, name, req, traceCtx)
122
+ span = web.startServerlessSpanWithInferredProxy(tracer, config, name, req, traceCtx)
122
123
  }
123
124
 
124
125
  context.tracer = tracer
@@ -274,7 +275,7 @@ const web = {
274
275
  return context.middleware.at(-1)
275
276
  },
276
277
 
277
- startChildSpan (tracer, config, name, req, traceCtx) {
278
+ startServerlessSpanWithInferredProxy (tracer, config, name, req, traceCtx) {
278
279
  const headers = req.headers
279
280
  const reqCtx = contexts.get(req)
280
281
  const { storage } = require('../../../../datadog-core')
@@ -337,12 +338,12 @@ const web = {
337
338
  }
338
339
  },
339
340
 
340
- finishSpan (context) {
341
+ finishSpan (context, spanType) {
341
342
  const { req, res } = context
342
343
 
343
344
  if (context.finished && !req.stream) return
344
345
 
345
- addRequestTags(context, this.TYPE)
346
+ addRequestTags(context, spanType)
346
347
  addResponseTags(context)
347
348
 
348
349
  context.config.hooks.request(context.span, req, res)
@@ -352,14 +353,14 @@ const web = {
352
353
  context.finished = true
353
354
  },
354
355
 
355
- finishAll (context) {
356
+ finishAll (context, spanType) {
356
357
  for (const beforeEnd of context.beforeEnd) {
357
358
  beforeEnd()
358
359
  }
359
360
 
360
361
  web.finishMiddleware(context)
361
362
 
362
- web.finishSpan(context)
363
+ web.finishSpan(context, spanType)
363
364
 
364
365
  finishInferredProxySpan(context)
365
366
  },
@@ -456,12 +457,13 @@ function reactivate (req, fn) {
456
457
  function addRequestTags (context, spanType) {
457
458
  const { req, span, inferredProxySpan, config } = context
458
459
  const url = extractURL(req)
460
+ const type = spanType ?? WEB
459
461
 
460
462
  span.addTags({
461
463
  [HTTP_URL]: obfuscateQs(config, url),
462
464
  [HTTP_METHOD]: req.method,
463
465
  [SPAN_KIND]: SERVER,
464
- [SPAN_TYPE]: spanType,
466
+ [SPAN_TYPE]: type,
465
467
  [HTTP_USERAGENT]: req.headers['user-agent'],
466
468
  })
467
469
 
@@ -1,8 +1,8 @@
1
1
  'use strict'
2
2
 
3
- const os = require('os')
4
3
  const path = require('path')
5
4
  const { pathToFileURL } = require('url')
5
+
6
6
  const satisfies = require('../../../../vendor/dist/semifies')
7
7
  const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
8
8
  const { getIsAzureFunction } = require('../serverless')
@@ -10,6 +10,8 @@ const { isFalse, isTrue } = require('../util')
10
10
  const { getAzureTagsFromMetadata, getAzureAppMetadata, getAzureFunctionMetadata } = require('../azure_metadata')
11
11
  const { getEnvironmentVariable, getValueFromEnvSources } = require('../config/helper')
12
12
  const { getAgentUrl } = require('../agent/url')
13
+ const { isACFActive } = require('../../../datadog-core/src/storage')
14
+
13
15
  const { AgentExporter } = require('./exporters/agent')
14
16
  const { FileExporter } = require('./exporters/file')
15
17
  const { ConsoleLogger } = require('./loggers/console')
@@ -18,12 +20,12 @@ const SpaceProfiler = require('./profilers/space')
18
20
  const EventsProfiler = require('./profilers/events')
19
21
  const { oomExportStrategies, snapshotKinds } = require('./constants')
20
22
  const { tagger } = require('./tagger')
23
+
21
24
  class Config {
22
25
  constructor (options = {}) {
23
26
  // TODO: Remove entries that were already resolved in config.
24
27
  // For the others, move them over to config.
25
28
  const AWS_LAMBDA_FUNCTION_NAME = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME')
26
- const NODE_OPTIONS = getEnvironmentVariable('NODE_OPTIONS')
27
29
 
28
30
  // TODO: Move initialization of these values to packages/dd-trace/src/config/index.js, and just read from config
29
31
  const {
@@ -50,7 +52,6 @@ class Config {
50
52
  DD_TAGS,
51
53
  } = getProfilingEnvValues()
52
54
 
53
- const host = os.hostname()
54
55
  // Must be longer than one minute so pad with five seconds
55
56
  const flushInterval = options.interval ?? (Number(DD_PROFILING_UPLOAD_PERIOD) * 1000 || 65 * 1000)
56
57
  const uploadTimeout = options.uploadTimeout ?? (Number(DD_PROFILING_UPLOAD_TIMEOUT) || 60 * 1000)
@@ -59,7 +60,6 @@ class Config {
59
60
  // TODO: Remove the fallback. Just use the value from the config.
60
61
  this.service = options.service || 'node'
61
62
  this.env = options.env
62
- this.host = host
63
63
  this.functionname = AWS_LAMBDA_FUNCTION_NAME
64
64
 
65
65
  this.version = options.version
@@ -68,7 +68,7 @@ class Config {
68
68
  tagger.parse(options.tags),
69
69
  tagger.parse({
70
70
  env: options.env,
71
- host,
71
+ host: options.reportHostname ? require('os').hostname() : undefined,
72
72
  service: this.service,
73
73
  version: this.version,
74
74
  functionname: AWS_LAMBDA_FUNCTION_NAME,
@@ -219,16 +219,8 @@ class Config {
219
219
  that.asyncContextFrameEnabled = false
220
220
  }
221
221
 
222
- const hasExecArg = (arg) => process.execArgv.includes(arg) || String(NODE_OPTIONS).includes(arg)
222
+ const canUseAsyncContextFrame = samplingContextsAvailable && isACFActive
223
223
 
224
- let canUseAsyncContextFrame = false
225
- if (samplingContextsAvailable) {
226
- if (isAtLeast24) {
227
- canUseAsyncContextFrame = !hasExecArg('--no-async-context-frame')
228
- } else if (satisfies(process.versions.node, '>=22.9.0')) {
229
- canUseAsyncContextFrame = hasExecArg('--experimental-async-context-frame')
230
- }
231
- }
232
224
  this.asyncContextFrameEnabled = isTrue(DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED ?? canUseAsyncContextFrame)
233
225
  if (this.asyncContextFrameEnabled && !canUseAsyncContextFrame) {
234
226
  if (!samplingContextsAvailable) {
@@ -38,32 +38,31 @@ function countStatusCode (statusCode) {
38
38
  function sendRequest (options, form, callback) {
39
39
  const request = options.protocol === 'https:' ? httpsRequest : httpRequest
40
40
 
41
- const store = storage('legacy').getStore()
42
- storage('legacy').enterWith({ noop: true })
43
- requestCounter.inc()
44
- const start = perf.now()
45
- const req = request(options, res => {
46
- durationDistribution.track(perf.now() - start)
47
- countStatusCode(res.statusCode)
48
- if (res.statusCode >= 400) {
49
- statusCodeErrorCounter.inc()
50
- const error = new Error(`HTTP Error ${res.statusCode}`)
51
- error.status = res.statusCode
52
- callback(error)
53
- } else {
54
- callback(null, res)
55
- }
56
- })
41
+ storage('legacy').run({ noop: true }, () => {
42
+ requestCounter.inc()
43
+ const start = perf.now()
44
+ const req = request(options, res => {
45
+ durationDistribution.track(perf.now() - start)
46
+ countStatusCode(res.statusCode)
47
+ if (res.statusCode >= 400) {
48
+ statusCodeErrorCounter.inc()
49
+ const error = new Error(`HTTP Error ${res.statusCode}`)
50
+ error.status = res.statusCode
51
+ callback(error)
52
+ } else {
53
+ callback(null, res)
54
+ }
55
+ })
57
56
 
58
- req.on('error', (err) => {
59
- networkErrorCounter.inc()
60
- callback(err)
57
+ req.on('error', (err) => {
58
+ networkErrorCounter.inc()
59
+ callback(err)
60
+ })
61
+ if (form) {
62
+ sizeDistribution.track(form.size())
63
+ form.pipe(req)
64
+ }
61
65
  })
62
- if (form) {
63
- sizeDistribution.track(form.size())
64
- form.pipe(req)
65
- }
66
- storage('legacy').enterWith(store)
67
66
  }
68
67
 
69
68
  function getBody (stream, callback) {
@@ -76,6 +76,7 @@ class Profiler extends EventEmitter {
76
76
  repositoryUrl,
77
77
  commitSHA,
78
78
  injectionEnabled,
79
+ reportHostname,
79
80
  } = config
80
81
  const { enabled, sourceMap, exporters } = config.profiling
81
82
  const { heartbeatInterval } = config.telemetry
@@ -112,6 +113,7 @@ class Profiler extends EventEmitter {
112
113
  libraryInjected,
113
114
  activation,
114
115
  heartbeatInterval,
116
+ reportHostname,
115
117
  }
116
118
 
117
119
  return this._start(options).catch((err) => {
@@ -4,7 +4,7 @@ const os = require('os')
4
4
  const { inspect } = require('util')
5
5
  const tracerVersion = require('../../../package.json').version
6
6
  const { getAgentUrl } = require('./agent/url')
7
- const { info, warn } = require('./log/writer')
7
+ const { warn } = require('./log/writer')
8
8
 
9
9
  const errors = {}
10
10
  let config
@@ -29,7 +29,7 @@ function startupLog (agentError) {
29
29
  out.agent_error = agentError.message
30
30
  }
31
31
 
32
- info('DATADOG TRACER CONFIGURATION - ' + out)
32
+ warn('DATADOG TRACER CONFIGURATION - ' + out)
33
33
  if (agentError) {
34
34
  warn('DATADOG TRACER DIAGNOSTIC - Agent Error: ' + agentError.message)
35
35
  errors.agentError = {
@@ -75,6 +75,7 @@ function tracerInfo () {
75
75
  profiling_enabled: config.profiling?.enabled === 'true' || config.profiling?.enabled === 'auto',
76
76
  integrations_loaded: Object.keys(pluginManager._pluginsByName),
77
77
  appsec_enabled: !!config.appsec.enabled,
78
+ data_streams_enabled: !!config.dsmEnabled,
78
79
  }
79
80
 
80
81
  return out
@@ -1,8 +0,0 @@
1
- 'use strict'
2
-
3
- const types = require('../../../../../ext/types')
4
- const web = require('./web')
5
-
6
- const serverless = { ...web, TYPE: types.SERVERLESS }
7
-
8
- module.exports = serverless