dd-trace 5.100.0 → 5.102.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 (189) hide show
  1. package/index.d.ts +14 -0
  2. package/package.json +11 -9
  3. package/packages/datadog-instrumentations/src/aerospike.js +2 -2
  4. package/packages/datadog-instrumentations/src/ai.js +8 -8
  5. package/packages/datadog-instrumentations/src/amqplib.js +6 -7
  6. package/packages/datadog-instrumentations/src/anthropic.js +10 -10
  7. package/packages/datadog-instrumentations/src/apollo-server-core.js +3 -3
  8. package/packages/datadog-instrumentations/src/apollo-server.js +5 -5
  9. package/packages/datadog-instrumentations/src/avsc.js +6 -6
  10. package/packages/datadog-instrumentations/src/aws-sdk.js +151 -67
  11. package/packages/datadog-instrumentations/src/azure-durable-functions.js +8 -8
  12. package/packages/datadog-instrumentations/src/bluebird.js +2 -2
  13. package/packages/datadog-instrumentations/src/body-parser.js +2 -2
  14. package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
  15. package/packages/datadog-instrumentations/src/child_process.js +12 -12
  16. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +9 -9
  17. package/packages/datadog-instrumentations/src/connect.js +7 -7
  18. package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
  19. package/packages/datadog-instrumentations/src/cookie.js +2 -2
  20. package/packages/datadog-instrumentations/src/couchbase.js +16 -30
  21. package/packages/datadog-instrumentations/src/crypto.js +4 -4
  22. package/packages/datadog-instrumentations/src/cucumber.js +77 -16
  23. package/packages/datadog-instrumentations/src/cypress.js +5 -3
  24. package/packages/datadog-instrumentations/src/dns.js +0 -3
  25. package/packages/datadog-instrumentations/src/elasticsearch.js +8 -11
  26. package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +6 -6
  27. package/packages/datadog-instrumentations/src/express-session.js +4 -4
  28. package/packages/datadog-instrumentations/src/express.js +10 -11
  29. package/packages/datadog-instrumentations/src/fastify.js +2 -2
  30. package/packages/datadog-instrumentations/src/fs.js +14 -14
  31. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +5 -7
  32. package/packages/datadog-instrumentations/src/google-genai.js +4 -4
  33. package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
  34. package/packages/datadog-instrumentations/src/hapi.js +2 -2
  35. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +8 -8
  36. package/packages/datadog-instrumentations/src/helpers/promise.js +2 -2
  37. package/packages/datadog-instrumentations/src/hono.js +2 -2
  38. package/packages/datadog-instrumentations/src/http/client.js +26 -9
  39. package/packages/datadog-instrumentations/src/http/server.js +9 -9
  40. package/packages/datadog-instrumentations/src/jest.js +93 -63
  41. package/packages/datadog-instrumentations/src/kafkajs.js +9 -9
  42. package/packages/datadog-instrumentations/src/knex.js +17 -17
  43. package/packages/datadog-instrumentations/src/koa.js +12 -12
  44. package/packages/datadog-instrumentations/src/ldapjs.js +5 -5
  45. package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
  46. package/packages/datadog-instrumentations/src/limitd-client.js +4 -4
  47. package/packages/datadog-instrumentations/src/lodash.js +4 -4
  48. package/packages/datadog-instrumentations/src/mariadb.js +13 -13
  49. package/packages/datadog-instrumentations/src/memcached.js +2 -2
  50. package/packages/datadog-instrumentations/src/microgateway-core.js +2 -2
  51. package/packages/datadog-instrumentations/src/mocha/common.js +7 -4
  52. package/packages/datadog-instrumentations/src/mocha/main.js +37 -14
  53. package/packages/datadog-instrumentations/src/mocha/utils.js +133 -16
  54. package/packages/datadog-instrumentations/src/mocha/worker.js +12 -7
  55. package/packages/datadog-instrumentations/src/mongodb-core.js +9 -22
  56. package/packages/datadog-instrumentations/src/mongodb.js +5 -5
  57. package/packages/datadog-instrumentations/src/mongoose.js +21 -21
  58. package/packages/datadog-instrumentations/src/mquery.js +5 -5
  59. package/packages/datadog-instrumentations/src/multer.js +4 -4
  60. package/packages/datadog-instrumentations/src/mysql.js +16 -16
  61. package/packages/datadog-instrumentations/src/mysql2.js +4 -4
  62. package/packages/datadog-instrumentations/src/net.js +14 -8
  63. package/packages/datadog-instrumentations/src/nyc.js +5 -5
  64. package/packages/datadog-instrumentations/src/openai.js +19 -19
  65. package/packages/datadog-instrumentations/src/oracledb.js +6 -6
  66. package/packages/datadog-instrumentations/src/otel-sdk-trace.js +11 -6
  67. package/packages/datadog-instrumentations/src/passport-utils.js +5 -5
  68. package/packages/datadog-instrumentations/src/pg.js +15 -15
  69. package/packages/datadog-instrumentations/src/pino.js +6 -10
  70. package/packages/datadog-instrumentations/src/playwright.js +20 -15
  71. package/packages/datadog-instrumentations/src/protobufjs.js +16 -16
  72. package/packages/datadog-instrumentations/src/redis.js +1 -2
  73. package/packages/datadog-instrumentations/src/restify.js +2 -2
  74. package/packages/datadog-instrumentations/src/router.js +12 -12
  75. package/packages/datadog-instrumentations/src/stripe.js +12 -12
  76. package/packages/datadog-instrumentations/src/vitest.js +107 -26
  77. package/packages/datadog-instrumentations/src/winston.js +4 -4
  78. package/packages/datadog-instrumentations/src/ws.js +7 -7
  79. package/packages/datadog-plugin-aws-sdk/src/base.js +52 -4
  80. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +19 -12
  81. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +45 -35
  82. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +33 -22
  83. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +12 -13
  84. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +73 -54
  85. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +19 -17
  86. package/packages/datadog-plugin-aws-sdk/src/util.js +22 -0
  87. package/packages/datadog-plugin-bullmq/src/consumer.js +2 -2
  88. package/packages/datadog-plugin-bullmq/src/producer.js +14 -20
  89. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -6
  90. package/packages/datadog-plugin-cucumber/src/index.js +4 -0
  91. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +18 -4
  92. package/packages/datadog-plugin-cypress/src/plugin.js +5 -14
  93. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -5
  94. package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +3 -1
  95. package/packages/datadog-plugin-http/src/client.js +1 -5
  96. package/packages/datadog-plugin-jest/src/util.js +1 -2
  97. package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -9
  98. package/packages/datadog-plugin-kafkajs/src/producer.js +2 -8
  99. package/packages/datadog-plugin-mocha/src/index.js +4 -0
  100. package/packages/datadog-plugin-mongodb-core/src/index.js +2 -1
  101. package/packages/datadog-plugin-openai/src/tracing.js +12 -23
  102. package/packages/datadog-plugin-playwright/src/index.js +1 -1
  103. package/packages/datadog-plugin-vitest/src/index.js +8 -1
  104. package/packages/datadog-shimmer/src/shimmer.js +7 -1
  105. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
  106. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +81 -81
  107. package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
  108. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +2 -2
  109. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -2
  110. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
  111. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
  112. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
  113. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +83 -48
  114. package/packages/dd-trace/src/appsec/index.js +21 -24
  115. package/packages/dd-trace/src/appsec/reporter.js +7 -2
  116. package/packages/dd-trace/src/appsec/rule_manager.js +4 -2
  117. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +31 -16
  118. package/packages/dd-trace/src/ci-visibility/lage.js +2 -1
  119. package/packages/dd-trace/src/ci-visibility/requests/request.js +11 -33
  120. package/packages/dd-trace/src/config/config-types.d.ts +0 -2
  121. package/packages/dd-trace/src/config/git_properties.js +2 -2
  122. package/packages/dd-trace/src/config/index.js +1 -55
  123. package/packages/dd-trace/src/datastreams/checkpointer.js +4 -10
  124. package/packages/dd-trace/src/datastreams/encoding.js +39 -28
  125. package/packages/dd-trace/src/datastreams/index.js +2 -1
  126. package/packages/dd-trace/src/datastreams/pathway.js +29 -26
  127. package/packages/dd-trace/src/datastreams/processor.js +18 -17
  128. package/packages/dd-trace/src/datastreams/size.js +6 -2
  129. package/packages/dd-trace/src/debugger/config.js +5 -2
  130. package/packages/dd-trace/src/debugger/devtools_client/index.js +2 -5
  131. package/packages/dd-trace/src/debugger/devtools_client/send.js +2 -1
  132. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +1 -0
  133. package/packages/dd-trace/src/dogstatsd.js +10 -7
  134. package/packages/dd-trace/src/encode/0.4.js +759 -234
  135. package/packages/dd-trace/src/encode/0.5.js +15 -9
  136. package/packages/dd-trace/src/encode/agentless-json.js +2 -2
  137. package/packages/dd-trace/src/encode/tags-processors.js +2 -27
  138. package/packages/dd-trace/src/exporters/common/request.js +22 -11
  139. package/packages/dd-trace/src/exporters/common/retry.js +104 -0
  140. package/packages/dd-trace/src/git_metadata.js +66 -0
  141. package/packages/dd-trace/src/git_metadata_tagger.js +13 -5
  142. package/packages/dd-trace/src/id.js +15 -26
  143. package/packages/dd-trace/src/llmobs/constants/tags.js +2 -0
  144. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -2
  145. package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +27 -16
  146. package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +3 -0
  147. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +33 -13
  148. package/packages/dd-trace/src/llmobs/plugins/openai/index.js +20 -50
  149. package/packages/dd-trace/src/llmobs/sdk.js +29 -27
  150. package/packages/dd-trace/src/llmobs/span_processor.js +52 -6
  151. package/packages/dd-trace/src/llmobs/tagger.js +42 -0
  152. package/packages/dd-trace/src/llmobs/telemetry.js +29 -0
  153. package/packages/dd-trace/src/llmobs/util.js +81 -5
  154. package/packages/dd-trace/src/msgpack/chunk.js +6 -3
  155. package/packages/dd-trace/src/openfeature/noop.js +40 -36
  156. package/packages/dd-trace/src/openfeature/writers/exposures.js +33 -52
  157. package/packages/dd-trace/src/opentelemetry/active-span-proxy.js +42 -0
  158. package/packages/dd-trace/src/opentelemetry/bridge-span-base.js +106 -0
  159. package/packages/dd-trace/src/opentelemetry/context_manager.js +11 -2
  160. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +1 -2
  161. package/packages/dd-trace/src/opentelemetry/span-helpers.js +188 -50
  162. package/packages/dd-trace/src/opentelemetry/span.js +42 -80
  163. package/packages/dd-trace/src/opentelemetry/tracer.js +0 -22
  164. package/packages/dd-trace/src/opentracing/propagation/text_map.js +65 -27
  165. package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -11
  166. package/packages/dd-trace/src/opentracing/propagation/tracestate.js +58 -22
  167. package/packages/dd-trace/src/opentracing/span.js +56 -48
  168. package/packages/dd-trace/src/opentracing/span_context.js +1 -0
  169. package/packages/dd-trace/src/plugins/util/ci.js +1 -1
  170. package/packages/dd-trace/src/plugins/util/git-cache.js +3 -5
  171. package/packages/dd-trace/src/plugins/util/test.js +19 -7
  172. package/packages/dd-trace/src/plugins/util/url.js +1 -3
  173. package/packages/dd-trace/src/plugins/util/user-provided-git.js +1 -1
  174. package/packages/dd-trace/src/plugins/util/web.js +5 -7
  175. package/packages/dd-trace/src/priority_sampler.js +6 -4
  176. package/packages/dd-trace/src/profiling/config.js +5 -4
  177. package/packages/dd-trace/src/profiling/profilers/events.js +3 -23
  178. package/packages/dd-trace/src/profiling/profilers/wall.js +4 -5
  179. package/packages/dd-trace/src/remote_config/index.js +5 -3
  180. package/packages/dd-trace/src/runtime_metrics/index.js +2 -2
  181. package/packages/dd-trace/src/scope.js +3 -10
  182. package/packages/dd-trace/src/serverless.js +1 -4
  183. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +7 -1
  184. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +4 -0
  185. package/packages/dd-trace/src/span_format.js +52 -5
  186. package/packages/dd-trace/src/span_processor.js +0 -4
  187. package/packages/dd-trace/src/spanleak.js +0 -1
  188. package/packages/dd-trace/src/tracer.js +7 -7
  189. package/packages/dd-trace/src/util.js +17 -0
