dd-trace 5.100.0 → 5.101.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 (64) hide show
  1. package/index.d.ts +14 -0
  2. package/package.json +5 -5
  3. package/packages/datadog-instrumentations/src/cypress.js +5 -3
  4. package/packages/datadog-instrumentations/src/http/client.js +20 -3
  5. package/packages/datadog-instrumentations/src/jest.js +62 -32
  6. package/packages/datadog-instrumentations/src/mocha/common.js +4 -1
  7. package/packages/datadog-instrumentations/src/mocha/main.js +25 -4
  8. package/packages/datadog-instrumentations/src/mocha/worker.js +5 -2
  9. package/packages/datadog-instrumentations/src/otel-sdk-trace.js +11 -6
  10. package/packages/datadog-plugin-bullmq/src/consumer.js +2 -2
  11. package/packages/datadog-plugin-bullmq/src/producer.js +14 -20
  12. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +17 -0
  13. package/packages/datadog-plugin-cypress/src/plugin.js +5 -14
  14. package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -9
  15. package/packages/datadog-plugin-kafkajs/src/producer.js +2 -8
  16. package/packages/dd-trace/src/appsec/reporter.js +4 -1
  17. package/packages/dd-trace/src/ci-visibility/lage.js +2 -1
  18. package/packages/dd-trace/src/ci-visibility/requests/request.js +11 -33
  19. package/packages/dd-trace/src/config/config-types.d.ts +0 -2
  20. package/packages/dd-trace/src/config/index.js +1 -55
  21. package/packages/dd-trace/src/datastreams/checkpointer.js +4 -10
  22. package/packages/dd-trace/src/datastreams/encoding.js +39 -28
  23. package/packages/dd-trace/src/datastreams/pathway.js +29 -26
  24. package/packages/dd-trace/src/datastreams/processor.js +17 -15
  25. package/packages/dd-trace/src/datastreams/size.js +6 -2
  26. package/packages/dd-trace/src/debugger/config.js +5 -2
  27. package/packages/dd-trace/src/debugger/devtools_client/index.js +2 -5
  28. package/packages/dd-trace/src/debugger/devtools_client/send.js +2 -1
  29. package/packages/dd-trace/src/dogstatsd.js +10 -7
  30. package/packages/dd-trace/src/encode/0.4.js +2 -2
  31. package/packages/dd-trace/src/encode/0.5.js +2 -2
  32. package/packages/dd-trace/src/encode/agentless-json.js +2 -2
  33. package/packages/dd-trace/src/encode/tags-processors.js +2 -27
  34. package/packages/dd-trace/src/exporters/common/request.js +22 -11
  35. package/packages/dd-trace/src/exporters/common/retry.js +104 -0
  36. package/packages/dd-trace/src/git_metadata.js +66 -0
  37. package/packages/dd-trace/src/git_metadata_tagger.js +13 -5
  38. package/packages/dd-trace/src/id.js +15 -26
  39. package/packages/dd-trace/src/llmobs/constants/tags.js +2 -0
  40. package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +27 -16
  41. package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +3 -0
  42. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +30 -13
  43. package/packages/dd-trace/src/llmobs/plugins/openai/index.js +20 -50
  44. package/packages/dd-trace/src/llmobs/sdk.js +5 -1
  45. package/packages/dd-trace/src/llmobs/span_processor.js +28 -2
  46. package/packages/dd-trace/src/llmobs/tagger.js +42 -0
  47. package/packages/dd-trace/src/llmobs/telemetry.js +29 -0
  48. package/packages/dd-trace/src/llmobs/util.js +80 -5
  49. package/packages/dd-trace/src/opentelemetry/active-span-proxy.js +42 -0
  50. package/packages/dd-trace/src/opentelemetry/bridge-span-base.js +106 -0
  51. package/packages/dd-trace/src/opentelemetry/context_manager.js +11 -2
  52. package/packages/dd-trace/src/opentelemetry/span-helpers.js +188 -50
  53. package/packages/dd-trace/src/opentelemetry/span.js +42 -80
  54. package/packages/dd-trace/src/opentracing/propagation/text_map.js +65 -27
  55. package/packages/dd-trace/src/opentracing/propagation/tracestate.js +58 -22
  56. package/packages/dd-trace/src/opentracing/span.js +56 -48
  57. package/packages/dd-trace/src/opentracing/span_context.js +1 -0
  58. package/packages/dd-trace/src/priority_sampler.js +6 -4
  59. package/packages/dd-trace/src/profiling/config.js +5 -4
  60. package/packages/dd-trace/src/remote_config/index.js +5 -3
  61. package/packages/dd-trace/src/span_format.js +52 -5
  62. package/packages/dd-trace/src/span_processor.js +0 -4
  63. package/packages/dd-trace/src/spanleak.js +0 -1
  64. package/packages/dd-trace/src/util.js +17 -0
