dd-trace 5.31.0 → 5.32.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 (62) hide show
  1. package/LICENSE-3rdparty.csv +1 -0
  2. package/README.md +9 -7
  3. package/package.json +5 -4
  4. package/packages/datadog-instrumentations/src/aws-sdk.js +2 -1
  5. package/packages/datadog-instrumentations/src/cucumber.js +14 -5
  6. package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -0
  7. package/packages/datadog-instrumentations/src/jest.js +70 -36
  8. package/packages/datadog-instrumentations/src/mocha/utils.js +23 -7
  9. package/packages/datadog-instrumentations/src/node-serialize.js +22 -0
  10. package/packages/datadog-instrumentations/src/openai.js +2 -0
  11. package/packages/datadog-instrumentations/src/vitest.js +107 -59
  12. package/packages/datadog-instrumentations/src/vm.js +49 -0
  13. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime.js +295 -0
  14. package/packages/datadog-plugin-aws-sdk/src/services/index.js +1 -0
  15. package/packages/datadog-plugin-cucumber/src/index.js +30 -32
  16. package/packages/datadog-plugin-jest/src/index.js +34 -37
  17. package/packages/datadog-plugin-langchain/src/index.js +12 -80
  18. package/packages/datadog-plugin-langchain/src/tracing.js +89 -0
  19. package/packages/datadog-plugin-mocha/src/index.js +18 -36
  20. package/packages/datadog-plugin-vitest/src/index.js +20 -34
  21. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
  22. package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +2 -0
  23. package/packages/dd-trace/src/appsec/iast/analyzers/untrusted-deserialization-analyzer.js +16 -0
  24. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +9 -8
  25. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
  26. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +37 -0
  27. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +65 -28
  28. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +57 -17
  29. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +18 -3
  30. package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +20 -3
  31. package/packages/dd-trace/src/config.js +39 -3
  32. package/packages/dd-trace/src/crashtracking/crashtracker.js +9 -0
  33. package/packages/dd-trace/src/crashtracking/noop.js +3 -0
  34. package/packages/dd-trace/src/datastreams/fnv.js +1 -1
  35. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +2 -2
  36. package/packages/dd-trace/src/debugger/devtools_client/config.js +1 -0
  37. package/packages/dd-trace/src/debugger/devtools_client/defaults.js +1 -0
  38. package/packages/dd-trace/src/debugger/devtools_client/index.js +30 -13
  39. package/packages/dd-trace/src/debugger/devtools_client/send.js +4 -8
  40. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +35 -1
  41. package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +112 -0
  42. package/packages/dd-trace/src/debugger/devtools_client/status.js +12 -10
  43. package/packages/dd-trace/src/debugger/index.js +2 -13
  44. package/packages/dd-trace/src/llmobs/plugins/base.js +40 -11
  45. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +24 -0
  46. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +111 -0
  47. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/embedding.js +42 -0
  48. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +102 -0
  49. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/llm.js +32 -0
  50. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +131 -0
  51. package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -1
  52. package/packages/dd-trace/src/llmobs/tagger.js +11 -3
  53. package/packages/dd-trace/src/llmobs/util.js +7 -1
  54. package/packages/dd-trace/src/llmobs/writers/spans/agentProxy.js +3 -3
  55. package/packages/dd-trace/src/opentelemetry/context_manager.js +43 -3
  56. package/packages/dd-trace/src/plugins/ci_plugin.js +57 -27
  57. package/packages/dd-trace/src/plugins/util/test.js +42 -12
  58. package/packages/dd-trace/src/priority_sampler.js +4 -1
  59. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +21 -0
  60. package/packages/dd-trace/src/profiling/profiler.js +11 -8
  61. package/packages/dd-trace/src/profiling/profilers/events.js +17 -1
  62. package/packages/dd-trace/src/proxy.js +6 -3
