dd-trace 6.16.0 → 6.17.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 +165 -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 +72 -12
- package/packages/datadog-instrumentations/src/cypress-config.js +0 -23
- package/packages/datadog-instrumentations/src/helpers/channel.js +0 -2
- package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +0 -5
- package/packages/datadog-instrumentations/src/helpers/hooks.js +8 -0
- 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 +4 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +72 -24
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +39 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +3 -17
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +12 -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/targets.json +16 -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 +141 -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 +22 -25
- 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 +3 -16
- package/packages/datadog-instrumentations/src/playwright.js +238 -55
- package/packages/datadog-instrumentations/src/postgres.js +7 -0
- 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/vitest-main-no-worker-init.js +18 -18
- package/packages/datadog-instrumentations/src/vitest-main.js +37 -17
- 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 +23 -42
- package/packages/datadog-instrumentations/src/ws.js +0 -1
- 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 +10 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +171 -75
- package/packages/datadog-plugin-cypress/src/finalization.js +0 -3
- 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 +13 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +0 -1
- package/packages/datadog-plugin-mocha/src/index.js +39 -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 +76 -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 +10 -0
- package/packages/datadog-plugin-ws/src/util.js +0 -4
- package/packages/datadog-turbopack/index.js +0 -6
- package/packages/datadog-turbopack/src/loader.js +0 -16
- package/packages/datadog-webpack/src/loader.js +0 -1
- 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 +73 -67
- package/packages/dd-trace/src/config/helper.js +0 -1
- package/packages/dd-trace/src/config/index.js +24 -24
- 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 +139 -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 +2 -0
- 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 +40 -14
- 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-pruner.js +0 -3
- package/packages/dd-trace/src/debugger/devtools_client/status.js +20 -6
- package/packages/dd-trace/src/debugger/guardrail-metrics.js +167 -0
- package/packages/dd-trace/src/debugger/index.js +50 -2
- 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/discovery.js +0 -1
- package/packages/dd-trace/src/evp_proxy/path.js +0 -2
- 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 +0 -2
- 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 +639 -0
- package/packages/dd-trace/src/llmobs/prompts/noop.js +29 -0
- package/packages/dd-trace/src/llmobs/prompts/prompt.js +92 -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 +30 -7
- 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/encoding.js +0 -2
- package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +0 -1
- package/packages/dd-trace/src/openfeature/index.js +0 -4
- 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 +0 -6
- package/packages/dd-trace/src/openfeature/writers/exposures.js +0 -5
- package/packages/dd-trace/src/openfeature/writers/util.js +0 -4
- 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/otel-thread-ctx.js +38 -11
- package/packages/dd-trace/src/payload-tagging/tagging.js +15 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +0 -1
- 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 +21 -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 +21 -45
- 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/telemetry.js +4 -1
- package/packages/dd-trace/src/util.js +13 -1
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
|
@@ -102,6 +102,7 @@ const TEST_STATUS = 'test.status'
|
|
|
102
102
|
const TEST_FINAL_STATUS = 'test.final_status'
|
|
103
103
|
const TEST_PARAMETERS = 'test.parameters'
|
|
104
104
|
const TEST_SKIP_REASON = 'test.skip_reason'
|
|
105
|
+
const TEST_SESSION_EMPTY_REASON = 'test.session.empty_reason'
|
|
105
106
|
const TEST_IS_RUM_ACTIVE = 'test.is_rum_active'
|
|
106
107
|
const TEST_CODE_OWNERS = 'test.codeowners'
|
|
107
108
|
const TEST_SOURCE_FILE = 'test.source.file'
|
|
@@ -445,7 +446,6 @@ function addTestOptimizationRequest (requestPromises, responseNames, responseNam
|
|
|
445
446
|
*
|
|
446
447
|
* @param {string} testSuite
|
|
447
448
|
* @param {string|undefined} testSuiteExecutionId
|
|
448
|
-
* @returns {string}
|
|
449
449
|
*/
|
|
450
450
|
function getTestSuiteExecutionKey (testSuite, testSuiteExecutionId) {
|
|
451
451
|
return testSuiteExecutionId ? `${testSuite}\0${testSuiteExecutionId}` : testSuite
|
|
@@ -471,9 +471,11 @@ module.exports = {
|
|
|
471
471
|
TEST_FINAL_STATUS,
|
|
472
472
|
TEST_PARAMETERS,
|
|
473
473
|
TEST_SKIP_REASON,
|
|
474
|
+
TEST_SESSION_EMPTY_REASON,
|
|
474
475
|
TEST_IS_RUM_ACTIVE,
|
|
475
476
|
setRumTestCorrelation,
|
|
476
477
|
setRumTestTags,
|
|
478
|
+
setExpectedEmptyTestSessionTags,
|
|
477
479
|
TEST_SOURCE_FILE,
|
|
478
480
|
TEST_FAILURE_SCREENSHOT_UPLOADED,
|
|
479
481
|
TEST_FAILURE_SCREENSHOT_UPLOAD_ERROR,
|
|
@@ -868,7 +870,6 @@ function finishAllTraceSpans (span) {
|
|
|
868
870
|
* @param {import('../../opentracing/span')} testSpan
|
|
869
871
|
* @param {boolean|undefined} isRumActive
|
|
870
872
|
* @param {string} [browserVersion]
|
|
871
|
-
* @returns {void}
|
|
872
873
|
*/
|
|
873
874
|
function setRumTestTags (testSpan, isRumActive, browserVersion) {
|
|
874
875
|
if (isRumActive) {
|
|
@@ -879,6 +880,24 @@ function setRumTestTags (testSpan, isRumActive, browserVersion) {
|
|
|
879
880
|
}
|
|
880
881
|
}
|
|
881
882
|
|
|
883
|
+
/**
|
|
884
|
+
* Marks a successful test session that intentionally executed no tests.
|
|
885
|
+
*
|
|
886
|
+
* @param {import('../../opentracing/span')} testSessionSpan
|
|
887
|
+
* @param {import('../../opentracing/span')|undefined} testModuleSpan
|
|
888
|
+
* @param {string} skipReason
|
|
889
|
+
* @param {string} emptyReason
|
|
890
|
+
*/
|
|
891
|
+
function setExpectedEmptyTestSessionTags (testSessionSpan, testModuleSpan, skipReason, emptyReason) {
|
|
892
|
+
for (const span of [testSessionSpan, testModuleSpan]) {
|
|
893
|
+
if (!span) continue
|
|
894
|
+
|
|
895
|
+
span.setTag(TEST_STATUS, 'skip')
|
|
896
|
+
span.setTag(TEST_SKIP_REASON, skipReason)
|
|
897
|
+
span.setTag(TEST_SESSION_EMPTY_REASON, emptyReason)
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
|
|
882
901
|
/**
|
|
883
902
|
* @param {RumTestCorrelationContext} context
|
|
884
903
|
* @param {import('../../opentracing/span')|undefined} activeSpan
|
|
@@ -942,7 +961,6 @@ function getTestCommonTags (name, suite, version, testFramework) {
|
|
|
942
961
|
*
|
|
943
962
|
* @param {string | undefined} testSuiteAbsolutePath
|
|
944
963
|
* @param {string} sourceRoot
|
|
945
|
-
* @returns {string}
|
|
946
964
|
*/
|
|
947
965
|
function getTestSuitePath (testSuiteAbsolutePath, sourceRoot) {
|
|
948
966
|
if (!testSuiteAbsolutePath) {
|
|
@@ -1069,7 +1087,6 @@ const codeOwnersPerEntries = new WeakMap()
|
|
|
1069
1087
|
|
|
1070
1088
|
/**
|
|
1071
1089
|
* @param {string} character
|
|
1072
|
-
* @returns {string}
|
|
1073
1090
|
*/
|
|
1074
1091
|
function escapeRegexCharacter (character) {
|
|
1075
1092
|
return character.replaceAll(/[|\\{}()[\]^$+*?.]/g, String.raw`\$&`)
|
|
@@ -1077,7 +1094,6 @@ function escapeRegexCharacter (character) {
|
|
|
1077
1094
|
|
|
1078
1095
|
/**
|
|
1079
1096
|
* @param {string} pattern
|
|
1080
|
-
* @returns {boolean}
|
|
1081
1097
|
*/
|
|
1082
1098
|
function hasUnescapedWildcard (pattern) {
|
|
1083
1099
|
for (let i = 0; i < pattern.length; i++) {
|
|
@@ -1093,7 +1109,6 @@ function hasUnescapedWildcard (pattern) {
|
|
|
1093
1109
|
|
|
1094
1110
|
/**
|
|
1095
1111
|
* @param {string} pattern
|
|
1096
|
-
* @returns {string}
|
|
1097
1112
|
*/
|
|
1098
1113
|
function codeOwnersPatternToRegexSource (pattern) {
|
|
1099
1114
|
let source = ''
|
|
@@ -1172,7 +1187,6 @@ function setCodeOwnersPatternRegex (entry) {
|
|
|
1172
1187
|
*
|
|
1173
1188
|
* @param {RegExp|null} regex
|
|
1174
1189
|
* @param {string} filename
|
|
1175
|
-
* @returns {boolean}
|
|
1176
1190
|
*/
|
|
1177
1191
|
function isCodeOwnersPatternMatch (regex, filename) {
|
|
1178
1192
|
if (!regex || !filename) {
|
|
@@ -1551,7 +1565,6 @@ function applySkippedCoverageToFileCoverage (fileCoverage, skippedBitmap) {
|
|
|
1551
1565
|
* @param {object} coverage
|
|
1552
1566
|
* @param {object} skippedCoverage
|
|
1553
1567
|
* @param {string} [rootDir]
|
|
1554
|
-
* @returns {boolean}
|
|
1555
1568
|
*/
|
|
1556
1569
|
function applySkippedCoverageToCoverage (coverage, skippedCoverage, rootDir) {
|
|
1557
1570
|
const skippedCoverageByFilename = getSkippedCoverageByFilename(skippedCoverage)
|
|
@@ -1616,7 +1629,6 @@ function fromCoverageMapToCoverage (coverageMap) {
|
|
|
1616
1629
|
|
|
1617
1630
|
/**
|
|
1618
1631
|
* @param {number} code
|
|
1619
|
-
* @returns {boolean}
|
|
1620
1632
|
*/
|
|
1621
1633
|
function isAsciiDigit (code) {
|
|
1622
1634
|
return code >= 0x30 && code <= 0x39
|
|
@@ -2042,7 +2054,6 @@ function getModifiedFilesFromDiff (diff) {
|
|
|
2042
2054
|
*
|
|
2043
2055
|
* @param {string | undefined} testSuite
|
|
2044
2056
|
* @param {string} testName
|
|
2045
|
-
* @returns {string}
|
|
2046
2057
|
*/
|
|
2047
2058
|
function getTestOptimizationIdentity (testSuite, testName) {
|
|
2048
2059
|
return JSON.stringify([testSuite, testName])
|
|
@@ -2053,7 +2064,6 @@ function getTestOptimizationIdentity (testSuite, testName) {
|
|
|
2053
2064
|
*
|
|
2054
2065
|
* @param {string | undefined} testSuite
|
|
2055
2066
|
* @param {string} testName
|
|
2056
|
-
* @returns {string}
|
|
2057
2067
|
*/
|
|
2058
2068
|
function formatTestOptimizationName (testSuite, testName) {
|
|
2059
2069
|
return testSuite ? `${testSuite} › ${testName}` : testName
|
|
@@ -2063,7 +2073,6 @@ function formatTestOptimizationName (testSuite, testName) {
|
|
|
2063
2073
|
* Replaces characters that could make one test occupy multiple CI log lines.
|
|
2064
2074
|
*
|
|
2065
2075
|
* @param {string} value
|
|
2066
|
-
* @returns {string}
|
|
2067
2076
|
*/
|
|
2068
2077
|
function sanitizeTestOptimizationName (value) {
|
|
2069
2078
|
return stripVTControlCharacters(value)
|
|
@@ -2077,7 +2086,6 @@ function sanitizeTestOptimizationName (value) {
|
|
|
2077
2086
|
*
|
|
2078
2087
|
* @param {string} value
|
|
2079
2088
|
* @param {number} maxLength
|
|
2080
|
-
* @returns {string}
|
|
2081
2089
|
*/
|
|
2082
2090
|
function truncateTestOptimizationNameStart (value, maxLength) {
|
|
2083
2091
|
if (value.length <= maxLength) return value
|
|
@@ -2093,7 +2101,6 @@ function truncateTestOptimizationNameStart (value, maxLength) {
|
|
|
2093
2101
|
*
|
|
2094
2102
|
* @param {string} value
|
|
2095
2103
|
* @param {number} maxLength
|
|
2096
|
-
* @returns {string}
|
|
2097
2104
|
*/
|
|
2098
2105
|
function truncateTestOptimizationNameMiddle (value, maxLength) {
|
|
2099
2106
|
if (value.length <= maxLength) return value
|
|
@@ -2112,7 +2119,6 @@ function truncateTestOptimizationNameMiddle (value, maxLength) {
|
|
|
2112
2119
|
*
|
|
2113
2120
|
* @param {string | undefined} testSuite
|
|
2114
2121
|
* @param {string} testName
|
|
2115
|
-
* @returns {string}
|
|
2116
2122
|
*/
|
|
2117
2123
|
function formatTestOptimizationDisplayName (testSuite, testName) {
|
|
2118
2124
|
const sanitizedSuite = testSuite ? sanitizeTestOptimizationName(testSuite) : ''
|
|
@@ -2136,7 +2142,6 @@ function formatTestOptimizationDisplayName (testSuite, testName) {
|
|
|
2136
2142
|
* Renders a bounded bullet list for Test Optimization summaries.
|
|
2137
2143
|
*
|
|
2138
2144
|
* @param {Array<{ text: string, suffix?: string }>} items
|
|
2139
|
-
* @returns {string}
|
|
2140
2145
|
*/
|
|
2141
2146
|
function formatTestOptimizationList (items) {
|
|
2142
2147
|
const shown = items.slice(0, MAX_TEST_OPTIMIZATION_SUMMARY_ITEMS)
|
|
@@ -2299,7 +2304,6 @@ function collectAttemptToFixExecutionFromTraceSpan (span, attemptToFixExecutions
|
|
|
2299
2304
|
*
|
|
2300
2305
|
* @param {{ meta?: Record<string, string> }} span
|
|
2301
2306
|
* @param {TestManagementExecutions} executions
|
|
2302
|
-
* @returns {void}
|
|
2303
2307
|
*/
|
|
2304
2308
|
function collectTestManagementExecutionFromTraceSpan (span, executions) {
|
|
2305
2309
|
const meta = span.meta
|
|
@@ -2405,7 +2409,6 @@ function addAttemptToFixResultLine (lines, result) {
|
|
|
2405
2409
|
*
|
|
2406
2410
|
* @param {AttemptToFixExecutions} attemptToFixExecutions
|
|
2407
2411
|
* @param {boolean} [includeTestNames]
|
|
2408
|
-
* @returns {string}
|
|
2409
2412
|
*/
|
|
2410
2413
|
function formatAttemptToFixSummary (attemptToFixExecutions, includeTestNames = true) {
|
|
2411
2414
|
if (attemptToFixExecutions.size === 0) return ''
|
|
@@ -2458,7 +2461,6 @@ function formatAttemptToFixSummary (attemptToFixExecutions, includeTestNames = t
|
|
|
2458
2461
|
*
|
|
2459
2462
|
* @param {TestManagementExecutions} executions
|
|
2460
2463
|
* @param {boolean} [includeTestNames]
|
|
2461
|
-
* @returns {string}
|
|
2462
2464
|
*/
|
|
2463
2465
|
function formatTestManagementSummary (executions, includeTestNames = true) {
|
|
2464
2466
|
if (executions.size === 0) return ''
|
|
@@ -2509,7 +2511,6 @@ function formatTestManagementSummary (executions, includeTestNames = true) {
|
|
|
2509
2511
|
* Formats the dynamic-name warning section of the Test Optimization summary.
|
|
2510
2512
|
*
|
|
2511
2513
|
* @param {Set<string>} newTestsWithDynamicNames
|
|
2512
|
-
* @returns {string}
|
|
2513
2514
|
*/
|
|
2514
2515
|
function formatDynamicNamesSummary (newTestsWithDynamicNames) {
|
|
2515
2516
|
if (newTestsWithDynamicNames.size === 0) return ''
|
|
@@ -19,7 +19,6 @@ const SPECIAL_CHARACTER_SEGMENT = /[%&'()*+,:=@]/
|
|
|
19
19
|
/**
|
|
20
20
|
* Extract full URL from HTTP request
|
|
21
21
|
* @param {import('http').IncomingMessage} req
|
|
22
|
-
* @returns {string} Full URL
|
|
23
22
|
*/
|
|
24
23
|
function extractURL (req) {
|
|
25
24
|
const headers = req.headers
|
|
@@ -42,7 +41,6 @@ function getProtocol (req) {
|
|
|
42
41
|
*
|
|
43
42
|
* @param {object} config
|
|
44
43
|
* @param {string} url
|
|
45
|
-
* @returns {string} obfuscated URL
|
|
46
44
|
*/
|
|
47
45
|
function obfuscateQs (config, url) {
|
|
48
46
|
const { queryStringObfuscation } = config
|
|
@@ -114,7 +112,6 @@ function getQsObfuscator (config) {
|
|
|
114
112
|
* @param {string} base `scheme://host[:port]`
|
|
115
113
|
* @param {string} [pathname] raw request path, may include `?query`
|
|
116
114
|
* @param {string} strippedUrl `base` + query-stripped path (used when there is no query)
|
|
117
|
-
* @returns {string}
|
|
118
115
|
*/
|
|
119
116
|
function buildClientHttpUrl (config, base, pathname, strippedUrl) {
|
|
120
117
|
if (pathname?.includes('?')) {
|
|
@@ -133,7 +130,6 @@ function buildClientHttpUrl (config, base, pathname, strippedUrl) {
|
|
|
133
130
|
* - Cross tracers compatibility
|
|
134
131
|
*
|
|
135
132
|
* @param {string} url
|
|
136
|
-
* @returns {string} Url path
|
|
137
133
|
*/
|
|
138
134
|
function extractPathFromUrl (url) {
|
|
139
135
|
if (!url) return '/'
|
|
@@ -146,7 +142,6 @@ function extractPathFromUrl (url) {
|
|
|
146
142
|
* Calculate http.endpoint from URL path
|
|
147
143
|
*
|
|
148
144
|
* @param {string} url
|
|
149
|
-
* @returns {string} The normalized endpoint
|
|
150
145
|
*/
|
|
151
146
|
function calculateHttpEndpoint (url) {
|
|
152
147
|
const path = extractPathFromUrl(url)
|
|
@@ -86,7 +86,6 @@ class PrioritySampler {
|
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
88
|
* @param {DatadogSpan} span
|
|
89
|
-
* @returns {boolean} True if the trace should be sampled based on priority.
|
|
90
89
|
*/
|
|
91
90
|
isSampled (span) {
|
|
92
91
|
const priority = this._getPriorityFromAuto(span)
|
|
@@ -99,7 +98,6 @@ class PrioritySampler {
|
|
|
99
98
|
*
|
|
100
99
|
* @param {DatadogSpan} span
|
|
101
100
|
* @param {boolean} [auto] - Whether to use automatic sampling if no manual tags are present.
|
|
102
|
-
* @returns {void}
|
|
103
101
|
*/
|
|
104
102
|
sample (span, auto = true) {
|
|
105
103
|
if (!span) return
|
|
@@ -131,7 +129,6 @@ class PrioritySampler {
|
|
|
131
129
|
* Updates agent-provided sampling rates keyed by `service:,env:`.
|
|
132
130
|
*
|
|
133
131
|
* @param {Record<string, number>} rates
|
|
134
|
-
* @returns {void}
|
|
135
132
|
*/
|
|
136
133
|
update (rates) {
|
|
137
134
|
const samplers = {}
|
|
@@ -151,7 +148,6 @@ class PrioritySampler {
|
|
|
151
148
|
* Validates that a sampling priority value is one of the allowed constants.
|
|
152
149
|
*
|
|
153
150
|
* @param {SamplingPriority|undefined} samplingPriority
|
|
154
|
-
* @returns {boolean}
|
|
155
151
|
*/
|
|
156
152
|
validate (samplingPriority) {
|
|
157
153
|
switch (samplingPriority) {
|
|
@@ -277,7 +273,6 @@ class PrioritySampler {
|
|
|
277
273
|
* records the effective rate on the trace.
|
|
278
274
|
*
|
|
279
275
|
* @param {DatadogSpanContext} context
|
|
280
|
-
* @returns {boolean}
|
|
281
276
|
*/
|
|
282
277
|
_isSampledByRateLimit (context) {
|
|
283
278
|
// TODO: Change underscored properties to private ones.
|
|
@@ -316,7 +311,6 @@ class PrioritySampler {
|
|
|
316
311
|
* Tags the trace with a decision maker when priority is keep, or removes it otherwise.
|
|
317
312
|
*
|
|
318
313
|
* @param {DatadogSpan} span
|
|
319
|
-
* @returns {void}
|
|
320
314
|
*/
|
|
321
315
|
#addDecisionMaker (span) {
|
|
322
316
|
const context = span.context()
|
|
@@ -1,42 +1,139 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const dc = require('dc-polyfill')
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const log = require('./log')
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
const configUpdateChannel = dc.channel('datadog:config:update')
|
|
8
|
+
|
|
9
|
+
/** @type {import('./profiling/ssi-heuristics').SSIHeuristics | undefined} */
|
|
10
|
+
let activeSSIHeuristics
|
|
11
|
+
|
|
12
|
+
/** @type {import('./profiling') | undefined} */
|
|
13
|
+
let profilingModule
|
|
14
|
+
|
|
15
|
+
function getProfilingModule () {
|
|
16
|
+
profilingModule ??= require('./profiling')
|
|
17
|
+
return profilingModule
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// The profiling engine can stop itself (e.g. a collection error) without going through stop(), so
|
|
21
|
+
// read its state directly rather than caching a flag that could drift out of sync. Checking
|
|
22
|
+
// `profilingModule` first avoids forcing the profiling engine (and its native crashtracker binding)
|
|
23
|
+
// to load just to read this.
|
|
24
|
+
function isStarted () {
|
|
25
|
+
return profilingModule !== undefined && profilingModule.profiler.enabled
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** @type {typeof import('./profiling/ssi-heuristics') | undefined} */
|
|
29
|
+
let ssiHeuristicsModule
|
|
30
|
+
|
|
31
|
+
function getSSIHeuristicsModule () {
|
|
32
|
+
ssiHeuristicsModule ??= require('./profiling/ssi-heuristics')
|
|
33
|
+
return ssiHeuristicsModule
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function disableSSIHeuristics () {
|
|
37
|
+
if (!activeSSIHeuristics) return
|
|
38
|
+
activeSSIHeuristics.disable()
|
|
39
|
+
activeSSIHeuristics = undefined
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {import('./config/config-base')} config - Tracer configuration
|
|
44
|
+
*/
|
|
45
|
+
function start (config) {
|
|
46
|
+
try {
|
|
12
47
|
// Forward the full tracer config to the profiling layer.
|
|
13
48
|
// Profiling code is responsible for deriving the specific options it needs.
|
|
14
|
-
return profiler.start(config)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
return getProfilingModule().profiler.start(config)
|
|
50
|
+
} catch (error) {
|
|
51
|
+
log.error(
|
|
52
|
+
'Error starting profiler. For troubleshooting tips, see <https://dtdg.co/nodejs-profiler-troubleshooting>',
|
|
53
|
+
error
|
|
54
|
+
)
|
|
55
|
+
return false
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function stop () {
|
|
60
|
+
// A stop command for a profiler that has never been loaded is already satisfied. Once loaded,
|
|
61
|
+
// always forward it so the profiling layer can also cancel a restart queued during shutdown.
|
|
62
|
+
if (profilingModule === undefined) return
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
profilingModule.profiler.stop()
|
|
66
|
+
} catch (error) {
|
|
67
|
+
log.error(
|
|
68
|
+
'Error stopping profiler. For troubleshooting tips, see <https://dtdg.co/nodejs-profiler-troubleshooting>',
|
|
69
|
+
error
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Declares the set of custom label keys that will be used with
|
|
76
|
+
* `runWithLabels`.
|
|
77
|
+
*
|
|
78
|
+
* @param {Iterable<string>} keys - Custom label key names
|
|
79
|
+
*/
|
|
80
|
+
function setCustomLabelKeys (keys) {
|
|
81
|
+
getProfilingModule().profiler.setCustomLabelKeys(keys)
|
|
42
82
|
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Runs a function with custom profiling labels attached to wall profiler samples.
|
|
86
|
+
*
|
|
87
|
+
* @param {Record<string, string | number>} labels - Custom labels to attach
|
|
88
|
+
* @param {function(): T} fn - Function to execute with the labels
|
|
89
|
+
* @returns {T} The return value of fn
|
|
90
|
+
* @template T
|
|
91
|
+
*/
|
|
92
|
+
function runWithLabels (labels, fn) {
|
|
93
|
+
return getProfilingModule().profiler.runWithLabels(labels, fn)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
configUpdateChannel.subscribe((config) => {
|
|
97
|
+
const enabled = config.profiling.DD_PROFILING_ENABLED
|
|
98
|
+
if (enabled === 'true') {
|
|
99
|
+
// A non-auto value means the SSI heuristics no longer get a say; disable them so a trigger that
|
|
100
|
+
// fires after this publish can't start the profiler behind this decision's back.
|
|
101
|
+
disableSSIHeuristics()
|
|
102
|
+
// Leave an already-running profiler alone; otherwise an unrelated remote-config publish
|
|
103
|
+
// (e.g. an unrelated sampling-rate change) would restart it on every update.
|
|
104
|
+
if (!isStarted()) start(config)
|
|
105
|
+
} else if (enabled === 'false') {
|
|
106
|
+
disableSSIHeuristics()
|
|
107
|
+
stop()
|
|
108
|
+
} else if (enabled === 'auto') {
|
|
109
|
+
if (!isStarted() && !activeSSIHeuristics) {
|
|
110
|
+
// 'auto' defers the start decision to SSI heuristics. A running profiler already reflects a
|
|
111
|
+
// decision that was made (by SSI or a prior unconditional enablement), so leave it alone
|
|
112
|
+
// rather than stopping and re-enabling it on every subsequent config publication. Also guard
|
|
113
|
+
// against creating another active instance; each SSIHeuristics instance owns listeners and a
|
|
114
|
+
// timer until the heuristic makes its decision or is explicitly disabled.
|
|
115
|
+
const { SSIHeuristics } = getSSIHeuristicsModule()
|
|
116
|
+
const heuristics = new SSIHeuristics(config)
|
|
117
|
+
activeSSIHeuristics = heuristics
|
|
118
|
+
heuristics.start()
|
|
119
|
+
heuristics.onTriggered(() => {
|
|
120
|
+
// Explicit true/false publishes disable the heuristics, so reaching this callback guarantees
|
|
121
|
+
// the latest valid published value is still 'auto'.
|
|
122
|
+
if (!isStarted()) start(config)
|
|
123
|
+
// The heuristic has made its decision, so release all of its listeners and timer before
|
|
124
|
+
// dropping the module-level reference. This does not stop the profiler that was just
|
|
125
|
+
// started; it only tears down the completed heuristic.
|
|
126
|
+
heuristics.disable()
|
|
127
|
+
if (activeSSIHeuristics === heuristics) activeSSIHeuristics = undefined
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
// Invalid config should preserve the last valid profiling decision, not accidentally behave
|
|
132
|
+
// like 'auto' or crash the customer application.
|
|
133
|
+
log.warn('Unexpected DD_PROFILING_ENABLED value: %o', enabled)
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
globalThis[Symbol.for('dd-trace')].beforeExitHandlers.add(stop)
|
|
138
|
+
|
|
139
|
+
module.exports = { isStarted, start, stop, setCustomLabelKeys, runWithLabels }
|
|
@@ -15,7 +15,6 @@ const processTags = require('../../process-tags')
|
|
|
15
15
|
* profile event.
|
|
16
16
|
*
|
|
17
17
|
* @param {string} [enabled] - config.profiling.DD_PROFILING_ENABLED ('true' | 'false' | 'auto')
|
|
18
|
-
* @returns {string}
|
|
19
18
|
*/
|
|
20
19
|
function getActivation (enabled) {
|
|
21
20
|
if (enabled === 'auto') return 'auto'
|
|
@@ -61,9 +61,12 @@ class Profiler extends EventEmitter {
|
|
|
61
61
|
#exporters
|
|
62
62
|
#flushInterval
|
|
63
63
|
#lastStart
|
|
64
|
+
#pendingStart
|
|
64
65
|
#profileSeq = 0
|
|
65
66
|
#profilers
|
|
66
67
|
#spanFinishListener
|
|
68
|
+
#startFailed = false
|
|
69
|
+
#stopping
|
|
67
70
|
#systemInfoReport
|
|
68
71
|
#currentSnapshotTags
|
|
69
72
|
#timer
|
|
@@ -175,48 +178,72 @@ class Profiler extends EventEmitter {
|
|
|
175
178
|
*/
|
|
176
179
|
start (config) {
|
|
177
180
|
if (this.enabled) return true
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
this
|
|
185
|
-
|
|
186
|
-
this
|
|
187
|
-
this.#
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
this.#applyCustomLabelKeys()
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
this._setInterval()
|
|
194
|
-
// Log errors if the source map finder fails, but don't prevent the rest
|
|
195
|
-
// of the profiler from running without source maps.
|
|
196
|
-
let mapper
|
|
197
|
-
const { setLogger, SourceMapper } = require('@datadog/pprof')
|
|
198
|
-
setLogger(pprofLogger)
|
|
199
|
-
|
|
200
|
-
if (config.DD_PROFILING_SOURCE_MAP) {
|
|
201
|
-
mapper = new SourceMapper(config.DD_PROFILING_DEBUG_SOURCE_MAPS)
|
|
202
|
-
mapper.loadDirectory(process.cwd())
|
|
203
|
-
.then(() => {
|
|
204
|
-
if (config.DD_PROFILING_DEBUG_SOURCE_MAPS) {
|
|
205
|
-
const count = mapper.infoMap.size
|
|
206
|
-
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
207
|
-
log.debug(() => {
|
|
208
|
-
return count === 0
|
|
209
|
-
? 'Found no source maps'
|
|
210
|
-
: `Found source maps for following files: [${[...mapper.infoMap.keys()].join(', ')}]`
|
|
211
|
-
})
|
|
212
|
-
}
|
|
213
|
-
})
|
|
214
|
-
.catch((error) => {
|
|
215
|
-
log.error(error)
|
|
216
|
-
})
|
|
181
|
+
// Initialization failures such as an unavailable native pprof binding are not expected to
|
|
182
|
+
// recover within the lifetime of this process. Preserve that decision without pretending the
|
|
183
|
+
// profiler is running or retrying setup on every subsequent config publication.
|
|
184
|
+
if (this.#startFailed) return false
|
|
185
|
+
|
|
186
|
+
// A prior stop()'s shutdown collection may still be encoding/exporting via #tags,
|
|
187
|
+
// #exporters and #endpointCounts. Wait for it to finish before this start() overwrites
|
|
188
|
+
// that shared state out from under it. Record the desired config rather than chaining
|
|
189
|
+
// straight onto #stopping, so a stop() arriving before it settles can cancel this restart.
|
|
190
|
+
if (this.#stopping) {
|
|
191
|
+
this.#pendingStart = config
|
|
192
|
+
return true
|
|
217
193
|
}
|
|
218
194
|
|
|
219
195
|
try {
|
|
196
|
+
const { tags: snapshotTags, exporters, flushInterval, profilers, uploadCompression, systemInfoReport } =
|
|
197
|
+
buildProfilingRuntime(config)
|
|
198
|
+
this.#config = config
|
|
199
|
+
this.#exporters = exporters
|
|
200
|
+
this.#flushInterval = flushInterval
|
|
201
|
+
this.#profilers = profilers
|
|
202
|
+
this.#currentSnapshotTags = snapshotTags
|
|
203
|
+
// A restart is installed only after the prior shutdown collection settles, so any endpoint
|
|
204
|
+
// counts left behind by a collection that produced no encodable profiles belong to the old run.
|
|
205
|
+
this.#endpointCounts.clear()
|
|
206
|
+
// Compression is initialized lazily and cached for a profiling run. A restarted profiler
|
|
207
|
+
// must derive it again from the newly built runtime instead of retaining the prior method
|
|
208
|
+
// or options.
|
|
209
|
+
this.#compressionFn = undefined
|
|
210
|
+
this.#compressionFnInitialized = false
|
|
211
|
+
this.#compressionOptions = undefined
|
|
212
|
+
this.#uploadCompression = uploadCompression
|
|
213
|
+
this.#systemInfoReport = systemInfoReport
|
|
214
|
+
if (this.#customLabelKeys.size > 0) {
|
|
215
|
+
this.#applyCustomLabelKeys()
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
this._setInterval()
|
|
219
|
+
// Log errors if the source map finder fails, but don't prevent the rest
|
|
220
|
+
// of the profiler from running without source maps.
|
|
221
|
+
let mapper
|
|
222
|
+
const { setLogger, SourceMapper } = require('@datadog/pprof')
|
|
223
|
+
setLogger(pprofLogger)
|
|
224
|
+
|
|
225
|
+
if (config.DD_PROFILING_SOURCE_MAP) {
|
|
226
|
+
mapper = new SourceMapper(config.DD_PROFILING_DEBUG_SOURCE_MAPS)
|
|
227
|
+
mapper.loadDirectory(process.cwd())
|
|
228
|
+
.then(() => {
|
|
229
|
+
if (config.DD_PROFILING_DEBUG_SOURCE_MAPS) {
|
|
230
|
+
const count = mapper.infoMap.size
|
|
231
|
+
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
232
|
+
log.debug(() => {
|
|
233
|
+
return count === 0
|
|
234
|
+
? 'Found no source maps'
|
|
235
|
+
: `Found source maps for following files: [${[...mapper.infoMap.keys()].join(', ')}]`
|
|
236
|
+
})
|
|
237
|
+
}
|
|
238
|
+
})
|
|
239
|
+
.catch((error) => {
|
|
240
|
+
log.error(error)
|
|
241
|
+
})
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Setup above does not start any sampler runtime resources. From this point onward, #stop()
|
|
245
|
+
// can safely clean up a partial start because #profilers and the rest of the runtime exist.
|
|
246
|
+
this.#enabled = true
|
|
220
247
|
const start = new Date()
|
|
221
248
|
const nearOOMCallback = this.#nearOOMExport.bind(this)
|
|
222
249
|
for (const profiler of profilers) {
|
|
@@ -236,7 +263,17 @@ class Profiler extends EventEmitter {
|
|
|
236
263
|
this._capture(this._timeoutInterval, start)
|
|
237
264
|
} catch (error) {
|
|
238
265
|
log.error(error)
|
|
239
|
-
this.#
|
|
266
|
+
this.#startFailed = true
|
|
267
|
+
if (this.enabled) {
|
|
268
|
+
try {
|
|
269
|
+
this.#stop()
|
|
270
|
+
} catch (stopError) {
|
|
271
|
+
// A cleanup failure must not leave the public running state stuck at true or escape into
|
|
272
|
+
// the customer application.
|
|
273
|
+
this.#enabled = false
|
|
274
|
+
log.error(stopError)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
240
277
|
return false
|
|
241
278
|
}
|
|
242
279
|
|
|
@@ -258,11 +295,34 @@ class Profiler extends EventEmitter {
|
|
|
258
295
|
}
|
|
259
296
|
|
|
260
297
|
stop () {
|
|
298
|
+
// A stop() always reflects the latest desired state, so it cancels any restart queued by a
|
|
299
|
+
// start() that arrived while a prior shutdown collection was still in flight.
|
|
300
|
+
this.#pendingStart = undefined
|
|
301
|
+
|
|
261
302
|
if (!this.enabled) return
|
|
262
303
|
|
|
263
304
|
// collect and export current profiles
|
|
264
305
|
// once collect returns, profilers can be safely stopped
|
|
265
|
-
this._collect(snapshotKinds.ON_SHUTDOWN, false)
|
|
306
|
+
this.#stopping = this._collect(snapshotKinds.ON_SHUTDOWN, false)
|
|
307
|
+
.catch(error => {
|
|
308
|
+
// _collect() contains its own failures, but its cleanup can still throw. Nothing awaits
|
|
309
|
+
// this shutdown chain, so consume and log that failure instead of leaking a rejection.
|
|
310
|
+
log.error(error)
|
|
311
|
+
})
|
|
312
|
+
.finally(() => {
|
|
313
|
+
this.#stopping = undefined
|
|
314
|
+
if (this.#pendingStart) {
|
|
315
|
+
const config = this.#pendingStart
|
|
316
|
+
this.#pendingStart = undefined
|
|
317
|
+
// Unlike the synchronous entry point, nothing awaits this promise, so a throw here would
|
|
318
|
+
// become an unhandled rejection instead of a caught error.
|
|
319
|
+
try {
|
|
320
|
+
this.start(config)
|
|
321
|
+
} catch (error) {
|
|
322
|
+
log.error(error)
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
})
|
|
266
326
|
this.#stop()
|
|
267
327
|
}
|
|
268
328
|
|