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.
- package/LICENSE-3rdparty.csv +5 -0
- package/README.md +0 -17
- package/index.d.ts +128 -6
- package/initialize.mjs +28 -17
- package/openfeature.js +2 -2
- package/package.json +27 -23
- 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/cucumber.js +30 -15
- 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 +9 -4
- package/packages/datadog-instrumentations/src/helpers/register.js +10 -8
- package/packages/datadog-instrumentations/src/jest.js +25 -17
- package/packages/datadog-instrumentations/src/mariadb.js +278 -21
- package/packages/datadog-instrumentations/src/mocha/main.js +539 -55
- package/packages/datadog-instrumentations/src/mocha/utils.js +135 -19
- package/packages/datadog-instrumentations/src/playwright-reporter.js +247 -0
- package/packages/datadog-instrumentations/src/playwright.js +182 -35
- package/packages/datadog-instrumentations/src/router.js +2 -0
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +6 -8
- package/packages/datadog-instrumentations/src/vitest-main.js +11 -3
- 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 +2 -8
- 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 +81 -29
- 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-jest/src/index.js +6 -0
- package/packages/datadog-plugin-mocha/src/index.js +56 -1
- package/packages/datadog-plugin-nats/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/tracing.js +41 -30
- package/packages/datadog-plugin-openai-agents/src/integration.js +1 -0
- package/packages/datadog-plugin-playwright/src/index.js +46 -13
- package/packages/datadog-plugin-vitest/src/index.js +6 -0
- 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/iast/taint-tracking/rewriter.js +9 -12
- package/packages/dd-trace/src/appsec/reporter.js +2 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +13 -0
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +16 -0
- package/packages/dd-trace/src/appsec/telemetry/waf.js +24 -0
- package/packages/dd-trace/src/carrier.js +107 -48
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +1 -0
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +5 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +29 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +27 -9
- 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 +26 -8
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +365 -32
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -4
- 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 +7 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -2
- 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-coverage-report.js +4 -2
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +10 -4
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +5 -5
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -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 +14 -0
- package/packages/dd-trace/src/datastreams/index.js +2 -0
- package/packages/dd-trace/src/datastreams/manager.js +9 -2
- package/packages/dd-trace/src/datastreams/processor.js +15 -13
- package/packages/dd-trace/src/datastreams/size.js +5 -0
- package/packages/dd-trace/src/debugger/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/index.js +5 -11
- package/packages/dd-trace/src/debugger/index.js +4 -2
- package/packages/dd-trace/src/debugger/inspect-segment.js +154 -0
- package/packages/dd-trace/src/evp_proxy/constants.js +8 -0
- package/packages/dd-trace/src/evp_proxy/direct.js +64 -0
- package/packages/dd-trace/src/evp_proxy/discovery.js +133 -0
- package/packages/dd-trace/src/evp_proxy/path.js +22 -0
- 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/request.js +5 -2
- package/packages/dd-trace/src/exporters/common/writer.js +11 -6
- package/packages/dd-trace/src/llmobs/experiments/client.js +167 -5
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +484 -92
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +302 -29
- package/packages/dd-trace/src/llmobs/experiments/index.js +75 -64
- package/packages/dd-trace/src/llmobs/experiments/noop.js +135 -7
- package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
- package/packages/dd-trace/src/llmobs/experiments/util.js +101 -9
- 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/noop/proxy.js +3 -4
- package/packages/dd-trace/src/openfeature/constants/constants.js +0 -18
- package/packages/dd-trace/src/openfeature/flagging_provider.js +18 -2
- package/packages/dd-trace/src/openfeature/index.js +7 -4
- package/packages/dd-trace/src/openfeature/remote_config.js +1 -1
- package/packages/dd-trace/src/openfeature/writers/base.js +153 -11
- package/packages/dd-trace/src/openfeature/writers/exposures.js +62 -14
- package/packages/dd-trace/src/openfeature/writers/util.js +97 -15
- 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 +22 -13
- 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 +3 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +6 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/jest.js +4 -3
- package/packages/dd-trace/src/plugins/util/test.js +9 -9
- package/packages/dd-trace/src/plugins/util/web.js +3 -0
- 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/telemetry/metrics.js +62 -8
- package/packages/dd-trace/src/telemetry/send-data.js +1 -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/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/https-proxy-agent/LICENSE +22 -0
- package/vendor/dist/https-proxy-agent/index.js +4 -0
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/vendor/dist/proxy-from-env/LICENSE +20 -0
- package/vendor/dist/proxy-from-env/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
|
@@ -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 }
|
|
@@ -113,6 +113,7 @@ class JestPlugin extends CiPlugin {
|
|
|
113
113
|
hasUnskippableSuites,
|
|
114
114
|
hasForcedToRunSuites,
|
|
115
115
|
error,
|
|
116
|
+
isTestSessionFinalizationError,
|
|
116
117
|
isEarlyFlakeDetectionEnabled,
|
|
117
118
|
isEarlyFlakeDetectionFaulty,
|
|
118
119
|
isTestManagementTestsEnabled,
|
|
@@ -123,6 +124,9 @@ class JestPlugin extends CiPlugin {
|
|
|
123
124
|
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
124
125
|
|
|
125
126
|
if (error) {
|
|
127
|
+
if (isTestSessionFinalizationError) {
|
|
128
|
+
this.tracer._exporter.setDeferredTestSuiteError?.(error)
|
|
129
|
+
}
|
|
126
130
|
this.testSessionSpan.setTag('error', error)
|
|
127
131
|
this.testModuleSpan.setTag('error', error)
|
|
128
132
|
}
|
|
@@ -159,6 +163,7 @@ class JestPlugin extends CiPlugin {
|
|
|
159
163
|
this.testSessionSpan.setTag(TEST_MANAGEMENT_ENABLED, 'true')
|
|
160
164
|
}
|
|
161
165
|
|
|
166
|
+
this.tracer._exporter.exportDeferredTestSuiteSpans?.()
|
|
162
167
|
this.testModuleSpan.finish()
|
|
163
168
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
164
169
|
this.testSessionSpan.finish()
|
|
@@ -329,6 +334,7 @@ class JestPlugin extends CiPlugin {
|
|
|
329
334
|
this.pendingTestSuiteFinishes.add(pendingFinish)
|
|
330
335
|
|
|
331
336
|
const finish = () => {
|
|
337
|
+
this.tracer._exporter.deferTestSuiteSpan?.(testSuiteSpan)
|
|
332
338
|
testSuiteSpan.finish()
|
|
333
339
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
334
340
|
// Suites potentially run in a different process than the session,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { performance } = require('node:perf_hooks')
|
|
4
|
+
const dateNow = Date.now
|
|
4
5
|
const { fileURLToPath } = require('node:url')
|
|
5
6
|
|
|
6
7
|
const { channel } = require('dc-polyfill')
|
|
@@ -173,6 +174,15 @@ class MochaPlugin extends CiPlugin {
|
|
|
173
174
|
|
|
174
175
|
this._testTitleToParams = {}
|
|
175
176
|
this.sourceRoot = process.cwd()
|
|
177
|
+
this._pendingTestSuiteSpans = []
|
|
178
|
+
this._timeOrigin = dateNow()
|
|
179
|
+
this._perfOrigin = performance.now()
|
|
180
|
+
|
|
181
|
+
this.addSub('ci:mocha:session:start', () => {
|
|
182
|
+
this._pendingTestSuiteSpans = []
|
|
183
|
+
this._timeOrigin = dateNow()
|
|
184
|
+
this._perfOrigin = performance.now()
|
|
185
|
+
})
|
|
176
186
|
|
|
177
187
|
this.addSub('ci:mocha:worker:configuration', ({
|
|
178
188
|
libraryConfig,
|
|
@@ -472,7 +482,19 @@ class MochaPlugin extends CiPlugin {
|
|
|
472
482
|
if (!testSuiteSpan.context().getTag(TEST_STATUS)) {
|
|
473
483
|
testSuiteSpan.setTag(TEST_STATUS, status)
|
|
474
484
|
}
|
|
475
|
-
|
|
485
|
+
const exporter = this.tracer._exporter
|
|
486
|
+
if (exporter.deferTestSuiteSpan) {
|
|
487
|
+
exporter.deferTestSuiteSpan(testSuiteSpan)
|
|
488
|
+
testSuiteSpan.finish()
|
|
489
|
+
} else if (exporter.exportDeferredTestSuiteSpans) {
|
|
490
|
+
const finishTime = this._now()
|
|
491
|
+
this._pendingTestSuiteSpans.push({
|
|
492
|
+
span: testSuiteSpan,
|
|
493
|
+
finishTime,
|
|
494
|
+
})
|
|
495
|
+
} else {
|
|
496
|
+
testSuiteSpan.finish()
|
|
497
|
+
}
|
|
476
498
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
477
499
|
}
|
|
478
500
|
})
|
|
@@ -522,6 +544,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
522
544
|
})
|
|
523
545
|
|
|
524
546
|
this.addSub('ci:mocha:worker:finish', ({ onDone } = {}) => {
|
|
547
|
+
this._finishPendingTestSuiteSpans()
|
|
525
548
|
this.tracer._exporter.flush(onDone)
|
|
526
549
|
})
|
|
527
550
|
|
|
@@ -715,6 +738,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
715
738
|
isEarlyFlakeDetectionFaulty,
|
|
716
739
|
isTestManagementEnabled,
|
|
717
740
|
isParallel,
|
|
741
|
+
isFrameworkError,
|
|
718
742
|
onDone,
|
|
719
743
|
}) => {
|
|
720
744
|
this._exportPendingWorkerTraces()
|
|
@@ -730,8 +754,17 @@ class MochaPlugin extends CiPlugin {
|
|
|
730
754
|
if (error) {
|
|
731
755
|
this.testSessionSpan.setTag('error', error)
|
|
732
756
|
this.testModuleSpan.setTag('error', error)
|
|
757
|
+
if (isFrameworkError) {
|
|
758
|
+
this.tracer._exporter.setDeferredTestSuiteError?.(error)
|
|
759
|
+
for (const testSuiteSpan of this._testSuiteSpansByTestSuite.values()) {
|
|
760
|
+
testSuiteSpan.setTag(TEST_STATUS, 'fail')
|
|
761
|
+
testSuiteSpan.setTag('error', error)
|
|
762
|
+
}
|
|
763
|
+
}
|
|
733
764
|
}
|
|
734
765
|
|
|
766
|
+
this._finishPendingTestSuiteSpans()
|
|
767
|
+
|
|
735
768
|
if (isParallel) {
|
|
736
769
|
this.testSessionSpan.setTag(MOCHA_IS_PARALLEL, 'true')
|
|
737
770
|
}
|
|
@@ -769,6 +802,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
769
802
|
this.testSessionSpan.setTag(TEST_EARLY_FLAKE_ABORT_REASON, 'faulty')
|
|
770
803
|
}
|
|
771
804
|
|
|
805
|
+
this.tracer._exporter.exportDeferredTestSuiteSpans?.()
|
|
772
806
|
this.testModuleSpan.finish()
|
|
773
807
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'module')
|
|
774
808
|
this.testSessionSpan.finish()
|
|
@@ -790,6 +824,27 @@ class MochaPlugin extends CiPlugin {
|
|
|
790
824
|
})
|
|
791
825
|
}
|
|
792
826
|
|
|
827
|
+
/**
|
|
828
|
+
* Returns the current time in the coordinate system used by spans.
|
|
829
|
+
*
|
|
830
|
+
* @returns {number}
|
|
831
|
+
*/
|
|
832
|
+
_now () {
|
|
833
|
+
return this._timeOrigin + performance.now() - this._perfOrigin
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* Finishes suites retained for a later framework finalization event.
|
|
838
|
+
*
|
|
839
|
+
* @returns {void}
|
|
840
|
+
*/
|
|
841
|
+
_finishPendingTestSuiteSpans () {
|
|
842
|
+
for (const { span, finishTime } of this._pendingTestSuiteSpans) {
|
|
843
|
+
span.finish(finishTime)
|
|
844
|
+
}
|
|
845
|
+
this._pendingTestSuiteSpans = []
|
|
846
|
+
}
|
|
847
|
+
|
|
793
848
|
/**
|
|
794
849
|
* Starts a Jasmine test span around WebdriverIO's test-function wrapper.
|
|
795
850
|
*
|
|
@@ -8,7 +8,7 @@ class NatsPlugin extends CompositePlugin {
|
|
|
8
8
|
static id = 'nats'
|
|
9
9
|
// Disabled by default — users must opt in via DD_TRACE_NATS_ENABLED=true
|
|
10
10
|
// or `tracer.use('nats')`. Matches the feature parity dashboard policy.
|
|
11
|
-
static
|
|
11
|
+
static optIn = true
|
|
12
12
|
static get plugins () {
|
|
13
13
|
return {
|
|
14
14
|
producer: ProducerPlugin,
|
|
@@ -102,23 +102,23 @@ class OpenAiTracingPlugin extends TracingPlugin {
|
|
|
102
102
|
},
|
|
103
103
|
}, false)
|
|
104
104
|
|
|
105
|
-
const openaiStore = Object.create(null)
|
|
106
|
-
|
|
107
105
|
const tags = {} // The remaining tags are added one at a time
|
|
108
106
|
|
|
109
107
|
if (payload.stream) {
|
|
110
108
|
tags['openai.request.stream'] = payload.stream
|
|
111
109
|
}
|
|
112
110
|
|
|
111
|
+
let openaiStore
|
|
112
|
+
|
|
113
113
|
switch (normalizedMethodName) {
|
|
114
114
|
case 'createImage':
|
|
115
115
|
case 'createImageEdit':
|
|
116
116
|
case 'createImageVariation':
|
|
117
|
-
commonCreateImageRequestExtraction(tags, payload
|
|
117
|
+
openaiStore = commonCreateImageRequestExtraction(tags, payload)
|
|
118
118
|
break
|
|
119
119
|
|
|
120
120
|
case 'createChatCompletion':
|
|
121
|
-
createChatCompletionRequestExtraction(tags, payload
|
|
121
|
+
openaiStore = createChatCompletionRequestExtraction(tags, payload)
|
|
122
122
|
break
|
|
123
123
|
|
|
124
124
|
case 'createFile':
|
|
@@ -128,7 +128,7 @@ class OpenAiTracingPlugin extends TracingPlugin {
|
|
|
128
128
|
|
|
129
129
|
case 'createTranscription':
|
|
130
130
|
case 'createTranslation':
|
|
131
|
-
commonCreateAudioRequestExtraction(tags, payload
|
|
131
|
+
openaiStore = commonCreateAudioRequestExtraction(tags, payload)
|
|
132
132
|
break
|
|
133
133
|
|
|
134
134
|
case 'retrieveModel':
|
|
@@ -136,11 +136,11 @@ class OpenAiTracingPlugin extends TracingPlugin {
|
|
|
136
136
|
break
|
|
137
137
|
|
|
138
138
|
case 'createEdit':
|
|
139
|
-
createEditRequestExtraction(tags, payload
|
|
139
|
+
openaiStore = createEditRequestExtraction(tags, payload)
|
|
140
140
|
break
|
|
141
141
|
|
|
142
142
|
case 'createResponse':
|
|
143
|
-
createResponseRequestExtraction(tags, payload
|
|
143
|
+
openaiStore = createResponseRequestExtraction(tags, payload)
|
|
144
144
|
break
|
|
145
145
|
}
|
|
146
146
|
|
|
@@ -177,8 +177,6 @@ class OpenAiTracingPlugin extends TracingPlugin {
|
|
|
177
177
|
|
|
178
178
|
body = coerceResponseBody(body, normalizedMethodName)
|
|
179
179
|
|
|
180
|
-
const openaiStore = store.openai
|
|
181
|
-
|
|
182
180
|
if (!error && (path?.startsWith('https://') || path?.startsWith('http://'))) {
|
|
183
181
|
// basic checking for if the path was set as a full URL
|
|
184
182
|
// not using a full regex as it will likely be "https://api.openai.com/..."
|
|
@@ -204,7 +202,7 @@ class OpenAiTracingPlugin extends TracingPlugin {
|
|
|
204
202
|
'openai.response.created_at': body.created_at,
|
|
205
203
|
}
|
|
206
204
|
|
|
207
|
-
responseDataExtractionByMethod(normalizedMethodName, tags, body,
|
|
205
|
+
const openaiStore = responseDataExtractionByMethod(normalizedMethodName, tags, body, store.openai)
|
|
208
206
|
span.addTags(tags)
|
|
209
207
|
|
|
210
208
|
span.finish()
|
|
@@ -298,7 +296,6 @@ class OpenAiTracingPlugin extends TracingPlugin {
|
|
|
298
296
|
|
|
299
297
|
sendLog (methodName, span, tags, openaiStore, error) {
|
|
300
298
|
if (!openaiStore) return
|
|
301
|
-
if (!Object.keys(openaiStore).length) return
|
|
302
299
|
if (!this.sampler.isSampled(span)) return
|
|
303
300
|
|
|
304
301
|
const log = {
|
|
@@ -395,45 +392,54 @@ function normalizeMethodName (methodName) {
|
|
|
395
392
|
}
|
|
396
393
|
}
|
|
397
394
|
|
|
398
|
-
function createEditRequestExtraction (tags, payload
|
|
399
|
-
const
|
|
400
|
-
openaiStore.instruction = instruction
|
|
395
|
+
function createEditRequestExtraction (tags, payload) {
|
|
396
|
+
const openaiStore = Object.create(null)
|
|
397
|
+
openaiStore.instruction = payload.instruction
|
|
398
|
+
return openaiStore
|
|
401
399
|
}
|
|
402
400
|
|
|
403
|
-
function createResponseRequestExtraction (tags, payload
|
|
401
|
+
function createResponseRequestExtraction (tags, payload) {
|
|
404
402
|
// Extract model information
|
|
405
403
|
if (payload.model) {
|
|
406
404
|
tags['openai.request.model'] = payload.model
|
|
407
405
|
}
|
|
408
406
|
|
|
409
407
|
// Store the full payload for response extraction
|
|
408
|
+
const openaiStore = Object.create(null)
|
|
410
409
|
openaiStore.responseData = payload
|
|
410
|
+
return openaiStore
|
|
411
411
|
}
|
|
412
412
|
|
|
413
413
|
function retrieveModelRequestExtraction (tags, payload) {
|
|
414
414
|
tags['openai.request.id'] = payload.id
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
-
function createChatCompletionRequestExtraction (tags, payload
|
|
417
|
+
function createChatCompletionRequestExtraction (tags, payload) {
|
|
418
418
|
const messages = payload.messages
|
|
419
419
|
if (!defensiveArrayLength(messages)) return
|
|
420
420
|
|
|
421
|
-
openaiStore
|
|
421
|
+
const openaiStore = Object.create(null)
|
|
422
|
+
openaiStore.messages = messages
|
|
423
|
+
return openaiStore
|
|
422
424
|
}
|
|
423
425
|
|
|
424
|
-
function commonCreateImageRequestExtraction (tags, payload
|
|
426
|
+
function commonCreateImageRequestExtraction (tags, payload) {
|
|
427
|
+
let openaiStore
|
|
428
|
+
|
|
425
429
|
// createImageEdit, createImageVariation
|
|
426
430
|
const img = payload.file || payload.image
|
|
427
431
|
if (img !== null && typeof img === 'object' && img.path) {
|
|
428
|
-
|
|
429
|
-
openaiStore.file =
|
|
432
|
+
openaiStore = Object.create(null)
|
|
433
|
+
openaiStore.file = path.basename(img.path)
|
|
430
434
|
}
|
|
431
435
|
|
|
432
436
|
// createImageEdit
|
|
433
437
|
if (payload.mask !== null && typeof payload.mask === 'object' && payload.mask.path) {
|
|
434
|
-
|
|
435
|
-
openaiStore.mask = mask
|
|
438
|
+
openaiStore ??= Object.create(null)
|
|
439
|
+
openaiStore.mask = path.basename(payload.mask.path)
|
|
436
440
|
}
|
|
441
|
+
|
|
442
|
+
return openaiStore
|
|
437
443
|
}
|
|
438
444
|
|
|
439
445
|
function responseDataExtractionByMethod (methodName, tags, body, openaiStore) {
|
|
@@ -441,12 +447,10 @@ function responseDataExtractionByMethod (methodName, tags, body, openaiStore) {
|
|
|
441
447
|
case 'createCompletion':
|
|
442
448
|
case 'createChatCompletion':
|
|
443
449
|
case 'createEdit':
|
|
444
|
-
commonCreateResponseExtraction(tags, body, openaiStore, methodName)
|
|
445
|
-
break
|
|
450
|
+
return commonCreateResponseExtraction(tags, body, openaiStore, methodName)
|
|
446
451
|
|
|
447
452
|
case 'createResponse':
|
|
448
|
-
createResponseResponseExtraction(tags, body, openaiStore)
|
|
449
|
-
break
|
|
453
|
+
return createResponseResponseExtraction(tags, body, openaiStore)
|
|
450
454
|
|
|
451
455
|
case 'listFiles':
|
|
452
456
|
case 'listFineTunes':
|
|
@@ -475,6 +479,8 @@ function responseDataExtractionByMethod (methodName, tags, body, openaiStore) {
|
|
|
475
479
|
retrieveModelResponseExtraction(tags, body)
|
|
476
480
|
break
|
|
477
481
|
}
|
|
482
|
+
|
|
483
|
+
return openaiStore
|
|
478
484
|
}
|
|
479
485
|
|
|
480
486
|
function retrieveModelResponseExtraction (tags, body) {
|
|
@@ -513,10 +519,11 @@ function deleteFileResponseExtraction (tags, body) {
|
|
|
513
519
|
tags['openai.response.id'] = body.id
|
|
514
520
|
}
|
|
515
521
|
|
|
516
|
-
function commonCreateAudioRequestExtraction (tags, body
|
|
522
|
+
function commonCreateAudioRequestExtraction (tags, body) {
|
|
517
523
|
if (body.file !== null && typeof body.file === 'object' && body.file.path) {
|
|
518
|
-
const
|
|
519
|
-
openaiStore.file =
|
|
524
|
+
const openaiStore = Object.create(null)
|
|
525
|
+
openaiStore.file = path.basename(body.file.path)
|
|
526
|
+
return openaiStore
|
|
520
527
|
}
|
|
521
528
|
}
|
|
522
529
|
|
|
@@ -546,9 +553,11 @@ function commonListCountResponseExtraction (tags, body) {
|
|
|
546
553
|
|
|
547
554
|
// createCompletion, createChatCompletion, createEdit
|
|
548
555
|
function commonCreateResponseExtraction (tags, body, openaiStore, methodName) {
|
|
549
|
-
if (!body.choices) return
|
|
556
|
+
if (!body.choices) return openaiStore
|
|
550
557
|
|
|
558
|
+
openaiStore ??= Object.create(null)
|
|
551
559
|
openaiStore.choices = body.choices
|
|
560
|
+
return openaiStore
|
|
552
561
|
}
|
|
553
562
|
|
|
554
563
|
function createResponseResponseExtraction (tags, body, openaiStore) {
|
|
@@ -568,7 +577,9 @@ function createResponseResponseExtraction (tags, body, openaiStore) {
|
|
|
568
577
|
}
|
|
569
578
|
|
|
570
579
|
// Store the full response for potential future use
|
|
580
|
+
openaiStore ??= Object.create(null)
|
|
571
581
|
openaiStore.response = body
|
|
582
|
+
return openaiStore
|
|
572
583
|
}
|
|
573
584
|
|
|
574
585
|
// The server almost always responds with JSON
|
|
@@ -498,6 +498,7 @@ class OpenAIAgentsIntegration {
|
|
|
498
498
|
|
|
499
499
|
this.#tagger.tagTextIO(ddSpan, inputValue, outputValue)
|
|
500
500
|
|
|
501
|
+
// eslint-disable-next-line no-restricted-syntax -- agents-core builds metadata before the plugin receives it
|
|
501
502
|
if (info.metadata && Object.keys(info.metadata).length > 0) {
|
|
502
503
|
this.#tagger.tagMetadata(ddSpan, info.metadata)
|
|
503
504
|
}
|