@@ -122,7 +122,10 @@ class PrioritySampler {
122
122
  const context = this._getContext(span)
123
123
  const root = context._trace.started[0]
124
124
 
125
- if (!root) return // noop span
125
+ if (!root) {
126
+ log.error('Skipping the setPriority on noop span')
127
+ return // noop span
128
+ }
126
129
 
127
130
  context._sampling.priority = samplingPriority
128
131
  context._sampling.mechanism = mechanism
@@ -2,6 +2,22 @@ const os = require('os')
2
2
  const perf = require('perf_hooks').performance
3
3
  const version = require('../../../../../package.json').version
4
4
 
5
+ const libuvThreadPoolSize = (() => {
6
+ const ss = process.env.UV_THREADPOOL_SIZE
7
+ if (ss === undefined) {
8
+ // Backend will apply the default size based on Node version.
9
+ return undefined
10
+ }
11
+ // libuv uses atoi to parse the value, which is almost the same as parseInt, except that parseInt
12
+ // will return NaN on invalid input, while atoi will return 0. This is handled at return.
13
+ const s = parseInt(ss)
14
+ // We dont' interpret the value further here in the library. Backend will interpret the number
15
+ // based on Node version. In all currently known Node versions, 0 results in 1 worker thread,
16
+ // negative values (because they're assigned to an unsigned int) become very high positive values,
17
+ // and the value is finally capped at 1024.
18
+ return isNaN(s) ? 0 : s
19
+ })()
20
+
5
21
  class EventSerializer {
6
22
  constructor ({ env, host, service, version, libraryInjected, activation } = {}) {
7
23
  this._env = env
@@ -56,11 +72,16 @@ class EventSerializer {
56
72
  version
57
73
  },
58
74
  runtime: {
75
+ // os.availableParallelism only available in node 18.14.0/19.4.0 and above
76
+ available_processors: typeof os.availableParallelism === 'function'
77
+ ? os.availableParallelism()
78
+ : os.cpus().length,
59
79
  // Using `nodejs` for consistency with the existing `runtime` tag.
60
80
  // Note that the event `family` property uses `node`, as that's what's
61
81
  // proscribed by the Intake API, but that's an internal enum and is
62
82
  // not customer visible.
63
83
  engine: 'nodejs',
84
+ libuv_threadpool_size: libuvThreadPoolSize,
64
85
  // strip off leading 'v'. This makes the format consistent with other
65
86
  // runtimes (e.g. Ruby) but not with the existing `runtime_version` tag.
66
87
  // We'll keep it like this as we want cross-engine consistency. We
@@ -6,6 +6,7 @@ const { snapshotKinds } = require('./constants')
6
6
  const { threadNamePrefix } = require('./profilers/shared')
7
7
  const { isWebServerSpan, endpointNameFromTags, getStartedSpans } = require('./webspan-utils')
8
8
  const dc = require('dc-polyfill')
9
+ const crashtracker = require('../crashtracking')
9
10
 
10
11
  const profileSubmittedChannel = dc.channel('datadog:profiling:profile-submitted')
11
12
  const spanFinishedChannel = dc.channel('dd-trace:span:finish')
@@ -197,15 +198,17 @@ class Profiler extends EventEmitter {
197
198
  throw new Error('No profile types configured.')
198
199
  }
199
200
 
200
- // collect profiles synchronously so that profilers can be safely stopped asynchronously
201
- for (const profiler of this._config.profilers) {
202
- const profile = profiler.profile(restart, startDate, endDate)
203
- if (!restart) {
204
- this._logger.debug(`Stopped ${profiler.type} profiler in ${threadNamePrefix} thread`)
201
+ crashtracker.withProfilerSerializing(() => {
202
+ // collect profiles synchronously so that profilers can be safely stopped asynchronously
203
+ for (const profiler of this._config.profilers) {
204
+ const profile = profiler.profile(restart, startDate, endDate)
205
+ if (!restart) {
206
+ this._logger.debug(`Stopped ${profiler.type} profiler in ${threadNamePrefix} thread`)
207
+ }
208
+ if (!profile) continue
209
+ profiles.push({ profiler, profile })
205
210
  }
206
- if (!profile) continue
207
- profiles.push({ profiler, profile })
208
- }
211
+ })
209
212
 
210
213
  if (restart) {
211
214
  this._capture(this._timeoutInterval, endDate)
@@ -14,7 +14,23 @@ const pprofValueUnit = 'nanoseconds'
14
14
  const dateOffset = BigInt(Math.round(performance.timeOrigin * MS_TO_NS))
15
15
 
16
16
  function labelFromStr (stringTable, key, valStr) {
17
- return new Label({ key, str: stringTable.dedup(valStr) })
17
+ return new Label({ key, str: stringTable.dedup(safeToString(valStr)) })
18
+ }
19
+
20
+ // We don't want to invoke toString for objects and functions, rather we'll
21
+ // provide dummy values. These values are not meant to emulate built-in toString
22
+ // behavior.
23
+ function safeToString (val) {
24
+ switch (typeof val) {
25
+ case 'string':
26
+ return val
27
+ case 'object':
28
+ return '[object]'
29
+ case 'function':
30
+ return '[function]'
31
+ default:
32
+ return String(val)
33
+ }
18
34
  }
19
35
 
20
36
  function labelFromStrStr (stringTable, keyStr, valStr) {
@@ -119,7 +119,7 @@ class Tracer extends NoopProxy {
119
119
  this._flare.module.send(conf.args)
120
120
  })
121
121
 
122
- if (config.dynamicInstrumentationEnabled) {
122
+ if (config.dynamicInstrumentation.enabled) {
123
123
  DynamicInstrumentation.start(config, rc)
124
124
  }
125
125
  }
@@ -166,7 +166,10 @@ class Tracer extends NoopProxy {
166
166
  if (config.isManualApiEnabled) {
167
167
  const TestApiManualPlugin = require('./ci-visibility/test-api-manual/test-api-manual-plugin')
168
168
  this._testApiManualPlugin = new TestApiManualPlugin(this)
169
- this._testApiManualPlugin.configure({ ...config, enabled: true })
169
+ // `shouldGetEnvironmentData` is passed as false so that we only lazily calculate it
170
+ // This is the only place where we need to do this because the rest of the plugins
171
+ // are lazily configured when the library is imported.
172
+ this._testApiManualPlugin.configure({ ...config, enabled: true }, false)
170
173
  }
171
174
  }
172
175
  if (config.ciVisAgentlessLogSubmissionEnabled) {
@@ -184,7 +187,7 @@ class Tracer extends NoopProxy {
184
187
 
185
188
  if (config.isTestDynamicInstrumentationEnabled) {
186
189
  const testVisibilityDynamicInstrumentation = require('./ci-visibility/dynamic-instrumentation')
187
- testVisibilityDynamicInstrumentation.start()
190
+ testVisibilityDynamicInstrumentation.start(config)
188
191
  }
189
192
  } catch (e) {
190
193
  log.error('Error initialising tracer', e)