dd-trace 5.66.0 → 5.68.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 (107) hide show
  1. package/LICENSE-3rdparty.csv +0 -3
  2. package/README.md +0 -2
  3. package/ci/init.js +52 -54
  4. package/ext/exporters.d.ts +2 -1
  5. package/ext/exporters.js +2 -1
  6. package/index.d.ts +85 -2
  7. package/initialize.mjs +1 -1
  8. package/package.json +8 -11
  9. package/packages/datadog-esbuild/index.js +56 -0
  10. package/packages/datadog-instrumentations/src/aws-sdk.js +42 -4
  11. package/packages/datadog-instrumentations/src/azure-functions.js +1 -1
  12. package/packages/datadog-instrumentations/src/azure-service-bus.js +1 -1
  13. package/packages/datadog-instrumentations/src/cassandra-driver.js +2 -2
  14. package/packages/datadog-instrumentations/src/connect.js +6 -2
  15. package/packages/datadog-instrumentations/src/cucumber.js +31 -6
  16. package/packages/datadog-instrumentations/src/express.js +5 -6
  17. package/packages/datadog-instrumentations/src/fastify.js +3 -3
  18. package/packages/datadog-instrumentations/src/helpers/hook.js +28 -15
  19. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
  20. package/packages/datadog-instrumentations/src/helpers/instrument.js +11 -2
  21. package/packages/datadog-instrumentations/src/helpers/register.js +10 -3
  22. package/packages/datadog-instrumentations/src/http2/client.js +1 -0
  23. package/packages/datadog-instrumentations/src/http2/server.js +0 -1
  24. package/packages/datadog-instrumentations/src/ioredis.js +12 -1
  25. package/packages/datadog-instrumentations/src/jest.js +48 -36
  26. package/packages/datadog-instrumentations/src/limitd-client.js +2 -1
  27. package/packages/datadog-instrumentations/src/mocha/main.js +15 -7
  28. package/packages/datadog-instrumentations/src/mocha/utils.js +3 -0
  29. package/packages/datadog-instrumentations/src/mongoose.js +2 -1
  30. package/packages/datadog-instrumentations/src/oracledb.js +19 -13
  31. package/packages/datadog-instrumentations/src/pg.js +9 -5
  32. package/packages/datadog-instrumentations/src/pino.js +18 -6
  33. package/packages/datadog-instrumentations/src/playwright.js +15 -1
  34. package/packages/datadog-instrumentations/src/sequelize.js +1 -1
  35. package/packages/datadog-instrumentations/src/vitest.js +155 -62
  36. package/packages/datadog-plugin-ai/src/tracing.js +3 -3
  37. package/packages/datadog-plugin-aws-sdk/src/base.js +23 -8
  38. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +2 -2
  39. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +101 -2
  40. package/packages/datadog-plugin-aws-sdk/src/util.js +1 -1
  41. package/packages/datadog-plugin-cucumber/src/index.js +4 -56
  42. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +6 -2
  43. package/packages/datadog-plugin-cypress/src/support.js +4 -0
  44. package/packages/datadog-plugin-express/src/code_origin.js +2 -2
  45. package/packages/datadog-plugin-fastify/src/code_origin.js +1 -2
  46. package/packages/datadog-plugin-jest/src/index.js +0 -21
  47. package/packages/datadog-plugin-mocha/src/index.js +3 -57
  48. package/packages/datadog-plugin-mongodb-core/src/index.js +20 -7
  49. package/packages/datadog-plugin-playwright/src/index.js +11 -5
  50. package/packages/datadog-plugin-vitest/src/index.js +5 -1
  51. package/packages/datadog-plugin-ws/src/close.js +1 -1
  52. package/packages/datadog-plugin-ws/src/producer.js +6 -1
  53. package/packages/datadog-plugin-ws/src/receiver.js +6 -1
  54. package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +1 -1
  55. package/packages/dd-trace/src/appsec/telemetry/waf.js +2 -2
  56. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -4
  57. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +11 -3
  58. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +10 -1
  59. package/packages/dd-trace/src/config.js +69 -304
  60. package/packages/dd-trace/src/config_defaults.js +186 -0
  61. package/packages/dd-trace/src/crashtracking/crashtracker.js +2 -1
  62. package/packages/dd-trace/src/datastreams/fnv.js +2 -2
  63. package/packages/dd-trace/src/datastreams/writer.js +3 -2
  64. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -1
  65. package/packages/dd-trace/src/dogstatsd.js +4 -3
  66. package/packages/dd-trace/src/encode/0.4.js +1 -5
  67. package/packages/dd-trace/src/exporter.js +1 -0
  68. package/packages/dd-trace/src/exporters/agent/index.js +3 -2
  69. package/packages/dd-trace/src/exporters/agent/writer.js +1 -1
  70. package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +3 -2
  71. package/packages/dd-trace/src/exporters/common/request.js +2 -1
  72. package/packages/dd-trace/src/exporters/span-stats/index.js +3 -2
  73. package/packages/dd-trace/src/llmobs/constants/tags.js +2 -0
  74. package/packages/dd-trace/src/llmobs/index.js +7 -0
  75. package/packages/dd-trace/src/llmobs/plugins/ai/index.js +4 -3
  76. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -1
  77. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +40 -13
  78. package/packages/dd-trace/src/llmobs/plugins/openai.js +7 -1
  79. package/packages/dd-trace/src/llmobs/sdk.js +28 -0
  80. package/packages/dd-trace/src/llmobs/span_processor.js +124 -28
  81. package/packages/dd-trace/src/llmobs/tagger.js +8 -0
  82. package/packages/dd-trace/src/llmobs/telemetry.js +9 -2
  83. package/packages/dd-trace/src/log/index.js +28 -17
  84. package/packages/dd-trace/src/log/log.js +29 -5
  85. package/packages/dd-trace/src/log/writer.js +5 -5
  86. package/packages/dd-trace/src/noop/span.js +1 -0
  87. package/packages/dd-trace/src/opentelemetry/span.js +14 -3
  88. package/packages/dd-trace/src/opentracing/span.js +18 -4
  89. package/packages/dd-trace/src/plugin_manager.js +20 -2
  90. package/packages/dd-trace/src/plugins/ci_plugin.js +97 -3
  91. package/packages/dd-trace/src/plugins/index.js +2 -0
  92. package/packages/dd-trace/src/plugins/util/git-cache.js +129 -0
  93. package/packages/dd-trace/src/plugins/util/git.js +40 -26
  94. package/packages/dd-trace/src/plugins/util/test.js +37 -27
  95. package/packages/dd-trace/src/plugins/util/web.js +1 -1
  96. package/packages/dd-trace/src/profiler.js +4 -1
  97. package/packages/dd-trace/src/profiling/config.js +73 -42
  98. package/packages/dd-trace/src/profiling/profiler.js +3 -1
  99. package/packages/dd-trace/src/profiling/profilers/events.js +3 -8
  100. package/packages/dd-trace/src/profiling/profilers/space.js +1 -0
  101. package/packages/dd-trace/src/profiling/profilers/wall.js +196 -117
  102. package/packages/dd-trace/src/remote_config/capabilities.js +5 -0
  103. package/packages/dd-trace/src/remote_config/manager.js +3 -2
  104. package/packages/dd-trace/src/startup-log.js +2 -1
  105. package/packages/dd-trace/src/supported-configurations.json +3 -0
  106. package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
  107. package/register.js +1 -1