@@ -8,11 +8,13 @@ const DEFAULT_MIN_SIZE = 2 * 1024 * 1024 // 2MB
8
8
  * either.
9
9
  */
10
10
  class MsgpackChunk {
11
+ #minSize
12
+
11
13
  constructor (minSize = DEFAULT_MIN_SIZE) {
12
14
  this.buffer = Buffer.allocUnsafe(minSize)
13
15
  this.view = new DataView(this.buffer.buffer)
14
16
  this.length = 0
15
- this._minSize = minSize
17
+ this.#minSize = minSize
16
18
  }
17
19
 
18
20
  write (value) {
@@ -50,13 +52,14 @@ class MsgpackChunk {
50
52
 
51
53
  reserve (size) {
52
54
  if (this.length + size > this.buffer.length) {
53
- this._resize(this._minSize * Math.ceil((this.length + size) / this._minSize))
55
+ const minSize = this.#minSize
56
+ this.#resize(minSize * Math.ceil((this.length + size) / minSize))
54
57
  }
55
58
 
56
59
  this.length += size
57
60
  }
58
61
 
59
- _resize (size) {
62
+ #resize (size) {
60
63
  const oldBuffer = this.buffer
61
64
 
62
65
  this.buffer = Buffer.allocUnsafe(size)
@@ -2,6 +2,18 @@
2
2
 
3
3
  const { NOOP_REASON } = require('./constants/constants')
4
4
 
5
+ /**
6
+ * @template T
7
+ * @param {T} defaultValue
8
+ * @returns {Promise<{value: T, reason: string}>}
9
+ */
10
+ function resolveDefault (defaultValue) {
11
+ return Promise.resolve({
12
+ value: defaultValue,
13
+ reason: NOOP_REASON,
14
+ })
15
+ }
16
+
5
17
  /**
6
18
  * No-op implementation of OpenFeature provider that always returns default values.
7
19
  * Used when the OpenFeature provider is not initialized or disabled.
@@ -20,59 +32,51 @@ class NoopFlaggingProvider {
20
32
  }
21
33
 
22
34
  /**
23
- * @param {string} flagKey - Flag key
24
- * @param {boolean} defaultValue - Default value to return
25
- * @param {object} context - Evaluation context
26
- * @param {object} logger - Logger instance
27
- * @returns {Promise<{value: boolean, reason: string}>} Resolution details
35
+ * @template T
36
+ * @param {string} flagKey
37
+ * @param {T} defaultValue
38
+ * @param {object} context
39
+ * @param {object} logger
40
+ * @returns {Promise<{value: T, reason: string}>}
28
41
  */
29
42
  resolveBooleanEvaluation (flagKey, defaultValue, context, logger) {
30
- return Promise.resolve({
31
- value: defaultValue,
32
- reason: NOOP_REASON,
33
- })
43
+ return resolveDefault(defaultValue)
34
44
  }
35
45
 
36
46
  /**
37
- * @param {string} flagKey - Flag key
38
- * @param {string} defaultValue - Default value to return
39
- * @param {object} context - Evaluation context
40
- * @param {object} logger - Logger instance
41
- * @returns {Promise<{value: string, reason: string}>} Resolution details
47
+ * @template T
48
+ * @param {string} flagKey
49
+ * @param {T} defaultValue
50
+ * @param {object} context
51
+ * @param {object} logger
52
+ * @returns {Promise<{value: T, reason: string}>}
42
53
  */
43
54
  resolveStringEvaluation (flagKey, defaultValue, context, logger) {
44
- return Promise.resolve({
45
- value: defaultValue,
46
- reason: NOOP_REASON,
47
- })
55
+ return resolveDefault(defaultValue)
48
56
  }
49
57
 
50
58
  /**
51
- * @param {string} flagKey - Flag key
52
- * @param {number} defaultValue - Default value to return
53
- * @param {object} context - Evaluation context
54
- * @param {object} logger - Logger instance
55
- * @returns {Promise<{value: number, reason: string}>} Resolution details
59
+ * @template T
60
+ * @param {string} flagKey
61
+ * @param {T} defaultValue
62
+ * @param {object} context
63
+ * @param {object} logger
64
+ * @returns {Promise<{value: T, reason: string}>}
56
65
  */
57
66
  resolveNumberEvaluation (flagKey, defaultValue, context, logger) {
58
- return Promise.resolve({
59
- value: defaultValue,
60
- reason: NOOP_REASON,
61
- })
67
+ return resolveDefault(defaultValue)
62
68
  }
63
69
 
64
70
  /**
65
- * @param {string} flagKey - Flag key
66
- * @param {object} defaultValue - Default value to return
67
- * @param {object} context - Evaluation context
68
- * @param {object} logger - Logger instance
69
- * @returns {Promise<{value: object, reason: string}>} Resolution details
71
+ * @template T
72
+ * @param {string} flagKey
73
+ * @param {T} defaultValue
74
+ * @param {object} context
75
+ * @param {object} logger
76
+ * @returns {Promise<{value: T, reason: string}>}
70
77
  */
71
78
  resolveObjectEvaluation (flagKey, defaultValue, context, logger) {
72
- return Promise.resolve({
73
- value: defaultValue,
74
- reason: NOOP_REASON,
75
- })
79
+ return resolveDefault(defaultValue)
76
80
  }
77
81
 
78
82
  /**
@@ -43,7 +43,7 @@ const BaseFFEWriter = require('./base')
43
43
  */
44
44
  class ExposuresWriter extends BaseFFEWriter {
45
45
  /**
46
- * @param {import('../../config')} config - Tracer configuration object
46
+ * @param {import('../../config/config-base')} config - Tracer configuration object
47
47
  */
48
48
  constructor (config) {
49
49
  // Build full EVP endpoint path
@@ -62,7 +62,19 @@ class ExposuresWriter extends BaseFFEWriter {
62
62
  })
63
63
  this._enabled = false // Start disabled until agent strategy is set
64
64
  this._pendingEvents = [] // Buffer events until enabled
65
- this._context = this._buildContext()
65
+
66
+ const context = {
67
+ service: config.service,
68
+ }
69
+ // Only include version and env if they are defined
70
+ if (config.version !== undefined) {
71
+ context.version = config.version
72
+ }
73
+ if (config.env !== undefined) {
74
+ context.env = config.env
75
+ }
76
+
77
+ this._context = context
66
78
  }
67
79
 
68
80
  /**
@@ -112,62 +124,31 @@ class ExposuresWriter extends BaseFFEWriter {
112
124
  * @returns {ExposureEventPayload} Formatted payload with service context
113
125
  */
114
126
  makePayload (events) {
115
- const formattedEvents = events.map(event => this._formatExposureEvent(event))
127
+ const formattedEvents = events.map(event => {
128
+ return {
129
+ timestamp: event.timestamp || Date.now(),
130
+ allocation: {
131
+ key: event.allocation?.key || event['allocation.key'],
132
+ },
133
+ flag: {
134
+ key: event.flag?.key || event['flag.key'],
135
+ },
136
+ variant: {
137
+ key: event.variant?.key || event['variant.key'],
138
+ },
139
+ subject: {
140
+ id: event.subject?.id || event['subject.id'],
141
+ type: event.subject?.type,
142
+ attributes: event.subject?.attributes,
143
+ },
144
+ }
145
+ })
116
146
 
117
147
  return {
118
148
  context: this._context,
119
149
  exposures: formattedEvents,
120
150
  }
121
151
  }
122
-
123
- /**
124
- * Builds service context metadata
125
- * @private
126
- * @returns {ExposureContext} Service context
127
- */
128
- _buildContext () {
129
- const context = {
130
- service: this._config.service || 'unknown',
131
- }
132
-
133
- // Only include version and env if they are defined
134
- if (this._config.version !== undefined) {
135
- context.version = this._config.version
136
- }
137
-
138
- if (this._config.env !== undefined) {
139
- context.env = this._config.env
140
- }
141
-
142
- return context
143
- }
144
-
145
- /**
146
- * @private
147
- * @param {ExposureEvent} event - Raw exposure event
148
- * @returns {ExposureEvent} Formatted exposure event
149
- */
150
- _formatExposureEvent (event) {
151
- // Ensure the event matches the expected schema
152
- const formattedEvent = {
153
- timestamp: event.timestamp || Date.now(),
154
- allocation: {
155
- key: event.allocation?.key || event['allocation.key'],
156
- },
157
- flag: {
158
- key: event.flag?.key || event['flag.key'],
159
- },
160
- variant: {
161
- key: event.variant?.key || event['variant.key'],
162
- },
163
- subject: {
164
- id: event.subject?.id || event['subject.id'],
165
- type: event.subject?.type,
166
- attributes: event.subject?.attributes,
167
- },
168
- }
169
- return formattedEvent
170
- }
171
152
  }
172
153
 
173
154
  module.exports = ExposuresWriter
@@ -0,0 +1,42 @@
1
+ 'use strict'
2
+
3
+ const BridgeSpanBase = require('./bridge-span-base')
4
+ const { setOtelResource } = require('./span-helpers')
5
+
6
+ /**
7
+ * OTel `Span`-compatible proxy around an already-active Datadog span.
8
+ *
9
+ * Makes `trace.getActiveSpan()` forward attribute/link/event/status/exception writes onto
10
+ * the Datadog span. `end()` is intentionally a no-op: the span's lifecycle belongs to
11
+ * whoever created it. Mutation methods all bail out once the underlying Datadog span has
12
+ * finished (gated inside the helpers), matching OTel `Span` semantics.
13
+ */
14
+ class ActiveSpanProxy extends BridgeSpanBase {
15
+ /** @type {import('./span_context')} */
16
+ #otelSpanContext
17
+
18
+ /**
19
+ * @param {import('../opentracing/span')} ddSpan
20
+ * @param {import('./span_context')} otelSpanContext
21
+ */
22
+ constructor (ddSpan, otelSpanContext) {
23
+ super(ddSpan)
24
+ this.#otelSpanContext = otelSpanContext
25
+ }
26
+
27
+ spanContext () {
28
+ return this.#otelSpanContext
29
+ }
30
+
31
+ /**
32
+ * @param {string} name
33
+ */
34
+ updateName (name) {
35
+ setOtelResource(this._ddSpan, name)
36
+ return this
37
+ }
38
+
39
+ end () {}
40
+ }
41
+
42
+ module.exports = ActiveSpanProxy
@@ -0,0 +1,106 @@
1
+ 'use strict'
2
+
3
+ const {
4
+ addOtelEvent,
5
+ addOtelLink,
6
+ addOtelLinks,
7
+ applyOtelStatus,
8
+ recordException,
9
+ setOtelAttribute,
10
+ setOtelAttributes,
11
+ } = require('./span-helpers')
12
+
13
+ /**
14
+ * Shared base for the OTel-bridge span classes (`Span` and `ActiveSpanProxy`). Subclasses
15
+ * pass the underlying Datadog span to `super(ddSpan)` and provide `spanContext()`, `end()`,
16
+ * and `updateName()`. The writable-span gate lives in the helpers in `span-helpers.js`,
17
+ * so neither bridge can drift from it.
18
+ *
19
+ * `_ddSpan` is left as a `_underscore` field rather than `#private` so the bridge does not
20
+ * expand its published API to expose the underlying DD span. External callers that need
21
+ * the reference (`ContextManager` proxy-cache check, OTLP serialization, tests) reach in
22
+ * via `_ddSpan`, matching the existing convention for "internal, may break".
23
+ */
24
+ class BridgeSpanBase {
25
+ // OTel SpanStatusCode: 0 = UNSET, 1 = OK, 2 = ERROR. Tracked for OK-is-final precedence.
26
+ #statusCode = 0
27
+
28
+ /**
29
+ * @param {import('../opentracing/span')} ddSpan
30
+ */
31
+ constructor (ddSpan) {
32
+ this._ddSpan = ddSpan
33
+ }
34
+
35
+ get ended () {
36
+ return this._ddSpan._duration !== undefined
37
+ }
38
+
39
+ isRecording () {
40
+ return !this.ended
41
+ }
42
+
43
+ /**
44
+ * @param {string} key
45
+ * @param {import('@opentelemetry/api').AttributeValue} value
46
+ */
47
+ setAttribute (key, value) {
48
+ setOtelAttribute(this._ddSpan, key, value)
49
+ return this
50
+ }
51
+
52
+ /**
53
+ * @param {import('@opentelemetry/api').Attributes} attributes
54
+ */
55
+ setAttributes (attributes) {
56
+ setOtelAttributes(this._ddSpan, attributes)
57
+ return this
58
+ }
59
+
60
+ /**
61
+ * @param {string} name
62
+ * @param {import('@opentelemetry/api').Attributes | import('@opentelemetry/api').TimeInput} [attributesOrStartTime]
63
+ * @param {import('@opentelemetry/api').TimeInput} [startTime]
64
+ */
65
+ addEvent (name, attributesOrStartTime, startTime) {
66
+ addOtelEvent(this._ddSpan, name, attributesOrStartTime, startTime)
67
+ return this
68
+ }
69
+
70
+ /**
71
+ * Accepts the OTel `Link` shape and the deprecated `(SpanContext, Attributes)` form.
72
+ *
73
+ * @param {import('@opentelemetry/api').Link | import('@opentelemetry/api').SpanContext} link
74
+ * @param {import('@opentelemetry/api').Attributes} [attrs]
75
+ */
76
+ addLink (link, attrs) {
77
+ addOtelLink(this._ddSpan, link, attrs)
78
+ return this
79
+ }
80
+
81
+ /**
82
+ * @param {import('@opentelemetry/api').Link[]} links
83
+ */
84
+ addLinks (links) {
85
+ addOtelLinks(this._ddSpan, links)
86
+ return this
87
+ }
88
+
89
+ /**
90
+ * @param {import('@opentelemetry/api').Exception} exception
91
+ * @param {import('@opentelemetry/api').TimeInput} [timeInput]
92
+ */
93
+ recordException (exception, timeInput) {
94
+ recordException(this._ddSpan, exception, timeInput)
95
+ }
96
+
97
+ /**
98
+ * @param {import('@opentelemetry/api').SpanStatus} status
99
+ */
100
+ setStatus (status) {
101
+ this.#statusCode = applyOtelStatus(this._ddSpan, this.#statusCode, status)
102
+ return this
103
+ }
104
+ }
105
+
106
+ module.exports = BridgeSpanBase
@@ -4,6 +4,7 @@ const { trace, ROOT_CONTEXT, propagation } = require('@opentelemetry/api')
4
4
  const { storage } = require('../../../datadog-core')
5
5
  const { getAllBaggageItems, setAllBaggageItems, removeAllBaggageItems } = require('../baggage')
6
6
 
7
+ const ActiveSpanProxy = require('./active-span-proxy')
7
8
  const SpanContext = require('./span_context')
8
9
 
9
10
  class ContextManager {
@@ -48,11 +49,19 @@ class ContextManager {
48
49
  ddContext._otelSpanContext = new SpanContext(ddContext)
49
50
  }
50
51
 
51
- if (store && trace.getSpanContext(store) === ddContext._otelSpanContext) {
52
+ // Cache the active-span proxy next to the bridge span context. This lets
53
+ // `trace.getActiveSpan()` forward attribute/status/link/exception writes
54
+ // onto the active Datadog span rather than returning a NonRecordingSpan
55
+ // whose mutation methods are silent no-ops.
56
+ if (!ddContext._otelActiveSpan) {
57
+ ddContext._otelActiveSpan = new ActiveSpanProxy(activeSpan, ddContext._otelSpanContext)
58
+ }
59
+
60
+ if (store && trace.getSpan(store) === ddContext._otelActiveSpan) {
52
61
  return otelBaggages ? propagation.setBaggage(store, otelBaggages) : store
53
62
  }
54
63
 
55
- const wrappedContext = trace.setSpanContext(baseContext, ddContext._otelSpanContext)
64
+ const wrappedContext = trace.setSpan(baseContext, ddContext._otelActiveSpan)
56
65
  return otelBaggages ? propagation.setBaggage(wrappedContext, otelBaggages) : wrappedContext
57
66
  }
58
67
 
@@ -141,8 +141,7 @@ class OtlpTransformerBase {
141
141
  */
142
142
  serializeToProtobuf (protoType, data) {
143
143
  const message = protoType.create(data)
144
- const buffer = protoType.encode(message).finish()
145
- return buffer
144
+ return protoType.encode(message).finish()
146
145
  }
147
146
 
148
147
  /**