dd-trace 6.10.0 → 6.12.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 (173) hide show
  1. package/LICENSE-3rdparty.csv +5 -0
  2. package/README.md +0 -17
  3. package/index.d.ts +128 -6
  4. package/initialize.mjs +28 -17
  5. package/openfeature.js +2 -2
  6. package/package.json +27 -23
  7. package/packages/datadog-esbuild/index.js +0 -34
  8. package/packages/datadog-instrumentations/src/anthropic.js +210 -15
  9. package/packages/datadog-instrumentations/src/aws-sdk.js +9 -1
  10. package/packages/datadog-instrumentations/src/browser-bunyan.js +11 -0
  11. package/packages/datadog-instrumentations/src/bunyan.js +3 -16
  12. package/packages/datadog-instrumentations/src/cucumber.js +30 -15
  13. package/packages/datadog-instrumentations/src/cypress-config.js +182 -16
  14. package/packages/datadog-instrumentations/src/cypress-legacy-finalizers.js +30 -0
  15. package/packages/datadog-instrumentations/src/cypress.js +2 -0
  16. package/packages/datadog-instrumentations/src/fastify.js +2 -0
  17. package/packages/datadog-instrumentations/src/helpers/bunyan.js +22 -0
  18. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -1
  19. package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +9 -4
  20. package/packages/datadog-instrumentations/src/helpers/register.js +10 -8
  21. package/packages/datadog-instrumentations/src/jest.js +25 -17
  22. package/packages/datadog-instrumentations/src/mariadb.js +278 -21
  23. package/packages/datadog-instrumentations/src/mocha/main.js +539 -55
  24. package/packages/datadog-instrumentations/src/mocha/utils.js +135 -19
  25. package/packages/datadog-instrumentations/src/playwright-reporter.js +247 -0
  26. package/packages/datadog-instrumentations/src/playwright.js +182 -35
  27. package/packages/datadog-instrumentations/src/router.js +2 -0
  28. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +6 -8
  29. package/packages/datadog-instrumentations/src/vitest-main.js +11 -3
  30. package/packages/datadog-plugin-aws-sdk/src/base.js +1 -0
  31. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +163 -44
  32. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -8
  33. package/packages/datadog-plugin-azure-functions/src/index.js +1 -1
  34. package/packages/datadog-plugin-browser-bunyan/src/index.js +9 -0
  35. package/packages/datadog-plugin-bunyan/src/index.js +5 -8
  36. package/packages/datadog-plugin-cucumber/src/index.js +11 -0
  37. package/packages/datadog-plugin-cypress/src/after-run.js +5 -1
  38. package/packages/datadog-plugin-cypress/src/after-spec.js +5 -1
  39. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +81 -29
  40. package/packages/datadog-plugin-cypress/src/finalization.js +76 -0
  41. package/packages/datadog-plugin-cypress/src/index.js +12 -6
  42. package/packages/datadog-plugin-cypress/src/plugin.js +16 -3
  43. package/packages/datadog-plugin-dd-trace-api/src/index.js +4 -0
  44. package/packages/datadog-plugin-electron/src/index.js +2 -0
  45. package/packages/datadog-plugin-fs/src/index.js +1 -1
  46. package/packages/datadog-plugin-jest/src/index.js +6 -0
  47. package/packages/datadog-plugin-mocha/src/index.js +56 -1
  48. package/packages/datadog-plugin-nats/src/index.js +1 -1
  49. package/packages/datadog-plugin-openai/src/tracing.js +41 -30
  50. package/packages/datadog-plugin-openai-agents/src/integration.js +1 -0
  51. package/packages/datadog-plugin-playwright/src/index.js +46 -13
  52. package/packages/datadog-plugin-vitest/src/index.js +6 -0
  53. package/packages/datadog-webpack/index.js +0 -11
  54. package/packages/dd-trace/index.js +0 -1
  55. package/packages/dd-trace/src/agent/info.js +6 -5
  56. package/packages/dd-trace/src/aiguard/client.js +100 -1
  57. package/packages/dd-trace/src/aiguard/errors.js +41 -0
  58. package/packages/dd-trace/src/aiguard/evaluation.js +357 -0
  59. package/packages/dd-trace/src/aiguard/integrations/anthropic.js +70 -0
  60. package/packages/dd-trace/src/aiguard/integrations/index.js +4 -0
  61. package/packages/dd-trace/src/aiguard/messages/anthropic.js +423 -0
  62. package/packages/dd-trace/src/aiguard/messages/openai.js +1 -24
  63. package/packages/dd-trace/src/aiguard/messages/utils.js +28 -0
  64. package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +1 -11
  65. package/packages/dd-trace/src/aiguard/sdk.js +22 -278
  66. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +9 -12
  67. package/packages/dd-trace/src/appsec/reporter.js +2 -0
  68. package/packages/dd-trace/src/appsec/telemetry/index.js +13 -0
  69. package/packages/dd-trace/src/appsec/telemetry/rasp.js +16 -0
  70. package/packages/dd-trace/src/appsec/telemetry/waf.js +24 -0
  71. package/packages/dd-trace/src/carrier.js +107 -48
  72. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +1 -0
  73. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +5 -5
  74. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +29 -3
  75. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +27 -9
  76. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +21 -5
  77. package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +164 -0
  78. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +26 -8
  79. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +365 -32
  80. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -4
  81. package/packages/dd-trace/src/ci-visibility/exporters/request.js +201 -0
  82. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -3
  83. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -5
  84. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +7 -4
  85. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -2
  86. package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +39 -0
  87. package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -6
  88. package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +4 -2
  89. package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +10 -4
  90. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +5 -5
  91. package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -0
  92. package/packages/dd-trace/src/config/index.js +13 -2
  93. package/packages/dd-trace/src/config/major-overrides.js +7 -0
  94. package/packages/dd-trace/src/config/supported-configurations.json +14 -0
  95. package/packages/dd-trace/src/datastreams/index.js +2 -0
  96. package/packages/dd-trace/src/datastreams/manager.js +9 -2
  97. package/packages/dd-trace/src/datastreams/processor.js +15 -13
  98. package/packages/dd-trace/src/datastreams/size.js +5 -0
  99. package/packages/dd-trace/src/debugger/constants.js +1 -0
  100. package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
  101. package/packages/dd-trace/src/debugger/devtools_client/index.js +5 -11
  102. package/packages/dd-trace/src/debugger/index.js +4 -2
  103. package/packages/dd-trace/src/debugger/inspect-segment.js +154 -0
  104. package/packages/dd-trace/src/evp_proxy/constants.js +8 -0
  105. package/packages/dd-trace/src/evp_proxy/direct.js +64 -0
  106. package/packages/dd-trace/src/evp_proxy/discovery.js +133 -0
  107. package/packages/dd-trace/src/evp_proxy/path.js +22 -0
  108. package/packages/dd-trace/src/exporters/agent/writer.js +49 -9
  109. package/packages/dd-trace/src/exporters/common/buffering-exporter.js +6 -4
  110. package/packages/dd-trace/src/exporters/common/request.js +5 -2
  111. package/packages/dd-trace/src/exporters/common/writer.js +11 -6
  112. package/packages/dd-trace/src/llmobs/experiments/client.js +167 -5
  113. package/packages/dd-trace/src/llmobs/experiments/dataset.js +484 -92
  114. package/packages/dd-trace/src/llmobs/experiments/experiment.js +302 -29
  115. package/packages/dd-trace/src/llmobs/experiments/index.js +75 -64
  116. package/packages/dd-trace/src/llmobs/experiments/noop.js +135 -7
  117. package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
  118. package/packages/dd-trace/src/llmobs/experiments/util.js +101 -9
  119. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -3
  120. package/packages/dd-trace/src/llmobs/plugins/base.js +4 -2
  121. package/packages/dd-trace/src/noop/proxy.js +3 -4
  122. package/packages/dd-trace/src/openfeature/constants/constants.js +0 -18
  123. package/packages/dd-trace/src/openfeature/flagging_provider.js +18 -2
  124. package/packages/dd-trace/src/openfeature/index.js +7 -4
  125. package/packages/dd-trace/src/openfeature/remote_config.js +1 -1
  126. package/packages/dd-trace/src/openfeature/writers/base.js +153 -11
  127. package/packages/dd-trace/src/openfeature/writers/exposures.js +62 -14
  128. package/packages/dd-trace/src/openfeature/writers/util.js +97 -15
  129. package/packages/dd-trace/src/opentelemetry/context_manager.js +7 -7
  130. package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +2 -1
  131. package/packages/dd-trace/src/opentelemetry/logs/logger.js +67 -11
  132. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +14 -3
  133. package/packages/dd-trace/src/opentelemetry/metrics/index.js +25 -12
  134. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +2 -5
  135. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +96 -43
  136. package/packages/dd-trace/src/opentracing/propagation/text_map.js +22 -13
  137. package/packages/dd-trace/src/opentracing/tracer.js +5 -2
  138. package/packages/dd-trace/src/otel-thread-ctx.js +387 -0
  139. package/packages/dd-trace/src/plugin_manager.js +3 -3
  140. package/packages/dd-trace/src/plugins/ci_plugin.js +6 -1
  141. package/packages/dd-trace/src/plugins/index.js +1 -0
  142. package/packages/dd-trace/src/plugins/util/jest.js +4 -3
  143. package/packages/dd-trace/src/plugins/util/test.js +9 -9
  144. package/packages/dd-trace/src/plugins/util/web.js +3 -0
  145. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  146. package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
  147. package/packages/dd-trace/src/profiling/profilers/wall.js +37 -90
  148. package/packages/dd-trace/src/profiling/webspan-utils.js +45 -0
  149. package/packages/dd-trace/src/proxy.js +38 -29
  150. package/packages/dd-trace/src/ritm.js +9 -2
  151. package/packages/dd-trace/src/serverless.js +37 -0
  152. package/packages/dd-trace/src/span_format.js +1 -0
  153. package/packages/dd-trace/src/span_stats.js +30 -3
  154. package/packages/dd-trace/src/storage-channels.js +86 -0
  155. package/packages/dd-trace/src/telemetry/metrics.js +62 -8
  156. package/packages/dd-trace/src/telemetry/send-data.js +1 -0
  157. package/packages/dd-trace/src/tracer.js +9 -2
  158. package/packages/dd-trace/src/tracer_metadata.js +14 -1
  159. package/packages/dd-trace/src/web-tags-cache.js +132 -0
  160. package/vendor/dist/@datadog/openfeature-node-server/LICENSE +201 -0
  161. package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -0
  162. package/vendor/dist/@datadog/sketches-js/index.js +1 -1
  163. package/vendor/dist/https-proxy-agent/LICENSE +22 -0
  164. package/vendor/dist/https-proxy-agent/index.js +4 -0
  165. package/vendor/dist/protobufjs/index.js +1 -1
  166. package/vendor/dist/protobufjs/minimal/index.js +1 -1
  167. package/vendor/dist/proxy-from-env/LICENSE +20 -0
  168. package/vendor/dist/proxy-from-env/index.js +1 -0
  169. package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +0 -65
  170. package/packages/datadog-webpack/src/optional-peer-loader.js +0 -17
  171. package/packages/dd-trace/src/feature-registry.js +0 -29
  172. package/packages/dd-trace/src/openfeature/register.js +0 -35
  173. package/packages/dd-trace/src/openfeature/require-provider.js +0 -18
