dd-trace 5.72.0 → 5.73.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 (35) hide show
  1. package/LICENSE-3rdparty.csv +2 -0
  2. package/index.d.ts +21 -0
  3. package/package.json +8 -6
  4. package/packages/datadog-esbuild/index.js +8 -0
  5. package/packages/datadog-instrumentations/src/azure-service-bus.js +49 -22
  6. package/packages/datadog-instrumentations/src/cookie-parser.js +2 -0
  7. package/packages/datadog-instrumentations/src/jest.js +59 -14
  8. package/packages/datadog-instrumentations/src/mocha/utils.js +3 -4
  9. package/packages/datadog-plugin-amqplib/src/consumer.js +1 -1
  10. package/packages/datadog-plugin-azure-functions/src/index.js +24 -14
  11. package/packages/datadog-plugin-azure-service-bus/src/index.js +1 -1
  12. package/packages/datadog-plugin-azure-service-bus/src/producer.js +60 -12
  13. package/packages/datadog-plugin-jest/src/index.js +53 -18
  14. package/packages/datadog-plugin-ws/src/close.js +1 -1
  15. package/packages/datadog-plugin-ws/src/producer.js +1 -1
  16. package/packages/datadog-plugin-ws/src/receiver.js +1 -1
  17. package/packages/dd-trace/src/appsec/index.js +9 -1
  18. package/packages/dd-trace/src/appsec/reporter.js +2 -3
  19. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +5 -0
  20. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +8 -3
  21. package/packages/dd-trace/src/llmobs/plugins/base.js +11 -12
  22. package/packages/dd-trace/src/llmobs/sdk.js +20 -4
  23. package/packages/dd-trace/src/llmobs/tagger.js +12 -0
  24. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +7 -127
  25. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +19 -134
  26. package/packages/dd-trace/src/opentelemetry/otlp/metrics.proto +720 -0
  27. package/packages/dd-trace/src/opentelemetry/otlp/metrics_service.proto +78 -0
  28. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +177 -0
  29. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +163 -0
  30. package/packages/dd-trace/src/opentelemetry/{protos → otlp}/protobuf_loader.js +24 -6
  31. package/packages/dd-trace/src/supported-configurations.json +1 -0
  32. /package/packages/dd-trace/src/opentelemetry/{protos → otlp}/common.proto +0 -0
  33. /package/packages/dd-trace/src/opentelemetry/{protos → otlp}/logs.proto +0 -0
  34. /package/packages/dd-trace/src/opentelemetry/{protos → otlp}/logs_service.proto +0 -0
  35. /package/packages/dd-trace/src/opentelemetry/{protos → otlp}/resource.proto +0 -0
@@ -1,14 +1,12 @@
1
1
  'use strict'
2
2
 
3
+ const OtlpTransformerBase = require('../otlp/otlp_transformer_base')
3
4
  const { SeverityNumber } = require('@opentelemetry/api-logs')
4
- const { getProtobufTypes } = require('../protos/protobuf_loader')
5
+ const { getProtobufTypes } = require('../otlp/protobuf_loader')
5
6
  const { trace } = require('@opentelemetry/api')
6
- const log = require('../../log')
7
7
 
8
8
  /**
9
- * @typedef {import('@opentelemetry/api').Attributes} Attributes
10
9
  * @typedef {import('@opentelemetry/api-logs').LogRecord} LogRecord
11
- * @typedef {import('@opentelemetry/resources').Resource} Resource
12
10
  */
13
11
 
14
12
  // Global severity mapping constant - no need to regenerate
