dd-trace 5.80.0 → 5.82.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-3rdparty.csv +79 -88
- package/ext/tags.d.ts +1 -0
- package/ext/tags.js +1 -0
- package/index.d.ts +42 -35
- package/loader-hook.mjs +16 -4
- package/package.json +33 -56
- package/packages/datadog-core/src/utils/src/parse-tags.js +1 -1
- package/packages/datadog-esbuild/index.js +44 -26
- package/packages/datadog-esbuild/src/utils.js +14 -2
- package/packages/datadog-instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/aerospike.js +3 -2
- package/packages/datadog-instrumentations/src/ai.js +2 -2
- package/packages/datadog-instrumentations/src/amqp10.js +1 -1
- package/packages/datadog-instrumentations/src/amqplib.js +4 -4
- package/packages/datadog-instrumentations/src/anthropic.js +14 -2
- package/packages/datadog-instrumentations/src/apollo-server-core.js +2 -2
- package/packages/datadog-instrumentations/src/apollo-server.js +1 -1
- package/packages/datadog-instrumentations/src/apollo.js +3 -2
- package/packages/datadog-instrumentations/src/avsc.js +1 -1
- package/packages/datadog-instrumentations/src/aws-sdk.js +6 -2
- package/packages/datadog-instrumentations/src/azure-event-hubs.js +4 -3
- package/packages/datadog-instrumentations/src/azure-functions.js +2 -2
- package/packages/datadog-instrumentations/src/azure-service-bus.js +3 -4
- package/packages/datadog-instrumentations/src/bluebird.js +1 -1
- package/packages/datadog-instrumentations/src/bullmq.js +11 -0
- package/packages/datadog-instrumentations/src/bunyan.js +1 -1
- package/packages/datadog-instrumentations/src/cassandra-driver.js +1 -1
- package/packages/datadog-instrumentations/src/child_process.js +2 -2
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +3 -3
- package/packages/datadog-instrumentations/src/couchbase.js +1 -1
- package/packages/datadog-instrumentations/src/crypto.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber.js +12 -13
- package/packages/datadog-instrumentations/src/cypress.js +1 -1
- package/packages/datadog-instrumentations/src/dns.js +1 -1
- package/packages/datadog-instrumentations/src/elasticsearch.js +1 -1
- package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +1 -1
- package/packages/datadog-instrumentations/src/express.js +1 -1
- package/packages/datadog-instrumentations/src/find-my-way.js +6 -5
- package/packages/datadog-instrumentations/src/fs.js +1 -1
- package/packages/datadog-instrumentations/src/generic-pool.js +1 -1
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +137 -15
- package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +2 -3
- package/packages/datadog-instrumentations/src/google-genai.js +120 -0
- package/packages/datadog-instrumentations/src/graphql.js +21 -1
- package/packages/datadog-instrumentations/src/grpc/client.js +1 -1
- package/packages/datadog-instrumentations/src/grpc/server.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/hook.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +5 -1
- package/packages/datadog-instrumentations/src/helpers/instrument.js +11 -1
- package/packages/datadog-instrumentations/src/helpers/register.js +12 -5
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +27 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +152 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/bullmq.json +106 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +6 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langchain.js +237 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.js +9 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +11 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +139 -0
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/shared-utils.js +9 -0
- package/packages/datadog-instrumentations/src/hono.js +55 -10
- package/packages/datadog-instrumentations/src/ioredis.js +1 -1
- package/packages/datadog-instrumentations/src/iovalkey.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +2 -2
- package/packages/datadog-instrumentations/src/kafkajs.js +3 -3
- package/packages/datadog-instrumentations/src/knex.js +1 -1
- package/packages/datadog-instrumentations/src/langchain.js +3 -109
- package/packages/datadog-instrumentations/src/ldapjs.js +1 -1
- package/packages/datadog-instrumentations/src/light-my-request.js +93 -0
- package/packages/datadog-instrumentations/src/limitd-client.js +1 -1
- package/packages/datadog-instrumentations/src/lodash.js +1 -2
- package/packages/datadog-instrumentations/src/mariadb.js +1 -2
- package/packages/datadog-instrumentations/src/memcached.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +1 -1
- package/packages/datadog-instrumentations/src/mongodb-core.js +1 -1
- package/packages/datadog-instrumentations/src/mongodb.js +1 -1
- package/packages/datadog-instrumentations/src/mongoose.js +1 -1
- package/packages/datadog-instrumentations/src/mquery.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/mysql2.js +2 -2
- package/packages/datadog-instrumentations/src/net.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +1 -1
- package/packages/datadog-instrumentations/src/nyc.js +1 -1
- package/packages/datadog-instrumentations/src/openai.js +2 -2
- package/packages/datadog-instrumentations/src/opensearch.js +1 -1
- package/packages/datadog-instrumentations/src/oracledb.js +1 -1
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +1 -1
- package/packages/datadog-instrumentations/src/pg.js +3 -3
- package/packages/datadog-instrumentations/src/pino.js +1 -1
- package/packages/datadog-instrumentations/src/playwright.js +46 -17
- package/packages/datadog-instrumentations/src/prisma.js +52 -37
- package/packages/datadog-instrumentations/src/process.js +1 -1
- package/packages/datadog-instrumentations/src/promise-js.js +1 -1
- package/packages/datadog-instrumentations/src/promise.js +1 -1
- package/packages/datadog-instrumentations/src/protobufjs.js +1 -1
- package/packages/datadog-instrumentations/src/q.js +1 -1
- package/packages/datadog-instrumentations/src/redis.js +1 -1
- package/packages/datadog-instrumentations/src/rhea.js +1 -1
- package/packages/datadog-instrumentations/src/router.js +1 -1
- package/packages/datadog-instrumentations/src/selenium.js +4 -2
- package/packages/datadog-instrumentations/src/sequelize.js +1 -2
- package/packages/datadog-instrumentations/src/sharedb.js +1 -1
- package/packages/datadog-instrumentations/src/tedious.js +1 -1
- package/packages/datadog-instrumentations/src/undici.js +4 -4
- package/packages/datadog-instrumentations/src/url.js +1 -1
- package/packages/datadog-instrumentations/src/vitest.js +1 -1
- package/packages/datadog-instrumentations/src/vm.js +1 -1
- package/packages/datadog-instrumentations/src/when.js +1 -1
- package/packages/datadog-instrumentations/src/winston.js +1 -1
- package/packages/datadog-instrumentations/src/ws.js +38 -19
- package/packages/datadog-plugin-amqp10/src/index.js +1 -1
- package/packages/datadog-plugin-amqplib/src/index.js +1 -1
- package/packages/datadog-plugin-anthropic/src/index.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +4 -4
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/util.js +3 -3
- package/packages/datadog-plugin-azure-event-hubs/src/index.js +1 -1
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +19 -5
- package/packages/datadog-plugin-azure-service-bus/src/index.js +1 -1
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +4 -0
- package/packages/datadog-plugin-bullmq/src/consumer.js +60 -0
- package/packages/datadog-plugin-bullmq/src/index.js +18 -0
- package/packages/datadog-plugin-bullmq/src/producer.js +178 -0
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -1
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/index.js +1 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +23 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +2 -2
- package/packages/datadog-plugin-cypress/src/support.js +73 -31
- package/packages/datadog-plugin-express/src/index.js +1 -1
- package/packages/datadog-plugin-fastify/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +13 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +171 -12
- package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +1 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +160 -13
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +217 -0
- package/packages/datadog-plugin-google-cloud-vertexai/src/index.js +1 -1
- package/packages/datadog-plugin-google-genai/src/index.js +17 -0
- package/packages/datadog-plugin-google-genai/src/tracing.js +41 -0
- package/packages/datadog-plugin-graphql/src/resolve.js +1 -1
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +5 -4
- package/packages/datadog-plugin-grpc/src/index.js +1 -1
- package/packages/datadog-plugin-http/src/client.js +2 -1
- package/packages/datadog-plugin-http/src/index.js +25 -5
- package/packages/datadog-plugin-http2/src/client.js +2 -2
- package/packages/datadog-plugin-http2/src/index.js +1 -1
- package/packages/datadog-plugin-jest/src/util.js +1 -1
- package/packages/datadog-plugin-kafkajs/src/index.js +1 -1
- package/packages/datadog-plugin-langchain/src/index.js +1 -1
- package/packages/datadog-plugin-langchain/src/tracing.js +7 -3
- package/packages/datadog-plugin-moleculer/src/index.js +1 -1
- package/packages/datadog-plugin-mongodb-core/src/index.js +6 -2
- package/packages/datadog-plugin-next/src/index.js +11 -3
- package/packages/datadog-plugin-openai/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/stream-helpers.js +30 -10
- package/packages/datadog-plugin-openai/src/tracing.js +2 -2
- package/packages/datadog-plugin-rhea/src/index.js +1 -1
- package/packages/datadog-plugin-ws/src/close.js +56 -3
- package/packages/datadog-plugin-ws/src/index.js +4 -0
- package/packages/datadog-plugin-ws/src/producer.js +39 -4
- package/packages/datadog-plugin-ws/src/receiver.js +39 -3
- package/packages/datadog-plugin-ws/src/server.js +13 -1
- package/packages/datadog-plugin-ws/src/util.js +107 -0
- package/packages/datadog-shimmer/src/shimmer.js +2 -2
- package/packages/dd-trace/src/aiguard/sdk.js +21 -13
- package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
- package/packages/dd-trace/src/appsec/graphql.js +2 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/code-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-base-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +3 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/ssrf-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/untrusted-deserialization-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-cipher-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +3 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-randomness-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +3 -3
- package/packages/dd-trace/src/appsec/iast/index.js +5 -5
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +1 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.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-esm.mjs +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +11 -16
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/namespaces.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +4 -4
- package/packages/dd-trace/src/appsec/index.js +8 -8
- package/packages/dd-trace/src/appsec/rasp/command_injection.js +1 -1
- package/packages/dd-trace/src/appsec/rasp/index.js +1 -1
- package/packages/dd-trace/src/appsec/rasp/lfi.js +1 -1
- package/packages/dd-trace/src/appsec/rc-products.js +10 -0
- package/packages/dd-trace/src/appsec/recommended.json +230 -3
- package/packages/dd-trace/src/appsec/remote_config.js +177 -0
- package/packages/dd-trace/src/appsec/reporter.js +3 -7
- package/packages/dd-trace/src/appsec/rule_manager.js +37 -20
- package/packages/dd-trace/src/appsec/sdk/index.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/set_user.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/track_event.js +2 -2
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +2 -2
- package/packages/dd-trace/src/appsec/user_tracking.js +2 -2
- package/packages/dd-trace/src/appsec/waf/index.js +17 -3
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +11 -0
- package/packages/dd-trace/src/azure_metadata.js +8 -2
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +8 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +1 -1
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +4 -2
- package/packages/dd-trace/src/config/remote_config.js +34 -0
- package/packages/dd-trace/src/config.js +109 -34
- package/packages/dd-trace/src/config_defaults.js +16 -3
- package/packages/dd-trace/src/constants.js +5 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +10 -1
- package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
- package/packages/dd-trace/src/datastreams/encoding.js +23 -6
- package/packages/dd-trace/src/datastreams/index.js +1 -1
- package/packages/dd-trace/src/datastreams/pathway.js +41 -2
- package/packages/dd-trace/src/datastreams/processor.js +3 -3
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -1
- package/packages/dd-trace/src/datastreams/writer.js +2 -2
- package/packages/dd-trace/src/debugger/config.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +15 -5
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/config.js +3 -1
- package/packages/dd-trace/src/debugger/devtools_client/index.js +37 -17
- package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +24 -18
- package/packages/dd-trace/src/debugger/devtools_client/send.js +21 -11
- package/packages/dd-trace/src/debugger/devtools_client/session.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +103 -15
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +25 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +56 -25
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +64 -23
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +3 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +404 -0
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/state.js +8 -3
- package/packages/dd-trace/src/debugger/devtools_client/status.js +3 -3
- package/packages/dd-trace/src/debugger/index.js +2 -2
- package/packages/dd-trace/src/dogstatsd.js +3 -2
- package/packages/dd-trace/src/encode/0.4.js +1 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +2 -2
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -1
- package/packages/dd-trace/src/encode/span-stats.js +13 -2
- package/packages/dd-trace/src/exporter.js +2 -2
- package/packages/dd-trace/src/exporters/agent/index.js +1 -1
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +1 -1
- package/packages/dd-trace/src/exporters/common/request.js +2 -2
- package/packages/dd-trace/src/exporters/common/writer.js +1 -1
- package/packages/dd-trace/src/exporters/span-stats/index.js +1 -1
- package/packages/dd-trace/src/external-logger/src/index.js +1 -2
- package/packages/dd-trace/src/flare/index.js +1 -1
- package/packages/dd-trace/src/guardrails/index.js +6 -3
- package/packages/dd-trace/src/histogram.js +1 -1
- package/packages/dd-trace/src/id.js +60 -0
- package/packages/dd-trace/src/index.js +1 -1
- package/packages/dd-trace/src/lambda/handler.js +4 -4
- package/packages/dd-trace/src/lambda/index.js +1 -1
- package/packages/dd-trace/src/lambda/runtime/patch.js +4 -4
- package/packages/dd-trace/src/lambda/runtime/ritm.js +2 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +8 -1
- package/packages/dd-trace/src/llmobs/index.js +8 -9
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +38 -7
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +30 -9
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +3 -3
- package/packages/dd-trace/src/llmobs/plugins/genai/index.js +104 -0
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +486 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/embedding.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/llm.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/vectorstore.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +2 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +16 -0
- package/packages/dd-trace/src/llmobs/plugins/{openai.js → openai/index.js} +63 -6
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +126 -0
- package/packages/dd-trace/src/llmobs/plugins/vertexai.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +20 -22
- package/packages/dd-trace/src/llmobs/span_processor.js +15 -14
- package/packages/dd-trace/src/llmobs/tagger.js +4 -0
- package/packages/dd-trace/src/llmobs/telemetry.js +3 -4
- package/packages/dd-trace/src/llmobs/writers/base.js +2 -2
- package/packages/dd-trace/src/llmobs/writers/spans.js +1 -2
- package/packages/dd-trace/src/log/index.js +1 -1
- package/packages/dd-trace/src/noop/proxy.js +2 -2
- package/packages/dd-trace/src/noop/span.js +1 -1
- package/packages/dd-trace/src/openfeature/index.js +2 -2
- package/packages/dd-trace/src/openfeature/noop.js +14 -14
- package/packages/dd-trace/src/openfeature/remote_config.js +31 -0
- package/packages/dd-trace/src/openfeature/writers/base.js +5 -5
- package/packages/dd-trace/src/openfeature/writers/exposures.js +9 -9
- package/packages/dd-trace/src/opentelemetry/context_manager.js +2 -2
- package/packages/dd-trace/src/opentelemetry/logs/index.js +2 -2
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +3 -2
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +4 -4
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +5 -3
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +17 -16
- package/packages/dd-trace/src/opentelemetry/metrics/constants.js +34 -0
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +81 -0
- package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +225 -0
- package/packages/dd-trace/src/opentelemetry/metrics/meter.js +171 -0
- package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +54 -0
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +62 -0
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +251 -0
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +557 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +10 -18
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +47 -32
- package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +1 -1
- package/packages/dd-trace/src/opentelemetry/span.js +3 -3
- package/packages/dd-trace/src/opentelemetry/tracer.js +4 -4
- package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +24 -8
- package/packages/dd-trace/src/opentracing/span.js +3 -3
- package/packages/dd-trace/src/opentracing/tracer.js +5 -5
- package/packages/dd-trace/src/payload-tagging/index.js +8 -4
- package/packages/dd-trace/src/plugin_manager.js +5 -3
- package/packages/dd-trace/src/plugins/apollo.js +1 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +27 -27
- package/packages/dd-trace/src/plugins/database.js +1 -1
- package/packages/dd-trace/src/plugins/index.js +6 -1
- package/packages/dd-trace/src/plugins/log_plugin.js +1 -1
- package/packages/dd-trace/src/plugins/outbound.js +1 -1
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/plugins/util/ci.js +1 -1
- package/packages/dd-trace/src/plugins/util/git.js +8 -8
- package/packages/dd-trace/src/plugins/util/stacktrace.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +27 -27
- package/packages/dd-trace/src/plugins/util/url.js +119 -1
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +18 -46
- package/packages/dd-trace/src/priority_sampler.js +15 -16
- package/packages/dd-trace/src/process-tags/index.js +83 -0
- package/packages/dd-trace/src/profiling/config.js +33 -22
- package/packages/dd-trace/src/profiling/exporter_cli.js +4 -4
- package/packages/dd-trace/src/profiling/exporters/agent.js +5 -5
- package/packages/dd-trace/src/profiling/index.js +1 -1
- package/packages/dd-trace/src/profiling/libuv-size.js +1 -1
- package/packages/dd-trace/src/profiling/profiler.js +4 -5
- package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +11 -2
- package/packages/dd-trace/src/profiling/profilers/wall.js +4 -4
- package/packages/dd-trace/src/proxy.js +17 -18
- package/packages/dd-trace/src/rate_limiter.js +1 -1
- package/packages/dd-trace/src/remote_config/index.js +541 -137
- package/packages/dd-trace/src/require-package-json.js +1 -1
- package/packages/dd-trace/src/ritm.js +50 -27
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +1 -1
- package/packages/dd-trace/src/serverless.js +16 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +8 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
- package/packages/dd-trace/src/span_format.js +10 -5
- package/packages/dd-trace/src/span_processor.js +8 -3
- package/packages/dd-trace/src/span_stats.js +21 -8
- package/packages/dd-trace/src/spanleak.js +1 -1
- package/packages/dd-trace/src/standalone/index.js +1 -1
- package/packages/dd-trace/src/startup-log.js +3 -3
- package/packages/dd-trace/src/supported-configurations.json +16 -0
- package/packages/dd-trace/src/telemetry/dependencies.js +4 -4
- package/packages/dd-trace/src/telemetry/endpoints.js +8 -8
- package/packages/dd-trace/src/telemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +22 -8
- package/packages/dd-trace/src/tracer.js +3 -3
- package/packages/dd-trace/src/tracer_metadata.js +19 -15
- package/vendor/dist/@datadog/sketches-js/LICENSE +39 -0
- package/vendor/dist/@datadog/sketches-js/index.js +1 -0
- package/vendor/dist/@datadog/source-map/LICENSE +28 -0
- package/vendor/dist/@datadog/source-map/index.js +1 -0
- package/vendor/dist/@isaacs/ttlcache/LICENSE +55 -0
- package/vendor/dist/@isaacs/ttlcache/index.js +1 -0
- package/vendor/dist/@opentelemetry/core/LICENSE +201 -0
- package/vendor/dist/@opentelemetry/core/index.js +1 -0
- package/vendor/dist/@opentelemetry/resources/LICENSE +201 -0
- package/vendor/dist/@opentelemetry/resources/index.js +1 -0
- package/vendor/dist/astring/LICENSE +19 -0
- package/vendor/dist/astring/index.js +1 -0
- package/vendor/dist/crypto-randomuuid/index.js +1 -0
- package/vendor/dist/escape-string-regexp/LICENSE +9 -0
- package/vendor/dist/escape-string-regexp/index.js +1 -0
- package/vendor/dist/esquery/LICENSE +24 -0
- package/vendor/dist/esquery/index.js +1 -0
- package/vendor/dist/ignore/LICENSE +21 -0
- package/vendor/dist/ignore/index.js +1 -0
- package/vendor/dist/istanbul-lib-coverage/LICENSE +24 -0
- package/vendor/dist/istanbul-lib-coverage/index.js +1 -0
- package/vendor/dist/jest-docblock/LICENSE +21 -0
- package/vendor/dist/jest-docblock/index.js +1 -0
- package/vendor/dist/jsonpath-plus/LICENSE +22 -0
- package/vendor/dist/jsonpath-plus/index.js +1 -0
- package/vendor/dist/limiter/LICENSE +19 -0
- package/vendor/dist/limiter/index.js +1 -0
- package/vendor/dist/lodash.sortby/LICENSE +47 -0
- package/vendor/dist/lodash.sortby/index.js +1 -0
- package/vendor/dist/lru-cache/LICENSE +15 -0
- package/vendor/dist/lru-cache/index.js +1 -0
- package/vendor/dist/meriyah/LICENSE +7 -0
- package/vendor/dist/meriyah/index.js +1 -0
- package/vendor/dist/module-details-from-path/LICENSE +21 -0
- package/vendor/dist/module-details-from-path/index.js +1 -0
- package/vendor/dist/mutexify/promise/LICENSE +21 -0
- package/vendor/dist/mutexify/promise/index.js +1 -0
- package/vendor/dist/opentracing/LICENSE +201 -0
- package/vendor/dist/opentracing/binary_carrier.d.ts +11 -0
- package/vendor/dist/opentracing/constants.d.ts +61 -0
- package/vendor/dist/opentracing/examples/demo/demo.d.ts +2 -0
- package/vendor/dist/opentracing/ext/tags.d.ts +90 -0
- package/vendor/dist/opentracing/functions.d.ts +20 -0
- package/vendor/dist/opentracing/global_tracer.d.ts +14 -0
- package/vendor/dist/opentracing/index.d.ts +12 -0
- package/vendor/dist/opentracing/index.js +1 -0
- package/vendor/dist/opentracing/mock_tracer/index.d.ts +5 -0
- package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +13 -0
- package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +16 -0
- package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +50 -0
- package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +26 -0
- package/vendor/dist/opentracing/noop.d.ts +8 -0
- package/vendor/dist/opentracing/reference.d.ts +33 -0
- package/vendor/dist/opentracing/span.d.ts +147 -0
- package/vendor/dist/opentracing/span_context.d.ts +26 -0
- package/vendor/dist/opentracing/test/api_compatibility.d.ts +16 -0
- package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +3 -0
- package/vendor/dist/opentracing/test/noop_implementation.d.ts +4 -0
- package/vendor/dist/opentracing/test/opentracing_api.d.ts +3 -0
- package/vendor/dist/opentracing/test/unittest.d.ts +2 -0
- package/vendor/dist/opentracing/tracer.d.ts +127 -0
- package/vendor/dist/path-to-regexp/LICENSE +21 -0
- package/vendor/dist/path-to-regexp/index.js +1 -0
- package/vendor/dist/pprof-format/LICENSE +8 -0
- package/vendor/dist/pprof-format/index.js +1 -0
- package/vendor/dist/protobufjs/LICENSE +39 -0
- package/vendor/dist/protobufjs/index.js +1 -0
- package/vendor/dist/protobufjs/minimal/LICENSE +39 -0
- package/vendor/dist/protobufjs/minimal/index.js +1 -0
- package/vendor/dist/retry/LICENSE +21 -0
- package/vendor/dist/retry/index.js +1 -0
- package/vendor/dist/rfdc/LICENSE +15 -0
- package/vendor/dist/rfdc/index.js +1 -0
- package/vendor/dist/semifies/LICENSE +201 -0
- package/vendor/dist/semifies/index.js +1 -0
- package/vendor/dist/shell-quote/LICENSE +24 -0
- package/vendor/dist/shell-quote/index.js +1 -0
- package/vendor/dist/source-map/LICENSE +28 -0
- package/vendor/dist/source-map/index.js +1 -0
- package/vendor/dist/source-map/lib/util/LICENSE +28 -0
- package/vendor/dist/source-map/lib/util/index.js +1 -0
- package/vendor/dist/source-map/mappings.wasm +0 -0
- package/vendor/dist/tlhunter-sorted-set/LICENSE +21 -0
- package/vendor/dist/tlhunter-sorted-set/index.js +1 -0
- package/vendor/dist/ttl-set/LICENSE +21 -0
- package/vendor/dist/ttl-set/index.js +1 -0
- package/packages/dd-trace/src/remote_config/manager.js +0 -368
|
@@ -8,6 +8,7 @@ module.exports = function getDebuggerConfig (config) {
|
|
|
8
8
|
hostname: config.hostname,
|
|
9
9
|
logLevel: config.logLevel,
|
|
10
10
|
port: config.port,
|
|
11
|
+
propagateProcessTags: config.propagateProcessTags,
|
|
11
12
|
repositoryUrl: config.repositoryUrl,
|
|
12
13
|
runtimeId: config.tags['runtime-id'],
|
|
13
14
|
service: config.service,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const mutex = require('mutexify/promise')()
|
|
3
|
+
const mutex = require('../../../../../vendor/dist/mutexify/promise')()
|
|
4
4
|
const { getGeneratedPosition } = require('./source-maps')
|
|
5
5
|
const session = require('./session')
|
|
6
6
|
const { compile: compileCondition, compileSegments, templateRequiresEvaluation } = require('./condition')
|
|
@@ -64,8 +64,9 @@ async function addBreakpoint (probe) {
|
|
|
64
64
|
const snapshotsPerSecond = probe.sampling?.snapshotsPerSecond ?? (probe.captureSnapshot
|
|
65
65
|
? MAX_SNAPSHOTS_PER_SECOND_PER_PROBE
|
|
66
66
|
: MAX_NON_SNAPSHOTS_PER_SECOND_PER_PROBE)
|
|
67
|
-
probe.nsBetweenSampling = BigInt(1 / snapshotsPerSecond * 1e9)
|
|
68
|
-
probe
|
|
67
|
+
probe.nsBetweenSampling = BigInt(Math.trunc(1 / snapshotsPerSecond * 1e9))
|
|
68
|
+
// Initialize to a large negative value to ensure first probe hit is always captured
|
|
69
|
+
probe.lastCaptureNs = BigInt(Number.MIN_SAFE_INTEGER)
|
|
69
70
|
|
|
70
71
|
// Warning: The code below relies on undocumented behavior of the inspector!
|
|
71
72
|
// It expects that `await session.post('Debugger.enable')` will wait for all loaded scripts to be emitted as
|
|
@@ -80,8 +81,17 @@ async function addBreakpoint (probe) {
|
|
|
80
81
|
log.debug(
|
|
81
82
|
'[debugger:devtools_client] Translating location using source map for %s:%d:%d (probe: %s, version: %d)',
|
|
82
83
|
file, lineNumber, columnNumber, probe.id, probe.version
|
|
83
|
-
)
|
|
84
|
-
|
|
84
|
+
)
|
|
85
|
+
const position = await getGeneratedPosition(url, source, lineNumber, sourceMapURL)
|
|
86
|
+
if (position.line !== null && position.column !== null) {
|
|
87
|
+
lineNumber = position.line
|
|
88
|
+
columnNumber = position.column
|
|
89
|
+
} else {
|
|
90
|
+
throw new Error(
|
|
91
|
+
// eslint-disable-next-line @stylistic/max-len
|
|
92
|
+
`Could not find generated position for ${url}:${lineNumber}:${columnNumber} (probe: ${probe.id}, version: ${probe.version})`
|
|
93
|
+
)
|
|
94
|
+
}
|
|
85
95
|
}
|
|
86
96
|
|
|
87
97
|
try {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const { workerData: { config: parentConfig, parentThreadId, configPort } } = require('node:worker_threads')
|
|
4
4
|
const { format } = require('node:url')
|
|
5
|
-
const log = require('./log')
|
|
6
5
|
const defaults = require('../../config_defaults')
|
|
6
|
+
const log = require('./log')
|
|
7
7
|
|
|
8
8
|
const config = module.exports = {
|
|
9
9
|
...parentConfig,
|
|
@@ -24,4 +24,6 @@ function updateUrl (updates) {
|
|
|
24
24
|
hostname: updates.hostname || defaults.hostname,
|
|
25
25
|
port: updates.port
|
|
26
26
|
})
|
|
27
|
+
|
|
28
|
+
config.dynamicInstrumentation.captureTimeoutNs = BigInt(updates.dynamicInstrumentation.captureTimeoutMs) * 1_000_000n
|
|
27
29
|
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { randomUUID } = require('crypto')
|
|
4
|
+
const { version } = require('../../../../../package.json')
|
|
5
|
+
const { NODE_MAJOR } = require('../../../../../version')
|
|
6
|
+
const processTags = require('../../process-tags')
|
|
4
7
|
const { breakpointToProbes } = require('./state')
|
|
5
8
|
const session = require('./session')
|
|
6
9
|
const { getLocalStateForCallFrame } = require('./snapshot')
|
|
7
10
|
const send = require('./send')
|
|
8
11
|
const { getStackFromCallFrames } = require('./state')
|
|
9
12
|
const { ackEmitting } = require('./status')
|
|
10
|
-
const
|
|
13
|
+
const config = require('./config')
|
|
11
14
|
const { MAX_SNAPSHOTS_PER_SECOND_GLOBALLY } = require('./defaults')
|
|
12
15
|
const log = require('./log')
|
|
13
|
-
const { version } = require('../../../../../package.json')
|
|
14
|
-
const { NODE_MAJOR } = require('../../../../../version')
|
|
15
16
|
|
|
16
17
|
require('./remote_config')
|
|
17
18
|
|
|
@@ -33,8 +34,8 @@ const getDDTagsExpression = `(() => {
|
|
|
33
34
|
|
|
34
35
|
// There doesn't seem to be an official standard for the content of these fields, so we're just populating them with
|
|
35
36
|
// something that should be useful to a Node.js developer.
|
|
36
|
-
const threadId = parentThreadId === 0 ? `pid:${process.pid}` : `pid:${process.pid};tid:${parentThreadId}`
|
|
37
|
-
const threadName = parentThreadId === 0 ? 'MainThread' : `WorkerThread:${parentThreadId}`
|
|
37
|
+
const threadId = config.parentThreadId === 0 ? `pid:${process.pid}` : `pid:${process.pid};tid:${config.parentThreadId}`
|
|
38
|
+
const threadName = config.parentThreadId === 0 ? 'MainThread' : `WorkerThread:${config.parentThreadId}`
|
|
38
39
|
|
|
39
40
|
const SUPPORT_ARRAY_BUFFER_RESIZE = NODE_MAJOR >= 20
|
|
40
41
|
const oneSecondNs = 1_000_000_000n
|
|
@@ -46,6 +47,7 @@ let snapshotProbeIndexBuffer, snapshotProbeIndex
|
|
|
46
47
|
|
|
47
48
|
if (SUPPORT_ARRAY_BUFFER_RESIZE) {
|
|
48
49
|
// TODO: Is a limit of 256 snapshots ever going to be a problem?
|
|
50
|
+
// @ts-ignore - ArrayBuffer constructor with maxByteLength is available in Node.js 20+ but not in @types/node@18
|
|
49
51
|
// eslint-disable-next-line n/no-unsupported-features/es-syntax
|
|
50
52
|
snapshotProbeIndexBuffer = new ArrayBuffer(1, { maxByteLength: 256 })
|
|
51
53
|
// TODO: Is a limit of 256 probes ever going to be a problem?
|
|
@@ -165,13 +167,20 @@ session.on('Debugger.paused', async ({ params }) => {
|
|
|
165
167
|
}
|
|
166
168
|
|
|
167
169
|
// TODO: Create unique states for each affected probe based on that probes unique `capture` settings (DEBUG-2863)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
let processLocalState, captureErrors
|
|
171
|
+
if (numberOfProbesWithSnapshots !== 0) {
|
|
172
|
+
const opts = {
|
|
173
|
+
maxReferenceDepth,
|
|
174
|
+
maxCollectionSize,
|
|
175
|
+
maxFieldCount,
|
|
176
|
+
maxLength,
|
|
177
|
+
deadlineNs: start + config.dynamicInstrumentation.captureTimeoutNs
|
|
178
|
+
}
|
|
179
|
+
;({ processLocalState, captureErrors } = await getLocalStateForCallFrame(params.callFrames[0], opts))
|
|
180
|
+
}
|
|
172
181
|
|
|
173
182
|
await session.post('Debugger.resume')
|
|
174
|
-
const diff = process.hrtime.bigint() - start // TODO:
|
|
183
|
+
const diff = process.hrtime.bigint() - start // TODO: Recorded as telemetry (DEBUG-2858)
|
|
175
184
|
|
|
176
185
|
// This doesn't measure the overhead of the CDP protocol. The actual pause time is slightly larger.
|
|
177
186
|
// On my machine I'm seeing around 1.7ms of overhead.
|
|
@@ -207,15 +216,26 @@ session.on('Debugger.paused', async ({ params }) => {
|
|
|
207
216
|
language: 'javascript'
|
|
208
217
|
}
|
|
209
218
|
|
|
219
|
+
if (config.propagateProcessTags.enabled) {
|
|
220
|
+
snapshot[processTags.DYNAMIC_INSTRUMENTATION_FIELD_NAME] = processTags.tagsObject
|
|
221
|
+
}
|
|
222
|
+
|
|
210
223
|
if (probe.captureSnapshot) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
224
|
+
if (captureErrors?.length > 0) {
|
|
225
|
+
// There was an error collecting the snapshot for this probe, let's not try again
|
|
226
|
+
probe.captureSnapshot = false
|
|
227
|
+
probe.permanentEvaluationErrors = captureErrors.map(error => ({
|
|
228
|
+
expr: '',
|
|
229
|
+
message: error.message
|
|
230
|
+
}))
|
|
218
231
|
}
|
|
232
|
+
snapshot.captures = {
|
|
233
|
+
lines: { [probe.location.lines[0]]: { locals: processLocalState() } }
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (probe.permanentEvaluationErrors !== undefined) {
|
|
238
|
+
snapshot.evaluationErrors = [...probe.permanentEvaluationErrors]
|
|
219
239
|
}
|
|
220
240
|
|
|
221
241
|
let message = ''
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
const { builtinModules } = require('node:module')
|
|
6
6
|
|
|
7
7
|
if (builtinModules.includes('inspector/promises')) {
|
|
8
|
+
// @ts-ignore - inspector/promises is available in Node.js 20+ but not in @types/node@18
|
|
8
9
|
module.exports = require('node:inspector/promises')
|
|
9
10
|
} else {
|
|
10
11
|
const inspector = require('node:inspector')
|
|
@@ -12,6 +13,7 @@ if (builtinModules.includes('inspector/promises')) {
|
|
|
12
13
|
|
|
13
14
|
// The rest of the code in this file is lifted from:
|
|
14
15
|
// https://github.com/nodejs/node/blob/1d4d76ff3fb08f9a0c55a1d5530b46c4d5d550c7/lib/inspector/promises.js
|
|
16
|
+
// @ts-expect-error - We intentionally override 'post' with a promisified version, changing its signature
|
|
15
17
|
class Session extends inspector.Session {
|
|
16
18
|
constructor () { super() } // eslint-disable-line no-useless-constructor
|
|
17
19
|
}
|
|
@@ -1,34 +1,40 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
class JSONBuffer {
|
|
4
|
+
#maxSize
|
|
5
|
+
#timeout
|
|
6
|
+
#onFlush
|
|
7
|
+
#timer
|
|
8
|
+
#partialJson
|
|
9
|
+
|
|
4
10
|
constructor ({ size, timeout, onFlush }) {
|
|
5
|
-
this
|
|
6
|
-
this
|
|
7
|
-
this
|
|
8
|
-
this
|
|
11
|
+
this.#maxSize = size
|
|
12
|
+
this.#timeout = timeout
|
|
13
|
+
this.#onFlush = onFlush
|
|
14
|
+
this.#reset()
|
|
9
15
|
}
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
clearTimeout(this
|
|
13
|
-
this
|
|
14
|
-
this
|
|
17
|
+
#reset () {
|
|
18
|
+
clearTimeout(this.#timer)
|
|
19
|
+
this.#timer = undefined
|
|
20
|
+
this.#partialJson = undefined
|
|
15
21
|
}
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
const json = `${this
|
|
19
|
-
this
|
|
20
|
-
this
|
|
23
|
+
#flush () {
|
|
24
|
+
const json = `${this.#partialJson}]`
|
|
25
|
+
this.#reset()
|
|
26
|
+
this.#onFlush(json)
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
write (str, size = Buffer.byteLength(str)) {
|
|
24
|
-
if (this
|
|
25
|
-
this
|
|
26
|
-
this
|
|
27
|
-
} else if (Buffer.byteLength(this
|
|
28
|
-
this
|
|
30
|
+
if (this.#timer === undefined) {
|
|
31
|
+
this.#partialJson = `[${str}`
|
|
32
|
+
this.#timer = setTimeout(() => this.#flush(), this.#timeout)
|
|
33
|
+
} else if (Buffer.byteLength(/** @type {string} */ (this.#partialJson)) + size + 2 > this.#maxSize) {
|
|
34
|
+
this.#flush()
|
|
29
35
|
this.write(str, size)
|
|
30
36
|
} else {
|
|
31
|
-
this
|
|
37
|
+
this.#partialJson += `,${str}`
|
|
32
38
|
}
|
|
33
39
|
}
|
|
34
40
|
}
|
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
const { hostname: getHostname } = require('os')
|
|
4
4
|
const { stringify } = require('querystring')
|
|
5
5
|
|
|
6
|
-
const config = require('./config')
|
|
7
|
-
const JSONBuffer = require('./json-buffer')
|
|
8
6
|
const request = require('../../exporters/common/request')
|
|
9
7
|
const { GIT_COMMIT_SHA, GIT_REPOSITORY_URL } = require('../../plugins/util/tags')
|
|
10
|
-
const log = require('./log')
|
|
11
8
|
const { version } = require('../../../../../package.json')
|
|
12
9
|
const { getEnvironmentVariable } = require('../../config-helper')
|
|
10
|
+
const log = require('./log')
|
|
11
|
+
const JSONBuffer = require('./json-buffer')
|
|
12
|
+
const config = require('./config')
|
|
13
|
+
const { pruneSnapshot } = require('./snapshot-pruner')
|
|
13
14
|
|
|
14
15
|
module.exports = send
|
|
15
16
|
|
|
@@ -55,14 +56,23 @@ function send (message, logger, dd, snapshot) {
|
|
|
55
56
|
let size = Buffer.byteLength(json)
|
|
56
57
|
|
|
57
58
|
if (size > MAX_LOG_PAYLOAD_SIZE_BYTES) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
'
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
let pruned
|
|
60
|
+
try {
|
|
61
|
+
pruned = pruneSnapshot(json, size, MAX_LOG_PAYLOAD_SIZE_BYTES)
|
|
62
|
+
} catch (err) {
|
|
63
|
+
log.error('[debugger:devtools_client] Error pruning snapshot', err)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (pruned) {
|
|
67
|
+
json = pruned
|
|
68
|
+
size = Buffer.byteLength(json)
|
|
69
|
+
} else {
|
|
70
|
+
// Fallback if pruning fails
|
|
71
|
+
const line = Object.keys(snapshot.captures.lines)[0]
|
|
72
|
+
snapshot.captures.lines[line] = { pruned: true }
|
|
73
|
+
json = JSON.stringify(payload)
|
|
74
|
+
size = Buffer.byteLength(json)
|
|
75
|
+
}
|
|
66
76
|
}
|
|
67
77
|
|
|
68
78
|
jsonBuffer.write(json, size)
|
|
@@ -7,7 +7,7 @@ const inspector = require('./inspector_promises_polyfill')
|
|
|
7
7
|
* connect: () => void,
|
|
8
8
|
* connectToMainThread: () => void
|
|
9
9
|
* disconnect: () => void,
|
|
10
|
-
* post: (method: string, params?: object) => Promise<
|
|
10
|
+
* post: (method: string, params?: object) => Promise<unknown>,
|
|
11
11
|
* }} CDPSession
|
|
12
12
|
*/
|
|
13
13
|
const session = /** @type {CDPSession} */ (new inspector.Session())
|
|
@@ -1,16 +1,42 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { collectionSizeSym, fieldCountSym } = require('./symbols')
|
|
4
3
|
const session = require('../session')
|
|
4
|
+
const { collectionSizeSym, largeCollectionSkipThresholdSym, fieldCountSym, timeBudgetSym } = require('./symbols')
|
|
5
|
+
const { LARGE_OBJECT_SKIP_THRESHOLD } = require('./constants')
|
|
5
6
|
|
|
6
7
|
const LEAF_SUBTYPES = new Set(['date', 'regexp'])
|
|
7
8
|
const ITERABLE_SUBTYPES = new Set(['map', 'set', 'weakmap', 'weakset'])
|
|
9
|
+
const SIZE_IN_DESCRIPTION_SUBTYPES = new Set(['array', 'typedarray', 'arraybuffer', 'dataview', 'map', 'set'])
|
|
8
10
|
|
|
9
11
|
module.exports = {
|
|
10
|
-
|
|
12
|
+
collectObjectProperties
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {object} GetObjectOptions
|
|
17
|
+
* @property {object} maxReferenceDepth - The maximum depth of the object to traverse
|
|
18
|
+
* @property {number} maxCollectionSize - The maximum size of a collection to include in the snapshot
|
|
19
|
+
* @property {number} maxFieldCount - The maximum number of properties on an object to include in the snapshot
|
|
20
|
+
* @property {bigint} deadlineNs - The deadline in nanoseconds compared to `process.hrtime.bigint()`
|
|
21
|
+
* @property {object} ctx - A context object to track the state/progress of the snapshot collection.
|
|
22
|
+
* @property {boolean} ctx.deadlineReached - Will be set to `true` if the deadline has been reached.
|
|
23
|
+
* @property {Error[]} ctx.captureErrors - An array on which errors can be pushed if an issue is detected while
|
|
24
|
+
* collecting the snapshot.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Collect the properties of an object using the Chrome DevTools Protocol.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} objectId - The ID of the object to get the properties of
|
|
31
|
+
* @param {GetObjectOptions} opts - The options for the snapshot. Also used to track the deadline and communicate the
|
|
32
|
+
* deadline overrun to the caller using the `deadlineReached` flag.
|
|
33
|
+
* @param {number} [depth=0] - The depth of the object. Only used internally by this module to track the current depth
|
|
34
|
+
* and should not be set by the caller.
|
|
35
|
+
* @param {boolean} [collection=false] - Whether the object is a collection. Only used internally by this module to
|
|
36
|
+
* track the current object type and should not be set by the caller.
|
|
37
|
+
* @returns {Promise<object[]>} The properties of the object
|
|
38
|
+
*/
|
|
39
|
+
async function collectObjectProperties (objectId, opts, depth = 0, collection = false) {
|
|
14
40
|
const { result, privateProperties } = await session.post('Runtime.getProperties', {
|
|
15
41
|
objectId,
|
|
16
42
|
ownProperties: true // exclude inherited properties
|
|
@@ -28,6 +54,13 @@ async function getObject (objectId, opts, depth = 0, collection = false) {
|
|
|
28
54
|
} else if (result.length > opts.maxFieldCount) {
|
|
29
55
|
// Trim the number of properties on the object if there's too many.
|
|
30
56
|
const size = result.length
|
|
57
|
+
if (size > LARGE_OBJECT_SKIP_THRESHOLD) {
|
|
58
|
+
opts.ctx.captureErrors.push(new Error(
|
|
59
|
+
`An object with ${size} properties was detected while collecting a snapshot. ` +
|
|
60
|
+
`This exceeds the maximum number of allowed properties of ${LARGE_OBJECT_SKIP_THRESHOLD}. ` +
|
|
61
|
+
'Future snapshots for existing probes in this location will be skipped until the Node.js process is restarted'
|
|
62
|
+
))
|
|
63
|
+
}
|
|
31
64
|
result.length = opts.maxFieldCount
|
|
32
65
|
result[fieldCountSym] = size
|
|
33
66
|
} else if (privateProperties) {
|
|
@@ -43,32 +76,61 @@ async function traverseGetPropertiesResult (props, opts, depth) {
|
|
|
43
76
|
|
|
44
77
|
if (depth >= opts.maxReferenceDepth) return props
|
|
45
78
|
|
|
46
|
-
const
|
|
79
|
+
const work = []
|
|
47
80
|
|
|
48
81
|
for (const prop of props) {
|
|
49
82
|
if (prop.value === undefined) continue
|
|
50
|
-
const { value: { type, objectId, subtype } } = prop
|
|
83
|
+
const { value: { type, objectId, subtype, description } } = prop
|
|
51
84
|
if (type === 'object') {
|
|
52
85
|
if (objectId === undefined) continue // if `subtype` is "null"
|
|
53
86
|
if (LEAF_SUBTYPES.has(subtype)) continue // don't waste time with these subtypes
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
87
|
+
const size = parseLengthFromDescription(description, subtype)
|
|
88
|
+
if (size !== null && size >= LARGE_OBJECT_SKIP_THRESHOLD) {
|
|
89
|
+
const empty = []
|
|
90
|
+
empty[largeCollectionSkipThresholdSym] = size
|
|
91
|
+
prop.value.properties = empty
|
|
92
|
+
continue
|
|
93
|
+
}
|
|
94
|
+
work.push([
|
|
95
|
+
prop.value,
|
|
96
|
+
() => collectPropertiesBySubtype(subtype, objectId, opts, depth).then((properties) => {
|
|
97
|
+
prop.value.properties = properties
|
|
98
|
+
})
|
|
99
|
+
])
|
|
57
100
|
} else if (type === 'function') {
|
|
58
|
-
|
|
59
|
-
prop.value
|
|
60
|
-
|
|
101
|
+
work.push([
|
|
102
|
+
prop.value,
|
|
103
|
+
() => getFunctionProperties(objectId, opts, depth + 1).then((properties) => {
|
|
104
|
+
prop.value.properties = properties
|
|
105
|
+
})
|
|
106
|
+
])
|
|
61
107
|
}
|
|
62
108
|
}
|
|
63
109
|
|
|
64
|
-
if (
|
|
65
|
-
|
|
110
|
+
if (work.length) {
|
|
111
|
+
// Iterate over the work in chunks of 2. The closer to 1, the less we'll overshoot the deadline, but the longer it
|
|
112
|
+
// takes to complete. `2` seems to be the best compromise.
|
|
113
|
+
// Anecdotally, on my machine, with no deadline, a concurrency of `1` takes twice as long as a concurrency of `2`.
|
|
114
|
+
// From thereon, there's no real measurable savings with a higher concurrency.
|
|
115
|
+
for (let i = 0; i < work.length; i += 2) {
|
|
116
|
+
if (overBudget(opts)) {
|
|
117
|
+
for (let j = i; j < work.length; j++) {
|
|
118
|
+
work[j][0][timeBudgetSym] = true
|
|
119
|
+
}
|
|
120
|
+
break
|
|
121
|
+
}
|
|
122
|
+
// eslint-disable-next-line no-await-in-loop
|
|
123
|
+
await Promise.all([
|
|
124
|
+
work[i][1](),
|
|
125
|
+
work[i + 1]?.[1]()
|
|
126
|
+
])
|
|
127
|
+
}
|
|
66
128
|
}
|
|
67
129
|
|
|
68
130
|
return props
|
|
69
131
|
}
|
|
70
132
|
|
|
71
|
-
function
|
|
133
|
+
function collectPropertiesBySubtype (subtype, objectId, opts, depth) {
|
|
72
134
|
if (ITERABLE_SUBTYPES.has(subtype)) {
|
|
73
135
|
return getIterable(objectId, opts, depth)
|
|
74
136
|
} else if (subtype === 'promise') {
|
|
@@ -78,7 +140,7 @@ function getObjectProperties (subtype, objectId, opts, depth) {
|
|
|
78
140
|
} else if (subtype === 'arraybuffer') {
|
|
79
141
|
return getArrayBuffer(objectId, opts, depth)
|
|
80
142
|
}
|
|
81
|
-
return
|
|
143
|
+
return collectObjectProperties(objectId, opts, depth + 1, subtype === 'array' || subtype === 'typedarray')
|
|
82
144
|
}
|
|
83
145
|
|
|
84
146
|
// TODO: The following extra information from `internalProperties` might be relevant to include for functions:
|
|
@@ -189,3 +251,29 @@ function removeNonEnumerableProperties (props) {
|
|
|
189
251
|
}
|
|
190
252
|
}
|
|
191
253
|
}
|
|
254
|
+
|
|
255
|
+
function parseLengthFromDescription (description, subtype) {
|
|
256
|
+
if (typeof description !== 'string') return null
|
|
257
|
+
if (!SIZE_IN_DESCRIPTION_SUBTYPES.has(subtype)) return null
|
|
258
|
+
|
|
259
|
+
const open = description.lastIndexOf('(')
|
|
260
|
+
if (open === -1) return null
|
|
261
|
+
|
|
262
|
+
const close = description.indexOf(')', open + 1)
|
|
263
|
+
if (close === -1) return null
|
|
264
|
+
|
|
265
|
+
const s = description.slice(open + 1, close)
|
|
266
|
+
if (s === '') return null
|
|
267
|
+
|
|
268
|
+
const n = Number(s)
|
|
269
|
+
if (!Number.isSafeInteger(n) || n < 0) return null
|
|
270
|
+
if (String(n) !== s) return null
|
|
271
|
+
|
|
272
|
+
return n
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function overBudget (opts) {
|
|
276
|
+
if (opts.ctx.deadlineReached) return true
|
|
277
|
+
opts.ctx.deadlineReached = process.hrtime.bigint() >= opts.deadlineNs
|
|
278
|
+
return opts.ctx.deadlineReached
|
|
279
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { getEnvironmentVariable } = require('../../../config-helper')
|
|
4
|
+
|
|
5
|
+
const largeObjectSkipThreshold = Number(
|
|
6
|
+
getEnvironmentVariable('_DD_DYNAMIC_INSTRUMENTATION_EXPERIMENTAL_LARGE_OBJECT_SKIP_THRESHOLD')
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
/**
|
|
11
|
+
* When collecting a snapshot, this constant controls what happens when objects with a large number of properties or
|
|
12
|
+
* collections (arrays, maps, sets, etc.) with a large number of elements are detected:
|
|
13
|
+
*
|
|
14
|
+
* - If a collection is detected with more than this number of elements, none of its elements will be included in the
|
|
15
|
+
* snapshot.
|
|
16
|
+
* - If an object is detected with more than this number of properties, it will be included in the snapshot, but
|
|
17
|
+
* snapshotting will be turned off for that probe in the future, until the probe is either updated or the Node.js
|
|
18
|
+
* process is restarted.
|
|
19
|
+
*/
|
|
20
|
+
LARGE_OBJECT_SKIP_THRESHOLD: Number.isNaN(largeObjectSkipThreshold) ? 500 : largeObjectSkipThreshold,
|
|
21
|
+
DEFAULT_MAX_COLLECTION_SIZE: 100,
|
|
22
|
+
DEFAULT_MAX_FIELD_COUNT: 20,
|
|
23
|
+
DEFAULT_MAX_LENGTH: 255,
|
|
24
|
+
DEFAULT_MAX_REFERENCE_DEPTH: 3,
|
|
25
|
+
}
|
|
@@ -1,52 +1,83 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const {
|
|
4
|
+
DEFAULT_MAX_REFERENCE_DEPTH,
|
|
5
|
+
DEFAULT_MAX_COLLECTION_SIZE,
|
|
6
|
+
DEFAULT_MAX_FIELD_COUNT,
|
|
7
|
+
DEFAULT_MAX_LENGTH
|
|
8
|
+
} = require('./constants')
|
|
9
|
+
const { collectObjectProperties } = require('./collector')
|
|
4
10
|
const { processRawState } = require('./processor')
|
|
5
|
-
const log = require('../log')
|
|
6
11
|
|
|
7
|
-
const
|
|
8
|
-
const DEFAULT_MAX_COLLECTION_SIZE = 100
|
|
9
|
-
const DEFAULT_MAX_FIELD_COUNT = 20
|
|
10
|
-
const DEFAULT_MAX_LENGTH = 255
|
|
12
|
+
const BIGINT_MAX = (1n << 256n) - 1n
|
|
11
13
|
|
|
12
14
|
module.exports = {
|
|
13
15
|
getLocalStateForCallFrame
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {object} GetLocalStateForCallFrameOptions
|
|
20
|
+
* @property {number} [maxReferenceDepth] - The maximum depth of the object to traverse. Defaults to
|
|
21
|
+
* {@link DEFAULT_MAX_REFERENCE_DEPTH}.
|
|
22
|
+
* @property {number} [maxCollectionSize] - The maximum size of a collection to include in the snapshot. Defaults to
|
|
23
|
+
* {@link DEFAULT_MAX_COLLECTION_SIZE}.
|
|
24
|
+
* @property {number} [maxFieldCount] - The maximum number of properties on an object to include in the snapshot.
|
|
25
|
+
* Defaults to {@link DEFAULT_MAX_FIELD_COUNT}.
|
|
26
|
+
* @property {number} [maxLength] - The maximum length of a string to include in the snapshot. Defaults to
|
|
27
|
+
* {@link DEFAULT_MAX_LENGTH}.
|
|
28
|
+
* @property {bigint} [deadlineNs] - The deadline in nanoseconds compared to `process.hrtime.bigint()`. Defaults to
|
|
29
|
+
* {@link BIGINT_MAX}. If the deadline is reached, the snapshot will be truncated.
|
|
30
|
+
*/
|
|
19
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Get the local state for a call frame.
|
|
34
|
+
*
|
|
35
|
+
* @param {import('inspector').Debugger.CallFrame} callFrame - The call frame to get the local state for
|
|
36
|
+
* @param {GetLocalStateForCallFrameOptions} [opts] - The options for the snapshot
|
|
37
|
+
* @returns {Promise<object>} The local state for the call frame
|
|
38
|
+
*/
|
|
20
39
|
async function getLocalStateForCallFrame (
|
|
21
40
|
callFrame,
|
|
22
41
|
{
|
|
23
42
|
maxReferenceDepth = DEFAULT_MAX_REFERENCE_DEPTH,
|
|
24
43
|
maxCollectionSize = DEFAULT_MAX_COLLECTION_SIZE,
|
|
25
44
|
maxFieldCount = DEFAULT_MAX_FIELD_COUNT,
|
|
26
|
-
maxLength = DEFAULT_MAX_LENGTH
|
|
45
|
+
maxLength = DEFAULT_MAX_LENGTH,
|
|
46
|
+
deadlineNs = BIGINT_MAX
|
|
27
47
|
} = {}
|
|
28
48
|
) {
|
|
49
|
+
/** @type {{ deadlineReached: boolean, captureErrors: Error[] }} */
|
|
50
|
+
const ctx = { deadlineReached: false, captureErrors: [] }
|
|
51
|
+
const opts = { maxReferenceDepth, maxCollectionSize, maxFieldCount, deadlineNs, ctx }
|
|
29
52
|
const rawState = []
|
|
30
53
|
let processedState = null
|
|
31
54
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
55
|
+
for (const scope of callFrame.scopeChain) {
|
|
56
|
+
if (scope.type === 'global') continue // The global scope is too noisy
|
|
57
|
+
const { objectId } = scope.object
|
|
58
|
+
if (objectId === undefined) continue // I haven't seen this happen, but according to the types it's possible
|
|
59
|
+
try {
|
|
60
|
+
// The objectId for a scope points to a pseudo-object whose properties are the actual variables in the scope.
|
|
61
|
+
// This is why we can just call `collectObjectProperties` directly and expect it to return the in-scope variables
|
|
62
|
+
// as an array.
|
|
63
|
+
// eslint-disable-next-line no-await-in-loop
|
|
64
|
+
rawState.push(...await collectObjectProperties(objectId, opts))
|
|
65
|
+
} catch (err) {
|
|
66
|
+
ctx.captureErrors.push(new Error(
|
|
67
|
+
`Error getting local state for closure scope (type: ${scope.type}). ` +
|
|
68
|
+
'Future snapshots for existing probes in this location will be skipped until the Node.js process is restarted',
|
|
69
|
+
{ cause: err } // TODO: The cause is not used by the backend
|
|
38
70
|
))
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// TODO: We might be able to get part of the scope chain.
|
|
42
|
-
// Consider if we could set errors just for the part of the scope chain that throws during collection.
|
|
43
|
-
log.error('[debugger:devtools_client] Error getting local state for call frame', err)
|
|
44
|
-
return returnError
|
|
71
|
+
}
|
|
72
|
+
if (ctx.deadlineReached === true) break // TODO: Bad UX; Variables in remaining scopes are silently dropped
|
|
45
73
|
}
|
|
46
74
|
|
|
47
75
|
// Delay calling `processRawState` so the caller gets a chance to resume the main thread before processing `rawState`
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
76
|
+
return {
|
|
77
|
+
processLocalState () {
|
|
78
|
+
processedState = processedState ?? processRawState(rawState, maxLength)
|
|
79
|
+
return processedState
|
|
80
|
+
},
|
|
81
|
+
captureErrors: ctx.captureErrors
|
|
51
82
|
}
|
|
52
83
|
}
|