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
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { INCOMPLETE_REASON } = require('../../guardrail-metrics')
|
|
3
4
|
const session = require('../session')
|
|
4
5
|
const { collectObjectProperties } = require('./collector')
|
|
5
6
|
const { processRawState, processRemoteObject } = require('./processor')
|
|
7
|
+
const { fieldCountSym } = require('./symbols')
|
|
6
8
|
|
|
7
9
|
const BIGINT_MAX = (1n << 256n) - 1n
|
|
8
10
|
|
|
@@ -26,8 +28,13 @@ module.exports = {
|
|
|
26
28
|
* @param {CaptureLimits} limits - The capture limits
|
|
27
29
|
* @param {bigint} [deadlineNs] - The deadline in nanoseconds compared to `process.hrtime.bigint()`. Defaults to
|
|
28
30
|
* {@link BIGINT_MAX}. If the deadline is reached, the snapshot will be truncated.
|
|
29
|
-
* @returns {Promise<{
|
|
30
|
-
*
|
|
31
|
+
* @returns {Promise<{
|
|
32
|
+
* processLocalState: () => ReturnType<typeof processRawState>,
|
|
33
|
+
* fatalErrors: Error[],
|
|
34
|
+
* incomplete: import('./processor').IncompleteCapture
|
|
35
|
+
* }>} The local state for the call frame. `incomplete` is only fully populated once `processLocalState` has run.
|
|
36
|
+
* Not every fatal error is recorded as a runtime error: the collector also raises one when it hits its large object
|
|
37
|
+
* safety threshold, which is reported as the field count limit it is.
|
|
31
38
|
*/
|
|
32
39
|
async function getLocalStateForCallFrame (callFrame, limits, deadlineNs = BIGINT_MAX) {
|
|
33
40
|
const { maxReferenceDepth, maxCollectionSize, maxFieldCount, maxLength } = limits
|
|
@@ -35,39 +42,63 @@ async function getLocalStateForCallFrame (callFrame, limits, deadlineNs = BIGINT
|
|
|
35
42
|
const ctx = { deadlineReached: false, fatalErrors: [] }
|
|
36
43
|
const opts = { maxReferenceDepth, maxCollectionSize, maxFieldCount, deadlineNs, ctx }
|
|
37
44
|
const rawState = []
|
|
45
|
+
/** @type {import('./processor').IncompleteCapture} */
|
|
46
|
+
const incomplete = { reasons: 0 }
|
|
38
47
|
/** @type {ReturnType<typeof processRawState> | null} */
|
|
39
48
|
let processedState = null
|
|
40
49
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
const { scopeChain } = callFrame
|
|
51
|
+
for (const scope of scopeChain) {
|
|
52
|
+
if (!isCollectable(scope)) continue
|
|
53
|
+
const objectId = /** @type {string} */ (scope.object.objectId)
|
|
45
54
|
try {
|
|
46
55
|
// The objectId for a scope points to a pseudo-object whose properties are the actual variables in the scope.
|
|
47
56
|
// This is why we can just call `collectObjectProperties` directly and expect it to return the in-scope variables
|
|
48
57
|
// as an array.
|
|
49
58
|
// eslint-disable-next-line no-await-in-loop
|
|
50
|
-
|
|
59
|
+
const variables = await collectObjectProperties(objectId, opts)
|
|
60
|
+
// A scope with more variables than the field count limit is trimmed like any other object, but since the scope
|
|
61
|
+
// itself is not part of the snapshot, the marker would be lost once its variables are spread into the state
|
|
62
|
+
if (variables[fieldCountSym] !== undefined) incomplete.reasons |= INCOMPLETE_REASON.FIELD_COUNT
|
|
63
|
+
rawState.push(...variables)
|
|
51
64
|
} catch (err) {
|
|
65
|
+
incomplete.reasons |= INCOMPLETE_REASON.RUNTIME_ERROR
|
|
52
66
|
ctx.fatalErrors.push(new Error(
|
|
53
67
|
`Error getting local state for closure scope (type: ${scope.type}). ` +
|
|
54
68
|
'Future snapshots for existing probes in this location will be skipped until the probes are re-applied',
|
|
55
69
|
{ cause: err } // TODO: The cause is not used by the backend
|
|
56
70
|
))
|
|
57
71
|
}
|
|
58
|
-
if (ctx.deadlineReached === true)
|
|
72
|
+
if (ctx.deadlineReached === true) {
|
|
73
|
+
// Nodes skipped within this scope carry the timeout marker and are recorded when processed (unless they end up
|
|
74
|
+
// redacted), but the remaining scopes are dropped without any marker.
|
|
75
|
+
// TODO: Bad UX; Variables in remaining scopes are silently dropped
|
|
76
|
+
// @ts-expect-error - findLast is available in Node.js 18+ but TypeScript doesn't know about it without ES2023 lib
|
|
77
|
+
if (scope !== scopeChain.findLast(isCollectable)) incomplete.reasons |= INCOMPLETE_REASON.TIMEOUT
|
|
78
|
+
break
|
|
79
|
+
}
|
|
59
80
|
}
|
|
60
81
|
|
|
61
82
|
// Delay calling `processRawState` so caller can resume the main thread before processing `rawState`
|
|
62
83
|
return {
|
|
63
84
|
processLocalState () {
|
|
64
|
-
processedState ??= processRawState(rawState, maxLength)
|
|
85
|
+
processedState ??= processRawState(rawState, maxLength, incomplete)
|
|
65
86
|
return processedState
|
|
66
87
|
},
|
|
67
88
|
fatalErrors: ctx.fatalErrors,
|
|
89
|
+
incomplete,
|
|
68
90
|
}
|
|
69
91
|
}
|
|
70
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Returns whether the scope variables are collected into the snapshot.
|
|
95
|
+
* @param {import('inspector').Debugger.Scope} scope
|
|
96
|
+
*/
|
|
97
|
+
function isCollectable (scope) {
|
|
98
|
+
// The global scope is too noisy, and a scope without an object id is possible according to the types
|
|
99
|
+
return scope.type !== 'global' && scope.object.objectId !== undefined
|
|
100
|
+
}
|
|
101
|
+
|
|
71
102
|
/**
|
|
72
103
|
* @typedef {object} CompiledCaptureExpression
|
|
73
104
|
* @property {string} name - The name of the expression (used as key in snapshot)
|
|
@@ -82,6 +113,9 @@ async function getLocalStateForCallFrame (callFrame, limits, deadlineNs = BIGINT
|
|
|
82
113
|
* @property {{ expr: string, message: string }[]} evaluationErrors - Transient errors from expression evaluation
|
|
83
114
|
* (safe to retry)
|
|
84
115
|
* @property {Error[]} fatalErrors - Fatal errors that should disable capture expressions for this probe permanently
|
|
116
|
+
* @property {import('./processor').IncompleteCapture} incomplete - The capture limits enforced on the expressions,
|
|
117
|
+
* including a runtime error for every expression that threw or could not be evaluated. Only fully populated once
|
|
118
|
+
* `processCaptureExpressions` has run.
|
|
85
119
|
*/
|
|
86
120
|
|
|
87
121
|
/**
|
|
@@ -108,6 +142,8 @@ async function evaluateCaptureExpressions (callFrame, expressions, deadlineNs =
|
|
|
108
142
|
const evaluationErrors = []
|
|
109
143
|
/** @type {Error[]} */
|
|
110
144
|
const fatalErrors = []
|
|
145
|
+
/** @type {import('./processor').IncompleteCapture} */
|
|
146
|
+
const incomplete = { reasons: 0 }
|
|
111
147
|
/** @type {Record<string, ReturnType<typeof processRemoteObject>> | null} */
|
|
112
148
|
let processedResult = null
|
|
113
149
|
|
|
@@ -126,6 +162,7 @@ async function evaluateCaptureExpressions (callFrame, expressions, deadlineNs =
|
|
|
126
162
|
|
|
127
163
|
// Handle evaluation exceptions (maybe transient - bad expression, undefined var, etc.)
|
|
128
164
|
if (exceptionDetails) {
|
|
165
|
+
incomplete.reasons |= INCOMPLETE_REASON.RUNTIME_ERROR
|
|
129
166
|
evaluationErrors.push({ expr: name, message: extractErrorMessage(exceptionDetails) })
|
|
130
167
|
continue
|
|
131
168
|
}
|
|
@@ -156,9 +193,11 @@ async function evaluateCaptureExpressions (callFrame, expressions, deadlineNs =
|
|
|
156
193
|
}
|
|
157
194
|
|
|
158
195
|
if (ctx.deadlineReached) {
|
|
159
|
-
// Add the current expression (properties may be incomplete due to timeout)
|
|
196
|
+
// Add the current expression (properties may be incomplete due to timeout). Those carry the timeout marker
|
|
197
|
+
// and are recorded when processed, unless they end up redacted.
|
|
160
198
|
rawResults.push({ name, remoteObject: result, maxLength })
|
|
161
|
-
// Add stub entries for remaining uncaptured expressions
|
|
199
|
+
// Add stub entries for remaining uncaptured expressions. The stubs are used as-is, so record them here.
|
|
200
|
+
if (i + 1 < expressions.length) incomplete.reasons |= INCOMPLETE_REASON.TIMEOUT
|
|
162
201
|
for (let j = i + 1; j < expressions.length; j++) {
|
|
163
202
|
rawResults.push({
|
|
164
203
|
name: expressions[j].name,
|
|
@@ -172,6 +211,7 @@ async function evaluateCaptureExpressions (callFrame, expressions, deadlineNs =
|
|
|
172
211
|
|
|
173
212
|
rawResults.push({ name, remoteObject: result, maxLength })
|
|
174
213
|
} catch (err) {
|
|
214
|
+
incomplete.reasons |= INCOMPLETE_REASON.RUNTIME_ERROR
|
|
175
215
|
fatalErrors.push(new Error(
|
|
176
216
|
`Error capturing expression "${name}". ` +
|
|
177
217
|
'Capture expressions for this probe will be skipped until the probe is re-applied',
|
|
@@ -189,7 +229,7 @@ async function evaluateCaptureExpressions (callFrame, expressions, deadlineNs =
|
|
|
189
229
|
for (const { name, remoteObject, maxLength } of rawResults) {
|
|
190
230
|
// If the remote object has notCapturedReason (e.g., timeout), use it as-is without processing
|
|
191
231
|
processedResult[name] = remoteObject.notCapturedReason === undefined
|
|
192
|
-
? processRemoteObject(remoteObject, maxLength)
|
|
232
|
+
? processRemoteObject(remoteObject, maxLength, incomplete)
|
|
193
233
|
: remoteObject
|
|
194
234
|
}
|
|
195
235
|
|
|
@@ -197,6 +237,7 @@ async function evaluateCaptureExpressions (callFrame, expressions, deadlineNs =
|
|
|
197
237
|
},
|
|
198
238
|
evaluationErrors,
|
|
199
239
|
fatalErrors,
|
|
240
|
+
incomplete,
|
|
200
241
|
}
|
|
201
242
|
}
|
|
202
243
|
|
|
@@ -204,7 +245,6 @@ async function evaluateCaptureExpressions (callFrame, expressions, deadlineNs =
|
|
|
204
245
|
* Extract the error message from the exception details.
|
|
205
246
|
*
|
|
206
247
|
* @param {import('inspector').Runtime.ExceptionDetails} exceptionDetails - The exception details
|
|
207
|
-
* @returns {string} The error message
|
|
208
248
|
*/
|
|
209
249
|
function extractErrorMessage (exceptionDetails) {
|
|
210
250
|
const description = exceptionDetails.exception?.description
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { INCOMPLETE_REASON } = require('../../guardrail-metrics')
|
|
3
4
|
const { LARGE_OBJECT_SKIP_THRESHOLD } = require('./constants')
|
|
4
5
|
const { collectionSizeSym, largeCollectionSkipThresholdSym, fieldCountSym, timeBudgetSym } = require('./symbols')
|
|
5
6
|
const { normalizeName, REDACTED_IDENTIFIERS } = require('./redaction')
|
|
@@ -15,15 +16,24 @@ module.exports = {
|
|
|
15
16
|
* @typedef {import('inspector').Runtime.RemoteObject & { properties?: object[] }} RemoteObjectWithProperties
|
|
16
17
|
*/
|
|
17
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Accumulates which capture limits were enforced while processing a single event, so they can be reported once per
|
|
21
|
+
* event instead of once per affected node.
|
|
22
|
+
*
|
|
23
|
+
* @typedef {object} IncompleteCapture
|
|
24
|
+
* @property {number} reasons - Bitmask of {@link INCOMPLETE_REASON} flags
|
|
25
|
+
*/
|
|
26
|
+
|
|
18
27
|
/**
|
|
19
28
|
* Process a RemoteObject into the snapshot format.
|
|
20
29
|
*
|
|
21
30
|
* @param {RemoteObjectWithProperties} remoteObject
|
|
22
31
|
* @param {number} maxLength - Maximum string length
|
|
32
|
+
* @param {IncompleteCapture} incomplete - Receives the capture limits enforced on the object
|
|
23
33
|
* @returns {object} The processed value in snapshot format
|
|
24
34
|
*/
|
|
25
|
-
function processRemoteObject (remoteObject, maxLength) {
|
|
26
|
-
return getPropertyValueRaw({ value: remoteObject }, maxLength)
|
|
35
|
+
function processRemoteObject (remoteObject, maxLength, incomplete) {
|
|
36
|
+
return getPropertyValueRaw({ value: remoteObject }, maxLength, incomplete)
|
|
27
37
|
}
|
|
28
38
|
|
|
29
39
|
// Matches classes in source code, no matter how it's written:
|
|
@@ -33,7 +43,15 @@ function processRemoteObject (remoteObject, maxLength) {
|
|
|
33
43
|
// - Anonymous, with odd whitespace: class\n{}
|
|
34
44
|
const CLASS_REGEX = /^class\s([^{]*)/
|
|
35
45
|
|
|
36
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Process the collected properties of an object into the snapshot format.
|
|
48
|
+
*
|
|
49
|
+
* @param {object[]} props - The collected property descriptors
|
|
50
|
+
* @param {number} maxLength - Maximum string length
|
|
51
|
+
* @param {IncompleteCapture} incomplete - Receives the capture limits enforced on the properties
|
|
52
|
+
* @returns {Record<string, object>} The processed properties in snapshot format
|
|
53
|
+
*/
|
|
54
|
+
function processProperties (props, maxLength, incomplete) {
|
|
37
55
|
const result = {}
|
|
38
56
|
|
|
39
57
|
for (const prop of props) {
|
|
@@ -42,20 +60,26 @@ function processProperties (props, maxLength) {
|
|
|
42
60
|
if (name.includes('.')) {
|
|
43
61
|
name = name.replaceAll('.', '_')
|
|
44
62
|
}
|
|
45
|
-
result[name] = getPropertyValue(prop, maxLength)
|
|
63
|
+
result[name] = getPropertyValue(prop, maxLength, incomplete)
|
|
46
64
|
}
|
|
47
65
|
|
|
48
66
|
return result
|
|
49
67
|
}
|
|
50
68
|
|
|
69
|
+
// Capture limits enforced while processing a value that ends up redacted never make it into the snapshot, so they are
|
|
70
|
+
// not recorded as incomplete capture reasons either
|
|
71
|
+
const discardedIncomplete = { reasons: 0 }
|
|
72
|
+
|
|
51
73
|
// TODO: Improve performance of redaction algorithm.
|
|
52
74
|
// This algorithm is probably slower than if we embedded the redaction logic inside the functions below.
|
|
53
75
|
// That way we didn't have to traverse objects that will just be redacted anyway.
|
|
54
|
-
function getPropertyValue (prop, maxLength) {
|
|
55
|
-
return
|
|
76
|
+
function getPropertyValue (prop, maxLength, incomplete) {
|
|
77
|
+
return shouldRedactProperty(prop)
|
|
78
|
+
? notCapturedRedacted(getPropertyValueRaw(prop, maxLength, discardedIncomplete).type)
|
|
79
|
+
: getPropertyValueRaw(prop, maxLength, incomplete)
|
|
56
80
|
}
|
|
57
81
|
|
|
58
|
-
function getPropertyValueRaw (prop, maxLength) {
|
|
82
|
+
function getPropertyValueRaw (prop, maxLength, incomplete) {
|
|
59
83
|
// Special case for getters and setters which does not have a value property
|
|
60
84
|
if (prop.get) {
|
|
61
85
|
const hasGet = prop.get.type !== 'undefined'
|
|
@@ -69,15 +93,15 @@ function getPropertyValueRaw (prop, maxLength) {
|
|
|
69
93
|
|
|
70
94
|
switch (prop.value?.type) {
|
|
71
95
|
case 'object':
|
|
72
|
-
return getObjectValue(prop.value, maxLength)
|
|
96
|
+
return getObjectValue(prop.value, maxLength, incomplete)
|
|
73
97
|
case 'string':
|
|
74
|
-
return toString(prop.value.value, maxLength)
|
|
98
|
+
return toString(prop.value.value, maxLength, incomplete)
|
|
75
99
|
case 'number':
|
|
76
100
|
return { type: 'number', value: prop.value.description } // use `description` to get it as string
|
|
77
101
|
case 'boolean':
|
|
78
102
|
return { type: 'boolean', value: prop.value.value === true ? 'true' : 'false' }
|
|
79
103
|
case 'function':
|
|
80
|
-
return toFunctionOrClass(prop.value, maxLength)
|
|
104
|
+
return toFunctionOrClass(prop.value, maxLength, incomplete)
|
|
81
105
|
case undefined: // TODO: Add test for when a prop has no value. I think it's if it's defined after the breakpoint?
|
|
82
106
|
case 'undefined':
|
|
83
107
|
return { type: 'undefined' }
|
|
@@ -88,18 +112,19 @@ function getPropertyValueRaw (prop, maxLength) {
|
|
|
88
112
|
default:
|
|
89
113
|
// As of this writing, the Chrome DevTools Protocol doesn't allow any other types than the ones listed above, but
|
|
90
114
|
// in the future new ones might be added.
|
|
115
|
+
incomplete.reasons |= INCOMPLETE_REASON.OTHER
|
|
91
116
|
return { type: prop.value.type, notCapturedReason: 'Unsupported property type' }
|
|
92
117
|
}
|
|
93
118
|
}
|
|
94
119
|
|
|
95
|
-
function getObjectValue (obj, maxLength) {
|
|
120
|
+
function getObjectValue (obj, maxLength, incomplete) {
|
|
96
121
|
const timeBudgetReached = obj[timeBudgetSym] === true
|
|
97
122
|
|
|
98
123
|
switch (obj.subtype) {
|
|
99
124
|
case undefined:
|
|
100
|
-
return toObject(obj.className, obj.properties, maxLength, timeBudgetReached)
|
|
125
|
+
return toObject(obj.className, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
101
126
|
case 'array':
|
|
102
|
-
return toArray(obj.className, obj.properties, maxLength, timeBudgetReached)
|
|
127
|
+
return toArray(obj.className, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
103
128
|
case 'null':
|
|
104
129
|
return { type: 'null', isNull: true }
|
|
105
130
|
// case 'node': // TODO: What does this subtype represent?
|
|
@@ -113,28 +138,28 @@ function getObjectValue (obj, maxLength) {
|
|
|
113
138
|
return { type: obj.className, value }
|
|
114
139
|
}
|
|
115
140
|
case 'map':
|
|
116
|
-
return toMap(obj.className, obj.properties, maxLength, timeBudgetReached)
|
|
141
|
+
return toMap(obj.className, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
117
142
|
case 'set':
|
|
118
|
-
return toSet(obj.className, obj.properties, maxLength, timeBudgetReached)
|
|
143
|
+
return toSet(obj.className, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
119
144
|
case 'error':
|
|
120
145
|
// TODO: Convert stack trace to array to avoid string truncation or disable truncation in this case?
|
|
121
|
-
return toObject(obj.className, obj.properties, maxLength, timeBudgetReached)
|
|
146
|
+
return toObject(obj.className, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
122
147
|
case 'proxy':
|
|
123
148
|
// Use `description` instead of `className` as the `type` to get type of target object (`Proxy(Error)` vs `proxy`)
|
|
124
|
-
return toObject(obj.description, obj.properties, maxLength, timeBudgetReached)
|
|
149
|
+
return toObject(obj.description, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
125
150
|
case 'promise':
|
|
126
|
-
return toObject(obj.className, obj.properties, maxLength, timeBudgetReached)
|
|
151
|
+
return toObject(obj.className, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
127
152
|
case 'typedarray':
|
|
128
|
-
return toArray(obj.className, obj.properties, maxLength, timeBudgetReached)
|
|
153
|
+
return toArray(obj.className, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
129
154
|
case 'generator':
|
|
130
155
|
// Use `subtype` instead of `className` to make it obvious it's a generator
|
|
131
|
-
return toObject(obj.subtype, obj.properties, maxLength, timeBudgetReached)
|
|
156
|
+
return toObject(obj.subtype, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
132
157
|
case 'arraybuffer':
|
|
133
|
-
return toArrayBuffer(obj.className, obj.properties, maxLength, timeBudgetReached)
|
|
158
|
+
return toArrayBuffer(obj.className, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
134
159
|
case 'weakmap':
|
|
135
|
-
return toMap(obj.className, obj.properties, maxLength, timeBudgetReached)
|
|
160
|
+
return toMap(obj.className, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
136
161
|
case 'weakset':
|
|
137
|
-
return toSet(obj.className, obj.properties, maxLength, timeBudgetReached)
|
|
162
|
+
return toSet(obj.className, obj.properties, maxLength, timeBudgetReached, incomplete)
|
|
138
163
|
// case 'iterator': // TODO: I've not been able to trigger this subtype
|
|
139
164
|
// case 'dataview': // TODO: Looks like the internal ArrayBuffer is only accessible via the `buffer` getter
|
|
140
165
|
// case 'webassemblymemory': // TODO: Looks like the internal ArrayBuffer is only accessible via the `buffer` getter
|
|
@@ -142,31 +167,34 @@ function getObjectValue (obj, maxLength) {
|
|
|
142
167
|
default:
|
|
143
168
|
// As of this writing, the Chrome DevTools Protocol doesn't allow any other subtypes than the ones listed above,
|
|
144
169
|
// but in the future new ones might be added.
|
|
170
|
+
incomplete.reasons |= INCOMPLETE_REASON.OTHER
|
|
145
171
|
return { type: obj.subtype, notCapturedReason: 'Unsupported object type' }
|
|
146
172
|
}
|
|
147
173
|
}
|
|
148
174
|
|
|
149
|
-
function toFunctionOrClass (value, maxLength) {
|
|
175
|
+
function toFunctionOrClass (value, maxLength, incomplete) {
|
|
150
176
|
const classMatch = value.description.match(CLASS_REGEX)
|
|
151
177
|
|
|
152
178
|
if (classMatch === null) {
|
|
153
179
|
// This is a function
|
|
154
180
|
const timeBudgetReached = value[timeBudgetSym] === true
|
|
155
181
|
// TODO: Would it make sense to detect if it's an arrow function or not?
|
|
156
|
-
return toObject(value.className, value.properties, maxLength, timeBudgetReached)
|
|
182
|
+
return toObject(value.className, value.properties, maxLength, timeBudgetReached, incomplete)
|
|
157
183
|
}
|
|
158
184
|
// This is a class
|
|
159
185
|
const className = classMatch[1].trim()
|
|
160
186
|
return { type: className ? `class ${className}` : 'class' }
|
|
161
187
|
}
|
|
162
188
|
|
|
163
|
-
function toString (str, maxLength) {
|
|
189
|
+
function toString (str, maxLength, incomplete) {
|
|
164
190
|
const size = str.length
|
|
165
191
|
|
|
166
192
|
if (size <= maxLength) {
|
|
167
193
|
return { type: 'string', value: str }
|
|
168
194
|
}
|
|
169
195
|
|
|
196
|
+
incomplete.reasons |= INCOMPLETE_REASON.STRING_LENGTH
|
|
197
|
+
|
|
170
198
|
return {
|
|
171
199
|
type: 'string',
|
|
172
200
|
value: str.slice(0, maxLength),
|
|
@@ -175,16 +203,17 @@ function toString (str, maxLength) {
|
|
|
175
203
|
}
|
|
176
204
|
}
|
|
177
205
|
|
|
178
|
-
function toObject (type, props, maxLength, timeBudgetReached) {
|
|
179
|
-
if (timeBudgetReached === true) return notCapturedTimeBudget(type)
|
|
180
|
-
if (props === undefined) return notCapturedDepth(type)
|
|
206
|
+
function toObject (type, props, maxLength, timeBudgetReached, incomplete) {
|
|
207
|
+
if (timeBudgetReached === true) return notCapturedTimeBudget(type, incomplete)
|
|
208
|
+
if (props === undefined) return notCapturedDepth(type, incomplete)
|
|
181
209
|
|
|
182
210
|
const result = {
|
|
183
211
|
type,
|
|
184
|
-
fields: processProperties(props, maxLength),
|
|
212
|
+
fields: processProperties(props, maxLength, incomplete),
|
|
185
213
|
}
|
|
186
214
|
|
|
187
215
|
if (props[fieldCountSym] !== undefined) {
|
|
216
|
+
incomplete.reasons |= INCOMPLETE_REASON.FIELD_COUNT
|
|
188
217
|
result.notCapturedReason = 'fieldCount'
|
|
189
218
|
result.size = props[fieldCountSym]
|
|
190
219
|
}
|
|
@@ -192,27 +221,29 @@ function toObject (type, props, maxLength, timeBudgetReached) {
|
|
|
192
221
|
return result
|
|
193
222
|
}
|
|
194
223
|
|
|
195
|
-
function toArray (type, elements, maxLength, timeBudgetReached) {
|
|
196
|
-
if (timeBudgetReached === true) return notCapturedTimeBudget(type)
|
|
197
|
-
if (elements === undefined) return notCapturedDepth(type)
|
|
224
|
+
function toArray (type, elements, maxLength, timeBudgetReached, incomplete) {
|
|
225
|
+
if (timeBudgetReached === true) return notCapturedTimeBudget(type, incomplete)
|
|
226
|
+
if (elements === undefined) return notCapturedDepth(type, incomplete)
|
|
198
227
|
|
|
199
228
|
const result = {
|
|
200
229
|
type,
|
|
201
230
|
elements: elements.map((element) => {
|
|
202
|
-
return getPropertyValue(element, maxLength)
|
|
231
|
+
return getPropertyValue(element, maxLength, incomplete)
|
|
203
232
|
}),
|
|
204
233
|
}
|
|
205
234
|
|
|
206
|
-
setNotCaptureReasonOnCollection(result, elements)
|
|
207
|
-
setNotCaptureReasonOnTooLargeCollection(result, elements)
|
|
235
|
+
setNotCaptureReasonOnCollection(result, elements, incomplete)
|
|
236
|
+
setNotCaptureReasonOnTooLargeCollection(result, elements, incomplete)
|
|
208
237
|
|
|
209
238
|
return result
|
|
210
239
|
}
|
|
211
240
|
|
|
212
|
-
function toMap (type, pairs, maxLength, timeBudgetReached) {
|
|
213
|
-
if (timeBudgetReached === true) return notCapturedTimeBudget(type)
|
|
214
|
-
if (pairs === undefined) return notCapturedDepth(type)
|
|
215
|
-
if (pairs.length > 0 && pairs.every(({ value }) => value[timeBudgetSym] === true))
|
|
241
|
+
function toMap (type, pairs, maxLength, timeBudgetReached, incomplete) {
|
|
242
|
+
if (timeBudgetReached === true) return notCapturedTimeBudget(type, incomplete)
|
|
243
|
+
if (pairs === undefined) return notCapturedDepth(type, incomplete)
|
|
244
|
+
if (pairs.length > 0 && pairs.every(({ value }) => value[timeBudgetSym] === true)) {
|
|
245
|
+
return notCapturedTimeBudget(type, incomplete)
|
|
246
|
+
}
|
|
216
247
|
|
|
217
248
|
const result = {
|
|
218
249
|
type,
|
|
@@ -227,32 +258,34 @@ function toMap (type, pairs, maxLength, timeBudgetReached) {
|
|
|
227
258
|
// second containing the value of this entry of the Map.
|
|
228
259
|
|
|
229
260
|
if (value[timeBudgetSym] === true) {
|
|
261
|
+
incomplete.reasons |= INCOMPLETE_REASON.TIMEOUT
|
|
230
262
|
return [{ notCapturedReason: 'timeout' }, { notCapturedReason: 'timeout' }]
|
|
231
263
|
}
|
|
232
264
|
if (value.properties === undefined) {
|
|
265
|
+
incomplete.reasons |= INCOMPLETE_REASON.OTHER
|
|
233
266
|
return [{ notCapturedReason: 'unknown' }, { notCapturedReason: 'unknown' }]
|
|
234
267
|
}
|
|
235
268
|
|
|
236
269
|
const shouldRedact = shouldRedactMapValue(value.properties[0])
|
|
237
|
-
const key = getPropertyValue(value.properties[0], maxLength)
|
|
270
|
+
const key = getPropertyValue(value.properties[0], maxLength, incomplete)
|
|
238
271
|
const val = shouldRedact
|
|
239
272
|
? notCapturedRedacted(value.properties[1].value.type)
|
|
240
|
-
: getPropertyValue(value.properties[1], maxLength)
|
|
273
|
+
: getPropertyValue(value.properties[1], maxLength, incomplete)
|
|
241
274
|
return [key, val]
|
|
242
275
|
}),
|
|
243
276
|
}
|
|
244
277
|
|
|
245
|
-
setNotCaptureReasonOnCollection(result, pairs)
|
|
246
|
-
setNotCaptureReasonOnTooLargeCollection(result, pairs)
|
|
278
|
+
setNotCaptureReasonOnCollection(result, pairs, incomplete)
|
|
279
|
+
setNotCaptureReasonOnTooLargeCollection(result, pairs, incomplete)
|
|
247
280
|
|
|
248
281
|
return result
|
|
249
282
|
}
|
|
250
283
|
|
|
251
|
-
function toSet (type, values, maxLength, timeBudgetReached) {
|
|
252
|
-
if (timeBudgetReached === true) return notCapturedTimeBudget(type)
|
|
253
|
-
if (values === undefined) return notCapturedDepth(type)
|
|
284
|
+
function toSet (type, values, maxLength, timeBudgetReached, incomplete) {
|
|
285
|
+
if (timeBudgetReached === true) return notCapturedTimeBudget(type, incomplete)
|
|
286
|
+
if (values === undefined) return notCapturedDepth(type, incomplete)
|
|
254
287
|
if (values.length > 0 && values.every(({ value }) => value[timeBudgetSym] === true)) {
|
|
255
|
-
return notCapturedTimeBudget(type)
|
|
288
|
+
return notCapturedTimeBudget(type, incomplete)
|
|
256
289
|
}
|
|
257
290
|
|
|
258
291
|
const result = {
|
|
@@ -267,33 +300,42 @@ function toSet (type, values, maxLength, timeBudgetReached) {
|
|
|
267
300
|
// children, of which there will always be exactly one, which contain the
|
|
268
301
|
// actual value in this entry of the Set.
|
|
269
302
|
|
|
270
|
-
if (value[timeBudgetSym] === true)
|
|
271
|
-
|
|
303
|
+
if (value[timeBudgetSym] === true) {
|
|
304
|
+
incomplete.reasons |= INCOMPLETE_REASON.TIMEOUT
|
|
305
|
+
return { notCapturedReason: 'timeout' }
|
|
306
|
+
}
|
|
307
|
+
if (value.properties === undefined) {
|
|
308
|
+
incomplete.reasons |= INCOMPLETE_REASON.OTHER
|
|
309
|
+
return { notCapturedReason: 'unknown' }
|
|
310
|
+
}
|
|
272
311
|
|
|
273
|
-
return getPropertyValue(value.properties[0], maxLength)
|
|
312
|
+
return getPropertyValue(value.properties[0], maxLength, incomplete)
|
|
274
313
|
}),
|
|
275
314
|
}
|
|
276
315
|
|
|
277
|
-
setNotCaptureReasonOnCollection(result, values)
|
|
278
|
-
setNotCaptureReasonOnTooLargeCollection(result, values)
|
|
316
|
+
setNotCaptureReasonOnCollection(result, values, incomplete)
|
|
317
|
+
setNotCaptureReasonOnTooLargeCollection(result, values, incomplete)
|
|
279
318
|
|
|
280
319
|
return result
|
|
281
320
|
}
|
|
282
321
|
|
|
283
|
-
function toArrayBuffer (type, bytes, maxLength, timeBudgetReached) {
|
|
284
|
-
if (timeBudgetReached === true) return notCapturedTimeBudget(type)
|
|
285
|
-
if (bytes === undefined) return notCapturedDepth(type)
|
|
322
|
+
function toArrayBuffer (type, bytes, maxLength, timeBudgetReached, incomplete) {
|
|
323
|
+
if (timeBudgetReached === true) return notCapturedTimeBudget(type, incomplete)
|
|
324
|
+
if (bytes === undefined) return notCapturedDepth(type, incomplete)
|
|
286
325
|
|
|
287
326
|
const size = bytes.length
|
|
288
327
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
328
|
+
if (size > maxLength) {
|
|
329
|
+
incomplete.reasons |= INCOMPLETE_REASON.STRING_LENGTH
|
|
330
|
+
return {
|
|
331
|
+
type,
|
|
332
|
+
value: arrayBufferToString(bytes, maxLength),
|
|
333
|
+
truncated: true,
|
|
334
|
+
size: bytes.length,
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return { type, value: arrayBufferToString(bytes, size) }
|
|
297
339
|
}
|
|
298
340
|
|
|
299
341
|
function arrayBufferToString (bytes, size) {
|
|
@@ -304,9 +346,8 @@ function arrayBufferToString (bytes, size) {
|
|
|
304
346
|
return buf.toString()
|
|
305
347
|
}
|
|
306
348
|
|
|
307
|
-
function
|
|
308
|
-
|
|
309
|
-
return REDACTED_IDENTIFIERS.has(name) ? notCapturedRedacted(obj.type) : obj
|
|
349
|
+
function shouldRedactProperty (prop) {
|
|
350
|
+
return REDACTED_IDENTIFIERS.has(getNormalizedNameFromProp(prop))
|
|
310
351
|
}
|
|
311
352
|
|
|
312
353
|
function shouldRedactMapValue (key) {
|
|
@@ -323,15 +364,19 @@ function getNormalizedNameFromProp (prop) {
|
|
|
323
364
|
return normalizeName(prop.name, prop.symbol !== undefined)
|
|
324
365
|
}
|
|
325
366
|
|
|
326
|
-
function setNotCaptureReasonOnCollection (result, collection) {
|
|
367
|
+
function setNotCaptureReasonOnCollection (result, collection, incomplete) {
|
|
327
368
|
if (collection[collectionSizeSym] !== undefined) {
|
|
369
|
+
incomplete.reasons |= INCOMPLETE_REASON.COLLECTION_SIZE
|
|
328
370
|
result.notCapturedReason = 'collectionSize'
|
|
329
371
|
result.size = collection[collectionSizeSym]
|
|
330
372
|
}
|
|
331
373
|
}
|
|
332
374
|
|
|
333
|
-
function setNotCaptureReasonOnTooLargeCollection (result, collection) {
|
|
375
|
+
function setNotCaptureReasonOnTooLargeCollection (result, collection, incomplete) {
|
|
334
376
|
if (collection[largeCollectionSkipThresholdSym] !== undefined) {
|
|
377
|
+
// The collection was skipped entirely because it exceeded the skip threshold, which is a different limit than the
|
|
378
|
+
// `maxCollectionSize` limit that `collectionSize` represents
|
|
379
|
+
incomplete.reasons |= INCOMPLETE_REASON.OTHER
|
|
335
380
|
result.notCapturedReason = `Large collection with too many elements (skip threshold: ${
|
|
336
381
|
LARGE_OBJECT_SKIP_THRESHOLD
|
|
337
382
|
})`
|
|
@@ -339,7 +384,8 @@ function setNotCaptureReasonOnTooLargeCollection (result, collection) {
|
|
|
339
384
|
}
|
|
340
385
|
}
|
|
341
386
|
|
|
342
|
-
function notCapturedDepth (type) {
|
|
387
|
+
function notCapturedDepth (type, incomplete) {
|
|
388
|
+
incomplete.reasons |= INCOMPLETE_REASON.DEPTH
|
|
343
389
|
return { type, notCapturedReason: 'depth' }
|
|
344
390
|
}
|
|
345
391
|
|
|
@@ -347,6 +393,7 @@ function notCapturedRedacted (type) {
|
|
|
347
393
|
return { type, notCapturedReason: 'redactedIdent' }
|
|
348
394
|
}
|
|
349
395
|
|
|
350
|
-
function notCapturedTimeBudget (type) {
|
|
396
|
+
function notCapturedTimeBudget (type, incomplete) {
|
|
397
|
+
incomplete.reasons |= INCOMPLETE_REASON.TIMEOUT
|
|
351
398
|
return { type, notCapturedReason: 'timeout' }
|
|
352
399
|
}
|
|
@@ -143,7 +143,6 @@ class PriorityQueue {
|
|
|
143
143
|
*
|
|
144
144
|
* @param {TreeNode} a - First node to compare
|
|
145
145
|
* @param {TreeNode} b - Second node to compare
|
|
146
|
-
* @returns {number} - > 0 if a has higher priority, < 0 if b has higher priority, 0 if equal
|
|
147
146
|
*/
|
|
148
147
|
#compare (a, b) {
|
|
149
148
|
const keyA = a.priorityKey
|
|
@@ -243,7 +242,6 @@ function parseJsonToTree (json) {
|
|
|
243
242
|
*
|
|
244
243
|
* @param {string} json - The JSON string to skip
|
|
245
244
|
* @param {number} startIndex - The index to start skipping from
|
|
246
|
-
* @returns {number} The index of the closing quote
|
|
247
245
|
*/
|
|
248
246
|
function skipString (json, startIndex) {
|
|
249
247
|
let index = startIndex + 1 // Skip opening quote
|
|
@@ -353,7 +351,6 @@ function selectNodesToPrune (root, bytesToRemove) {
|
|
|
353
351
|
*
|
|
354
352
|
* @param {string} json - The JSON string to rebuild
|
|
355
353
|
* @param {Set<TreeNode>} prunedNodes - The set of nodes to replace with {"pruned":true}
|
|
356
|
-
* @returns {string} The rebuilt JSON string
|
|
357
354
|
*/
|
|
358
355
|
function rebuildJson (json, prunedNodes) {
|
|
359
356
|
// Convert set to array and sort by start position (descending)
|