@@ -2,6 +2,11 @@
2
2
 
3
3
  const tags = require('../../../ext/tags')
4
4
  const constants = require('./constants')
5
+ const {
6
+ MAX_META_KEY_LENGTH,
7
+ MAX_META_VALUE_LENGTH,
8
+ MAX_METRIC_KEY_LENGTH,
9
+ } = require('./encode/tags-processors')
5
10
  const id = require('./id')
6
11
  const { isError } = require('./util')
7
12
  const { registerExtraService } = require('./service-naming/extra-services')
@@ -33,6 +38,23 @@ const map = {
33
38
  'resource.name': 'resource',
34
39
  }
35
40
 
41
+ /**
42
+ * @typedef {object} FormattedSpan
43
+ * @property {import('./id').Identifier} trace_id
44
+ * @property {import('./id').Identifier} span_id
45
+ * @property {import('./id').Identifier} parent_id
46
+ * @property {string} name
47
+ * @property {string} resource
48
+ * @property {number} error
49
+ * @property {Record<string, string>} meta
50
+ * @property {Record<string, number>} metrics
51
+ * @property {Record<string, unknown> | undefined} meta_struct
52
+ * @property {number} start
53
+ * @property {number} duration
54
+ * @property {Array} links
55
+ * @property {Array<{ name: string, time_unix_nano: number, attributes?: Record<string, string> }>} [span_events]
56
+ */
57
+
36
58
  function format (span, isFirstSpanInChunk = false, tagForFirstSpanInChunk = false) {
37
59
  const formatted = formatSpan(span)
38
60
 
@@ -71,12 +93,15 @@ function setSingleSpanIngestionTags (span, options) {
71
93
  addTag({}, span.metrics, SPAN_SAMPLING_MAX_PER_SECOND, options.maxPerSecond)
72
94
  }
73
95
 
96
+ /**
97
+ * @param {FormattedSpan} formattedSpan
98
+ * @param {import('./opentracing/span')} span
99
+ */
74
100
  function extractSpanLinks (formattedSpan, span) {
75
101
  if (!span._links?.length) {
76
102
  return
77
103
  }
78
- const links = span._links.map(link => {
79
- const { context, attributes } = link
104
+ const links = span._links.map(({ context, attributes }) => {
80
105
  const formattedLink = {
81
106
  trace_id: context.toTraceId(true),
82
107
  span_id: context.toSpanId(true),
@@ -90,21 +115,28 @@ function extractSpanLinks (formattedSpan, span) {
90
115
 
91
116
  return formattedLink
92
117
  })
93
- formattedSpan.meta['_dd.span_links'] = JSON.stringify(links)
118
+ let serialized = JSON.stringify(links)
119
+ if (serialized.length > MAX_META_VALUE_LENGTH) {
120
+ serialized = `${serialized.slice(0, MAX_META_VALUE_LENGTH)}...`
121
+ }
122
+ formattedSpan.meta['_dd.span_links'] = serialized
94
123
  }
95
124
 
125
+ /**
126
+ * @param {FormattedSpan} formattedSpan
127
+ * @param {import('./opentracing/span')} span
128
+ */
96
129
  function extractSpanEvents (formattedSpan, span) {
97
130
  if (!span._events?.length) {
98
131
  return
99
132
  }
100
- const events = span._events.map(event => {
133
+ formattedSpan.span_events = span._events.map(event => {
101
134
  return {
102
135
  name: event.name,
103
136
  time_unix_nano: Math.round(event.startTime * 1e6),
104
137
  attributes: event.attributes && Object.keys(event.attributes).length > 0 ? event.attributes : undefined,
105
138
  }
106
139
  })
107
- formattedSpan.span_events = events
108
140
  }
109
141
 
110
142
  function extractTags (formattedSpan, span) {
@@ -225,13 +257,25 @@ function extractError (formattedSpan, error) {
225
257
  function addTag (meta, metrics, key, value, nested) {
226
258
  switch (typeof value) {
227
259
  case 'string':
260
+ if (key.length > MAX_META_KEY_LENGTH) {
261
+ key = `${key.slice(0, MAX_META_KEY_LENGTH)}...`
262
+ }
263
+ if (value.length > MAX_META_VALUE_LENGTH) {
264
+ value = `${value.slice(0, MAX_META_VALUE_LENGTH)}...`
265
+ }
228
266
  meta[key] = value
229
267
  break
230
268
  case 'number':
231
269
  if (Number.isNaN(value)) break
270
+ if (key.length > MAX_METRIC_KEY_LENGTH) {
271
+ key = `${key.slice(0, MAX_METRIC_KEY_LENGTH)}...`
272
+ }
232
273
  metrics[key] = value
233
274
  break
234
275
  case 'boolean':
276
+ if (key.length > MAX_METRIC_KEY_LENGTH) {
277
+ key = `${key.slice(0, MAX_METRIC_KEY_LENGTH)}...`
278
+ }
235
279
  metrics[key] = value ? 1 : 0
236
280
  break
237
281
  default:
@@ -240,6 +284,9 @@ function addTag (meta, metrics, key, value, nested) {
240
284
  // Special case for Node.js Buffer and URL
241
285
  // TODO(BridgeAR)[31.03.2025]: Figure out if all typed arrays should be treated as buffers.
242
286
  if (isNodeBuffer(value) || isUrl(value)) {
287
+ if (key.length > MAX_METRIC_KEY_LENGTH) {
288
+ key = `${key.slice(0, MAX_METRIC_KEY_LENGTH)}...`
289
+ }
243
290
  metrics[key] = value.toString()
244
291
  } else if (!Array.isArray(value) && !nested) {
245
292
  for (const [prop, val] of Object.entries(value)) {
@@ -158,10 +158,6 @@ class SpanProcessor {
158
158
  }
159
159
  }
160
160
 
161
- for (const span of trace.finished) {
162
- span.context()._tags = {}
163
- }
164
-
165
161
  trace.started = active
166
162
  trace.finished = []
167
163
  }
@@ -85,7 +85,6 @@ module.exports.addSpan = function (span) {
85
85
  const expiration = now + LIFETIME
86
86
  const wrapped = new WeakRef(span)
87
87
  spans.add(wrapped, expiration)
88
- // registry.register(span, span._name)
89
88
  }
90
89
 
91
90
  function isEnabled () {
@@ -2,6 +2,22 @@
2
2
 
3
3
  const path = require('path')
4
4
 
5
+ /**
6
+ * `for-in` with an early return is the only allocation-free shape for
7
+ * "does this object have any own enumerable properties". Microbenchmarks
8
+ * pin it as 1.3-1.4x faster than `Object.keys(obj).length === 0` across
9
+ * small / medium / large objects -- enough that hot paths in the AWS SDK
10
+ * and AppSec reporter promote it.
11
+ *
12
+ * @param {object | undefined} obj
13
+ * @returns {boolean}
14
+ */
15
+ function isEmpty (obj) {
16
+ // eslint-disable-next-line no-unreachable-loop
17
+ for (const _ in obj) return false
18
+ return true
19
+ }
20
+
5
21
  function isTrue (str) {
6
22
  str = String(str).toLowerCase()
7
23
  return str === 'true' || str === '1'
@@ -76,6 +92,7 @@ function normalizePluginEnvName (envPluginName, makeLowercase = false) {
76
92
  }
77
93
 
78
94
  module.exports = {
95
+ isEmpty,
79
96
  isTrue,
80
97
  isFalse,
81
98
  isError,