dd-trace 6.16.0 → 6.18.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/ci/diagnose.js +0 -23
- package/ci/test-optimization-validation/approval-artifacts.js +0 -3
- package/ci/test-optimization-validation/approval.js +0 -6
- package/ci/test-optimization-validation/artifact-id.js +0 -1
- package/ci/test-optimization-validation/bounded-json.js +0 -1
- package/ci/test-optimization-validation/cli.js +0 -12
- package/ci/test-optimization-validation/command-output-policy.js +0 -1
- package/ci/test-optimization-validation/command-runner.js +0 -3
- package/ci/test-optimization-validation/environment.js +0 -4
- package/ci/test-optimization-validation/executable-approval.js +0 -1
- package/ci/test-optimization-validation/executable.js +0 -5
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +0 -6
- package/ci/test-optimization-validation/framework-adapters/cypress.js +0 -3
- package/ci/test-optimization-validation/framework-adapters/playwright.js +0 -6
- package/ci/test-optimization-validation/framework-adapters/vitest.js +0 -4
- package/ci/test-optimization-validation/generated-test-contract.js +0 -5
- package/ci/test-optimization-validation/generated-verifier.js +0 -1
- package/ci/test-optimization-validation/literal-environment.js +0 -1
- package/ci/test-optimization-validation/manifest-scaffold.js +0 -17
- package/ci/test-optimization-validation/manifest-schema.js +0 -21
- package/ci/test-optimization-validation/offline-fixtures.js +0 -4
- package/ci/test-optimization-validation/plan-writer.js +0 -11
- package/ci/test-optimization-validation/preflight-runner.js +0 -1
- package/ci/test-optimization-validation/redaction.js +0 -4
- package/ci/test-optimization-validation/report-writer.js +0 -16
- package/ci/test-optimization-validation/runner-command.js +0 -3
- package/ci/test-optimization-validation/runner-contract.js +0 -4
- package/ci/test-optimization-validation/safe-files.js +0 -1
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +0 -1
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +0 -1
- package/ci/test-optimization-validation/source-text.js +0 -3
- package/ci/vitest-no-worker-init-setup.mjs +41 -16
- package/index.d.ts +208 -0
- package/package.json +17 -16
- package/packages/datadog-esbuild/src/utils.js +0 -2
- package/packages/datadog-instrumentations/src/aerospike.js +28 -6
- package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -2
- package/packages/datadog-instrumentations/src/aws-sdk.js +0 -2
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +0 -2
- package/packages/datadog-instrumentations/src/console.js +97 -0
- package/packages/datadog-instrumentations/src/cucumber.js +77 -12
- package/packages/datadog-instrumentations/src/cypress-config.js +27 -38
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +6 -0
- package/packages/datadog-instrumentations/src/helpers/channel.js +0 -2
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/hooks.js +8 -6
- package/packages/datadog-instrumentations/src/helpers/instrumentation-utils.js +0 -3
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +0 -6
- package/packages/datadog-instrumentations/src/helpers/register.js +24 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +111 -26
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +41 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +3 -17
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +55 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +36 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/supabase.js +128 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +13 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +28 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +20 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +388 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +0 -1
- package/packages/datadog-instrumentations/src/jest.js +165 -51
- package/packages/datadog-instrumentations/src/knex.js +0 -1
- package/packages/datadog-instrumentations/src/mariadb-bundle.js +0 -24
- package/packages/datadog-instrumentations/src/mariadb.js +0 -2
- package/packages/datadog-instrumentations/src/mocha/common.js +0 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +25 -26
- package/packages/datadog-instrumentations/src/mocha/utils.js +119 -49
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +0 -6
- package/packages/datadog-instrumentations/src/mocha/worker.js +14 -17
- package/packages/datadog-instrumentations/src/mysql2.js +0 -2
- package/packages/datadog-instrumentations/src/openai-realtime/audio-accumulator.js +241 -0
- package/packages/datadog-instrumentations/src/openai-realtime/events.js +76 -0
- package/packages/datadog-instrumentations/src/openai-realtime/index.js +301 -0
- package/packages/datadog-instrumentations/src/openai-realtime/session.js +998 -0
- package/packages/datadog-instrumentations/src/openai-realtime/turns.js +211 -0
- package/packages/datadog-instrumentations/src/openai.js +51 -12
- package/packages/datadog-instrumentations/src/oracledb.js +9 -3
- package/packages/datadog-instrumentations/src/playwright-reporter.js +6 -20
- package/packages/datadog-instrumentations/src/playwright.js +280 -56
- package/packages/datadog-instrumentations/src/{azure-cosmos.js → postgres.js} +1 -1
- package/packages/datadog-instrumentations/src/router.js +0 -2
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +0 -2
- package/packages/datadog-instrumentations/src/sequelize.js +0 -1
- package/packages/datadog-instrumentations/src/supabase.js +15 -0
- package/packages/datadog-instrumentations/src/undici.js +7 -3
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +18 -18
- package/packages/datadog-instrumentations/src/vitest-main.js +121 -30
- package/packages/datadog-instrumentations/src/vitest-util.js +7 -1
- package/packages/datadog-instrumentations/src/vitest-worker.js +49 -13
- package/packages/datadog-instrumentations/src/webdriverio.js +44 -47
- package/packages/datadog-instrumentations/src/ws.js +41 -2
- package/packages/datadog-plugin-ai/src/utils.js +0 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +0 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +0 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +0 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +0 -1
- package/packages/datadog-plugin-azure-durable-functions/src/index.js +0 -1
- package/packages/datadog-plugin-cucumber/src/index.js +9 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +211 -85
- package/packages/datadog-plugin-cypress/src/finalization.js +0 -3
- package/packages/datadog-plugin-cypress/src/index.js +3 -1
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +0 -4
- package/packages/datadog-plugin-cypress/src/support.js +52 -7
- package/packages/datadog-plugin-graphql/src/resolve-error.js +1 -2
- package/packages/datadog-plugin-graphql/src/utils.js +0 -5
- package/packages/datadog-plugin-jest/src/index.js +12 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +0 -1
- package/packages/datadog-plugin-mocha/src/index.js +38 -11
- package/packages/datadog-plugin-mongodb-core/src/query.js +0 -1
- package/packages/datadog-plugin-openai/src/index.js +16 -1
- package/packages/datadog-plugin-openai/src/realtime.js +144 -0
- package/packages/datadog-plugin-openai-agents/src/integration.js +0 -4
- package/packages/datadog-plugin-openai-agents/src/util.js +0 -1
- package/packages/datadog-plugin-playwright/src/index.js +81 -9
- package/packages/datadog-plugin-postgres/src/index.js +167 -0
- package/packages/datadog-plugin-prisma/src/datadog-tracing-helper.js +0 -1
- package/packages/datadog-plugin-redis/src/index.js +15 -1
- package/packages/datadog-plugin-supabase/src/error.js +18 -0
- package/packages/datadog-plugin-supabase/src/index.js +21 -0
- package/packages/datadog-plugin-supabase/src/supabase-auth-js-gotrueclient-getuser.js +69 -0
- package/packages/datadog-plugin-supabase/src/supabase-functions-js-functionsclient-invoke.js +70 -0
- package/packages/datadog-plugin-supabase/src/supabase-postgrest-js-postgrestbuilder-then.js +122 -0
- package/packages/datadog-plugin-supabase/src/supabase-realtime-js-realtimechannel-send.js +66 -0
- package/packages/datadog-plugin-supabase/src/supabase-storage-js-handle-request.js +93 -0
- package/packages/datadog-plugin-supabase/src/url.js +17 -0
- package/packages/datadog-plugin-vitest/src/index.js +9 -0
- package/packages/datadog-plugin-ws/src/producer.js +1 -1
- package/packages/datadog-plugin-ws/src/util.js +0 -4
- package/packages/datadog-shimmer/src/shimmer.js +14 -10
- package/packages/datadog-turbopack/index.js +4 -7
- package/packages/datadog-turbopack/src/loader.js +6 -18
- package/packages/datadog-webpack/src/loader.js +0 -1
- package/packages/dd-trace/src/agent/info.js +5 -4
- package/packages/dd-trace/src/aiguard/client.js +2 -3
- package/packages/dd-trace/src/aiguard/evaluation.js +6 -12
- package/packages/dd-trace/src/aiguard/index.js +2 -2
- package/packages/dd-trace/src/aiguard/integrations/index.js +1 -1
- package/packages/dd-trace/src/aiguard/integrations/openai.js +81 -7
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +0 -2
- package/packages/dd-trace/src/aiguard/messages/openai.js +64 -1
- package/packages/dd-trace/src/aiguard/messages/utils.js +0 -1
- package/packages/dd-trace/src/aiguard/redaction.js +0 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/activation.js +1 -1
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +0 -5
- package/packages/dd-trace/src/appsec/api_security/sampler.js +0 -4
- package/packages/dd-trace/src/appsec/blocking/index.js +3 -3
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -4
- package/packages/dd-trace/src/appsec/iast/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +5 -5
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +3 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +8 -10
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +4 -1
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +7 -7
- package/packages/dd-trace/src/appsec/index.js +2 -2
- package/packages/dd-trace/src/appsec/lambda.js +71 -2
- package/packages/dd-trace/src/appsec/rasp/utils.js +5 -1
- package/packages/dd-trace/src/appsec/remote_config.js +8 -6
- package/packages/dd-trace/src/appsec/reporter.js +10 -6
- package/packages/dd-trace/src/appsec/rule_manager.js +3 -3
- package/packages/dd-trace/src/appsec/sdk/track_event.js +0 -2
- package/packages/dd-trace/src/appsec/waf/index.js +2 -2
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +8 -5
- package/packages/dd-trace/src/carrier.js +0 -5
- package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +104 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +0 -2
- package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +34 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +0 -4
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +0 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +0 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +37 -15
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +0 -3
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +0 -11
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +0 -6
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -2
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +0 -1
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +0 -5
- package/packages/dd-trace/src/ci-visibility/requests/video-request.js +0 -1
- package/packages/dd-trace/src/ci-visibility/telemetry.js +13 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +0 -1
- package/packages/dd-trace/src/ci-visibility/test-screenshot.js +0 -2
- package/packages/dd-trace/src/ci-visibility/test-video.js +0 -1
- package/packages/dd-trace/src/config/defaults.js +3 -2
- package/packages/dd-trace/src/config/generated-config-types.d.ts +88 -82
- package/packages/dd-trace/src/config/helper.js +0 -1
- package/packages/dd-trace/src/config/index.js +31 -30
- package/packages/dd-trace/src/config/parsers.js +34 -6
- package/packages/dd-trace/src/config/remote_config.js +25 -109
- package/packages/dd-trace/src/config/supported-configurations.json +150 -10
- package/packages/dd-trace/src/datastreams/encoding.js +0 -1
- package/packages/dd-trace/src/datastreams/pathway.js +0 -1
- package/packages/dd-trace/src/debugger/constants.js +10 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +62 -10
- package/packages/dd-trace/src/debugger/devtools_client/config.js +4 -1
- package/packages/dd-trace/src/debugger/devtools_client/guardrail-metrics.js +15 -0
- package/packages/dd-trace/src/debugger/devtools_client/index.js +103 -27
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +50 -7
- package/packages/dd-trace/src/debugger/devtools_client/log.js +3 -1
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +21 -8
- package/packages/dd-trace/src/debugger/devtools_client/send.js +41 -15
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +53 -13
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +118 -71
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +5 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +0 -3
- package/packages/dd-trace/src/debugger/devtools_client/status.js +21 -7
- package/packages/dd-trace/src/debugger/guardrail-metrics.js +167 -0
- package/packages/dd-trace/src/debugger/index.js +51 -3
- package/packages/dd-trace/src/debugger/inspect-segment.js +0 -3
- package/packages/dd-trace/src/debugger/probe_sampler.js +133 -9
- package/packages/dd-trace/src/debugger/probe_sampler_constants.js +31 -1
- package/packages/dd-trace/src/dogstatsd.js +0 -23
- package/packages/dd-trace/src/encode/0.4-cross-payload.js +0 -3
- package/packages/dd-trace/src/encode/0.4.js +0 -7
- package/packages/dd-trace/src/encode/0.5.js +0 -2
- package/packages/dd-trace/src/encode/tags-processors.js +0 -1
- package/packages/dd-trace/src/evp_proxy/constants.js +2 -0
- package/packages/dd-trace/src/evp_proxy/direct.js +17 -13
- package/packages/dd-trace/src/evp_proxy/discovery.js +14 -11
- package/packages/dd-trace/src/evp_proxy/path.js +21 -9
- package/packages/dd-trace/src/exporters/agent/writer.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/index.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/intake.js +0 -1
- package/packages/dd-trace/src/exporters/agentless/writer.js +0 -3
- package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +0 -6
- package/packages/dd-trace/src/exporters/common/request.js +1 -0
- package/packages/dd-trace/src/exporters/common/url.js +33 -4
- package/packages/dd-trace/src/exporters/common/writer.js +0 -2
- package/packages/dd-trace/src/id.js +0 -11
- package/packages/dd-trace/src/llmobs/audio-codec.js +192 -0
- package/packages/dd-trace/src/llmobs/audio-utils.js +121 -0
- package/packages/dd-trace/src/llmobs/constants/audio.js +35 -0
- package/packages/dd-trace/src/llmobs/constants/prompts.js +14 -0
- package/packages/dd-trace/src/llmobs/constants/tags.js +17 -0
- package/packages/dd-trace/src/llmobs/eval-metric.js +0 -6
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +0 -4
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +0 -3
- package/packages/dd-trace/src/llmobs/experiments/index.js +7 -6
- package/packages/dd-trace/src/llmobs/experiments/util.js +1 -11
- package/packages/dd-trace/src/llmobs/index.js +1 -3
- package/packages/dd-trace/src/llmobs/noop.js +10 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +0 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +0 -4
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +4 -6
- package/packages/dd-trace/src/llmobs/plugins/openai/realtime.js +285 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +16 -3
- package/packages/dd-trace/src/llmobs/prompts/cache.js +272 -0
- package/packages/dd-trace/src/llmobs/prompts/manager.js +647 -0
- package/packages/dd-trace/src/llmobs/prompts/noop.js +29 -0
- package/packages/dd-trace/src/llmobs/prompts/prompt.js +158 -0
- package/packages/dd-trace/src/llmobs/sdk.js +21 -6
- package/packages/dd-trace/src/llmobs/span_processor.js +81 -2
- package/packages/dd-trace/src/llmobs/tagger.js +39 -11
- package/packages/dd-trace/src/llmobs/telemetry.js +36 -4
- package/packages/dd-trace/src/llmobs/util.js +0 -34
- package/packages/dd-trace/src/llmobs/writers/base.js +0 -1
- package/packages/dd-trace/src/llmobs/writers/util.js +1 -2
- package/packages/dd-trace/src/log/channels.js +3 -0
- package/packages/dd-trace/src/log/index.js +23 -5
- package/packages/dd-trace/src/log-submission/log-submission-plugin.js +74 -6
- package/packages/dd-trace/src/msgpack/chunk.js +0 -1
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +0 -12
- package/packages/dd-trace/src/openfeature/configuration_source.js +4 -1
- package/packages/dd-trace/src/openfeature/encoding.js +0 -2
- package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -3
- package/packages/dd-trace/src/openfeature/index.js +6 -6
- package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/span-enrichment.js +0 -4
- package/packages/dd-trace/src/openfeature/writers/base.js +90 -23
- package/packages/dd-trace/src/openfeature/writers/exposures.js +4 -5
- package/packages/dd-trace/src/openfeature/writers/util.js +104 -37
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +0 -2
- package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +0 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -14
- package/packages/dd-trace/src/opentelemetry/metrics/time.js +0 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +30 -13
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +0 -1
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +0 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +0 -3
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -6
- package/packages/dd-trace/src/opentracing/span_context.js +0 -1
- package/packages/dd-trace/src/opentracing/tracer.js +3 -3
- package/packages/dd-trace/src/otel-thread-ctx.js +38 -11
- package/packages/dd-trace/src/payload-tagging/tagging.js +15 -3
- package/packages/dd-trace/src/plugin_manager.js +27 -8
- package/packages/dd-trace/src/plugins/ci_plugin.js +1 -2
- package/packages/dd-trace/src/plugins/database.js +2 -6
- package/packages/dd-trace/src/plugins/index.js +7 -0
- package/packages/dd-trace/src/plugins/plugin.js +0 -4
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/plugins/util/git.js +1 -3
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +0 -1
- package/packages/dd-trace/src/plugins/util/llm.js +0 -2
- package/packages/dd-trace/src/plugins/util/status-validator.js +0 -1
- package/packages/dd-trace/src/plugins/util/test.js +26 -20
- package/packages/dd-trace/src/plugins/util/url.js +0 -5
- package/packages/dd-trace/src/priority_sampler.js +0 -6
- package/packages/dd-trace/src/process-tags/index.js +0 -1
- package/packages/dd-trace/src/profiler.js +132 -35
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +0 -1
- package/packages/dd-trace/src/profiling/profiler.js +101 -41
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +29 -15
- package/packages/dd-trace/src/propagation-hash/index.js +0 -1
- package/packages/dd-trace/src/proxy.js +23 -47
- package/packages/dd-trace/src/random_sampler.js +0 -4
- package/packages/dd-trace/src/rate_limiter.js +0 -4
- package/packages/dd-trace/src/remote_config/capabilities.js +1 -9
- package/packages/dd-trace/src/remote_config/index.js +0 -1
- package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +0 -3
- package/packages/dd-trace/src/sampler.js +0 -4
- package/packages/dd-trace/src/sampling_rule.js +0 -7
- package/packages/dd-trace/src/serverless/vercel.js +0 -1
- package/packages/dd-trace/src/serverless.js +0 -1
- package/packages/dd-trace/src/service-naming/index.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +7 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +5 -0
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/span_sampler.js +0 -1
- package/packages/dd-trace/src/standalone/product.js +2 -2
- package/packages/dd-trace/src/standalone/tracesource.js +0 -1
- package/packages/dd-trace/src/startup-log.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +0 -8
- package/packages/dd-trace/src/telemetry/logs/index.js +16 -5
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +16 -6
- package/packages/dd-trace/src/telemetry/metrics.js +0 -2
- package/packages/dd-trace/src/telemetry/send-data.js +2 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +4 -1
- package/packages/dd-trace/src/tracer.js +5 -4
- package/packages/dd-trace/src/util.js +13 -1
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
- package/packages/datadog-instrumentations/src/bullmq.js +0 -11
- package/packages/datadog-instrumentations/src/langchain.js +0 -7
- package/packages/datadog-instrumentations/src/langgraph.js +0 -7
- package/packages/datadog-instrumentations/src/mercurius.js +0 -11
|
@@ -19,9 +19,6 @@ function runUserHandler (handler) {
|
|
|
19
19
|
return userHandlerContext.run(true, handler)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
/**
|
|
23
|
-
* @returns {boolean} whether a managed finalizer owns the current lifecycle event
|
|
24
|
-
*/
|
|
25
22
|
function shouldDeferLegacyFinalization () {
|
|
26
23
|
return userHandlerContext.getStore() === true
|
|
27
24
|
}
|
|
@@ -26,6 +26,7 @@ class CypressPlugin extends Plugin {
|
|
|
26
26
|
userAfterRunHandlers,
|
|
27
27
|
userAfterScreenshotHandlers,
|
|
28
28
|
cleanupWrapper,
|
|
29
|
+
registerBeforeRun,
|
|
29
30
|
} = payload
|
|
30
31
|
|
|
31
32
|
const registerAfterRunWithCleanup = (afterRunHandler) => {
|
|
@@ -79,6 +80,7 @@ class CypressPlugin extends Plugin {
|
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
if (cypressPlugin._isInit) {
|
|
83
|
+
registerBeforeRun()
|
|
82
84
|
// Already initialized by manual plugin call — just chain user handlers.
|
|
83
85
|
// Pass the plugin's afterScreenshot so chaining a user handler doesn't drop the upload
|
|
84
86
|
// (the chained registration replaces the one plugin.js set, so it must include it).
|
|
@@ -94,7 +96,7 @@ class CypressPlugin extends Plugin {
|
|
|
94
96
|
return
|
|
95
97
|
}
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
registerBeforeRun(cypressPlugin.beforeRun.bind(cypressPlugin))
|
|
98
100
|
registerAfterScreenshot(datadogAfterScreenshotHandler)
|
|
99
101
|
|
|
100
102
|
on('after:spec', (spec, results) => {
|
|
@@ -15,7 +15,6 @@ const SOURCE_MAP_CACHE = new Map()
|
|
|
15
15
|
/**
|
|
16
16
|
* Whether a file path references JavaScript.
|
|
17
17
|
* @param {string} absoluteFilePath
|
|
18
|
-
* @returns {boolean}
|
|
19
18
|
*/
|
|
20
19
|
function isJavaScriptFile (absoluteFilePath) {
|
|
21
20
|
return absoluteFilePath.endsWith('.js') || absoluteFilePath.endsWith('.cjs') || absoluteFilePath.endsWith('.mjs')
|
|
@@ -25,7 +24,6 @@ function isJavaScriptFile (absoluteFilePath) {
|
|
|
25
24
|
* Decide whether invocationDetails line can be trusted as final source line.
|
|
26
25
|
* @param {string} absoluteFilePath
|
|
27
26
|
* @param {number} testSourceLine
|
|
28
|
-
* @returns {boolean}
|
|
29
27
|
*/
|
|
30
28
|
function shouldTrustInvocationDetailsLine (absoluteFilePath, testSourceLine) {
|
|
31
29
|
if (!Number.isInteger(testSourceLine) || testSourceLine < 1) return false
|
|
@@ -38,7 +36,6 @@ function shouldTrustInvocationDetailsLine (absoluteFilePath, testSourceLine) {
|
|
|
38
36
|
* Decode one VLQ-encoded integer from `str` at `cursor.pos`, advancing the cursor in place.
|
|
39
37
|
* @param {string} str
|
|
40
38
|
* @param {{ pos: number }} cursor
|
|
41
|
-
* @returns {number}
|
|
42
39
|
*/
|
|
43
40
|
function decodeVLQ (str, cursor) {
|
|
44
41
|
let result = 0
|
|
@@ -243,7 +240,6 @@ function templateBodyToRegExp (templateBody) {
|
|
|
243
240
|
* Count 1-indexed line number for a character index in `content`.
|
|
244
241
|
* @param {string} content
|
|
245
242
|
* @param {number} endIndex
|
|
246
|
-
* @returns {number}
|
|
247
243
|
*/
|
|
248
244
|
function lineNumberForIndex (content, endIndex) {
|
|
249
245
|
let line = 1
|
|
@@ -16,10 +16,15 @@ let testManagementTests = {}
|
|
|
16
16
|
let isImpactedTestsEnabled = false
|
|
17
17
|
let isModifiedTest = false
|
|
18
18
|
let isTestIsolationEnabled = false
|
|
19
|
+
let isDynamicAtrEnabled = false
|
|
20
|
+
let isTextTerminal = false
|
|
19
21
|
let hasWarnedMissingBeforeEachTaskResult = false
|
|
20
22
|
let hasWarnedMissingBeforeEachRetryResult = false
|
|
21
23
|
// Array of test names that have been retried and the reason
|
|
22
24
|
const retryReasonsByTestName = new Map()
|
|
25
|
+
// Dynamic ATR computes the selected budget after the first attempt. Keep that result
|
|
26
|
+
// in browser state and apply it when Cypress starts the retry runnable.
|
|
27
|
+
const dynamicAtrRetryCountByTest = new Map()
|
|
23
28
|
// Track test errors suppressed by test management so we can still report them to Datadog.
|
|
24
29
|
const suppressedTestFailures = new Map()
|
|
25
30
|
|
|
@@ -93,7 +98,6 @@ function getTestProperties (testName) {
|
|
|
93
98
|
|
|
94
99
|
/**
|
|
95
100
|
* @param {string} message
|
|
96
|
-
* @returns {void}
|
|
97
101
|
*/
|
|
98
102
|
function warnMissingBeforeEachTaskResult (message) {
|
|
99
103
|
// eslint-disable-next-line no-console
|
|
@@ -192,7 +196,6 @@ function setRumCorrelationCookie (traceId) {
|
|
|
192
196
|
|
|
193
197
|
/**
|
|
194
198
|
* @param {boolean} isCookieSet
|
|
195
|
-
* @returns {void}
|
|
196
199
|
*/
|
|
197
200
|
function restartRumSession (isCookieSet) {
|
|
198
201
|
if (!isCookieSet || isTestIsolationEnabled || !originalWindow) {
|
|
@@ -362,20 +365,47 @@ Cypress.mocha.getRunner().runTests = function (suite, fn) {
|
|
|
362
365
|
return oldRunTests.apply(this, [suite, fn])
|
|
363
366
|
}
|
|
364
367
|
|
|
365
|
-
|
|
368
|
+
/**
|
|
369
|
+
* @param {{ id: string }} test
|
|
370
|
+
*/
|
|
371
|
+
function getDynamicAtrTestKey (test) {
|
|
372
|
+
// Cypress preserves the runnable ID when cloning a retry, including across browser reloads.
|
|
373
|
+
return `${Cypress.mocha.getRootSuite().file}\0${test.id}`
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* @param {{ id: string, _retries: number }} test
|
|
378
|
+
*/
|
|
379
|
+
function configureTestRetries (test) {
|
|
366
380
|
if (shouldDisableFrameworkRetries(test)) {
|
|
367
381
|
disableFrameworkRetries(test)
|
|
382
|
+
return
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (!isTextTerminal) return
|
|
386
|
+
|
|
387
|
+
const dynamicAtrRetryCount = dynamicAtrRetryCountByTest.get(getDynamicAtrTestKey(test))
|
|
388
|
+
if (Number.isSafeInteger(dynamicAtrRetryCount)) {
|
|
389
|
+
test._retries = dynamicAtrRetryCount
|
|
390
|
+
} else if (isDynamicAtrEnabled) {
|
|
391
|
+
// Cypress forbids calling retries(count) on the original runnable.
|
|
392
|
+
// Ensure local retries: 0 overrides still reach the duration-based budget selection.
|
|
393
|
+
test._retries = Math.max(1, test._retries)
|
|
368
394
|
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
Cypress.on('test:before:run', (attributes, test) => {
|
|
398
|
+
configureTestRetries(test)
|
|
369
399
|
})
|
|
370
400
|
|
|
371
401
|
Cypress.on('test:before:run:async', (attributes, test) => {
|
|
372
|
-
|
|
373
|
-
disableFrameworkRetries(test)
|
|
374
|
-
}
|
|
402
|
+
configureTestRetries(test)
|
|
375
403
|
})
|
|
376
404
|
|
|
377
405
|
beforeEach(function () {
|
|
378
406
|
const currentTest = Cypress.mocha.getRunner().suite.ctx.currentTest
|
|
407
|
+
// The first test:before:run event can precede the suite configuration task.
|
|
408
|
+
configureTestRetries(currentTest)
|
|
379
409
|
const testName = currentTest.fullTitle()
|
|
380
410
|
|
|
381
411
|
const retryMessage = retryReasonsByTestName.get(testName)
|
|
@@ -427,6 +457,7 @@ before(function () {
|
|
|
427
457
|
cy.task('dd:testSuiteStart', {
|
|
428
458
|
testSuite: Cypress.mocha.getRootSuite().file,
|
|
429
459
|
testSuiteAbsolutePath: Cypress.spec && Cypress.spec.absolute,
|
|
460
|
+
isTextTerminal: Cypress.config('isTextTerminal'),
|
|
430
461
|
}).then((suiteConfig) => {
|
|
431
462
|
if (suiteConfig) {
|
|
432
463
|
isEarlyFlakeDetectionEnabled = suiteConfig.isEarlyFlakeDetectionEnabled
|
|
@@ -439,6 +470,12 @@ before(function () {
|
|
|
439
470
|
isImpactedTestsEnabled = suiteConfig.isImpactedTestsEnabled
|
|
440
471
|
isModifiedTest = suiteConfig.isModifiedTest
|
|
441
472
|
isTestIsolationEnabled = suiteConfig.isTestIsolationEnabled
|
|
473
|
+
isDynamicAtrEnabled = suiteConfig.isDynamicAtrEnabled
|
|
474
|
+
isTextTerminal = suiteConfig.isTextTerminal
|
|
475
|
+
if (isDynamicAtrEnabled && isTextTerminal) {
|
|
476
|
+
// The first test event can precede this task, and an earlier user hook can skip our beforeEach.
|
|
477
|
+
Cypress.mocha.getRootSuite().eachTest(configureTestRetries)
|
|
478
|
+
}
|
|
442
479
|
rumTestExecutionIdCookieName = suiteConfig.rumTestExecutionIdCookieName
|
|
443
480
|
if (Number.isFinite(suiteConfig.rumFlushWaitMillis)) {
|
|
444
481
|
rumFlushWaitMillis = suiteConfig.rumFlushWaitMillis
|
|
@@ -448,6 +485,7 @@ before(function () {
|
|
|
448
485
|
})
|
|
449
486
|
|
|
450
487
|
after(() => {
|
|
488
|
+
dynamicAtrRetryCountByTest.clear()
|
|
451
489
|
try {
|
|
452
490
|
if (safeGetRum(originalWindow)) {
|
|
453
491
|
originalWindow.dispatchEvent(new Event('beforeunload'))
|
|
@@ -475,6 +513,7 @@ afterEach(function () {
|
|
|
475
513
|
: currentTest.err
|
|
476
514
|
|
|
477
515
|
const testInfo = {
|
|
516
|
+
testId: currentTest.id,
|
|
478
517
|
testName,
|
|
479
518
|
testItTitle: currentTest.title,
|
|
480
519
|
testSuite: Cypress.mocha.getRootSuite().file,
|
|
@@ -522,5 +561,11 @@ afterEach(function () {
|
|
|
522
561
|
suppressedTestFailures.delete(testName)
|
|
523
562
|
}
|
|
524
563
|
|
|
525
|
-
cy.task('dd:afterEach', { test: testInfo, coverage, commands: commandsToReport })
|
|
564
|
+
cy.task('dd:afterEach', { test: testInfo, coverage, commands: commandsToReport }).then((taskResult) => {
|
|
565
|
+
// Preserve the first-attempt result until Cypress starts the retry runnable.
|
|
566
|
+
// Changing the completed test here is too late for Cypress's retry lifecycle.
|
|
567
|
+
if (taskResult && Number.isSafeInteger(taskResult.dynamicAtrRetryCount)) {
|
|
568
|
+
dynamicAtrRetryCountByTest.set(getDynamicAtrTestKey(currentTest), taskResult.dynamicAtrRetryCount)
|
|
569
|
+
}
|
|
570
|
+
})
|
|
526
571
|
})
|
|
@@ -62,7 +62,7 @@ class GraphQLToolsResolveErrorPlugin extends TracingPlugin {
|
|
|
62
62
|
*/
|
|
63
63
|
function recordResolveErrorForPath (error, path, fieldNodes) {
|
|
64
64
|
const rootCtx = legacyStorage.getStore()?.graphqlRootCtx
|
|
65
|
-
if (!rootCtx?.config
|
|
65
|
+
if (!rootCtx?.config?.collapse || !rootCtx.fields) return
|
|
66
66
|
|
|
67
67
|
const field = findResolveField(rootCtx.fields, getPathString(path), fieldNodes?.[0])
|
|
68
68
|
if (field) recordResolveError(field, error)
|
|
@@ -70,7 +70,6 @@ function recordResolveErrorForPath (error, path, fieldNodes) {
|
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
72
|
* @param {(string | number)[]} path
|
|
73
|
-
* @returns {string}
|
|
74
73
|
*/
|
|
75
74
|
function getPathString (path) {
|
|
76
75
|
let pathString = ''
|
|
@@ -54,7 +54,6 @@ function getRequestCache (owner, configuredLimit) {
|
|
|
54
54
|
/**
|
|
55
55
|
* @param {string | null | undefined} operationName
|
|
56
56
|
* @param {boolean} calculateSignature
|
|
57
|
-
* @returns {string}
|
|
58
57
|
*/
|
|
59
58
|
function operationCacheKey (operationName, calculateSignature) {
|
|
60
59
|
return `${calculateSignature === false ? 0 : 1}\n${operationName ?? ''}`
|
|
@@ -309,7 +308,6 @@ const HEALTH_CHECK_QUERY = 'query __ApolloServiceHealthCheck__ { __typename }'
|
|
|
309
308
|
* Matches the raw query string before it is parsed (the only input parse has).
|
|
310
309
|
*
|
|
311
310
|
* @param {unknown} source Raw query string or a graphql `Source` body.
|
|
312
|
-
* @returns {boolean}
|
|
313
311
|
*/
|
|
314
312
|
function isApolloHealthCheckSource (source) {
|
|
315
313
|
return source === HEALTH_CHECK_QUERY
|
|
@@ -319,7 +317,6 @@ function isApolloHealthCheckSource (source) {
|
|
|
319
317
|
* Matches Apollo's parsed health-check operation exactly for cached documents.
|
|
320
318
|
*
|
|
321
319
|
* @param {import('graphql').OperationDefinitionNode | undefined} operation
|
|
322
|
-
* @returns {boolean}
|
|
323
320
|
*/
|
|
324
321
|
function isApolloHealthCheck (operation) {
|
|
325
322
|
const selections = operation?.selectionSet?.selections
|
|
@@ -342,7 +339,6 @@ function isApolloHealthCheck (operation) {
|
|
|
342
339
|
|
|
343
340
|
/**
|
|
344
341
|
* @param {import('graphql').GraphQLOutputType} type
|
|
345
|
-
* @returns {string}
|
|
346
342
|
*/
|
|
347
343
|
function getBaseTypeName (type) {
|
|
348
344
|
let current = type
|
|
@@ -357,7 +353,6 @@ let tools
|
|
|
357
353
|
* @param {string | undefined} operationName
|
|
358
354
|
* @param {import('graphql').OperationTypeNode} operationType
|
|
359
355
|
* @param {boolean} [calculate]
|
|
360
|
-
* @returns {string}
|
|
361
356
|
*/
|
|
362
357
|
function getSignature (document, operationName, operationType, calculate) {
|
|
363
358
|
if (calculate !== false && tools !== false) {
|
|
@@ -41,6 +41,7 @@ const {
|
|
|
41
41
|
TEST_HAS_FAILED_ALL_RETRIES,
|
|
42
42
|
TEST_RETRY_REASON_TYPES,
|
|
43
43
|
TEST_IS_MODIFIED,
|
|
44
|
+
setExpectedEmptyTestSessionTags,
|
|
44
45
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
45
46
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
46
47
|
const id = require('../../dd-trace/src/id')
|
|
@@ -116,12 +117,21 @@ class JestPlugin extends CiPlugin {
|
|
|
116
117
|
isEarlyFlakeDetectionEnabled,
|
|
117
118
|
isEarlyFlakeDetectionFaulty,
|
|
118
119
|
isTestManagementTestsEnabled,
|
|
120
|
+
testSessionEmptyReason,
|
|
119
121
|
onDone,
|
|
120
122
|
}) => {
|
|
121
123
|
const finishSession = () => {
|
|
122
124
|
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
123
125
|
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
124
126
|
|
|
127
|
+
if (testSessionEmptyReason) {
|
|
128
|
+
setExpectedEmptyTestSessionTags(
|
|
129
|
+
this.testSessionSpan,
|
|
130
|
+
this.testModuleSpan,
|
|
131
|
+
testSessionEmptyReason
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
|
|
125
135
|
if (error) {
|
|
126
136
|
this.testSessionSpan.setTag('error', error)
|
|
127
137
|
this.testModuleSpan.setTag('error', error)
|
|
@@ -204,6 +214,8 @@ class JestPlugin extends CiPlugin {
|
|
|
204
214
|
config._ddIsTestManagementTestsEnabled = this.libraryConfig?.isTestManagementEnabled ?? false
|
|
205
215
|
config._ddTestManagementAttemptToFixRetries = this.libraryConfig?.testManagementAttemptToFixRetries ?? 0
|
|
206
216
|
config._ddFlakyTestRetriesCount = this.libraryConfig?.flakyTestRetriesCount
|
|
217
|
+
config._ddIsDynamicAtrEnabled = this.libraryConfig?.isDynamicAtrEnabled ?? false
|
|
218
|
+
config._ddDynamicAtrBuckets = this.libraryConfig?.dynamicAtrBuckets
|
|
207
219
|
config._ddIsDiEnabled = this.libraryConfig?.isDiEnabled ?? false
|
|
208
220
|
config._ddIsKnownTestsEnabled = this.libraryConfig?.isKnownTestsEnabled ?? false
|
|
209
221
|
config._ddIsImpactedTestsEnabled = this.libraryConfig?.isImpactedTestsEnabled ?? false
|
|
@@ -12,6 +12,9 @@ const {
|
|
|
12
12
|
getEfdRetryCountForDuration,
|
|
13
13
|
hasEfdRetries,
|
|
14
14
|
} = require('../../dd-trace/src/ci-visibility/efd-retry-policy')
|
|
15
|
+
const {
|
|
16
|
+
getDynamicAtrRetryCount,
|
|
17
|
+
} = require('../../dd-trace/src/ci-visibility/dynamic-atr-retries')
|
|
15
18
|
const {
|
|
16
19
|
SCREENSHOT_UPLOAD_RESULT_ERROR,
|
|
17
20
|
SCREENSHOT_UPLOAD_RESULT_UPLOADED,
|
|
@@ -65,6 +68,7 @@ const {
|
|
|
65
68
|
TEST_BROWSER_NAME,
|
|
66
69
|
TEST_BROWSER_VERSION,
|
|
67
70
|
TEST_IS_RUM_ACTIVE,
|
|
71
|
+
setExpectedEmptyTestSessionTags,
|
|
68
72
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
69
73
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
70
74
|
const {
|
|
@@ -184,7 +188,6 @@ function setWebdriverioRumTestCorrelation (context, activeSpan) {
|
|
|
184
188
|
* Converts a screenshot capture failure into its upload result.
|
|
185
189
|
*
|
|
186
190
|
* @param {unknown} error
|
|
187
|
-
* @returns {string}
|
|
188
191
|
*/
|
|
189
192
|
function handleWebdriverioScreenshotError (error) {
|
|
190
193
|
log.error('Error capturing WebdriverIO failure screenshot: %s', error?.message || String(error))
|
|
@@ -882,6 +885,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
882
885
|
isTestManagementEnabled,
|
|
883
886
|
isParallel,
|
|
884
887
|
isFrameworkError,
|
|
888
|
+
testSessionEmptyReason,
|
|
885
889
|
onDone,
|
|
886
890
|
}) => {
|
|
887
891
|
this._exportPendingWorkerTraces()
|
|
@@ -894,6 +898,14 @@ class MochaPlugin extends CiPlugin {
|
|
|
894
898
|
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
895
899
|
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
896
900
|
|
|
901
|
+
if (testSessionEmptyReason) {
|
|
902
|
+
setExpectedEmptyTestSessionTags(
|
|
903
|
+
this.testSessionSpan,
|
|
904
|
+
this.testModuleSpan,
|
|
905
|
+
testSessionEmptyReason
|
|
906
|
+
)
|
|
907
|
+
}
|
|
908
|
+
|
|
897
909
|
if (error) {
|
|
898
910
|
this.testSessionSpan.setTag('error', error)
|
|
899
911
|
this.testModuleSpan.setTag('error', error)
|
|
@@ -1027,7 +1039,17 @@ class MochaPlugin extends CiPlugin {
|
|
|
1027
1039
|
} else if (isEarlyFlakeDetection) {
|
|
1028
1040
|
retryCount = this.libraryConfig.earlyFlakeDetectionRetryPolicy.schedulingRetryCount
|
|
1029
1041
|
} else if (isAtr) {
|
|
1030
|
-
|
|
1042
|
+
// When dynamic ATR is enabled, use the max bucket value as the initial count.
|
|
1043
|
+
// The actual duration-based count is computed after the first attempt.
|
|
1044
|
+
if (this.libraryConfig.isDynamicAtrEnabled) {
|
|
1045
|
+
const maximumDynamicAtrRetries = this.libraryConfig.dynamicAtrBuckets
|
|
1046
|
+
? Math.max(...this.libraryConfig.dynamicAtrBuckets)
|
|
1047
|
+
: this.libraryConfig.earlyFlakeDetectionRetryPolicy.schedulingRetryCount
|
|
1048
|
+
// Dynamic ATR guarantees one retry, including the >5m EFD fallback bucket.
|
|
1049
|
+
retryCount = Math.max(1, maximumDynamicAtrRetries)
|
|
1050
|
+
} else {
|
|
1051
|
+
retryCount = this.libraryConfig.flakyTestRetriesCount
|
|
1052
|
+
}
|
|
1031
1053
|
}
|
|
1032
1054
|
|
|
1033
1055
|
const test = {
|
|
@@ -1041,6 +1063,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
1041
1063
|
isAttemptToFix,
|
|
1042
1064
|
isAtr,
|
|
1043
1065
|
isDisabled,
|
|
1066
|
+
isDynamicAtr: isAtr && this.libraryConfig?.isDynamicAtrEnabled,
|
|
1044
1067
|
isEarlyFlakeDetection,
|
|
1045
1068
|
isModified,
|
|
1046
1069
|
isNew,
|
|
@@ -1090,7 +1113,6 @@ class MochaPlugin extends CiPlugin {
|
|
|
1090
1113
|
*
|
|
1091
1114
|
* @param {object} test
|
|
1092
1115
|
* @param {object|undefined} parentStore
|
|
1093
|
-
* @returns {void}
|
|
1094
1116
|
*/
|
|
1095
1117
|
#startWebdriverioJasmineAttempt (test, parentStore) {
|
|
1096
1118
|
test.attemptStart = performance.now()
|
|
@@ -1121,7 +1143,6 @@ class MochaPlugin extends CiPlugin {
|
|
|
1121
1143
|
* Delays Jasmine's parent runner until every Datadog-managed spec execution has completed.
|
|
1122
1144
|
*
|
|
1123
1145
|
* @param {object} context
|
|
1124
|
-
* @returns {void}
|
|
1125
1146
|
*/
|
|
1126
1147
|
#configureWebdriverioJasmineLifecycle (context) {
|
|
1127
1148
|
const isLegacyJasmine = Boolean(context.self?.queueableFn)
|
|
@@ -1215,6 +1236,19 @@ class MochaPlugin extends CiPlugin {
|
|
|
1215
1236
|
}
|
|
1216
1237
|
}
|
|
1217
1238
|
|
|
1239
|
+
// Dynamic ATR: after the first attempt, compute the duration-based retry budget.
|
|
1240
|
+
if (
|
|
1241
|
+
testStatus !== 'skip' &&
|
|
1242
|
+
test.isDynamicAtr &&
|
|
1243
|
+
test.attempt === 0
|
|
1244
|
+
) {
|
|
1245
|
+
test.retryCount = getDynamicAtrRetryCount(
|
|
1246
|
+
performance.now() - test.attemptStart,
|
|
1247
|
+
this.libraryConfig.earlyFlakeDetectionRetryPolicy,
|
|
1248
|
+
this.libraryConfig.dynamicAtrBuckets
|
|
1249
|
+
)
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1218
1252
|
const hasManagedRetry = testStatus !== 'skip' && test.attempt < test.retryCount
|
|
1219
1253
|
test.willRetry = hasManagedRetry && (
|
|
1220
1254
|
test.isAttemptToFix ||
|
|
@@ -1250,7 +1284,6 @@ class MochaPlugin extends CiPlugin {
|
|
|
1250
1284
|
*
|
|
1251
1285
|
* @param {object} test
|
|
1252
1286
|
* @param {WebdriverioJasmineResult} result
|
|
1253
|
-
* @returns {void}
|
|
1254
1287
|
*/
|
|
1255
1288
|
#finishWebdriverioJasmineRetry (test, result) {
|
|
1256
1289
|
const status = getJasmineStatus(test.reportedStatus || result.status)
|
|
@@ -1290,7 +1323,6 @@ class MochaPlugin extends CiPlugin {
|
|
|
1290
1323
|
* Advances a Jasmine test and starts its next attempt span.
|
|
1291
1324
|
*
|
|
1292
1325
|
* @param {object} test
|
|
1293
|
-
* @returns {void}
|
|
1294
1326
|
*/
|
|
1295
1327
|
#startNextWebdriverioJasmineAttempt (test) {
|
|
1296
1328
|
test.attempt++
|
|
@@ -1404,7 +1436,6 @@ class MochaPlugin extends CiPlugin {
|
|
|
1404
1436
|
*
|
|
1405
1437
|
* @param {object} test
|
|
1406
1438
|
* @param {WebdriverioJasmineResult} result
|
|
1407
|
-
* @returns {void}
|
|
1408
1439
|
*/
|
|
1409
1440
|
#completeWebdriverioJasmineTest (test, result) {
|
|
1410
1441
|
const state = this._webdriverioJasmineState
|
|
@@ -1460,7 +1491,6 @@ class MochaPlugin extends CiPlugin {
|
|
|
1460
1491
|
*
|
|
1461
1492
|
* @param {object} span - Failed test span
|
|
1462
1493
|
* @param {() => void} [onDone] - Called after the screenshot upload finishes
|
|
1463
|
-
* @returns {boolean} Whether a screenshot upload exists for the span
|
|
1464
1494
|
*/
|
|
1465
1495
|
#startWebdriverioScreenshotUpload (span, onDone) {
|
|
1466
1496
|
if (
|
|
@@ -1547,7 +1577,6 @@ class MochaPlugin extends CiPlugin {
|
|
|
1547
1577
|
* @param {object} span - Failed test span
|
|
1548
1578
|
* @param {{callbacks: Array<() => void>, finished: boolean}} upload - Upload state
|
|
1549
1579
|
* @param {string} result - Aggregate screenshot upload result
|
|
1550
|
-
* @returns {void}
|
|
1551
1580
|
*/
|
|
1552
1581
|
#finishWebdriverioScreenshotUpload (span, upload, result) {
|
|
1553
1582
|
if (upload.finished) return
|
|
@@ -1577,7 +1606,6 @@ class MochaPlugin extends CiPlugin {
|
|
|
1577
1606
|
* @param {object} span - Failed test span
|
|
1578
1607
|
* @param {string|string[]} screenshots - Base64-encoded PNG data
|
|
1579
1608
|
* @param {(result: string) => void} onDone - Aggregate upload completion callback
|
|
1580
|
-
* @returns {void}
|
|
1581
1609
|
*/
|
|
1582
1610
|
#uploadWebdriverioScreenshots (span, screenshots, onDone) {
|
|
1583
1611
|
const screenshotList = Array.isArray(screenshots) ? screenshots : [screenshots]
|
|
@@ -1647,7 +1675,6 @@ class MochaPlugin extends CiPlugin {
|
|
|
1647
1675
|
* resolveCallback?: (onDone: () => void) => void,
|
|
1648
1676
|
* rejectCallback?: (onDone: () => void) => void
|
|
1649
1677
|
* }} context
|
|
1650
|
-
* @returns {void}
|
|
1651
1678
|
*/
|
|
1652
1679
|
#finishWebdriverioJasmineWorker (context) {
|
|
1653
1680
|
const state = this._webdriverioJasmineState
|
|
@@ -2,15 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
4
4
|
const OpenAiLLMObsPlugin = require('../../dd-trace/src/llmobs/plugins/openai')
|
|
5
|
+
const OpenAiRealtimeLLMObsPlugins = require('../../dd-trace/src/llmobs/plugins/openai/realtime')
|
|
6
|
+
const OpenAiRealtimeTracingPlugins = require('./realtime')
|
|
5
7
|
const OpenAiTracingPlugin = require('./tracing')
|
|
6
8
|
|
|
7
9
|
class OpenAiPlugin extends CompositePlugin {
|
|
8
10
|
static id = 'openai'
|
|
9
11
|
static get plugins () {
|
|
10
|
-
|
|
12
|
+
const plugins = {
|
|
11
13
|
llmobs: OpenAiLLMObsPlugin,
|
|
12
14
|
tracing: OpenAiTracingPlugin,
|
|
13
15
|
}
|
|
16
|
+
|
|
17
|
+
// LLM Obs plugins must be registered before their tracing counterparts so that annotations are
|
|
18
|
+
// added to the span before it finishes: subscribers run in registration order, and the realtime
|
|
19
|
+
// tracing plugins finish their span in `end`.
|
|
20
|
+
for (const Plugin of OpenAiRealtimeLLMObsPlugins) {
|
|
21
|
+
plugins[Plugin.id] = Plugin
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
for (const Plugin of OpenAiRealtimeTracingPlugins) {
|
|
25
|
+
plugins[Plugin.id] = Plugin
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return plugins
|
|
14
29
|
}
|
|
15
30
|
}
|
|
16
31
|
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { MEASURED } = require('../../../ext/tags')
|
|
4
|
+
const { ERROR_MESSAGE, ERROR_TYPE } = require('../../dd-trace/src/constants')
|
|
5
|
+
const { storage } = require('../../datadog-core')
|
|
6
|
+
const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* APM spans for the phases of one OpenAI Realtime turn.
|
|
10
|
+
*
|
|
11
|
+
* The turn is replayed as a back-dated tree once it is complete, so every span here is created with
|
|
12
|
+
* an explicit `startTime` and finished with an explicit `finishTime` rather than measuring wall
|
|
13
|
+
* clock. Nesting falls out of the synchronous scoping of the instrumentation's `traceSync` calls:
|
|
14
|
+
* the phase spans are created inside the turn root's callback, so `startSpan` picks the root up as
|
|
15
|
+
* their parent from the active store.
|
|
16
|
+
*/
|
|
17
|
+
class RealtimeTracingPlugin extends TracingPlugin {
|
|
18
|
+
// `component` defaults to the plugin id, which differs per phase here, so pin both explicitly to
|
|
19
|
+
// keep `component:openai` consistent with every other span the integration emits.
|
|
20
|
+
static component = 'openai'
|
|
21
|
+
static system = 'openai'
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Whether a failed response marks this span errored. True for the model's own work and for the
|
|
25
|
+
* turn as a whole; false for the speaking windows, which describe when audio moved rather than
|
|
26
|
+
* whether the model succeeded.
|
|
27
|
+
*/
|
|
28
|
+
static flagsFailure = true
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The APM resource name for this phase. Implemented by every subclass.
|
|
32
|
+
*
|
|
33
|
+
* @param {object} ctx
|
|
34
|
+
* @throws {Error} When a subclass has not implemented it.
|
|
35
|
+
*/
|
|
36
|
+
resource (ctx) {
|
|
37
|
+
throw new Error(`resource must be implemented by ${this.constructor.name}`)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {object} ctx
|
|
42
|
+
* @returns {object}
|
|
43
|
+
*/
|
|
44
|
+
bindStart (ctx) {
|
|
45
|
+
this.startSpan('openai.request', {
|
|
46
|
+
service: this.config.service,
|
|
47
|
+
resource: this.resource(ctx),
|
|
48
|
+
type: 'openai',
|
|
49
|
+
kind: 'client',
|
|
50
|
+
meta: {
|
|
51
|
+
[MEASURED]: 1,
|
|
52
|
+
'openai.request.model': ctx.turn.model,
|
|
53
|
+
},
|
|
54
|
+
startTime: ctx.startTime,
|
|
55
|
+
}, ctx)
|
|
56
|
+
|
|
57
|
+
return ctx.currentStore
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {object} ctx
|
|
62
|
+
*/
|
|
63
|
+
end (ctx) {
|
|
64
|
+
const span = ctx.currentStore?.span
|
|
65
|
+
if (span === undefined) return
|
|
66
|
+
|
|
67
|
+
if (ctx.turn.failed && this.constructor.flagsFailure) {
|
|
68
|
+
span.setTag('error', 1)
|
|
69
|
+
|
|
70
|
+
// The provider's own account of the failure, when `response.done` carried one. Without it the
|
|
71
|
+
// span says only that a realtime call broke. The LLM Observability error event reads these
|
|
72
|
+
// same tags, so setting them here serves both.
|
|
73
|
+
const { error } = ctx.turn
|
|
74
|
+
if (error !== undefined) {
|
|
75
|
+
if (error.type !== undefined) span.setTag(ERROR_TYPE, error.type)
|
|
76
|
+
const message = error.message ?? error.code
|
|
77
|
+
if (message !== undefined) span.setTag(ERROR_MESSAGE, message)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
span.finish(ctx.finishTime)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** The whole perceived turn, and the root of this turn's trace. */
|
|
85
|
+
class RealtimeTurnTracingPlugin extends RealtimeTracingPlugin {
|
|
86
|
+
static id = 'openai_realtime_turn'
|
|
87
|
+
static operation = 'turn'
|
|
88
|
+
static prefix = 'tracing:apm:openai:realtime:turn'
|
|
89
|
+
|
|
90
|
+
constructor (...args) {
|
|
91
|
+
super(...args)
|
|
92
|
+
|
|
93
|
+
// Captured at `response.created`, replayed at finalize: by then the active context belongs to
|
|
94
|
+
// the WebSocket message handler, not to the caller who opened the connection. The LLM
|
|
95
|
+
// Observability plugin composes its own store on top of whatever this sets.
|
|
96
|
+
this.addSub('dd-trace:openai:realtime:capture-context', turn => {
|
|
97
|
+
const store = storage('legacy').getStore()
|
|
98
|
+
const previous = turn.runInContext
|
|
99
|
+
turn.runInContext = previous === undefined
|
|
100
|
+
? fn => storage('legacy').run(store, fn)
|
|
101
|
+
: fn => previous(() => storage('legacy').run(store, fn))
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
resource () {
|
|
106
|
+
return 'createRealtimeTurn'
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** The model's generation work: opens at the end of user speech, closes at `response.done`. */
|
|
111
|
+
class RealtimeResponseTracingPlugin extends RealtimeTracingPlugin {
|
|
112
|
+
static id = 'openai_realtime_response'
|
|
113
|
+
static operation = 'response'
|
|
114
|
+
static prefix = 'tracing:apm:openai:realtime:response'
|
|
115
|
+
|
|
116
|
+
resource () {
|
|
117
|
+
return 'createRealtimeResponse'
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* A speaking window — the human's or the agent's. One plugin covers both: they differ only by
|
|
123
|
+
* resource and name, which is data, not a type.
|
|
124
|
+
*/
|
|
125
|
+
class RealtimeSpeechTracingPlugin extends RealtimeTracingPlugin {
|
|
126
|
+
static id = 'openai_realtime_speech'
|
|
127
|
+
static operation = 'speech'
|
|
128
|
+
static prefix = 'tracing:apm:openai:realtime:speech'
|
|
129
|
+
// A speaking window happened regardless of whether the model's response failed.
|
|
130
|
+
static flagsFailure = false
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @param {{ phase: { operation: string } }} ctx
|
|
134
|
+
*/
|
|
135
|
+
resource (ctx) {
|
|
136
|
+
return ctx.phase.operation
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = [
|
|
141
|
+
RealtimeTurnTracingPlugin,
|
|
142
|
+
RealtimeResponseTracingPlugin,
|
|
143
|
+
RealtimeSpeechTracingPlugin,
|
|
144
|
+
]
|
|
@@ -578,7 +578,6 @@ class OpenAIAgentsIntegration {
|
|
|
578
578
|
*
|
|
579
579
|
* @param {string | undefined | null} spanId agents-core spanId to start from
|
|
580
580
|
* @param {string} ancestorId agents-core ancestor spanId
|
|
581
|
-
* @returns {boolean}
|
|
582
581
|
*/
|
|
583
582
|
#hasUntracedPathToAncestor (spanId, ancestorId) {
|
|
584
583
|
let currentId = spanId
|
|
@@ -596,7 +595,6 @@ class OpenAIAgentsIntegration {
|
|
|
596
595
|
* mistaken for top-level, or an error would finalize the workflow span early.
|
|
597
596
|
*
|
|
598
597
|
* @param {object} oaiSpan
|
|
599
|
-
* @returns {boolean}
|
|
600
598
|
*/
|
|
601
599
|
#isTopLevelSpan (oaiSpan) {
|
|
602
600
|
let currentId = oaiSpan.parentId
|
|
@@ -681,7 +679,6 @@ class OpenAIAgentsIntegration {
|
|
|
681
679
|
* Read the mutable tracer configuration so remote/runtime enablement is
|
|
682
680
|
* reflected without reconstructing the plugin.
|
|
683
681
|
*
|
|
684
|
-
* @returns {boolean}
|
|
685
682
|
*/
|
|
686
683
|
#isLLMObsEnabled () {
|
|
687
684
|
return this.#llmobsEnabled && !!this.#config.llmobs?.DD_LLMOBS_ENABLED
|
|
@@ -690,7 +687,6 @@ class OpenAIAgentsIntegration {
|
|
|
690
687
|
/**
|
|
691
688
|
* Resolve model provider from the model invocation's async-local context.
|
|
692
689
|
*
|
|
693
|
-
* @returns {string}
|
|
694
690
|
*/
|
|
695
691
|
#getCurrentModelProvider () {
|
|
696
692
|
const baseURL = legacyStorage.getStore()?.[MODEL_BASE_URL_STORE_KEY]
|