@@ -46,24 +44,17 @@ const SEVERITY_MAP = {
46
44
  * https://opentelemetry.io/docs/specs/otlp/#log-data-model
47
45
  *
48
46
  * @class OtlpTransformer
47
+ * @extends OtlpTransformerBase
49
48
  */
50
- class OtlpTransformer {
51
- #resourceAttributes
52
-
49
+ class OtlpTransformer extends OtlpTransformerBase {
53
50
  /**
54
51
  * Creates a new OtlpTransformer instance.
55
52
  *
56
- * @param {Attributes} resourceAttributes - Resource attributes
53
+ * @param {import('@opentelemetry/api').Attributes} resourceAttributes - Resource attributes
57
54
  * @param {string} protocol - OTLP protocol (http/protobuf or http/json)
58
55
  */
59
56
  constructor (resourceAttributes, protocol) {
60
- this.#resourceAttributes = this.#transformAttributes(resourceAttributes)
61
- if (protocol === 'grpc') {
62
- log.warn('OTLP gRPC protocol is not supported for logs. ' +
63
- 'Defaulting to http/protobuf. gRPC protobuf support may be added in a future release.')
64
- protocol = 'http/protobuf'
65
- }
66
- this.protocol = protocol
57
+ super(resourceAttributes, protocol, 'logs')
67
58
  }
68
59
 
69
60
  /**
@@ -72,37 +63,12 @@ class OtlpTransformer {
72
63
  * @returns {Buffer} Transformed log records in the appropriate format
73
64
  */
74
65
  transformLogRecords (logRecords) {
75
- // Use the configured protocol to determine serialization format
76
66
  if (this.protocol === 'http/json') {
77
67
  return this.#transformToJson(logRecords)
78
68
  }
79
- // Default to protobuf for http/protobuf or any other protocol
80
69
  return this.#transformToProtobuf(logRecords)
81
70
  }
82
71
 
83
- /**
84
- * Groups log records by instrumentation library (name and version).
85
- * @param {LogRecord[]} logRecords - Array of log records to group
86
- * @returns {Map<string, LogRecord[]>} Map of instrumentation library key to log records
87
- * @private
88
- */
89
- #groupByInstrumentationScope (logRecords) {
90
- const grouped = new Map()
91
-
92
- for (const record of logRecords) {
93
- const instrumentationScope = record.instrumentationScope || { name: '', version: '0.0.0', schemaUrl: '' }
94
- const key = `${instrumentationScope.name}@${instrumentationScope.version}@${instrumentationScope.schemaUrl}`
95
-
96
- const group = grouped.get(key)
97
- if (group === undefined) {
98
- grouped.set(key, [record])
99
- } else {
100
- group.push(record)
101
- }
102
- }
103
- return grouped
104
- }
105
-
106
72
  /**
107
73
  * Transforms log records to protobuf format.
108
74
  * @param {LogRecord[]} logRecords - Array of enriched log records to transform
@@ -111,19 +77,15 @@ class OtlpTransformer {
111
77
  */
112
78
  #transformToProtobuf (logRecords) {
113
79
  const { protoLogsService } = getProtobufTypes()
114
- // Create the OTLP LogsData structure
80
+
115
81
  const logsData = {
116
82
  resourceLogs: [{
117
- resource: this.#transformResource(),
83
+ resource: this._transformResource(),
118
84
  scopeLogs: this.#transformScope(logRecords),
119
85
  }]
120
86
  }
121
87
 
122
- // Serialize to protobuf
123
- const message = protoLogsService.create(logsData)
124
- const buffer = protoLogsService.encode(message).finish()
125
-
126
- return buffer
88
+ return this._serializeToProtobuf(protoLogsService, logsData)
127
89
  }
128
90
 
129
91
  /**
@@ -135,11 +97,11 @@ class OtlpTransformer {
135
97
  #transformToJson (logRecords) {
136
98
  const logsData = {
137
99
  resourceLogs: [{
138
- resource: this.#transformResource(),
100
+ resource: this._transformResource(),
139
101
  scopeLogs: this.#transformScope(logRecords)
140
102
  }]
141
103
  }
142
- return Buffer.from(JSON.stringify(logsData))
104
+ return this._serializeToJson(logsData)
143
105
  }
144
106
 
145
107
  /**
@@ -149,10 +111,7 @@ class OtlpTransformer {
149
111
  * @private
150
112
  */
151
113
  #transformScope (logRecords) {
152
- // Group log records by instrumentation library
153
- const groupedRecords = this.#groupByInstrumentationScope(logRecords)
154
-
155
- // Create scope logs for each instrumentation library
114
+ const groupedRecords = this._groupByInstrumentationScope(logRecords)
156
115
  const scopeLogs = []
157
116
 
158
117
  for (const records of groupedRecords.values()) {
@@ -161,7 +120,6 @@ class OtlpTransformer {
161
120
  scope: {
162
121
  name: records[0]?.instrumentationScope?.name || 'dd-trace-js',
163
122
  version: records[0]?.instrumentationScope?.version || '',
164
- // TODO: Support setting attributes on instrumentation scope
165
123
  attributes: [],
166
124
  droppedAttributesCount: 0
167
125
  },
@@ -173,18 +131,6 @@ class OtlpTransformer {
173
131
  return scopeLogs
174
132
  }
175
133
 
176
- /**
177
- * Transforms resource attributes to OTLP resource format.
178
- * @returns {Resource} OTLP resource object
179
- * @private
180
- */
181
- #transformResource () {
182
- return {
183
- attributes: this.#resourceAttributes,
184
- droppedAttributesCount: 0
185
- }
186
- }
187
-
188
134
  /**
189
135
  * Transforms a single log record to OTLP format.
190
136
  * @param {LogRecord} logRecord - Log record to transform
@@ -192,14 +138,10 @@ class OtlpTransformer {
192
138
  * @private
193
139
  */
194
140
  #transformLogRecord (logRecord) {
195
- const timestamp = logRecord.timestamp
196
-
197
- // Extract span context from the log record's context
198
141
  const spanContext = this.#extractSpanContext(logRecord.context)
199
142
 
200
- // Only timeUnixNano and body are required
201
143
  const result = {
202
- timeUnixNano: timestamp,
144
+ timeUnixNano: logRecord.timestamp,
203
145
  body: this.#transformBody(logRecord.body)
204
146
  }
205
147
 
@@ -217,14 +159,14 @@ class OtlpTransformer {
217
159
  }
218
160
 
219
161
  if (logRecord.attributes) {
220
- result.attributes = this.#transformAttributes(logRecord.attributes)
162
+ result.attributes = this._transformAttributes(logRecord.attributes)
221
163
  }
222
164
 
223
165
  if (spanContext?.traceFlags !== undefined) {
224
166
  result.flags = spanContext.traceFlags
225
167
  }
226
168
 
227
- // Only include traceId and spanId if they are valid (not empty, undefined, or all zeros)
169
+ // Only include traceId and spanId if they are valid
228
170
  if (spanContext?.traceId && spanContext.traceId !== '00000000000000000000000000000000') {
229
171
  result.traceId = this.#hexToBytes(spanContext.traceId)
230
172
  }
@@ -285,82 +227,25 @@ class OtlpTransformer {
285
227
  */
286
228
  #transformBody (body) {
287
229
  if (typeof body === 'string') {
288
- return {
289
- stringValue: body
290
- }
230
+ return { stringValue: body }
291
231
  } else if (typeof body === 'number') {
292
232
  if (Number.isInteger(body)) {
293
233
  return { intValue: body }
294
234
  }
295
235
  return { doubleValue: body }
296
236
  } else if (typeof body === 'boolean') {
297
- return {
298
- boolValue: body
299
- }
237
+ return { boolValue: body }
300
238
  } else if (body && typeof body === 'object') {
301
239
  return {
302
240
  kvlistValue: {
303
241
  values: Object.entries(body).map(([key, value]) => ({
304
242
  key,
305
- value: this.#transformAnyValue(value)
306
- }))
307
- }
308
- }
309
- }
310
- return {
311
- stringValue: String(body)
312
- }
313
- }
314
-
315
- /**
316
- * Transforms attributes to OTLP KeyValue format.
317
- * @param {Object} attributes - Attributes to transform
318
- * @returns {Object[]} Array of OTLP KeyValue objects
319
- * @private
320
- */
321
- #transformAttributes (attributes) {
322
- if (!attributes) {
323
- return {}
324
- }
325
- return Object.entries(attributes).map(([key, value]) => ({
326
- key,
327
- value: this.#transformAnyValue(value)
328
- }))
329
- }
330
-
331
- /**
332
- * Transforms any value to OTLP AnyValue format.
333
- * @param {any} value - Value to transform
334
- * @returns {Object} OTLP AnyValue object
335
- * @private
336
- */
337
- #transformAnyValue (value) {
338
- if (typeof value === 'string') {
339
- return { stringValue: value }
340
- } else if (typeof value === 'number') {
341
- if (Number.isInteger(value)) {
342
- return { intValue: value }
343
- }
344
- return { doubleValue: value }
345
- } else if (typeof value === 'boolean') {
346
- return { boolValue: value }
347
- } else if (Array.isArray(value)) {
348
- return {
349
- arrayValue: {
350
- values: value.map(v => this.#transformAnyValue(v))
351
- }
352
- }
353
- } else if (value && typeof value === 'object') {
354
- return {
355
- kvlistValue: {
356
- values: Object.entries(value).map(([k, v]) => ({
357
- key: k,
358
- value: this.#transformAnyValue(v)
243
+ value: this._transformAnyValue(value)
359
244
  }))
360
245
  }
361
246
  }
362
247
  }
363
- return { stringValue: String(value) }
248
+ return { stringValue: String(body) }
364
249
  }
365
250
  }
366
251