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
|
@@ -78,6 +78,7 @@ const {
|
|
|
78
78
|
TEST_HAS_DYNAMIC_NAME,
|
|
79
79
|
getIsFaultyEarlyFlakeDetection,
|
|
80
80
|
DYNAMIC_NAME_RE,
|
|
81
|
+
isMarkedAsUnskippable,
|
|
81
82
|
recordAttemptToFixExecution,
|
|
82
83
|
recordTestManagementExecution,
|
|
83
84
|
logAttemptToFixTestExecution,
|
|
@@ -86,7 +87,6 @@ const {
|
|
|
86
87
|
TEST_FINAL_STATUS,
|
|
87
88
|
getTestOptimizationRequestResults,
|
|
88
89
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
89
|
-
const { isMarkedAsUnskippable } = require('../../datadog-plugin-jest/src/util')
|
|
90
90
|
const { ORIGIN_KEY, COMPONENT } = require('../../dd-trace/src/constants')
|
|
91
91
|
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
92
92
|
const getConfig = require('../../dd-trace/src/config')
|
|
@@ -477,7 +477,7 @@ class CypressPlugin {
|
|
|
477
477
|
testsToSkip = []
|
|
478
478
|
skippedTests = []
|
|
479
479
|
skippedTestIds = new Set()
|
|
480
|
-
skippableTestsCoverage
|
|
480
|
+
skippableTestsCoverage
|
|
481
481
|
testSessionCoverageMap = createCoverageMap()
|
|
482
482
|
hasForcedToRunSuites = false
|
|
483
483
|
hasUnskippableSuites = false
|
|
@@ -492,6 +492,7 @@ class CypressPlugin {
|
|
|
492
492
|
loggedAttemptToFixTests = new Set()
|
|
493
493
|
uploadedScreenshotPaths = new Set()
|
|
494
494
|
screenshotUploadPromisesByTraceId = new Map()
|
|
495
|
+
screenshotUploadAbortControllers = new Set()
|
|
495
496
|
afterScreenshotHandler = undefined
|
|
496
497
|
lastFinishedTest = null
|
|
497
498
|
pendingScreenshotUploads = []
|
|
@@ -565,7 +566,7 @@ class CypressPlugin {
|
|
|
565
566
|
this.testsToSkip = []
|
|
566
567
|
this.skippedTests = []
|
|
567
568
|
this.skippedTestIds = new Set()
|
|
568
|
-
this.skippableTestsCoverage =
|
|
569
|
+
this.skippableTestsCoverage = undefined
|
|
569
570
|
this.testSessionCoverageMap = createCoverageMap()
|
|
570
571
|
this.hasForcedToRunSuites = false
|
|
571
572
|
this.hasUnskippableSuites = false
|
|
@@ -581,10 +582,12 @@ class CypressPlugin {
|
|
|
581
582
|
this.loggedAttemptToFixTests = new Set()
|
|
582
583
|
this.uploadedScreenshotPaths = new Set()
|
|
583
584
|
this.screenshotUploadPromisesByTraceId = new Map()
|
|
585
|
+
this.screenshotUploadAbortControllers = new Set()
|
|
584
586
|
this.lastFinishedTest = null
|
|
585
587
|
this.pendingScreenshotUploads = []
|
|
586
588
|
this.activeTestSpan = null
|
|
587
589
|
this.testSuiteSpan = null
|
|
590
|
+
this.finishedTestSuiteSpans = []
|
|
588
591
|
this.testModuleSpan = null
|
|
589
592
|
this.testSessionSpan = null
|
|
590
593
|
this.command = undefined
|
|
@@ -643,6 +646,19 @@ class CypressPlugin {
|
|
|
643
646
|
return Promise.all(uploadPromises).then(getScreenshotUploadResult)
|
|
644
647
|
}
|
|
645
648
|
|
|
649
|
+
/**
|
|
650
|
+
* Cancels screenshot work that must not outlive an errored after:spec finalization boundary.
|
|
651
|
+
*
|
|
652
|
+
* @param {Error} error - Error that triggered finalization
|
|
653
|
+
* @returns {void}
|
|
654
|
+
*/
|
|
655
|
+
abortPendingScreenshotUploads (error) {
|
|
656
|
+
for (const controller of this.screenshotUploadAbortControllers) controller.abort(error)
|
|
657
|
+
this.screenshotUploadAbortControllers.clear()
|
|
658
|
+
this.screenshotUploadPromisesByTraceId.clear()
|
|
659
|
+
this.pendingScreenshotUploads = []
|
|
660
|
+
}
|
|
661
|
+
|
|
646
662
|
/**
|
|
647
663
|
* Returns the current time in the same coordinate system used by span
|
|
648
664
|
* start/finish. Captured at session span creation so it shares the same
|
|
@@ -663,17 +679,6 @@ class CypressPlugin {
|
|
|
663
679
|
return this.repositoryRoot || this.rootDir || process.cwd()
|
|
664
680
|
}
|
|
665
681
|
|
|
666
|
-
/**
|
|
667
|
-
* Returns whether the backend supplied skipped-test coverage data.
|
|
668
|
-
*
|
|
669
|
-
* @returns {boolean}
|
|
670
|
-
*/
|
|
671
|
-
hasSkippableTestsCoverage () {
|
|
672
|
-
return !!(this.skippableTestsCoverage &&
|
|
673
|
-
typeof this.skippableTestsCoverage === 'object' &&
|
|
674
|
-
Object.keys(this.skippableTestsCoverage).length > 0)
|
|
675
|
-
}
|
|
676
|
-
|
|
677
682
|
/**
|
|
678
683
|
* Returns whether skipped test coverage should be backfilled into the session coverage map.
|
|
679
684
|
*
|
|
@@ -683,7 +688,7 @@ class CypressPlugin {
|
|
|
683
688
|
return this.isItrEnabled &&
|
|
684
689
|
this.isCoverageReportUploadEnabled &&
|
|
685
690
|
this.isTestsSkipped &&
|
|
686
|
-
this.
|
|
691
|
+
this.skippableTestsCoverage !== undefined
|
|
687
692
|
}
|
|
688
693
|
|
|
689
694
|
/**
|
|
@@ -800,6 +805,17 @@ class CypressPlugin {
|
|
|
800
805
|
// Depending on the received configuration, the Cypress configuration can be modified:
|
|
801
806
|
// for example, to enable retries for failed tests.
|
|
802
807
|
init (tracer, cypressConfig) {
|
|
808
|
+
if (this.cypressConfig === cypressConfig && this.hasOriginalCypressRetries) {
|
|
809
|
+
cypressConfig.retries = this.originalCypressRetries !== null &&
|
|
810
|
+
typeof this.originalCypressRetries === 'object'
|
|
811
|
+
? { ...this.originalCypressRetries }
|
|
812
|
+
: this.originalCypressRetries
|
|
813
|
+
} else {
|
|
814
|
+
this.originalCypressRetries = cypressConfig.retries !== null && typeof cypressConfig.retries === 'object'
|
|
815
|
+
? { ...cypressConfig.retries }
|
|
816
|
+
: cypressConfig.retries
|
|
817
|
+
this.hasOriginalCypressRetries = true
|
|
818
|
+
}
|
|
803
819
|
this.resetRunState()
|
|
804
820
|
this._isInit = true
|
|
805
821
|
this.tracer = tracer
|
|
@@ -1063,9 +1079,13 @@ class CypressPlugin {
|
|
|
1063
1079
|
}
|
|
1064
1080
|
|
|
1065
1081
|
async beforeRun (details) {
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1082
|
+
if (this._isInit) {
|
|
1083
|
+
// The user may not have returned the promise from the init function.
|
|
1084
|
+
await this.libraryConfigurationPromise
|
|
1085
|
+
} else {
|
|
1086
|
+
// Cypress open reuses the same plugin process for every interactive run.
|
|
1087
|
+
await this.init(this.tracer, this.cypressConfig)
|
|
1088
|
+
}
|
|
1069
1089
|
|
|
1070
1090
|
this.command = getCypressCommand(details)
|
|
1071
1091
|
this.frameworkVersion = getCypressVersion(details)
|
|
@@ -1131,7 +1151,7 @@ class CypressPlugin {
|
|
|
1131
1151
|
} else {
|
|
1132
1152
|
const { skippableTests, correlationId, skippableTestsCoverage } = skippableTestsResponse
|
|
1133
1153
|
this.testsToSkip = skippableTests || []
|
|
1134
|
-
this.skippableTestsCoverage = skippableTestsCoverage
|
|
1154
|
+
this.skippableTestsCoverage = skippableTestsCoverage
|
|
1135
1155
|
this.itrCorrelationId = correlationId
|
|
1136
1156
|
incrementCountMetric(TELEMETRY_ITR_SKIPPED, { testLevel: 'test' }, this.testsToSkip.length)
|
|
1137
1157
|
}
|
|
@@ -1252,18 +1272,29 @@ class CypressPlugin {
|
|
|
1252
1272
|
return details
|
|
1253
1273
|
}
|
|
1254
1274
|
|
|
1255
|
-
afterRun (suiteStats) {
|
|
1275
|
+
afterRun (suiteStats, error, shouldFailFinishedSuites = true) {
|
|
1256
1276
|
if (!this._isInit) {
|
|
1257
1277
|
log.warn('Attemping to call afterRun without initializating the plugin first')
|
|
1258
1278
|
return
|
|
1259
1279
|
}
|
|
1260
1280
|
if (this.testSessionSpan && this.testModuleSpan) {
|
|
1261
|
-
const testStatus = getSessionStatus(suiteStats)
|
|
1281
|
+
const testStatus = error ? 'fail' : getSessionStatus(suiteStats)
|
|
1262
1282
|
const hasBackfilledCoverage = this.applySkippedCoverageToTestSessionCoverage()
|
|
1263
1283
|
const testCodeCoverageLinesTotal = this.getTestCodeCoverageLinesTotal(hasBackfilledCoverage)
|
|
1264
1284
|
|
|
1265
1285
|
this.testModuleSpan.setTag(TEST_STATUS, testStatus)
|
|
1266
1286
|
this.testSessionSpan.setTag(TEST_STATUS, testStatus)
|
|
1287
|
+
for (const span of this.finishedTestSuiteSpans) {
|
|
1288
|
+
if (error && shouldFailFinishedSuites) {
|
|
1289
|
+
span.setTag(TEST_STATUS, 'fail')
|
|
1290
|
+
span.setTag('error', error)
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
this.finishedTestSuiteSpans = []
|
|
1294
|
+
if (error) {
|
|
1295
|
+
this.testModuleSpan.setTag('error', error)
|
|
1296
|
+
this.testSessionSpan.setTag('error', error)
|
|
1297
|
+
}
|
|
1267
1298
|
|
|
1268
1299
|
addIntelligentTestRunnerSpanTags(
|
|
1269
1300
|
this.testSessionSpan,
|
|
@@ -1301,6 +1332,7 @@ class CypressPlugin {
|
|
|
1301
1332
|
})
|
|
1302
1333
|
|
|
1303
1334
|
finishAllTraceSpans(this.testSessionSpan)
|
|
1335
|
+
this.tracer._tracer._exporter?.exportDeferredTestSuiteSpans?.()
|
|
1304
1336
|
}
|
|
1305
1337
|
|
|
1306
1338
|
return new Promise(resolve => {
|
|
@@ -1358,7 +1390,7 @@ class CypressPlugin {
|
|
|
1358
1390
|
}
|
|
1359
1391
|
}
|
|
1360
1392
|
|
|
1361
|
-
afterSpec (spec, results) {
|
|
1393
|
+
afterSpec (spec, results, error) {
|
|
1362
1394
|
const { tests, stats, screenshots } = results || {}
|
|
1363
1395
|
const cypressTests = tests || []
|
|
1364
1396
|
const specScreenshots = screenshots || []
|
|
@@ -1572,13 +1604,16 @@ class CypressPlugin {
|
|
|
1572
1604
|
const screenshotUploadResultPromise = failedTestTraceId
|
|
1573
1605
|
? this.getScreenshotUploadResultPromise(failedTestTraceId)
|
|
1574
1606
|
: undefined
|
|
1575
|
-
if (screenshotUploadResultPromise) {
|
|
1607
|
+
if (screenshotUploadResultPromise && !error) {
|
|
1576
1608
|
testSpanFinishPromises.push(screenshotUploadResultPromise.then((uploadResult) => {
|
|
1577
1609
|
setScreenshotUploadTags(finishedTest.testSpan, uploadResult)
|
|
1578
1610
|
this.screenshotUploadPromisesByTraceId.delete(failedTestTraceId)
|
|
1579
1611
|
finishedTest.testSpan.finish(finishedTest.finishTime)
|
|
1580
1612
|
}))
|
|
1581
1613
|
} else {
|
|
1614
|
+
if (screenshotUploadResultPromise) {
|
|
1615
|
+
this.screenshotUploadPromisesByTraceId.delete(failedTestTraceId)
|
|
1616
|
+
}
|
|
1582
1617
|
finishedTest.testSpan.finish(finishedTest.finishTime)
|
|
1583
1618
|
}
|
|
1584
1619
|
}
|
|
@@ -1586,13 +1621,18 @@ class CypressPlugin {
|
|
|
1586
1621
|
|
|
1587
1622
|
const finishSuite = () => {
|
|
1588
1623
|
if (this.testSuiteSpan) {
|
|
1589
|
-
const status = getSuiteStatus(stats)
|
|
1624
|
+
const status = error ? 'fail' : getSuiteStatus(stats)
|
|
1590
1625
|
this.testSuiteSpan.setTag(TEST_STATUS, status)
|
|
1591
1626
|
|
|
1592
|
-
if (latestError) {
|
|
1593
|
-
this.testSuiteSpan.setTag('error', latestError)
|
|
1627
|
+
if (error || latestError) {
|
|
1628
|
+
this.testSuiteSpan.setTag('error', error || latestError)
|
|
1594
1629
|
}
|
|
1630
|
+
const canRunAfterRun = this.cypressConfig.isTextTerminal ||
|
|
1631
|
+
this.cypressConfig.experimentalInteractiveRunEvents
|
|
1632
|
+
const exporter = this.tracer._tracer._exporter
|
|
1633
|
+
if (canRunAfterRun && exporter?.deferTestSuiteSpan) exporter.deferTestSuiteSpan(this.testSuiteSpan)
|
|
1595
1634
|
this.testSuiteSpan.finish()
|
|
1635
|
+
if (canRunAfterRun) this.finishedTestSuiteSpans.push(this.testSuiteSpan)
|
|
1596
1636
|
this.testSuiteSpan = null
|
|
1597
1637
|
this.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
1598
1638
|
}
|
|
@@ -1608,16 +1648,23 @@ class CypressPlugin {
|
|
|
1608
1648
|
|
|
1609
1649
|
finishSuite()
|
|
1610
1650
|
|
|
1651
|
+
if (error) {
|
|
1652
|
+
this.abortPendingScreenshotUploads(error)
|
|
1653
|
+
return this.afterRun(undefined, error, false)
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1611
1656
|
const screenshotUploadsPromise = waitForScreenshotUploads()
|
|
1657
|
+
let afterSpecPromise = screenshotUploadsPromise
|
|
1612
1658
|
if (testSpanFinishPromises.length > 0) {
|
|
1613
1659
|
const testSpansPromise = Promise.all(testSpanFinishPromises).then(() => null)
|
|
1614
1660
|
if (screenshotUploadsPromise) {
|
|
1615
|
-
|
|
1661
|
+
afterSpecPromise = Promise.all([testSpansPromise, screenshotUploadsPromise]).then(() => null)
|
|
1662
|
+
} else {
|
|
1663
|
+
afterSpecPromise = testSpansPromise
|
|
1616
1664
|
}
|
|
1617
|
-
return testSpansPromise
|
|
1618
1665
|
}
|
|
1619
1666
|
|
|
1620
|
-
return
|
|
1667
|
+
return afterSpecPromise
|
|
1621
1668
|
}
|
|
1622
1669
|
|
|
1623
1670
|
/**
|
|
@@ -1637,6 +1684,7 @@ class CypressPlugin {
|
|
|
1637
1684
|
}
|
|
1638
1685
|
|
|
1639
1686
|
const uploadPromises = []
|
|
1687
|
+
const abortController = new AbortController()
|
|
1640
1688
|
|
|
1641
1689
|
for (const screenshot of screenshots) {
|
|
1642
1690
|
const filePath = getScreenshotFilePath(screenshot)
|
|
@@ -1655,6 +1703,7 @@ class CypressPlugin {
|
|
|
1655
1703
|
traceId,
|
|
1656
1704
|
idempotencyKey,
|
|
1657
1705
|
capturedAtMs,
|
|
1706
|
+
signal: abortController.signal,
|
|
1658
1707
|
}, (err) => {
|
|
1659
1708
|
resolve(err ? SCREENSHOT_UPLOAD_RESULT_ERROR : SCREENSHOT_UPLOAD_RESULT_UPLOADED)
|
|
1660
1709
|
})
|
|
@@ -1662,7 +1711,10 @@ class CypressPlugin {
|
|
|
1662
1711
|
}
|
|
1663
1712
|
|
|
1664
1713
|
if (uploadPromises.length > 0) {
|
|
1665
|
-
|
|
1714
|
+
this.screenshotUploadAbortControllers.add(abortController)
|
|
1715
|
+
const uploadPromise = Promise.all(uploadPromises).then(getScreenshotUploadResult).finally(() => {
|
|
1716
|
+
this.screenshotUploadAbortControllers.delete(abortController)
|
|
1717
|
+
})
|
|
1666
1718
|
this.addScreenshotUploadPromise(traceId, uploadPromise)
|
|
1667
1719
|
return uploadPromise
|
|
1668
1720
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { AsyncLocalStorage } = require('node:async_hooks')
|
|
4
|
+
|
|
5
|
+
const log = require('../../dd-trace/src/log')
|
|
6
|
+
|
|
7
|
+
const DD_CYPRESS_USER_HANDLER_CONTEXT = Symbol.for('dd-trace.cypress.user-handler.context')
|
|
8
|
+
const userHandlerContext = globalThis[DD_CYPRESS_USER_HANDLER_CONTEXT] ||= new AsyncLocalStorage()
|
|
9
|
+
const manualPluginOwner = {}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Runs a Cypress user handler while allowing wrapped legacy Datadog helpers to
|
|
13
|
+
* defer to the managed finalizer.
|
|
14
|
+
*
|
|
15
|
+
* @param {() => unknown} handler user handler invocation
|
|
16
|
+
* @returns {unknown} handler result
|
|
17
|
+
*/
|
|
18
|
+
function runUserHandler (handler) {
|
|
19
|
+
return userHandlerContext.run(true, handler)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @returns {boolean} whether a managed finalizer owns the current lifecycle event
|
|
24
|
+
*/
|
|
25
|
+
function shouldDeferLegacyFinalization () {
|
|
26
|
+
return userHandlerContext.getStore() === true
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Converts a Cypress rejection reason into error metadata without changing the
|
|
31
|
+
* value rethrown to Cypress.
|
|
32
|
+
*
|
|
33
|
+
* @param {unknown} reason rejection reason
|
|
34
|
+
* @returns {Error} error used for Test Optimization finalization
|
|
35
|
+
*/
|
|
36
|
+
function normalizeUserHandlerError (reason) {
|
|
37
|
+
if (reason instanceof Error) return reason
|
|
38
|
+
if (reason == null) return new Error('Cypress user handler rejected without an error')
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
return new Error(String(reason))
|
|
42
|
+
} catch {
|
|
43
|
+
return new Error('Cypress user handler failed')
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Runs the Datadog finalizer after user handlers while preserving the user
|
|
49
|
+
* error as the framework-visible failure.
|
|
50
|
+
*
|
|
51
|
+
* @param {Promise<void>} userHandlers collected user-handler chain
|
|
52
|
+
* @param {(userError?: unknown) => unknown} finalizer Datadog finalizer
|
|
53
|
+
* @returns {Promise<unknown>} finalizer result
|
|
54
|
+
*/
|
|
55
|
+
function finalizeAfterUserHandlers (userHandlers, finalizer) {
|
|
56
|
+
return userHandlers.then(
|
|
57
|
+
() => finalizer(),
|
|
58
|
+
userError => Promise.resolve().then(() => {
|
|
59
|
+
return finalizer(normalizeUserHandlerError(userError))
|
|
60
|
+
}).then(
|
|
61
|
+
() => { throw userError },
|
|
62
|
+
finalizerError => {
|
|
63
|
+
log.error('Datadog Cypress finalizer failed after a user handler error', finalizerError)
|
|
64
|
+
throw userError
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = {
|
|
71
|
+
finalizeAfterUserHandlers,
|
|
72
|
+
manualPluginOwner,
|
|
73
|
+
normalizeUserHandlerError,
|
|
74
|
+
runUserHandler,
|
|
75
|
+
shouldDeferLegacyFinalization,
|
|
76
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const NoopTracer = require('../../dd-trace/src/noop/tracer')
|
|
4
4
|
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
5
|
+
const { finalizeAfterUserHandlers, runUserHandler } = require('./finalization')
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Cypress plugin handles setup-node-events from the instrumentation layer
|
|
@@ -30,11 +31,12 @@ class CypressPlugin extends Plugin {
|
|
|
30
31
|
const registerAfterRunWithCleanup = (afterRunHandler) => {
|
|
31
32
|
on('after:run', (results) => {
|
|
32
33
|
const chain = userAfterRunHandlers.reduce(
|
|
33
|
-
(p, h) => p.then(() => h(results)),
|
|
34
|
+
(p, h) => p.then(() => runUserHandler(() => h(results))),
|
|
34
35
|
Promise.resolve()
|
|
35
36
|
)
|
|
36
37
|
if (afterRunHandler) {
|
|
37
|
-
return chain
|
|
38
|
+
return finalizeAfterUserHandlers(chain, userError => afterRunHandler(results, userError))
|
|
39
|
+
.finally(cleanupWrapper)
|
|
38
40
|
}
|
|
39
41
|
return chain.finally(cleanupWrapper)
|
|
40
42
|
})
|
|
@@ -82,7 +84,7 @@ class CypressPlugin extends Plugin {
|
|
|
82
84
|
// (the chained registration replaces the one plugin.js set, so it must include it).
|
|
83
85
|
if (userAfterSpecHandlers.length > 0) {
|
|
84
86
|
on('after:spec', (spec, results) => userAfterSpecHandlers.reduce(
|
|
85
|
-
(chain, handler) => chain.then(() => handler(spec, results)),
|
|
87
|
+
(chain, handler) => chain.then(() => runUserHandler(() => handler(spec, results))),
|
|
86
88
|
Promise.resolve()
|
|
87
89
|
))
|
|
88
90
|
}
|
|
@@ -97,13 +99,17 @@ class CypressPlugin extends Plugin {
|
|
|
97
99
|
|
|
98
100
|
on('after:spec', (spec, results) => {
|
|
99
101
|
const chain = userAfterSpecHandlers.reduce(
|
|
100
|
-
(p, h) => p.then(() => h(spec, results)),
|
|
102
|
+
(p, h) => p.then(() => runUserHandler(() => h(spec, results))),
|
|
101
103
|
Promise.resolve()
|
|
102
104
|
)
|
|
103
|
-
return chain
|
|
105
|
+
return finalizeAfterUserHandlers(chain, userError => cypressPlugin.afterSpec(spec, results, userError))
|
|
106
|
+
.catch((error) => {
|
|
107
|
+
cleanupWrapper()
|
|
108
|
+
throw error
|
|
109
|
+
})
|
|
104
110
|
})
|
|
105
111
|
|
|
106
|
-
registerAfterRunWithCleanup((results) => cypressPlugin.afterRun(results))
|
|
112
|
+
registerAfterRunWithCleanup((results, userError) => cypressPlugin.afterRun(results, userError))
|
|
107
113
|
|
|
108
114
|
on('task', cypressPlugin.getTasks())
|
|
109
115
|
|
|
@@ -4,6 +4,12 @@ const NoopTracer = require('../../dd-trace/src/noop/tracer')
|
|
|
4
4
|
const satisfies = require('../../../vendor/dist/semifies')
|
|
5
5
|
const { DD_MAJOR } = require('../../../version')
|
|
6
6
|
const cypressPlugin = require('./cypress-plugin')
|
|
7
|
+
const { manualPluginOwner } = require('./finalization')
|
|
8
|
+
|
|
9
|
+
const DD_CYPRESS_AFTER_SPEC_HANDLER = Symbol.for('dd-trace.cypress.after-spec.handler')
|
|
10
|
+
const DD_CYPRESS_AFTER_RUN_HANDLER = Symbol.for('dd-trace.cypress.after-run.handler')
|
|
11
|
+
const DD_CYPRESS_TASK_HANDLER = Symbol.for('dd-trace.cypress.task.handler')
|
|
12
|
+
const DD_CYPRESS_NOOP_TASK_HANDLER = Symbol.for('dd-trace.cypress.noop-task.handler')
|
|
7
13
|
|
|
8
14
|
const noopTask = {
|
|
9
15
|
'dd:testSuiteStart': () => {
|
|
@@ -18,6 +24,7 @@ const noopTask = {
|
|
|
18
24
|
'dd:addTags': () => {
|
|
19
25
|
return null
|
|
20
26
|
},
|
|
27
|
+
[DD_CYPRESS_NOOP_TASK_HANDLER]: true,
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
module.exports = function CypressPlugin (on, config) {
|
|
@@ -41,9 +48,15 @@ module.exports = function CypressPlugin (on, config) {
|
|
|
41
48
|
|
|
42
49
|
on('before:run', cypressPlugin.beforeRun.bind(cypressPlugin))
|
|
43
50
|
on('after:screenshot', cypressPlugin.getAfterScreenshotHandler())
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
on('
|
|
51
|
+
const afterSpecHandler = cypressPlugin.afterSpec.bind(cypressPlugin)
|
|
52
|
+
afterSpecHandler[DD_CYPRESS_AFTER_SPEC_HANDLER] = true
|
|
53
|
+
on('after:spec', afterSpecHandler)
|
|
54
|
+
const afterRunHandler = cypressPlugin.afterRun.bind(cypressPlugin)
|
|
55
|
+
afterRunHandler[DD_CYPRESS_AFTER_RUN_HANDLER] = true
|
|
56
|
+
on('after:run', afterRunHandler)
|
|
57
|
+
const taskHandler = cypressPlugin.getTasks()
|
|
58
|
+
taskHandler[DD_CYPRESS_TASK_HANDLER] = manualPluginOwner
|
|
59
|
+
on('task', taskHandler)
|
|
47
60
|
|
|
48
61
|
return cypressPlugin.init(tracer, config)
|
|
49
62
|
}
|
|
@@ -78,6 +78,10 @@ module.exports = class DdTraceApiPlugin extends Plugin {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// handleEvent('configure')
|
|
81
|
+
// No handoff for `openfeature` yet: an application that calls into the tracer
|
|
82
|
+
// exclusively through the `dd-trace-api` shim (instead of `require('dd-trace')`) cannot
|
|
83
|
+
// reach `tracer.openfeature` through that shim. This does not affect SSI itself --
|
|
84
|
+
// auto-injection and vendored-provider resolution work regardless of this gap.
|
|
81
85
|
handleEvent('startSpan')
|
|
82
86
|
handleEvent('wrap')
|
|
83
87
|
handleEvent('trace')
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { DD_MAJOR } = require('../../../version')
|
|
3
4
|
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
4
5
|
const ElectronIpcPlugin = require('./ipc')
|
|
5
6
|
const ElectronNetPlugin = require('./net')
|
|
6
7
|
|
|
7
8
|
class ElectronPlugin extends CompositePlugin {
|
|
8
9
|
static id = 'electron'
|
|
10
|
+
static optIn = DD_MAJOR >= 7
|
|
9
11
|
static get plugins () {
|
|
10
12
|
return {
|
|
11
13
|
net: ElectronNetPlugin,
|
|
@@ -5,7 +5,7 @@ const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
|
|
|
5
5
|
class FsPlugin extends TracingPlugin {
|
|
6
6
|
static id = 'fs'
|
|
7
7
|
static operation = 'operation'
|
|
8
|
-
static
|
|
8
|
+
static optIn = true
|
|
9
9
|
|
|
10
10
|
bindStart (ctx) {
|
|
11
11
|
if (!this.activeSpan) return { noop: true }
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const {
|
|
4
|
+
readDatadogParentId,
|
|
5
|
+
readDatadogSamplingPriority,
|
|
6
|
+
readDatadogTraceId,
|
|
7
|
+
readTraceparent,
|
|
8
|
+
writeDatadogParentId,
|
|
9
|
+
writeDatadogSamplingPriority,
|
|
10
|
+
writeDatadogTraceId,
|
|
11
|
+
} = require('../../dd-trace/src/carrier')
|
|
4
12
|
const { DsmPathwayCodec, getHeadersSize } = require('../../dd-trace/src/datastreams')
|
|
5
13
|
const id = require('../../dd-trace/src/id')
|
|
14
|
+
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
6
15
|
|
|
7
16
|
class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
|
|
8
17
|
static id = 'google-cloud-pubsub'
|
|
@@ -21,7 +30,7 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
|
|
|
21
30
|
|
|
22
31
|
handleMessagePublish ({ attributes, pubsub, topicName }) {
|
|
23
32
|
// Skip if message already has trace context from upstream
|
|
24
|
-
if (attributes
|
|
33
|
+
if (readDatadogTraceId(attributes) || readTraceparent(attributes)) return
|
|
25
34
|
|
|
26
35
|
const activeSpan = this.tracer.scope().active()
|
|
27
36
|
if (!activeSpan) return
|
|
@@ -62,7 +71,7 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
|
|
|
62
71
|
const messages = request.messages || []
|
|
63
72
|
const topic = request.topic
|
|
64
73
|
const messageCount = messages.length
|
|
65
|
-
const hasTraceContext = messages[0]?.attributes
|
|
74
|
+
const hasTraceContext = messages[0]?.attributes && readDatadogTraceId(messages[0].attributes)
|
|
66
75
|
|
|
67
76
|
/**
|
|
68
77
|
* Batch Publishing Strategy:
|
|
@@ -82,12 +91,14 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
|
|
|
82
91
|
}
|
|
83
92
|
|
|
84
93
|
const firstAttrs = messages[0]?.attributes
|
|
85
|
-
const
|
|
94
|
+
const traceId = firstAttrs && readDatadogTraceId(firstAttrs)
|
|
95
|
+
const spanId = firstAttrs && readDatadogParentId(firstAttrs)
|
|
96
|
+
const parentData = traceId && spanId
|
|
86
97
|
? {
|
|
87
|
-
traceId
|
|
88
|
-
spanId
|
|
98
|
+
traceId,
|
|
99
|
+
spanId,
|
|
89
100
|
traceIdUpper: firstAttrs['_dd.p.tid'],
|
|
90
|
-
samplingPriority: firstAttrs
|
|
101
|
+
samplingPriority: readDatadogSamplingPriority(firstAttrs),
|
|
91
102
|
}
|
|
92
103
|
: null
|
|
93
104
|
|
|
@@ -174,33 +185,36 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
|
|
|
174
185
|
}
|
|
175
186
|
|
|
176
187
|
#extractSpanLink (attrs) {
|
|
177
|
-
if (!attrs
|
|
188
|
+
if (!attrs) return null
|
|
189
|
+
const traceId = readDatadogTraceId(attrs)
|
|
190
|
+
const spanId = readDatadogParentId(attrs)
|
|
191
|
+
if (!traceId || !spanId) return null
|
|
178
192
|
|
|
179
193
|
// Convert to hex strings
|
|
180
|
-
const lowerHex = id(
|
|
181
|
-
const spanIdHex = id(
|
|
194
|
+
const lowerHex = id(traceId).toString(16)
|
|
195
|
+
const spanIdHex = id(spanId).toString(16)
|
|
182
196
|
|
|
183
197
|
// Build full 128-bit trace ID
|
|
184
198
|
const traceIdHex = attrs['_dd.p.tid']
|
|
185
199
|
? attrs['_dd.p.tid'] + lowerHex
|
|
186
200
|
: lowerHex.padStart(32, '0')
|
|
187
201
|
|
|
202
|
+
const samplingPriority = readDatadogSamplingPriority(attrs)
|
|
188
203
|
return {
|
|
189
204
|
traceId: traceIdHex,
|
|
190
205
|
spanId: spanIdHex,
|
|
191
|
-
samplingPriority:
|
|
192
|
-
? Number.parseInt(
|
|
206
|
+
samplingPriority: samplingPriority
|
|
207
|
+
? Number.parseInt(samplingPriority, 10)
|
|
193
208
|
: undefined,
|
|
194
209
|
}
|
|
195
210
|
}
|
|
196
211
|
|
|
197
212
|
#extractParentContext (data) {
|
|
198
|
-
const carrier = {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
213
|
+
const carrier = /** @type {Record<string, unknown>} */ ({})
|
|
214
|
+
writeDatadogTraceId(carrier, data.traceId)
|
|
215
|
+
writeDatadogParentId(carrier, data.spanId)
|
|
202
216
|
if (data.traceIdUpper) carrier['_dd.p.tid'] = data.traceIdUpper
|
|
203
|
-
if (data.samplingPriority) carrier
|
|
217
|
+
if (data.samplingPriority) writeDatadogSamplingPriority(carrier, String(data.samplingPriority))
|
|
204
218
|
|
|
205
219
|
return this.tracer.extract('text_map', carrier)
|
|
206
220
|
}
|
|
@@ -5,6 +5,7 @@ const realSetTimeout = setTimeout
|
|
|
5
5
|
|
|
6
6
|
const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
|
|
7
7
|
const { storage } = require('../../datadog-core')
|
|
8
|
+
const { writeDatadogParentId, writeDatadogTraceId } = require('../../dd-trace/src/carrier')
|
|
8
9
|
const { getEnvironmentVariable } = require('../../dd-trace/src/config/helper')
|
|
9
10
|
const { appClosing: appClosingTelemetry } = require('../../dd-trace/src/telemetry')
|
|
10
11
|
|
|
@@ -112,6 +113,7 @@ class JestPlugin extends CiPlugin {
|
|
|
112
113
|
hasUnskippableSuites,
|
|
113
114
|
hasForcedToRunSuites,
|
|
114
115
|
error,
|
|
116
|
+
isTestSessionFinalizationError,
|
|
115
117
|
isEarlyFlakeDetectionEnabled,
|
|
116
118
|
isEarlyFlakeDetectionFaulty,
|
|
117
119
|
isTestManagementTestsEnabled,
|
|
@@ -122,6 +124,9 @@ class JestPlugin extends CiPlugin {
|
|
|
122
124
|
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
123
125
|
|
|
124
126
|
if (error) {
|
|
127
|
+
if (isTestSessionFinalizationError) {
|
|
128
|
+
this.tracer._exporter.setDeferredTestSuiteError?.(error)
|
|
129
|
+
}
|
|
125
130
|
this.testSessionSpan.setTag('error', error)
|
|
126
131
|
this.testModuleSpan.setTag('error', error)
|
|
127
132
|
}
|
|
@@ -158,6 +163,7 @@ class JestPlugin extends CiPlugin {
|
|
|
158
163
|
this.testSessionSpan.setTag(TEST_MANAGEMENT_ENABLED, 'true')
|
|
159
164
|
}
|
|
160
165
|
|
|
166
|
+
this.tracer._exporter.exportDeferredTestSuiteSpans?.()
|
|
161
167
|
this.testModuleSpan.finish()
|
|
162
168
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
163
169
|
this.testSessionSpan.finish()
|
|
@@ -230,10 +236,10 @@ class JestPlugin extends CiPlugin {
|
|
|
230
236
|
_ddItrSkippingEnabledTags: itrSkippingEnabledTags,
|
|
231
237
|
} = testEnvironmentOptions
|
|
232
238
|
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
239
|
+
const carrier = /** @type {Record<string, unknown>} */ ({})
|
|
240
|
+
writeDatadogTraceId(carrier, testSessionId)
|
|
241
|
+
writeDatadogParentId(carrier, testModuleId)
|
|
242
|
+
const testSessionSpanContext = this.tracer.extract('text_map', carrier)
|
|
237
243
|
|
|
238
244
|
const testSuiteMetadata = {
|
|
239
245
|
...getTestSuiteCommonTags(testCommand, frameworkVersion, testSuite, 'jest'),
|
|
@@ -328,6 +334,7 @@ class JestPlugin extends CiPlugin {
|
|
|
328
334
|
this.pendingTestSuiteFinishes.add(pendingFinish)
|
|
329
335
|
|
|
330
336
|
const finish = () => {
|
|
337
|
+
this.tracer._exporter.deferTestSuiteSpan?.(testSuiteSpan)
|
|
331
338
|
testSuiteSpan.finish()
|
|
332
339
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
333
340
|
// Suites potentially run in a different process than the session,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
|
|
4
|
-
const {
|
|
5
|
-
const { convertToTextMap } = require('./utils')
|
|
4
|
+
const { convertToTextMap, getKafkaMessageSize } = require('./utils')
|
|
6
5
|
|
|
7
6
|
class KafkajsBatchConsumerPlugin extends ConsumerPlugin {
|
|
8
7
|
static id = 'kafkajs'
|
|
@@ -39,7 +38,7 @@ class KafkajsBatchConsumerPlugin extends ConsumerPlugin {
|
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
if (!this.config.dsmEnabled) continue
|
|
42
|
-
const payloadSize =
|
|
41
|
+
const payloadSize = getKafkaMessageSize(message)
|
|
43
42
|
this.tracer.decodeDataStreamsContext(headers)
|
|
44
43
|
const edgeTags = ['direction:in', `group:${groupId}`, `topic:${topic}`, 'type:kafka']
|
|
45
44
|
if (clusterId) {
|