@@ -6,6 +6,144 @@ const { addHook } = require('./helpers/instrument')
6
6
 
7
7
  const anthropicTracingChannel = tracingChannel('apm:anthropic:request')
8
8
  const onStreamedChunkCh = channel('apm:anthropic:request:chunk')
9
+ const messagesBeforeChannel = channel('dd-trace:anthropic:messages:before')
10
+ const messagesAfterChannel = channel('dd-trace:anthropic:messages:after')
11
+
12
+ /**
13
+ * Publishes a provider-native lifecycle payload to a cancelable lifecycle channel.
14
+ *
15
+ * Subscribers push async work into `pending` synchronously during publication and
16
+ * abort `abortController` with an error before the pushed promise resolves to block.
17
+ *
18
+ * @param {object} channel
19
+ * @param {object} payload
20
+ * @returns {Promise<void>}
21
+ */
22
+ function publishLifecycle (channel, payload) {
23
+ const abortController = new AbortController()
24
+ const ctx = { ...payload, abortController, pending: [] }
25
+
26
+ channel.publish(ctx)
27
+
28
+ return Promise.all(ctx.pending).then(() => {
29
+ if (abortController.signal.aborted) {
30
+ throw abortController.signal.reason
31
+ }
32
+ })
33
+ }
34
+
35
+ /**
36
+ * @template T
37
+ * @param {Promise<T>} promise
38
+ * @param {Promise<void>|undefined} verdict
39
+ * @returns {Promise<T>}
40
+ */
41
+ function waitForVerdict (promise, verdict) {
42
+ if (!verdict) return promise
43
+
44
+ // The lifecycle verdict takes precedence over an earlier SDK rejection.
45
+ promise.catch(() => {})
46
+ return verdict.then(() => promise)
47
+ }
48
+
49
+ /**
50
+ * @param {Array<unknown>} args
51
+ * @returns {Array<unknown>|undefined}
52
+ */
53
+ function snapshotLifecycleArgs (args) {
54
+ const options = args[0]
55
+ if (!options || typeof options !== 'object') return
56
+
57
+ const input = { messages: options.messages }
58
+ if (options.system !== undefined) input.system = options.system
59
+
60
+ // Snapshot via JSON so AI Guard evaluates exactly what the SDK serializes and sends, immune to
61
+ // later caller mutation. If it can't serialize (e.g. circular), the SDK's own serialization would
62
+ // fail too, so skipping evaluation is safe — nothing reaches the model.
63
+ try {
64
+ const snapshot = [...args]
65
+ // eslint-disable-next-line unicorn/prefer-structured-clone
66
+ snapshot[0] = { ...options, ...JSON.parse(JSON.stringify(input)) }
67
+ return snapshot
68
+ } catch {
69
+ // Unserializable input — leave AI Guard inactive for this call (the SDK send would fail too).
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Finishes after output evaluation so a block propagates to the caller and span.
75
+ *
76
+ * @param {object} ctx
77
+ * @param {object} result
78
+ * @param {(body: object) => Promise<void>|undefined} getVerdict
79
+ * @param {object|string} [returnedResult]
80
+ * @returns {object|string|Promise<object|string>}
81
+ */
82
+ function finishResult (ctx, result, getVerdict, returnedResult = result) {
83
+ const verdict = getVerdict(result)
84
+ if (!verdict) {
85
+ finish(ctx, result)
86
+ return returnedResult
87
+ }
88
+
89
+ return verdict.then(() => {
90
+ finish(ctx, result)
91
+ return returnedResult
92
+ })
93
+ }
94
+
95
+ /**
96
+ * @param {object} ctx
97
+ * @param {Error} error
98
+ * @throws {Error} Always rethrows the supplied error.
99
+ */
100
+ function finishAndThrow (ctx, error) {
101
+ finish(ctx, null, error)
102
+ throw error
103
+ }
104
+
105
+ /**
106
+ * @param {object} response
107
+ * @param {'json'|'text'} method
108
+ * @param {object} ctx
109
+ * @param {(body: object) => Promise<void>|undefined} getVerdict
110
+ */
111
+ function wrapResponseReader (response, method, ctx, getVerdict) {
112
+ if (typeof response[method] !== 'function') return
113
+
114
+ shimmer.wrap(response, method, original => function (...args) {
115
+ return original.apply(this, args)
116
+ .then(body => {
117
+ if (method === 'json') return finishResult(ctx, body, getVerdict)
118
+
119
+ try {
120
+ return finishResult(ctx, JSON.parse(body), getVerdict, body)
121
+ } catch {
122
+ finish(ctx)
123
+ return body
124
+ }
125
+ })
126
+ .catch(error => finishAndThrow(ctx, error))
127
+ })
128
+ }
129
+
130
+ /**
131
+ * @param {object} response
132
+ * @param {object} ctx
133
+ * @param {(body: object) => Promise<void>|undefined} getVerdict
134
+ */
135
+ function wrapRawResponse (response, ctx, getVerdict) {
136
+ wrapResponseReader(response, 'json', ctx, getVerdict)
137
+ wrapResponseReader(response, 'text', ctx, getVerdict)
138
+
139
+ if (typeof response.clone !== 'function') return
140
+
141
+ shimmer.wrap(response, 'clone', clone => function (...args) {
142
+ const clonedResponse = clone.apply(this, args)
143
+ wrapRawResponse(clonedResponse, ctx, getVerdict)
144
+ return clonedResponse
145
+ })
146
+ }
9
147
 
10
148
  function wrapStreamIterator (iterator, ctx) {
11
149
  return function (...args) {
@@ -34,40 +172,94 @@ function wrapStreamIterator (iterator, ctx) {
34
172
 
35
173
  function wrapCreate (create) {
36
174
  return function (...args) {
37
- if (!anthropicTracingChannel.start.hasSubscribers) {
175
+ const options = args[0]
176
+ const stream = options?.stream
177
+
178
+ // Streaming is out of scope for lifecycle evaluation.
179
+ const lifecycleArgs = !stream &&
180
+ (messagesBeforeChannel.hasSubscribers || messagesAfterChannel.hasSubscribers)
181
+ ? snapshotLifecycleArgs(args)
182
+ : undefined
183
+
184
+ if (!anthropicTracingChannel.start.hasSubscribers && !lifecycleArgs) {
38
185
  return create.apply(this, args)
39
186
  }
40
187
 
41
- const options = args[0]
42
- const stream = options.stream
43
-
44
- const ctx = { options, resource: 'create', baseUrl: this._client?.baseURL }
188
+ const ctx = { options: lifecycleArgs?.[0] ?? options, resource: 'create', baseUrl: this._client?.baseURL }
45
189
 
46
190
  return anthropicTracingChannel.start.runStores(ctx, () => {
191
+ const parentSpan = lifecycleArgs ? ctx.currentStore?.span : undefined
192
+
47
193
  let apiPromise
48
194
  try {
49
- apiPromise = create.apply(this, args)
195
+ // Anthropic starts the request eagerly; the input verdict only gates result delivery.
196
+ apiPromise = create.apply(this, lifecycleArgs ?? args)
50
197
  } catch (error) {
51
198
  finish(ctx, null, error)
52
199
  throw error
53
200
  }
54
201
 
55
- shimmer.wrap(apiPromise, 'parse', parse => function (...args) {
56
- return parse.apply(this, args)
202
+ let beforeVerdict
203
+ let afterVerdict
204
+ let parseResult
205
+ let wrappedResponse
206
+
207
+ function getBeforeVerdict () {
208
+ if (!lifecycleArgs || beforeVerdict) return beforeVerdict
209
+ if (!messagesBeforeChannel.hasSubscribers) return
210
+
211
+ beforeVerdict = publishLifecycle(messagesBeforeChannel, { args: lifecycleArgs, parentSpan })
212
+ return beforeVerdict
213
+ }
214
+
215
+ /**
216
+ * @param {object|string} body
217
+ */
218
+ function getAfterVerdict (body) {
219
+ if (!lifecycleArgs || afterVerdict) return afterVerdict
220
+ if (!messagesAfterChannel.hasSubscribers) return
221
+
222
+ afterVerdict = publishLifecycle(messagesAfterChannel, { args: lifecycleArgs, body, parentSpan })
223
+ return afterVerdict
224
+ }
225
+
226
+ shimmer.wrap(apiPromise, 'parse', parse => function (...parseArgs) {
227
+ if (parseResult) return parseResult
228
+
229
+ const parsed = parse.apply(this, parseArgs)
230
+ parseResult = waitForVerdict(parsed, getBeforeVerdict())
57
231
  .then(response => {
58
232
  if (stream) {
59
233
  shimmer.wrap(response, Symbol.asyncIterator, iterator => wrapStreamIterator(iterator, ctx))
60
- } else {
61
- finish(ctx, response, null)
234
+ return response
62
235
  }
63
-
64
- return response
65
- }).catch(error => {
66
- finish(ctx, null, error)
67
- throw error
236
+ return finishResult(ctx, response, getAfterVerdict)
68
237
  })
238
+ .catch(error => finishAndThrow(ctx, error))
239
+
240
+ return parseResult
69
241
  })
70
242
 
243
+ if (typeof apiPromise.asResponse === 'function') {
244
+ shimmer.wrap(apiPromise, 'asResponse', origAsResponse => function (...asResponseArgs) {
245
+ return waitForVerdict(origAsResponse.apply(this, asResponseArgs), getBeforeVerdict())
246
+ .then(response => {
247
+ // Wrap the raw response's json()/text()/clone() readers to evaluate output on read,
248
+ // but only while someone still consumes the result and not twice for the same response.
249
+ const outputObserved = anthropicTracingChannel.start.hasSubscribers ||
250
+ afterVerdict || messagesAfterChannel.hasSubscribers
251
+ if (!stream && outputObserved && wrappedResponse !== response) {
252
+ wrappedResponse = response
253
+ wrapRawResponse(response, ctx, getAfterVerdict)
254
+ }
255
+
256
+ if (afterVerdict) return afterVerdict.then(() => response)
257
+ return response
258
+ })
259
+ .catch(error => finishAndThrow(ctx, error))
260
+ })
261
+ }
262
+
71
263
  anthropicTracingChannel.end.publish(ctx)
72
264
 
73
265
  return apiPromise
@@ -76,6 +268,8 @@ function wrapCreate (create) {
76
268
  }
77
269
 
78
270
  function finish (ctx, result, error) {
271
+ if (ctx.finished) return
272
+
79
273
  if (error) {
80
274
  ctx.error = error
81
275
  anthropicTracingChannel.error.publish(ctx)
@@ -83,6 +277,7 @@ function finish (ctx, result, error) {
83
277
 
84
278
  // streamed responses are handled and set separately
85
279
  ctx.result ??= result
280
+ ctx.finished = true
86
281
 
87
282
  anthropicTracingChannel.asyncEnd.publish(ctx)
88
283
  }
@@ -25,6 +25,13 @@ const KNOWN_CHANNEL_SUFFIXES = new Set([
25
25
  'bedrockruntime',
26
26
  ])
27
27
 
28
+ // Older SDK clients report EventBridge under its CloudWatch Events name or its `events` endpoint
29
+ // prefix; both share the EventBridge channels.
30
+ const CHANNEL_SUFFIX_ALIASES = new Map([
31
+ ['cloudwatchevents', 'eventbridge'],
32
+ ['events', 'eventbridge'],
33
+ ])
34
+
28
35
  /**
29
36
  * @typedef {object} ChannelBag
30
37
  * @property {ReturnType<typeof channel>} start
@@ -314,7 +321,8 @@ function addResponse (ctx, error, result) {
314
321
  function getChannelSuffix (name) {
315
322
  // some resource identifiers have spaces between ex: bedrock runtime
316
323
  name = String(name).replaceAll(' ', '')
317
- return KNOWN_CHANNEL_SUFFIXES.has(name) ? name : 'default'
324
+ if (KNOWN_CHANNEL_SUFFIXES.has(name)) return name
325
+ return CHANNEL_SUFFIX_ALIASES.get(name) ?? 'default'
318
326
  }
319
327
 
320
328
  addHook({ name: '@smithy/smithy-client', versions: ['>=1.0.3'] }, smithy => {
@@ -0,0 +1,11 @@
1
+ 'use strict'
2
+
3
+ const wrapLogger = require('./helpers/bunyan')
4
+ const { addHook } = require('./helpers/instrument')
5
+
6
+ addHook({ name: 'browser-bunyan', versions: ['>=1'] }, browserBunyan => {
7
+ // Published versions generate `_emit` through different bundle shapes,
8
+ // so Orchestrion has no stable function to match.
9
+ wrapLogger(browserBunyan.Logger, 'browser-bunyan')
10
+ return browserBunyan
11
+ })
@@ -1,22 +1,9 @@
1
1
  'use strict'
2
2
 
3
- const shimmer = require('../../datadog-shimmer')
4
- const {
5
- channel,
6
- addHook,
7
- } = require('./helpers/instrument')
3
+ const wrapLogger = require('./helpers/bunyan')
4
+ const { addHook } = require('./helpers/instrument')
8
5
 
9
6
  addHook({ name: 'bunyan', versions: ['>=1'] }, Logger => {
10
- const logCh = channel('apm:bunyan:log')
11
- shimmer.wrap(Logger.prototype, '_emit', emit => {
12
- return function wrappedEmit (rec) {
13
- if (logCh.hasSubscribers) {
14
- const payload = { message: rec }
15
- logCh.publish(payload)
16
- arguments[0] = payload.message
17
- }
18
- return emit.apply(this, arguments)
19
- }
20
- })
7
+ wrapLogger(Logger, 'bunyan')
21
8
  return Logger
22
9
  })
@@ -116,7 +116,7 @@ let pickleByFile = {}
116
116
  const pickleResultByFile = {}
117
117
 
118
118
  let skippableSuites = []
119
- let skippableSuitesCoverage = {}
119
+ let skippableSuitesCoverage
120
120
  let skippedSuitesCoverage = {}
121
121
  let itrCorrelationId = ''
122
122
  let isForcedToRun = false
@@ -153,12 +153,6 @@ function isValidKnownTests (receivedKnownTests) {
153
153
  return !!receivedKnownTests.cucumber
154
154
  }
155
155
 
156
- function hasSkippableSuitesCoverage () {
157
- return skippableSuitesCoverage &&
158
- typeof skippableSuitesCoverage === 'object' &&
159
- Object.keys(skippableSuitesCoverage).length > 0
160
- }
161
-
162
156
  function isTiaCoverageBackfillEnabled () {
163
157
  return isItrEnabled && isCoverageReportUploadEnabled
164
158
  }
@@ -172,7 +166,7 @@ function shouldReportCodeCoverageLinesPct (hasBackfilledCoverage) {
172
166
  }
173
167
 
174
168
  function getSkippedSuitesCoverageForRun () {
175
- return isSuitesSkipped && isTiaCoverageBackfillEnabled() && hasSkippableSuitesCoverage()
169
+ return isSuitesSkipped && isTiaCoverageBackfillEnabled() && skippableSuitesCoverage !== undefined
176
170
  ? skippableSuitesCoverage
177
171
  : {}
178
172
  }
@@ -188,7 +182,7 @@ function getCucumberTestSessionCoverageFiles () {
188
182
 
189
183
  function resetSuiteSkippingRunState () {
190
184
  skippableSuites = []
191
- skippableSuitesCoverage = {}
185
+ skippableSuitesCoverage = undefined
192
186
  skippedSuitesCoverage = {}
193
187
  skippedSuites = []
194
188
  isSuitesSkipped = false
@@ -1143,7 +1137,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
1143
1137
 
1144
1138
  errorSkippableRequest = skippableResponse.err
1145
1139
  skippableSuites = skippableResponse.skippableSuites ?? []
1146
- skippableSuitesCoverage = skippableResponse.skippableSuitesCoverage ?? {}
1140
+ skippableSuitesCoverage = skippableResponse.skippableSuitesCoverage
1147
1141
 
1148
1142
  if (!errorSkippableRequest) {
1149
1143
  const filteredPickles = isCoordinator
@@ -1222,7 +1216,28 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
1222
1216
  itrSkippedSuitesCh.publish({ skippedSuites, frameworkVersion })
1223
1217
  }
1224
1218
 
1225
- const result = await start.apply(this, arguments)
1219
+ let result
1220
+ try {
1221
+ result = await start.apply(this, arguments)
1222
+ } catch (error) {
1223
+ try {
1224
+ await getChannelPromise(sessionFinishCh, {
1225
+ status: 'fail',
1226
+ error,
1227
+ isSuitesSkipped,
1228
+ numSkippedSuites: skippedSuites.length,
1229
+ hasUnskippableSuites: isUnskippable,
1230
+ hasForcedToRunSuites: isForcedToRun,
1231
+ isEarlyFlakeDetectionEnabled,
1232
+ isEarlyFlakeDetectionFaulty,
1233
+ isTestManagementTestsEnabled,
1234
+ isParallel,
1235
+ })
1236
+ } catch (finalizationError) {
1237
+ log.error('Cucumber test session finalization error: %s', finalizationError)
1238
+ }
1239
+ throw error
1240
+ }
1226
1241
  const success = satisfies(frameworkVersion, '>=13.1.0') ? result.success : result
1227
1242
 
1228
1243
  let untestedCoverage
@@ -1467,14 +1482,14 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
1467
1482
 
1468
1483
  this.options.retry = originalRetry
1469
1484
 
1470
- if (isNewerCucumberVersion && shouldRunEarlyFlakeDetection() && (isNew || isModified)) {
1471
- return shouldBePassedByEFD
1472
- }
1473
-
1474
1485
  if (isNewerCucumberVersion && isTestManagementTestsEnabled && !isAttemptToFix && (isQuarantined || isDisabled)) {
1475
1486
  return shouldBePassedByTestManagement
1476
1487
  }
1477
1488
 
1489
+ if (isNewerCucumberVersion && shouldRunEarlyFlakeDetection() && (isNew || isModified)) {
1490
+ return shouldBePassedByEFD
1491
+ }
1492
+
1478
1493
  if (isNewerCucumberVersion && isAttemptToFix && shouldBeFailedByAttemptToFix) {
1479
1494
  return false
1480
1495
  }