@@ -1,9 +1,9 @@
1
1
  'use strict'
2
2
 
3
- const coalesce = require('koalas')
4
3
  const os = require('os')
5
4
  const path = require('path')
6
5
  const { URL, format, pathToFileURL } = require('url')
6
+ const satisfies = require('semifies')
7
7
  const { AgentExporter } = require('./exporters/agent')
8
8
  const { FileExporter } = require('./exporters/file')
9
9
  const { ConsoleLogger } = require('./loggers/console')
@@ -16,6 +16,7 @@ const { tagger } = require('./tagger')
16
16
  const { isFalse, isTrue } = require('../util')
17
17
  const { getAzureTagsFromMetadata, getAzureAppMetadata } = require('../azure_metadata')
18
18
  const { getEnvironmentVariables } = require('../config-helper')
19
+ const defaults = require('../config_defaults')
19
20
 
20
21
  class Config {
21
22
  constructor (options = {}) {
@@ -41,27 +42,26 @@ class Config {
41
42
  DD_PROFILING_TIMELINE_ENABLED,
42
43
  DD_PROFILING_UPLOAD_PERIOD,
43
44
  DD_PROFILING_UPLOAD_TIMEOUT,
45
+ DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED,
44
46
  DD_PROFILING_V8_PROFILER_BUG_WORKAROUND,
45
47
  DD_PROFILING_WALLTIME_ENABLED,
46
48
  DD_SERVICE,
47
49
  DD_TAGS,
48
50
  DD_TRACE_AGENT_PORT,
49
51
  DD_TRACE_AGENT_URL,
50
- DD_VERSION
52
+ DD_VERSION,
53
+ NODE_OPTIONS
51
54
  } = getEnvironmentVariables()
52
55
 
53
- const env = coalesce(options.env, DD_ENV)
56
+ const env = options.env ?? DD_ENV
54
57
  const service = options.service || DD_SERVICE || 'node'
55
58
  const host = os.hostname()
56
- const version = coalesce(options.version, DD_VERSION)
59
+ const version = options.version ?? DD_VERSION
57
60
  // Must be longer than one minute so pad with five seconds
58
- const flushInterval = coalesce(options.interval, Number(DD_PROFILING_UPLOAD_PERIOD) * 1000, 65 * 1000)
59
- const uploadTimeout = coalesce(options.uploadTimeout,
60
- Number(DD_PROFILING_UPLOAD_TIMEOUT), 60 * 1000)
61
- const sourceMap = coalesce(options.sourceMap,
62
- DD_PROFILING_SOURCE_MAP, true)
63
- const pprofPrefix = coalesce(options.pprofPrefix,
64
- DD_PROFILING_PPROF_PREFIX, '')
61
+ const flushInterval = options.interval ?? (Number(DD_PROFILING_UPLOAD_PERIOD) * 1000 || 65 * 1000)
62
+ const uploadTimeout = options.uploadTimeout ?? (Number(DD_PROFILING_UPLOAD_TIMEOUT) || 60 * 1000)
63
+ const sourceMap = options.sourceMap ?? DD_PROFILING_SOURCE_MAP ?? true
64
+ const pprofPrefix = options.pprofPrefix ?? DD_PROFILING_PPROF_PREFIX ?? ''
65
65
 
66
66
  this.service = service
67
67
  this.env = env
@@ -104,21 +104,21 @@ class Config {
104
104
  this.flushInterval = flushInterval
105
105
  this.uploadTimeout = uploadTimeout
106
106
  this.sourceMap = sourceMap
107
- this.debugSourceMaps = isTrue(coalesce(options.debugSourceMaps, DD_PROFILING_DEBUG_SOURCE_MAPS, false))
108
- this.endpointCollectionEnabled = isTrue(coalesce(options.endpointCollection,
109
- DD_PROFILING_ENDPOINT_COLLECTION_ENABLED, samplingContextsAvailable))
107
+ this.debugSourceMaps = isTrue(options.debugSourceMaps ?? DD_PROFILING_DEBUG_SOURCE_MAPS)
108
+ this.endpointCollectionEnabled = isTrue(options.endpointCollection ??
109
+ DD_PROFILING_ENDPOINT_COLLECTION_ENABLED ?? samplingContextsAvailable)
110
110
  checkOptionWithSamplingContextAllowed(this.endpointCollectionEnabled, 'Endpoint collection')
111
111
 
112
112
  this.pprofPrefix = pprofPrefix
113
- this.v8ProfilerBugWorkaroundEnabled = isTrue(coalesce(options.v8ProfilerBugWorkaround,
114
- DD_PROFILING_V8_PROFILER_BUG_WORKAROUND, true))
115
- const hostname = coalesce(options.hostname, DD_AGENT_HOST) || 'localhost'
116
- const port = coalesce(options.port, DD_TRACE_AGENT_PORT) || 8126
117
- this.url = new URL(coalesce(options.url, DD_TRACE_AGENT_URL, format({
113
+ this.v8ProfilerBugWorkaroundEnabled = isTrue(options.v8ProfilerBugWorkaround ??
114
+ DD_PROFILING_V8_PROFILER_BUG_WORKAROUND ?? true)
115
+ const hostname = (options.hostname ?? DD_AGENT_HOST) || defaults.hostname
116
+ const port = (options.port ?? DD_TRACE_AGENT_PORT) || defaults.port
117
+ this.url = new URL(options.url ?? DD_TRACE_AGENT_URL ?? format({
118
118
  protocol: 'http:',
119
119
  hostname,
120
120
  port
121
- })))
121
+ }))
122
122
 
123
123
  this.libraryInjected = options.libraryInjected
124
124
  this.activation = options.activation
@@ -129,17 +129,17 @@ class Config {
129
129
  // OOM monitoring does not work well on Windows, so it is disabled by default.
130
130
  const oomMonitoringSupported = process.platform !== 'win32'
131
131
 
132
- const oomMonitoringEnabled = isTrue(coalesce(options.oomMonitoring,
133
- DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED, oomMonitoringSupported))
132
+ const oomMonitoringEnabled = isTrue(options.oomMonitoring ??
133
+ DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED ?? oomMonitoringSupported)
134
134
  checkOptionAllowed(oomMonitoringEnabled, 'OOM monitoring', oomMonitoringSupported)
135
135
 
136
- const heapLimitExtensionSize = coalesce(options.oomHeapLimitExtensionSize,
137
- Number(DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE), 0)
138
- const maxHeapExtensionCount = coalesce(options.oomMaxHeapExtensionCount,
139
- Number(DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT), 0)
136
+ const heapLimitExtensionSize = options.oomHeapLimitExtensionSize ??
137
+ (Number(DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE) || 0)
138
+ const maxHeapExtensionCount = options.oomMaxHeapExtensionCount ??
139
+ (Number(DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT) || 0)
140
140
  const exportStrategies = oomMonitoringEnabled
141
- ? ensureOOMExportStrategies(coalesce(options.oomExportStrategies, DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES,
142
- [oomExportStrategies.PROCESS]), this)
141
+ ? ensureOOMExportStrategies(options.oomExportStrategies ?? DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES ??
142
+ [oomExportStrategies.PROCESS], this)
143
143
  : []
144
144
  const exportCommand = oomMonitoringEnabled ? buildExportCommand(this) : undefined
145
145
  this.oomMonitoring = {
@@ -156,26 +156,29 @@ class Config {
156
156
  DD_PROFILING_PROFILERS
157
157
  })
158
158
 
159
- this.timelineEnabled = isTrue(coalesce(options.timelineEnabled,
160
- DD_PROFILING_TIMELINE_ENABLED, samplingContextsAvailable))
159
+ this.timelineEnabled = isTrue(
160
+ options.timelineEnabled ?? DD_PROFILING_TIMELINE_ENABLED ?? samplingContextsAvailable
161
+ )
161
162
  checkOptionWithSamplingContextAllowed(this.timelineEnabled, 'Timeline view')
162
- this.timelineSamplingEnabled = isTrue(coalesce(options.timelineSamplingEnabled,
163
- DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED, true))
163
+ this.timelineSamplingEnabled = isTrue(
164
+ options.timelineSamplingEnabled ?? DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED ?? true
165
+ )
164
166
 
165
- this.codeHotspotsEnabled = isTrue(coalesce(options.codeHotspotsEnabled,
166
- DD_PROFILING_CODEHOTSPOTS_ENABLED, samplingContextsAvailable))
167
+ this.codeHotspotsEnabled = isTrue(
168
+ options.codeHotspotsEnabled ?? DD_PROFILING_CODEHOTSPOTS_ENABLED ?? samplingContextsAvailable
169
+ )
167
170
  checkOptionWithSamplingContextAllowed(this.codeHotspotsEnabled, 'Code hotspots')
168
171
 
169
- this.cpuProfilingEnabled = isTrue(coalesce(options.cpuProfilingEnabled,
170
- DD_PROFILING_CPU_ENABLED,
171
- samplingContextsAvailable))
172
+ this.cpuProfilingEnabled = isTrue(
173
+ options.cpuProfilingEnabled ?? DD_PROFILING_CPU_ENABLED ?? samplingContextsAvailable
174
+ )
172
175
  checkOptionWithSamplingContextAllowed(this.cpuProfilingEnabled, 'CPU profiling')
173
176
 
174
- this.samplingInterval = coalesce(options.samplingInterval, 1e3 / 99) // 99hz in millis
177
+ this.samplingInterval = options.samplingInterval || 1e3 / 99 // 99hz in millis
175
178
 
176
- this.heapSamplingInterval = coalesce(options.heapSamplingInterval,
177
- Number(DD_PROFILING_HEAP_SAMPLING_INTERVAL))
178
- const uploadCompression0 = coalesce(options.uploadCompression, DD_PROFILING_DEBUG_UPLOAD_COMPRESSION, 'on')
179
+ this.heapSamplingInterval = options.heapSamplingInterval ??
180
+ (Number(DD_PROFILING_HEAP_SAMPLING_INTERVAL) || 512 * 1024)
181
+ const uploadCompression0 = options.uploadCompression ?? DD_PROFILING_DEBUG_UPLOAD_COMPRESSION ?? 'on'
179
182
  let [uploadCompression, level0] = uploadCompression0.split('-')
180
183
  if (!['on', 'off', 'gzip', 'zstd'].includes(uploadCompression)) {
181
184
  this.logger.warn(`Invalid profile upload compression method "${uploadCompression0}". Will use "on".`)
@@ -209,6 +212,34 @@ class Config {
209
212
 
210
213
  this.uploadCompression = { method: uploadCompression, level }
211
214
 
215
+ const that = this
216
+ function turnOffAsyncContextFrame (msg) {
217
+ that.logger.warn(
218
+ `DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED was set ${msg}, it will have no effect.`)
219
+ that.asyncContextFrameEnabled = false
220
+ }
221
+
222
+ const hasExecArg = (arg) => process.execArgv.includes(arg) || String(NODE_OPTIONS).includes(arg)
223
+
224
+ this.asyncContextFrameEnabled = isTrue(options.useAsyncContextFrame ?? DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED)
225
+ if (this.asyncContextFrameEnabled) {
226
+ if (satisfies(process.versions.node, '>=24.0.0')) {
227
+ if (hasExecArg('--no-async-context-frame')) {
228
+ turnOffAsyncContextFrame('with --no-async-context-frame')
229
+ }
230
+ } else if (satisfies(process.versions.node, '>=23.0.0')) {
231
+ if (!hasExecArg('--experimental-async-context-frame')) {
232
+ turnOffAsyncContextFrame('without --experimental-async-context-frame')
233
+ }
234
+ } else {
235
+ // NOTE: technically, this should work starting with 22.7.0 which is when
236
+ // AsyncContextFrame debuted, but it would require a change in pprof-nodejs too.
237
+ turnOffAsyncContextFrame('but it requires at least Node.js 23')
238
+ }
239
+ }
240
+
241
+ this.heartbeatInterval = options.heartbeatInterval || 60 * 1000 // 1 minute
242
+
212
243
  this.profilers = ensureProfilers(profilers, this)
213
244
  }
214
245
  }
@@ -220,7 +251,7 @@ function getProfilers ({
220
251
  }) {
221
252
  // First consider "legacy" DD_PROFILING_PROFILERS env variable, defaulting to wall + space
222
253
  // Use a Set to avoid duplicates
223
- const profilers = new Set(coalesce(DD_PROFILING_PROFILERS, 'wall,space').split(','))
254
+ const profilers = new Set((DD_PROFILING_PROFILERS ?? 'wall,space').split(','))
224
255
 
225
256
  // Add/remove wall depending on the value of DD_PROFILING_WALLTIME_ENABLED
226
257
  if (DD_PROFILING_WALLTIME_ENABLED != null) {
@@ -110,11 +110,13 @@ class Profiler extends EventEmitter {
110
110
  }
111
111
  break
112
112
  case 'zstd':
113
- if (typeof zlib.zstdCompress === 'function') {
113
+ if (typeof zlib.zstdCompress === 'function') { // eslint-disable-line n/no-unsupported-features/node-builtins
114
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins
114
115
  this.#compressionFn = promisify(zlib.zstdCompress)
115
116
  if (clevel !== undefined) {
116
117
  this.#compressionOptions = {
117
118
  params: {
119
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins
118
120
  [zlib.constants.ZSTD_c_compressionLevel]: clevel
119
121
  }
120
122
  }
@@ -41,14 +41,9 @@ function labelFromStrStr (stringTable, keyStr, valStr) {
41
41
  return labelFromStr(stringTable, stringTable.dedup(keyStr), valStr)
42
42
  }
43
43
 
44
- function getSamplingIntervalMillis (options) {
45
- return (options.samplingInterval || 1e3 / 99) // 99Hz
46
- }
47
-
48
44
  function getMaxSamples (options) {
49
- const cpuSamplingInterval = getSamplingIntervalMillis(options)
50
- const flushInterval = options.flushInterval || 65 * 1e3 // 60 seconds
51
- const maxCpuSamples = flushInterval / cpuSamplingInterval
45
+ const flushInterval = options.flushInterval || 65 * 1e3 // 65 seconds
46
+ const maxCpuSamples = flushInterval / options.samplingInterval
52
47
 
53
48
  // The lesser of max parallelism and libuv thread pool size, plus one so we can detect
54
49
  // oversubscription on libuv thread pool, plus another one for GC.
@@ -399,7 +394,7 @@ class EventsProfiler {
399
394
 
400
395
  const eventHandler = event => this.#eventSerializer.addEvent(event)
401
396
  const eventFilter = options.timelineSamplingEnabled
402
- ? createPoissonProcessSamplingFilter(getSamplingIntervalMillis(options))
397
+ ? createPoissonProcessSamplingFilter(options.samplingInterval)
403
398
  : () => true
404
399
  const filteringEventHandler = event => {
405
400
  if (eventFilter(event)) {
@@ -13,6 +13,7 @@ class NativeSpaceProfiler {
13
13
  _started = false
14
14
 
15
15
  constructor (options = {}) {
16
+ // TODO: Remove default value. It is only used in testing.
16
17
  this._samplingInterval = options.heapSamplingInterval || 512 * 1024
17
18
  this._stackDepth = options.stackDepth || 64
18
19
  this._oomMonitoring = options.oomMonitoring || {}