dd-trace 6.9.0 → 6.11.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.
- package/README.md +0 -17
- package/ci/vitest-no-worker-init-setup.mjs +112 -10
- package/index.d.ts +150 -3
- package/initialize.mjs +28 -17
- package/openfeature.js +2 -2
- package/package.json +14 -10
- package/packages/datadog-esbuild/index.js +0 -34
- package/packages/datadog-instrumentations/src/anthropic.js +210 -15
- package/packages/datadog-instrumentations/src/aws-sdk.js +9 -1
- package/packages/datadog-instrumentations/src/browser-bunyan.js +11 -0
- package/packages/datadog-instrumentations/src/bunyan.js +3 -16
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +111 -6
- package/packages/datadog-instrumentations/src/cucumber.js +26 -11
- package/packages/datadog-instrumentations/src/cypress-config.js +182 -16
- package/packages/datadog-instrumentations/src/cypress-legacy-finalizers.js +30 -0
- package/packages/datadog-instrumentations/src/cypress.js +2 -0
- package/packages/datadog-instrumentations/src/fastify.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/bunyan.js +22 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +634 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +10 -8
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +81 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +83 -1
- package/packages/datadog-instrumentations/src/jest.js +26 -18
- package/packages/datadog-instrumentations/src/mariadb.js +278 -21
- package/packages/datadog-instrumentations/src/mocha/main.js +540 -56
- package/packages/datadog-instrumentations/src/mocha/utils.js +132 -25
- package/packages/datadog-instrumentations/src/mysql.js +45 -15
- package/packages/datadog-instrumentations/src/mysql2.js +119 -18
- package/packages/datadog-instrumentations/src/path-to-regexp.js +67 -1
- package/packages/datadog-instrumentations/src/pg.js +116 -92
- package/packages/datadog-instrumentations/src/playwright-reporter.js +99 -0
- package/packages/datadog-instrumentations/src/playwright.js +149 -2
- package/packages/datadog-instrumentations/src/router.js +2 -0
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +43 -4
- package/packages/datadog-instrumentations/src/vitest-main.js +180 -20
- package/packages/datadog-instrumentations/src/vitest-util.js +64 -5
- package/packages/datadog-instrumentations/src/vitest-worker.js +150 -25
- package/packages/datadog-instrumentations/src/webdriverio.js +31 -17
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +12 -6
- package/packages/datadog-plugin-aws-sdk/src/base.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +163 -44
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -13
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -5
- package/packages/datadog-plugin-azure-functions/src/index.js +1 -1
- package/packages/datadog-plugin-browser-bunyan/src/index.js +9 -0
- package/packages/datadog-plugin-bunyan/src/index.js +5 -8
- package/packages/datadog-plugin-cucumber/src/index.js +11 -0
- package/packages/datadog-plugin-cypress/src/after-run.js +5 -1
- package/packages/datadog-plugin-cypress/src/after-spec.js +5 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +82 -30
- package/packages/datadog-plugin-cypress/src/finalization.js +76 -0
- package/packages/datadog-plugin-cypress/src/index.js +12 -6
- package/packages/datadog-plugin-cypress/src/plugin.js +16 -3
- package/packages/datadog-plugin-dd-trace-api/src/index.js +4 -0
- package/packages/datadog-plugin-electron/src/index.js +2 -0
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +31 -17
- package/packages/datadog-plugin-jest/src/index.js +11 -4
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -3
- package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -3
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -2
- package/packages/datadog-plugin-kafkajs/src/utils.js +65 -7
- package/packages/datadog-plugin-mocha/src/index.js +606 -40
- package/packages/datadog-plugin-mysql/src/index.js +37 -0
- package/packages/datadog-plugin-nats/src/index.js +1 -1
- package/packages/datadog-plugin-next/src/index.js +1 -19
- package/packages/datadog-plugin-openai/src/tracing.js +41 -30
- package/packages/datadog-plugin-openai-agents/src/integration.js +279 -69
- package/packages/datadog-plugin-openai-agents/src/processor.js +16 -4
- package/packages/datadog-plugin-pg/src/index.js +1 -0
- package/packages/datadog-plugin-playwright/src/index.js +42 -13
- package/packages/datadog-plugin-vitest/src/index.js +14 -20
- package/packages/datadog-plugin-ws/src/util.js +2 -1
- package/packages/datadog-webpack/index.js +0 -11
- package/packages/dd-trace/index.js +0 -1
- package/packages/dd-trace/src/agent/info.js +6 -5
- package/packages/dd-trace/src/aiguard/client.js +100 -1
- package/packages/dd-trace/src/aiguard/errors.js +41 -0
- package/packages/dd-trace/src/aiguard/evaluation.js +357 -0
- package/packages/dd-trace/src/aiguard/integrations/anthropic.js +70 -0
- package/packages/dd-trace/src/aiguard/integrations/index.js +4 -0
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +423 -0
- package/packages/dd-trace/src/aiguard/messages/openai.js +1 -24
- package/packages/dd-trace/src/aiguard/messages/utils.js +28 -0
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +1 -11
- package/packages/dd-trace/src/aiguard/sdk.js +22 -278
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +453 -0
- package/packages/dd-trace/src/appsec/handlers/http-request.js +13 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +9 -12
- package/packages/dd-trace/src/carrier.js +356 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +1 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +27 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +22 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +21 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +164 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +22 -6
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +365 -32
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +201 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -5
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -1
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +39 -0
- package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -6
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +6 -2
- package/packages/dd-trace/src/config/generated-config-types.d.ts +7 -0
- package/packages/dd-trace/src/config/index.js +13 -2
- package/packages/dd-trace/src/config/major-overrides.js +7 -0
- package/packages/dd-trace/src/config/supported-configurations.json +24 -0
- package/packages/dd-trace/src/datastreams/context.js +6 -1
- package/packages/dd-trace/src/datastreams/index.js +2 -0
- package/packages/dd-trace/src/datastreams/manager.js +14 -3
- package/packages/dd-trace/src/datastreams/pathway.js +23 -22
- package/packages/dd-trace/src/datastreams/processor.js +16 -13
- package/packages/dd-trace/src/datastreams/size.js +5 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +3 -2
- package/packages/dd-trace/src/exporters/agent/writer.js +49 -9
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +6 -4
- package/packages/dd-trace/src/exporters/common/writer.js +11 -6
- package/packages/dd-trace/src/llmobs/constants/tags.js +5 -0
- package/packages/dd-trace/src/llmobs/experiments/client.js +163 -5
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +241 -87
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +280 -20
- package/packages/dd-trace/src/llmobs/experiments/index.js +58 -59
- package/packages/dd-trace/src/llmobs/experiments/noop.js +71 -3
- package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
- package/packages/dd-trace/src/llmobs/experiments/util.js +41 -5
- package/packages/dd-trace/src/llmobs/index.js +34 -2
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -3
- package/packages/dd-trace/src/llmobs/plugins/base.js +4 -2
- package/packages/dd-trace/src/llmobs/span_processor.js +16 -0
- package/packages/dd-trace/src/llmobs/tagger.js +96 -0
- package/packages/dd-trace/src/llmobs/util.js +78 -0
- package/packages/dd-trace/src/noop/proxy.js +3 -4
- package/packages/dd-trace/src/openfeature/flagging_provider.js +18 -2
- package/packages/dd-trace/src/openfeature/remote_config.js +1 -1
- package/packages/dd-trace/src/opentelemetry/context_manager.js +7 -7
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +2 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +67 -11
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +14 -3
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +25 -12
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +2 -5
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +96 -43
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +126 -120
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +4 -8
- package/packages/dd-trace/src/opentracing/tracer.js +5 -2
- package/packages/dd-trace/src/otel-thread-ctx.js +387 -0
- package/packages/dd-trace/src/plugin_manager.js +5 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +6 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/{datadog-plugin-jest/src/util.js → dd-trace/src/plugins/util/jest.js} +5 -65
- package/packages/dd-trace/src/plugins/util/test.js +93 -14
- package/packages/dd-trace/src/plugins/util/web.js +56 -2
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +37 -90
- package/packages/dd-trace/src/profiling/webspan-utils.js +45 -0
- package/packages/dd-trace/src/proxy.js +38 -29
- package/packages/dd-trace/src/ritm.js +9 -2
- package/packages/dd-trace/src/serverless.js +37 -0
- package/packages/dd-trace/src/span_format.js +1 -0
- package/packages/dd-trace/src/span_stats.js +30 -3
- package/packages/dd-trace/src/storage-channels.js +86 -0
- package/packages/dd-trace/src/tracer.js +9 -2
- package/packages/dd-trace/src/tracer_metadata.js +14 -1
- package/packages/dd-trace/src/web-tags-cache.js +132 -0
- package/vendor/dist/@datadog/openfeature-node-server/LICENSE +201 -0
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +0 -65
- package/packages/datadog-webpack/src/optional-peer-loader.js +0 -17
- package/packages/dd-trace/src/feature-registry.js +0 -29
- package/packages/dd-trace/src/openfeature/register.js +0 -35
- package/packages/dd-trace/src/openfeature/require-provider.js +0 -18
|
@@ -1,35 +1,90 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
|
|
3
|
+
const { DsmPathwayCodec, PATHWAY_FIELD_BYTES } = require('../../../dd-trace/src/datastreams')
|
|
2
4
|
const log = require('../../../dd-trace/src/log')
|
|
3
5
|
const BaseAwsSdkPlugin = require('../base')
|
|
4
6
|
|
|
7
|
+
const DEFAULT_EVENT_BUS = 'default'
|
|
8
|
+
const DEFAULT_DETAIL_TYPE = 'unknown'
|
|
5
9
|
// EventBridge enforces this limit over the whole PutEvents request (the sum of
|
|
6
|
-
// every entry), not over a single entry.
|
|
10
|
+
// every entry), not over a single entry.
|
|
7
11
|
const MAX_PUT_EVENTS_BYTES = 1024 * 1024
|
|
12
|
+
// Sizing runs before any checkpoint exists, so entries that carry nothing but a pathway are
|
|
13
|
+
// measured against this stand-in.
|
|
14
|
+
const PATHWAY_SIZE_PROBE = { hash: Buffer.alloc(8), pathwayStartNs: 0, edgeStartNs: 0 }
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {object} PutEventsRequestEntry
|
|
18
|
+
* @property {string} [Detail]
|
|
19
|
+
* @property {string} [DetailType]
|
|
20
|
+
* @property {string} [EventBusName]
|
|
21
|
+
* @property {string[]} [Resources]
|
|
22
|
+
* @property {string} [Source]
|
|
23
|
+
* @property {Date} [Time]
|
|
24
|
+
* @property {string} [TraceHeader]
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Size a single entry the way DSM reports payloads across tracers: the UTF-8 byte length of every
|
|
29
|
+
* string field the caller supplied. `Time` is excluded because it is not part of the message the
|
|
30
|
+
* consumer receives, which is also why this differs from `putEventEntrySize`.
|
|
31
|
+
*
|
|
32
|
+
* @param {PutEventsRequestEntry} entry whose `Detail` the caller has already checked is a string.
|
|
33
|
+
* @returns {number}
|
|
34
|
+
*/
|
|
35
|
+
function dsmPayloadSize (entry) {
|
|
36
|
+
let size = Buffer.byteLength(entry.Detail)
|
|
37
|
+
if (typeof entry.DetailType === 'string') size += Buffer.byteLength(entry.DetailType)
|
|
38
|
+
if (typeof entry.EventBusName === 'string') size += Buffer.byteLength(entry.EventBusName)
|
|
39
|
+
if (typeof entry.Source === 'string') size += Buffer.byteLength(entry.Source)
|
|
40
|
+
if (typeof entry.TraceHeader === 'string') size += Buffer.byteLength(entry.TraceHeader)
|
|
41
|
+
if (Array.isArray(entry.Resources)) {
|
|
42
|
+
for (const resource of entry.Resources) {
|
|
43
|
+
if (typeof resource === 'string') size += Buffer.byteLength(resource)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return size
|
|
47
|
+
}
|
|
8
48
|
|
|
9
49
|
/**
|
|
10
50
|
* Size a single `PutEventsRequestEntry` the way EventBridge does server-side:
|
|
11
51
|
* the UTF-8 byte length of `Source`, `DetailType`, `Detail`, and each
|
|
12
52
|
* `Resources` ARN, plus a flat 14 bytes when `Time` is set.
|
|
13
53
|
*
|
|
14
|
-
* @param {
|
|
54
|
+
* @param {PutEventsRequestEntry} entry
|
|
15
55
|
* @param {string} [detail] overrides `entry.Detail`, used to size the entry as
|
|
16
56
|
* it would be sent with the injected `_datadog` context
|
|
17
|
-
* @returns {number}
|
|
18
57
|
* @see https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-putevents.html
|
|
19
58
|
*/
|
|
20
|
-
function putEventEntrySize (entry, detail
|
|
59
|
+
function putEventEntrySize (entry, detail) {
|
|
60
|
+
if (entry == null) return 0
|
|
61
|
+
|
|
62
|
+
detail ??= entry.Detail
|
|
21
63
|
let size = entry.Time == null ? 0 : 14
|
|
22
|
-
if (entry.Source
|
|
23
|
-
if (entry.DetailType
|
|
24
|
-
if (detail
|
|
25
|
-
if (entry.Resources
|
|
64
|
+
if (typeof entry.Source === 'string') size += Buffer.byteLength(entry.Source)
|
|
65
|
+
if (typeof entry.DetailType === 'string') size += Buffer.byteLength(entry.DetailType)
|
|
66
|
+
if (typeof detail === 'string') size += Buffer.byteLength(detail)
|
|
67
|
+
if (Array.isArray(entry.Resources)) {
|
|
26
68
|
for (const resource of entry.Resources) {
|
|
27
|
-
if (resource
|
|
69
|
+
if (typeof resource === 'string') size += Buffer.byteLength(resource)
|
|
28
70
|
}
|
|
29
71
|
}
|
|
30
72
|
return size
|
|
31
73
|
}
|
|
32
74
|
|
|
75
|
+
/**
|
|
76
|
+
* @param {string} detail
|
|
77
|
+
* @param {Record<string, string>} carrier
|
|
78
|
+
* @returns {string|undefined} `undefined` when `detail` is not a JSON object
|
|
79
|
+
*/
|
|
80
|
+
function injectDetail (detail, carrier) {
|
|
81
|
+
try {
|
|
82
|
+
return BaseAwsSdkPlugin.injectFieldIntoJsonObject(detail, '_datadog', carrier)
|
|
83
|
+
} catch (error) {
|
|
84
|
+
log.error('EventBridge error injecting request', error)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
33
88
|
class EventBridge extends BaseAwsSdkPlugin {
|
|
34
89
|
static id = 'eventbridge'
|
|
35
90
|
static isPayloadReporter = true
|
|
@@ -46,44 +101,31 @@ class EventBridge extends BaseAwsSdkPlugin {
|
|
|
46
101
|
}
|
|
47
102
|
|
|
48
103
|
/**
|
|
49
|
-
*
|
|
50
|
-
* @param {import('../../../..').Span} span
|
|
51
|
-
* @param {object} request
|
|
104
|
+
* The context goes into `Detail` because EventBridge reserves an entry's `TraceHeader` for X-Ray.
|
|
52
105
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* (https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-putevent-size.html)
|
|
106
|
+
* @param {import('../../../..').Span} span
|
|
107
|
+
* @param {{ operation: string, params?: { Entries?: PutEventsRequestEntry[] } }} request
|
|
108
|
+
* @see https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutEventsRequestEntry.html
|
|
109
|
+
* @see https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-putevent-size.html
|
|
58
110
|
*/
|
|
59
111
|
requestInject (span, request) {
|
|
60
|
-
const operation = request
|
|
61
|
-
if (operation
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
this.tracer.inject(span, 'text_map', injected)
|
|
69
|
-
|
|
70
|
-
// Only `injectFieldIntoJsonObject` can throw (the slow path
|
|
71
|
-
// `JSON.parse` for non-`{...}` payloads). Tighten the catch around
|
|
72
|
-
// it so the rest of the body stays in V8's optimisable surface.
|
|
73
|
-
let finalData
|
|
74
|
-
try {
|
|
75
|
-
finalData = BaseAwsSdkPlugin.injectFieldIntoJsonObject(entries[0].Detail, '_datadog', injected)
|
|
76
|
-
} catch (error) {
|
|
77
|
-
log.error('EventBridge error injecting request', error)
|
|
78
|
-
return
|
|
79
|
-
}
|
|
112
|
+
const { operation, params } = request
|
|
113
|
+
if (operation !== 'putEvents' || !params?.Entries?.length) return
|
|
114
|
+
|
|
115
|
+
const entries = params.Entries
|
|
116
|
+
const dsmEnabled = this.config.dsmEnabled
|
|
117
|
+
const batchPropagationEnabled = this.config.batchPropagationEnabled
|
|
118
|
+
const traceCarrier = this.tracer.inject(span, 'text_map')
|
|
119
|
+
if (traceCarrier === undefined && !dsmEnabled) return
|
|
80
120
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
121
|
+
// The default configuration injects the first entry alone and records no checkpoint, so it
|
|
122
|
+
// needs none of the deferred-write bookkeeping the paths below depend on.
|
|
123
|
+
if (!dsmEnabled && !batchPropagationEnabled) {
|
|
124
|
+
const entry = entries[0]
|
|
125
|
+
if (typeof entry?.Detail !== 'string') return
|
|
126
|
+
const detail = injectDetail(entry.Detail, traceCarrier)
|
|
127
|
+
if (detail === undefined) return
|
|
128
|
+
let requestSize = putEventEntrySize(entry, detail)
|
|
87
129
|
for (let i = 1; requestSize < MAX_PUT_EVENTS_BYTES && i < entries.length; i++) {
|
|
88
130
|
requestSize += putEventEntrySize(entries[i])
|
|
89
131
|
}
|
|
@@ -91,8 +133,85 @@ class EventBridge extends BaseAwsSdkPlugin {
|
|
|
91
133
|
log.info('Payload size too large to pass context')
|
|
92
134
|
return
|
|
93
135
|
}
|
|
94
|
-
|
|
136
|
+
entry.Detail = detail
|
|
137
|
+
return
|
|
95
138
|
}
|
|
139
|
+
|
|
140
|
+
// Both carriers are reused across entries; the write pass overwrites the pathway on each one
|
|
141
|
+
// immediately before serializing it, so nothing may come between the two.
|
|
142
|
+
let pathwayOnlyCarrier
|
|
143
|
+
const injectable = []
|
|
144
|
+
let requestSize = 0
|
|
145
|
+
|
|
146
|
+
for (let i = 0; i < entries.length && requestSize < MAX_PUT_EVENTS_BYTES; i++) {
|
|
147
|
+
const entry = entries[i]
|
|
148
|
+
const tracePropagated = traceCarrier !== undefined && (i === 0 || batchPropagationEnabled)
|
|
149
|
+
let carrier = traceCarrier
|
|
150
|
+
if (!tracePropagated) {
|
|
151
|
+
if (dsmEnabled) pathwayOnlyCarrier ??= DsmPathwayCodec.encode(PATHWAY_SIZE_PROBE)
|
|
152
|
+
carrier = pathwayOnlyCarrier
|
|
153
|
+
}
|
|
154
|
+
if (carrier !== undefined && typeof entry?.Detail === 'string') {
|
|
155
|
+
// A malformed Detail is skipped rather than fatal: EventBridge partial-fails that entry,
|
|
156
|
+
// so the rest of the batch still propagates.
|
|
157
|
+
const traceOnlyDetail = injectDetail(entry.Detail, carrier)
|
|
158
|
+
if (traceOnlyDetail !== undefined) {
|
|
159
|
+
// The pathway field is a fixed width, so reserving it is exact and saves building the
|
|
160
|
+
// detail a second time just to measure it.
|
|
161
|
+
const reserved = dsmEnabled && tracePropagated ? PATHWAY_FIELD_BYTES : 0
|
|
162
|
+
requestSize += putEventEntrySize(entry, traceOnlyDetail) + reserved
|
|
163
|
+
injectable.push({
|
|
164
|
+
entry,
|
|
165
|
+
carrier,
|
|
166
|
+
payloadSize: dsmEnabled ? dsmPayloadSize(entry) : 0,
|
|
167
|
+
traceOnlyDetail: tracePropagated ? traceOnlyDetail : undefined,
|
|
168
|
+
})
|
|
169
|
+
continue
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
requestSize += putEventEntrySize(entry)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (injectable.length === 0) return
|
|
176
|
+
if (requestSize >= MAX_PUT_EVENTS_BYTES) {
|
|
177
|
+
log.info('Payload size too large to pass context')
|
|
178
|
+
return
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
for (const { entry, carrier, payloadSize, traceOnlyDetail } of injectable) {
|
|
182
|
+
let detail = traceOnlyDetail
|
|
183
|
+
if (dsmEnabled) {
|
|
184
|
+
const dataStreamsContext = this.setDSMCheckpoint(span, entry, payloadSize)
|
|
185
|
+
// Anything short of a real pathway leaves the carrier on the sizing stand-in, which must
|
|
186
|
+
// never ship; a pathway-only entry then has no fallback and keeps the caller's detail.
|
|
187
|
+
if (DsmPathwayCodec.encode(dataStreamsContext, carrier) !== undefined) {
|
|
188
|
+
detail = injectDetail(entry.Detail, carrier)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (detail !== undefined) entry.Detail = detail
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Edge tags feed the pathway hash, so they are a cross-tracer contract: renaming or merging one
|
|
197
|
+
* splits the DSM pathway instead of extending it.
|
|
198
|
+
*
|
|
199
|
+
* @param {import('../../../..').Span} span
|
|
200
|
+
* @param {PutEventsRequestEntry} entry
|
|
201
|
+
* @param {number} payloadSize `dsmPayloadSize(entry)`, taken before the `_datadog` context is
|
|
202
|
+
* injected. The trailing `0` opts out of the pathway estimate the processor adds by default,
|
|
203
|
+
* because that context is propagation overhead rather than the caller's payload.
|
|
204
|
+
* @returns {object|undefined}
|
|
205
|
+
*/
|
|
206
|
+
setDSMCheckpoint (span, entry, payloadSize) {
|
|
207
|
+
const eventBus = entry.EventBusName || DEFAULT_EVENT_BUS
|
|
208
|
+
const detailType = entry.DetailType ?? DEFAULT_DETAIL_TYPE
|
|
209
|
+
return this.tracer.setCheckpoint(
|
|
210
|
+
['direction:out', `exchange:${eventBus}`, `topic:${detailType}`, 'type:eventbridge'],
|
|
211
|
+
span,
|
|
212
|
+
payloadSize,
|
|
213
|
+
0,
|
|
214
|
+
)
|
|
96
215
|
}
|
|
97
216
|
}
|
|
98
217
|
module.exports = EventBridge
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
const { DsmPathwayCodec, getSizeOrZero } = require('../../../dd-trace/src/datastreams')
|
|
2
|
+
const { DsmPathwayCodec, getSizeOrZero, PATHWAY_FIELD_BYTES } = require('../../../dd-trace/src/datastreams')
|
|
3
3
|
const log = require('../../../dd-trace/src/log')
|
|
4
4
|
const BaseAwsSdkPlugin = require('../base')
|
|
5
5
|
|
|
@@ -16,12 +16,6 @@ const MAX_TRACKED_SHARD_ITERATORS = 1000
|
|
|
16
16
|
// conservatively skip propagation above this point because the request does not expose that limit.
|
|
17
17
|
const KINESIS_DEFAULT_MAX_RECORD_BYTES = 1_048_576
|
|
18
18
|
|
|
19
|
-
// The DSM pathway field (`dd-pathway-ctx-base64`) always serializes to a fixed 55 bytes: a
|
|
20
|
-
// 21-char key, a 28-char base64 value, and 6 bytes of JSON framing. Mirrors PATHWAY_HEADER_BYTES
|
|
21
|
-
// in dd-trace/src/datastreams/processor.js. Reserved in the size gate so setDSMCheckpoint never
|
|
22
|
-
// runs for a record that would ship over the cap once the pathway context is attached.
|
|
23
|
-
const DSM_PATHWAY_FIELD_BYTES = 55
|
|
24
|
-
|
|
25
19
|
class Kinesis extends BaseAwsSdkPlugin {
|
|
26
20
|
static id = 'kinesis'
|
|
27
21
|
static peerServicePrecursors = ['streamname']
|
|
@@ -196,14 +190,11 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
196
190
|
try {
|
|
197
191
|
parsedAttributes = JSON.parse(recordDataAsString(record.Data))
|
|
198
192
|
} catch {
|
|
199
|
-
// Non-JSON record
|
|
200
|
-
// checkpoint payload size below is still reported.
|
|
193
|
+
// Non-JSON record: it carries no context, so the checkpoint below starts a new pathway.
|
|
201
194
|
}
|
|
202
195
|
|
|
203
196
|
const payloadSize = getSizeOrZero(record.Data)
|
|
204
|
-
|
|
205
|
-
this.tracer.decodeDataStreamsContext(parsedAttributes._datadog)
|
|
206
|
-
}
|
|
197
|
+
this.tracer.decodeDataStreamsContext(parsedAttributes?._datadog)
|
|
207
198
|
this.tracer.setCheckpoint(tags, span, payloadSize)
|
|
208
199
|
}
|
|
209
200
|
}
|
|
@@ -279,7 +270,7 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
279
270
|
// Gate before setDSMCheckpoint: a record we can't ship must not record a checkpoint.
|
|
280
271
|
// Reserve the pathway field that DSM appends after the gate.
|
|
281
272
|
let serialized = JSON.stringify(parsedData)
|
|
282
|
-
const reservedBytes = dsmEnabled ?
|
|
273
|
+
const reservedBytes = dsmEnabled ? PATHWAY_FIELD_BYTES : 0
|
|
283
274
|
const partitionKeyBytes = Buffer.byteLength(params.PartitionKey ?? '', 'utf8')
|
|
284
275
|
if (
|
|
285
276
|
Buffer.byteLength(serialized, 'utf8') + partitionKeyBytes + reservedBytes >
|
|
@@ -275,11 +275,7 @@ class Sqs extends BaseAwsSdkPlugin {
|
|
|
275
275
|
for (let i = 0; i < messages.length; i++) {
|
|
276
276
|
const message = messages[i]
|
|
277
277
|
const carrier = carriers === undefined ? this.parseMessageCarrier(message) : carriers[i]
|
|
278
|
-
|
|
279
|
-
// Inert for EventBridge until its producer emits a pathway (separate
|
|
280
|
-
// change) — no `dd-pathway-ctx-base64` to decode yet; SQS/SNS decode now.
|
|
281
|
-
this.tracer.decodeDataStreamsContext(carrier)
|
|
282
|
-
}
|
|
278
|
+
this.tracer.decodeDataStreamsContext(carrier)
|
|
283
279
|
const payloadSize = getHeadersSize({
|
|
284
280
|
Body: message.Body,
|
|
285
281
|
MessageAttributes: message.MessageAttributes,
|
|
@@ -156,7 +156,7 @@ function setSpanLinks (triggerType, tracer, span, ctx) {
|
|
|
156
156
|
: triggerMetadata.propertiesArray
|
|
157
157
|
|
|
158
158
|
const addLinkFromProperties = (props) => {
|
|
159
|
-
if (!props
|
|
159
|
+
if (!props) return
|
|
160
160
|
const spanContext = tracer.extract('text_map', props)
|
|
161
161
|
if (spanContext) {
|
|
162
162
|
span.addLink({ context: spanContext })
|
|
@@ -8,17 +8,14 @@ class BunyanPlugin extends LogPlugin {
|
|
|
8
8
|
|
|
9
9
|
constructor (...args) {
|
|
10
10
|
super(...args)
|
|
11
|
-
this.addSub(
|
|
11
|
+
this.addSub(`apm:${this.constructor.id}:log`, (arg) => this.handleLog(arg))
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Inject `dd` directly on the record
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* prototype, and is never the caller's input directly. Mutating it adds
|
|
20
|
-
* `dd` for every consumer (JSON streams via `JSON.stringify(rec)`, raw
|
|
21
|
-
* streams via the record reference) without paying for a Proxy view.
|
|
15
|
+
* Inject `dd` directly on the record Bunyan implementations hand us. They build the record
|
|
16
|
+
* inside `mkRecord` from a copy of the logger and caller fields, so the `rec` object that flows
|
|
17
|
+
* through `_emit` is always logger-owned. Mutating it adds `dd` for every consumer without
|
|
18
|
+
* paying for a Proxy view.
|
|
22
19
|
*
|
|
23
20
|
* @param {{ message: object }} arg
|
|
24
21
|
*/
|
|
@@ -72,6 +72,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
72
72
|
isEarlyFlakeDetectionFaulty,
|
|
73
73
|
isTestManagementTestsEnabled,
|
|
74
74
|
isParallel,
|
|
75
|
+
error,
|
|
75
76
|
onDone,
|
|
76
77
|
}) => {
|
|
77
78
|
this._exportPendingWorkerTraces()
|
|
@@ -115,6 +116,15 @@ class CucumberPlugin extends CiPlugin {
|
|
|
115
116
|
|
|
116
117
|
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
117
118
|
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
119
|
+
if (error) {
|
|
120
|
+
for (const testSuiteSpan of this._testSuiteSpansByTestSuite.values()) {
|
|
121
|
+
testSuiteSpan.setTag(TEST_STATUS, 'fail')
|
|
122
|
+
testSuiteSpan.setTag('error', error)
|
|
123
|
+
}
|
|
124
|
+
this.testSessionSpan.setTag('error', error)
|
|
125
|
+
this.testModuleSpan.setTag('error', error)
|
|
126
|
+
}
|
|
127
|
+
this.tracer._exporter.exportDeferredTestSuiteSpans?.()
|
|
118
128
|
this.testModuleSpan.finish()
|
|
119
129
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
120
130
|
this.testSessionSpan.finish()
|
|
@@ -192,6 +202,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
192
202
|
this.addSub('ci:cucumber:test-suite:finish', ({ status, testSuitePath }) => {
|
|
193
203
|
const testSuiteSpan = this._testSuiteSpansByTestSuite.get(testSuitePath)
|
|
194
204
|
testSuiteSpan.setTag(TEST_STATUS, status)
|
|
205
|
+
this.tracer._exporter.deferTestSuiteSpan?.(testSuiteSpan)
|
|
195
206
|
testSuiteSpan.finish()
|
|
196
207
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
197
208
|
})
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const cypressPlugin = require('./cypress-plugin')
|
|
4
|
+
const { shouldDeferLegacyFinalization } = require('./finalization')
|
|
4
5
|
|
|
5
|
-
module.exports =
|
|
6
|
+
module.exports = function afterRun () {
|
|
7
|
+
if (shouldDeferLegacyFinalization()) return
|
|
8
|
+
return cypressPlugin.afterRun.apply(cypressPlugin, arguments)
|
|
9
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const cypressPlugin = require('./cypress-plugin')
|
|
4
|
+
const { shouldDeferLegacyFinalization } = require('./finalization')
|
|
4
5
|
|
|
5
|
-
module.exports =
|
|
6
|
+
module.exports = function afterSpec () {
|
|
7
|
+
if (shouldDeferLegacyFinalization()) return
|
|
8
|
+
return cypressPlugin.afterSpec.apply(cypressPlugin, arguments)
|
|
9
|
+
}
|