dd-trace 5.53.0 → 5.55.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 +2 -1
- package/ci/cypress/plugin.js +8 -0
- package/ci/cypress/polyfills.js +23 -0
- package/ci/init.js +8 -7
- package/index.d.ts +33 -16
- package/initialize.mjs +5 -6
- package/package.json +40 -38
- package/packages/datadog-code-origin/index.js +22 -4
- package/packages/datadog-core/src/utils/src/get.js +1 -1
- package/packages/datadog-core/src/utils/src/has.js +1 -1
- package/packages/datadog-core/src/utils/src/kebabcase.js +4 -6
- package/packages/datadog-core/src/utils/src/parse-tags.js +1 -1
- package/packages/datadog-core/src/utils/src/pick.js +2 -2
- package/packages/datadog-core/src/utils/src/set.js +1 -1
- package/packages/datadog-core/src/utils/src/uniq.js +1 -1
- package/packages/datadog-instrumentations/src/amqp10.js +19 -17
- package/packages/datadog-instrumentations/src/amqplib.js +52 -35
- package/packages/datadog-instrumentations/src/apollo.js +2 -2
- package/packages/datadog-instrumentations/src/aws-sdk.js +1 -1
- package/packages/datadog-instrumentations/src/cassandra-driver.js +10 -10
- package/packages/datadog-instrumentations/src/child_process.js +1 -2
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +89 -75
- package/packages/datadog-instrumentations/src/cookie-parser.js +1 -1
- package/packages/datadog-instrumentations/src/couchbase.js +6 -9
- package/packages/datadog-instrumentations/src/cucumber.js +108 -68
- package/packages/datadog-instrumentations/src/cypress.js +2 -1
- package/packages/datadog-instrumentations/src/dns.js +5 -5
- package/packages/datadog-instrumentations/src/elasticsearch.js +9 -10
- package/packages/datadog-instrumentations/src/fastify.js +7 -9
- package/packages/datadog-instrumentations/src/fs.js +1 -1
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +35 -43
- package/packages/datadog-instrumentations/src/graphql.js +7 -10
- package/packages/datadog-instrumentations/src/grpc/client.js +11 -23
- package/packages/datadog-instrumentations/src/grpc/server.js +7 -20
- package/packages/datadog-instrumentations/src/hapi.js +10 -11
- package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +16 -10
- package/packages/datadog-instrumentations/src/helpers/fetch.js +4 -5
- package/packages/datadog-instrumentations/src/helpers/hook.js +2 -3
- package/packages/datadog-instrumentations/src/helpers/hooks.js +0 -1
- package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -41
- package/packages/datadog-instrumentations/src/helpers/register.js +11 -12
- package/packages/datadog-instrumentations/src/http/client.js +14 -20
- package/packages/datadog-instrumentations/src/jest.js +201 -143
- package/packages/datadog-instrumentations/src/kafkajs.js +52 -44
- package/packages/datadog-instrumentations/src/knex.js +4 -4
- package/packages/datadog-instrumentations/src/koa.js +2 -3
- package/packages/datadog-instrumentations/src/ldapjs.js +3 -4
- package/packages/datadog-instrumentations/src/mariadb.js +49 -65
- package/packages/datadog-instrumentations/src/mocha/main.js +116 -73
- package/packages/datadog-instrumentations/src/mocha/utils.js +36 -12
- package/packages/datadog-instrumentations/src/mocha/worker.js +6 -0
- package/packages/datadog-instrumentations/src/mocha.js +3 -1
- package/packages/datadog-instrumentations/src/mongodb-core.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +30 -37
- package/packages/datadog-instrumentations/src/mysql2.js +53 -47
- package/packages/datadog-instrumentations/src/net.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +1 -0
- package/packages/datadog-instrumentations/src/nyc.js +3 -2
- package/packages/datadog-instrumentations/src/openai.js +22 -24
- package/packages/datadog-instrumentations/src/oracledb.js +1 -1
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -3
- package/packages/datadog-instrumentations/src/pg.js +3 -5
- package/packages/datadog-instrumentations/src/playwright.js +123 -83
- package/packages/datadog-instrumentations/src/protobufjs.js +3 -4
- package/packages/datadog-instrumentations/src/redis.js +4 -4
- package/packages/datadog-instrumentations/src/restify.js +9 -13
- package/packages/datadog-instrumentations/src/rhea.js +42 -54
- package/packages/datadog-instrumentations/src/router.js +30 -32
- package/packages/datadog-instrumentations/src/tedious.js +2 -3
- package/packages/datadog-instrumentations/src/vitest.js +87 -52
- package/packages/datadog-plugin-amqp10/src/consumer.js +7 -3
- package/packages/datadog-plugin-amqp10/src/producer.js +7 -3
- package/packages/datadog-plugin-amqplib/src/client.js +6 -2
- package/packages/datadog-plugin-amqplib/src/consumer.js +7 -3
- package/packages/datadog-plugin-amqplib/src/producer.js +7 -3
- package/packages/datadog-plugin-amqplib/src/util.js +1 -1
- package/packages/datadog-plugin-apollo/src/gateway/request.js +5 -6
- package/packages/datadog-plugin-apollo/src/gateway/validate.js +2 -3
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +12 -12
- package/packages/datadog-plugin-aws-sdk/src/base.js +15 -10
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +13 -13
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +28 -43
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +10 -11
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +4 -6
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -3
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +11 -15
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +5 -6
- package/packages/datadog-plugin-cassandra-driver/src/index.js +1 -1
- package/packages/datadog-plugin-child_process/src/index.js +4 -4
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +23 -23
- package/packages/datadog-plugin-cucumber/src/index.js +60 -4
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +99 -28
- package/packages/datadog-plugin-cypress/src/plugin.js +11 -1
- package/packages/datadog-plugin-cypress/src/support.js +24 -5
- package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -1
- package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
- package/packages/datadog-plugin-express/src/code_origin.js +30 -0
- package/packages/datadog-plugin-express/src/index.js +10 -12
- package/packages/datadog-plugin-express/src/tracing.js +19 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +7 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +12 -7
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +6 -2
- package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +27 -10
- package/packages/datadog-plugin-graphql/src/execute.js +2 -2
- package/packages/datadog-plugin-graphql/src/index.js +10 -8
- package/packages/datadog-plugin-graphql/src/resolve.js +19 -12
- package/packages/datadog-plugin-graphql/src/tools/index.js +1 -0
- package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -0
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +1 -0
- package/packages/datadog-plugin-grpc/src/client.js +2 -2
- package/packages/datadog-plugin-grpc/src/util.js +2 -2
- package/packages/datadog-plugin-http/src/client.js +23 -13
- package/packages/datadog-plugin-http2/src/client.js +24 -25
- package/packages/datadog-plugin-jest/src/index.js +26 -23
- package/packages/datadog-plugin-jest/src/util.js +8 -8
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +3 -1
- package/packages/datadog-plugin-kafkajs/src/consumer.js +9 -5
- package/packages/datadog-plugin-kafkajs/src/producer.js +8 -3
- package/packages/datadog-plugin-kafkajs/src/utils.js +1 -1
- package/packages/datadog-plugin-langchain/src/handlers/chain.js +7 -7
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -2
- package/packages/datadog-plugin-langchain/src/handlers/language_models/chat_model.js +6 -4
- package/packages/datadog-plugin-langchain/src/handlers/language_models/llm.js +5 -4
- package/packages/datadog-plugin-langchain/src/tracing.js +11 -10
- package/packages/datadog-plugin-mariadb/src/index.js +3 -9
- package/packages/datadog-plugin-mocha/src/index.js +39 -14
- package/packages/datadog-plugin-mongodb-core/src/index.js +3 -2
- package/packages/datadog-plugin-mysql/src/index.js +22 -9
- package/packages/datadog-plugin-mysql2/src/index.js +16 -0
- package/packages/datadog-plugin-net/src/tcp.js +1 -1
- package/packages/datadog-plugin-next/src/index.js +7 -6
- package/packages/datadog-plugin-openai/src/services.js +6 -10
- package/packages/datadog-plugin-openai/src/tracing.js +12 -18
- package/packages/datadog-plugin-oracledb/src/index.js +1 -1
- package/packages/datadog-plugin-playwright/src/index.js +25 -4
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +8 -9
- package/packages/datadog-plugin-redis/src/index.js +2 -4
- package/packages/datadog-plugin-rhea/src/consumer.js +8 -6
- package/packages/datadog-plugin-rhea/src/producer.js +5 -2
- package/packages/datadog-plugin-router/src/index.js +1 -1
- package/packages/datadog-plugin-selenium/src/index.js +1 -6
- package/packages/datadog-plugin-vitest/src/index.js +52 -35
- package/packages/datadog-shimmer/src/shimmer.js +4 -8
- package/packages/dd-trace/src/appsec/api_security_sampler.js +2 -2
- package/packages/dd-trace/src/appsec/blocked_templates.js +1 -1
- package/packages/dd-trace/src/appsec/blocking.js +6 -20
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +7 -12
- package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +5 -8
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +4 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +9 -12
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +5 -4
- package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +2 -3
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +3 -3
- package/packages/dd-trace/src/appsec/iast/index.js +1 -0
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +102 -7
- package/packages/dd-trace/src/appsec/iast/path-line.js +7 -8
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +16 -24
- package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +6 -6
- package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +3 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +4 -28
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -8
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +3 -4
- 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 +7 -8
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +7 -7
- package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +2 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +10 -11
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +7 -7
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +23 -28
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +3 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +4 -4
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +6 -11
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +0 -1
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +9 -11
- package/packages/dd-trace/src/appsec/index.js +5 -5
- package/packages/dd-trace/src/appsec/rasp/index.js +15 -15
- package/packages/dd-trace/src/appsec/rasp/lfi.js +2 -1
- package/packages/dd-trace/src/appsec/reporter.js +232 -41
- package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
- package/packages/dd-trace/src/appsec/sdk/set_user.js +2 -2
- package/packages/dd-trace/src/appsec/sdk/track_event.js +3 -3
- package/packages/dd-trace/src/appsec/stack_trace.js +2 -4
- package/packages/dd-trace/src/appsec/telemetry/index.js +31 -1
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +3 -5
- package/packages/dd-trace/src/appsec/telemetry/waf.js +3 -5
- package/packages/dd-trace/src/appsec/user_tracking.js +3 -5
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +8 -4
- package/packages/dd-trace/src/azure_metadata.js +9 -9
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +9 -8
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +2 -2
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +3 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +3 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +3 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +3 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +3 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +6 -4
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -5
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +7 -6
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +0 -2
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +3 -2
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +5 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +12 -8
- package/packages/dd-trace/src/ci-visibility/telemetry.js +4 -0
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +3 -2
- package/packages/dd-trace/src/config-helper.js +89 -0
- package/packages/dd-trace/src/config.js +159 -129
- package/packages/dd-trace/src/config_stable.js +10 -7
- package/packages/dd-trace/src/datastreams/encoding.js +9 -9
- package/packages/dd-trace/src/datastreams/fnv.js +2 -2
- package/packages/dd-trace/src/datastreams/pathway.js +4 -4
- package/packages/dd-trace/src/datastreams/processor.js +5 -7
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +7 -7
- package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +4 -6
- package/packages/dd-trace/src/datastreams/size.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +75 -69
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +7 -10
- package/packages/dd-trace/src/debugger/devtools_client/defaults.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/index.js +9 -2
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +18 -38
- package/packages/dd-trace/src/debugger/devtools_client/send.js +3 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +11 -14
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +4 -4
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +2 -10
- package/packages/dd-trace/src/debugger/devtools_client/state.js +10 -3
- package/packages/dd-trace/src/debugger/index.js +1 -0
- package/packages/dd-trace/src/dogstatsd.js +7 -6
- package/packages/dd-trace/src/encode/0.4.js +14 -11
- package/packages/dd-trace/src/encode/0.5.js +4 -6
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +8 -8
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -1
- package/packages/dd-trace/src/encode/tags-processors.js +1 -1
- package/packages/dd-trace/src/exporter.js +7 -6
- package/packages/dd-trace/src/exporters/agent/writer.js +1 -5
- package/packages/dd-trace/src/exporters/common/docker.js +4 -3
- package/packages/dd-trace/src/exporters/common/form-data.js +6 -4
- package/packages/dd-trace/src/exporters/common/request.js +5 -2
- package/packages/dd-trace/src/exporters/common/util.js +4 -2
- package/packages/dd-trace/src/external-logger/src/index.js +5 -5
- package/packages/dd-trace/src/flare/file.js +1 -5
- package/packages/dd-trace/src/format.js +1 -1
- package/packages/dd-trace/src/git_properties.js +1 -1
- package/packages/dd-trace/src/id.js +15 -9
- package/packages/dd-trace/src/iitm.js +10 -22
- package/packages/dd-trace/src/index.js +4 -3
- package/packages/dd-trace/src/lambda/handler.js +7 -6
- package/packages/dd-trace/src/lambda/index.js +2 -1
- package/packages/dd-trace/src/lambda/runtime/patch.js +7 -6
- package/packages/dd-trace/src/lambda/runtime/ritm.js +4 -3
- package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
- package/packages/dd-trace/src/llmobs/index.js +21 -5
- package/packages/dd-trace/src/llmobs/noop.js +18 -20
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +6 -6
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +2 -6
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -3
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +11 -13
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +6 -6
- package/packages/dd-trace/src/llmobs/plugins/openai.js +2 -3
- package/packages/dd-trace/src/llmobs/sdk.js +4 -3
- package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
- package/packages/dd-trace/src/llmobs/tagger.js +129 -102
- package/packages/dd-trace/src/llmobs/util.js +9 -9
- package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
- package/packages/dd-trace/src/llmobs/writers/util.js +1 -1
- package/packages/dd-trace/src/log/index.js +9 -8
- package/packages/dd-trace/src/log/log.js +1 -1
- package/packages/dd-trace/src/log/writer.js +3 -4
- package/packages/dd-trace/src/msgpack/chunk.js +3 -3
- package/packages/dd-trace/src/msgpack/encoder.js +31 -31
- package/packages/dd-trace/src/noop/dogstatsd.js +6 -6
- package/packages/dd-trace/src/noop/span.js +4 -6
- package/packages/dd-trace/src/noop/tracer.js +1 -2
- package/packages/dd-trace/src/opentelemetry/span_processor.js +2 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +7 -6
- package/packages/dd-trace/src/opentracing/propagation/log.js +10 -13
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +40 -37
- package/packages/dd-trace/src/opentracing/propagation/tracestate.js +8 -4
- package/packages/dd-trace/src/opentracing/span.js +16 -20
- package/packages/dd-trace/src/opentracing/tracer.js +9 -6
- package/packages/dd-trace/src/payload-tagging/config/index.js +17 -21
- package/packages/dd-trace/src/payload-tagging/index.js +1 -1
- package/packages/dd-trace/src/payload-tagging/tagging.js +6 -6
- package/packages/dd-trace/src/pkg.js +1 -1
- package/packages/dd-trace/src/plugin_manager.js +4 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +87 -11
- package/packages/dd-trace/src/plugins/consumer.js +2 -2
- package/packages/dd-trace/src/plugins/inbound.js +5 -1
- package/packages/dd-trace/src/plugins/index.js +0 -1
- package/packages/dd-trace/src/plugins/outbound.js +4 -5
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/producer.js +2 -2
- package/packages/dd-trace/src/plugins/storage.js +2 -2
- package/packages/dd-trace/src/plugins/util/ci.js +28 -20
- package/packages/dd-trace/src/plugins/util/git.js +166 -12
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -1
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/llm.js +27 -10
- package/packages/dd-trace/src/plugins/util/stacktrace.js +9 -2
- package/packages/dd-trace/src/plugins/util/test.js +315 -51
- package/packages/dd-trace/src/plugins/util/url.js +1 -1
- package/packages/dd-trace/src/plugins/util/urlfilter.js +13 -17
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +14 -4
- package/packages/dd-trace/src/plugins/util/web.js +8 -8
- package/packages/dd-trace/src/priority_sampler.js +64 -53
- package/packages/dd-trace/src/profiling/config.js +51 -35
- package/packages/dd-trace/src/profiling/exporter_cli.js +20 -20
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +7 -6
- package/packages/dd-trace/src/profiling/exporters/file.js +2 -1
- package/packages/dd-trace/src/profiling/index.js +2 -1
- package/packages/dd-trace/src/profiling/profiler.js +44 -6
- package/packages/dd-trace/src/profiling/profilers/events.js +14 -17
- package/packages/dd-trace/src/profiling/profilers/shared.js +6 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +3 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +6 -7
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +3 -5
- package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +3 -1
- package/packages/dd-trace/src/profiling/tagger.js +21 -13
- package/packages/dd-trace/src/profiling/webspan-utils.js +1 -1
- package/packages/dd-trace/src/proxy.js +9 -10
- package/packages/dd-trace/src/random_sampler.js +40 -0
- package/packages/dd-trace/src/rate_limiter.js +4 -4
- package/packages/dd-trace/src/remote_config/index.js +3 -7
- package/packages/dd-trace/src/remote_config/manager.js +25 -13
- package/packages/dd-trace/src/require-package-json.js +1 -1
- package/packages/dd-trace/src/ritm.js +8 -8
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -4
- package/packages/dd-trace/src/sampler.js +41 -4
- package/packages/dd-trace/src/sampling_rule.js +12 -3
- package/packages/dd-trace/src/scope.js +1 -1
- package/packages/dd-trace/src/serverless.js +11 -4
- package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +2 -3
- package/packages/dd-trace/src/span_processor.js +5 -4
- package/packages/dd-trace/src/span_sampler.js +4 -1
- package/packages/dd-trace/src/standalone/tracesource.js +2 -3
- package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +1 -2
- package/packages/dd-trace/src/startup-log.js +6 -18
- package/packages/dd-trace/src/supported-configurations.json +439 -0
- package/packages/dd-trace/src/telemetry/dependencies.js +64 -59
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +9 -10
- package/packages/dd-trace/src/telemetry/metrics.js +10 -5
- package/packages/dd-trace/src/telemetry/send-data.js +8 -7
- package/packages/dd-trace/src/telemetry/telemetry.js +31 -45
- package/packages/dd-trace/src/tracer.js +3 -7
- package/packages/dd-trace/src/util.js +1 -6
- package/version.js +1 -0
- package/packages/datadog-instrumentations/src/paperplane.js +0 -77
- package/packages/datadog-plugin-paperplane/src/index.js +0 -25
- package/packages/datadog-plugin-paperplane/src/logger.js +0 -11
- package/packages/datadog-plugin-paperplane/src/server.js +0 -24
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +0 -122
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +0 -20
|
@@ -5,7 +5,6 @@ const RateLimiter = require('./rate_limiter')
|
|
|
5
5
|
const Sampler = require('./sampler')
|
|
6
6
|
const { setSamplingRules } = require('./startup-log')
|
|
7
7
|
const SamplingRule = require('./sampling_rule')
|
|
8
|
-
const { hasOwn } = require('./util')
|
|
9
8
|
|
|
10
9
|
const {
|
|
11
10
|
SAMPLING_MECHANISM_DEFAULT,
|
|
@@ -40,16 +39,28 @@ const DEFAULT_KEY = 'service:,env:'
|
|
|
40
39
|
const defaultSampler = new Sampler(AUTO_KEEP)
|
|
41
40
|
|
|
42
41
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
42
|
+
* PrioritySampler is responsible for determining whether a span should be sampled
|
|
43
|
+
* based on various rules, rate limits, and priorities. It supports manual and
|
|
44
|
+
* automatic sampling mechanisms and integrates with Datadog's tracing system.
|
|
45
45
|
*
|
|
46
|
-
*
|
|
47
|
-
* @typedef {
|
|
46
|
+
* @class PrioritySampler
|
|
47
|
+
* @typedef {import('./opentracing/span')} DatadogSpan
|
|
48
|
+
* @typedef {import('./opentracing/span_context')} DatadogSpanContext
|
|
49
|
+
* @typedef {import('./standalone/product')} PRODUCTS
|
|
50
|
+
* @typedef {2|-1|1|0} SamplingPriority Empirically defined sampling priorities.
|
|
48
51
|
*/
|
|
49
52
|
class PrioritySampler {
|
|
50
53
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
54
|
+
* Creates an instance of PrioritySampler.
|
|
55
|
+
*
|
|
56
|
+
* @typedef {Object} SamplingConfig
|
|
57
|
+
* @property {number} [sampleRate] - The default sample rate for traces.
|
|
58
|
+
* @property {string} [provenance] - The provenance of the sampling rule (e.g., "customer", "dynamic").
|
|
59
|
+
* @property {number} [rateLimit=100] - The maximum number of traces to sample per second.
|
|
60
|
+
* @property {Array<SamplingRule>} [rules=[]] - An array of sampling rules to apply.
|
|
61
|
+
*
|
|
62
|
+
* @param {string} env - The environment name (e.g., "production", "staging").
|
|
63
|
+
* @param {SamplingConfig} config - The configuration object for sampling.
|
|
53
64
|
*/
|
|
54
65
|
constructor (env, config) {
|
|
55
66
|
this.configure(env, config)
|
|
@@ -62,9 +73,9 @@ class PrioritySampler {
|
|
|
62
73
|
* @param opts {SamplingConfig}
|
|
63
74
|
*/
|
|
64
75
|
configure (env, opts = {}) {
|
|
65
|
-
const { sampleRate, provenance
|
|
76
|
+
const { sampleRate, provenance, rateLimit = 100, rules } = opts
|
|
66
77
|
this._env = env
|
|
67
|
-
this._rules = this.#
|
|
78
|
+
this._rules = this.#normalizeRules(rules || [], sampleRate, rateLimit, provenance)
|
|
68
79
|
this._limiter = new RateLimiter(rateLimit)
|
|
69
80
|
|
|
70
81
|
log.trace(env, opts)
|
|
@@ -110,7 +121,7 @@ class PrioritySampler {
|
|
|
110
121
|
return
|
|
111
122
|
}
|
|
112
123
|
|
|
113
|
-
this.#
|
|
124
|
+
this.#addDecisionMaker(root)
|
|
114
125
|
}
|
|
115
126
|
|
|
116
127
|
/**
|
|
@@ -154,7 +165,7 @@ class PrioritySampler {
|
|
|
154
165
|
*
|
|
155
166
|
* @param span {DatadogSpan}
|
|
156
167
|
* @param samplingPriority {SamplingPriority}
|
|
157
|
-
* @param product {import('./standalone/product')
|
|
168
|
+
* @param product {import('./standalone/product')}
|
|
158
169
|
*/
|
|
159
170
|
setPriority (span, samplingPriority, product) {
|
|
160
171
|
if (!span || !this.validate(samplingPriority)) return
|
|
@@ -174,7 +185,7 @@ class PrioritySampler {
|
|
|
174
185
|
|
|
175
186
|
log.trace(span, samplingPriority, mechanism)
|
|
176
187
|
|
|
177
|
-
this.#
|
|
188
|
+
this.#addDecisionMaker(root)
|
|
178
189
|
}
|
|
179
190
|
|
|
180
191
|
/**
|
|
@@ -193,11 +204,11 @@ class PrioritySampler {
|
|
|
193
204
|
*/
|
|
194
205
|
_getPriorityFromAuto (span) {
|
|
195
206
|
const context = this._getContext(span)
|
|
196
|
-
const rule = this.#
|
|
207
|
+
const rule = this.#findRule(span)
|
|
197
208
|
|
|
198
209
|
return rule
|
|
199
|
-
? this.#
|
|
200
|
-
: this.#
|
|
210
|
+
? this.#getPriorityByRule(context, rule)
|
|
211
|
+
: this.#getPriorityByAgent(context)
|
|
201
212
|
}
|
|
202
213
|
|
|
203
214
|
/**
|
|
@@ -208,18 +219,17 @@ class PrioritySampler {
|
|
|
208
219
|
* @returns {SamplingPriority}
|
|
209
220
|
*/
|
|
210
221
|
_getPriorityFromTags (tags, _context) {
|
|
211
|
-
if (hasOwn(tags, MANUAL_KEEP) && tags[MANUAL_KEEP] !== false) {
|
|
222
|
+
if (Object.hasOwn(tags, MANUAL_KEEP) && tags[MANUAL_KEEP] !== false) {
|
|
212
223
|
return USER_KEEP
|
|
213
|
-
} else if (hasOwn(tags, MANUAL_DROP) && tags[MANUAL_DROP] !== false) {
|
|
224
|
+
} else if (Object.hasOwn(tags, MANUAL_DROP) && tags[MANUAL_DROP] !== false) {
|
|
214
225
|
return USER_REJECT
|
|
215
|
-
}
|
|
216
|
-
|
|
226
|
+
}
|
|
227
|
+
const priority = Number.parseInt(tags[SAMPLING_PRIORITY], 10)
|
|
217
228
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
229
|
+
if (priority === 1 || priority === 2) {
|
|
230
|
+
return USER_KEEP
|
|
231
|
+
} else if (priority === 0 || priority === -1) {
|
|
232
|
+
return USER_REJECT
|
|
223
233
|
}
|
|
224
234
|
}
|
|
225
235
|
|
|
@@ -229,13 +239,13 @@ class PrioritySampler {
|
|
|
229
239
|
* @param rule {SamplingRule}
|
|
230
240
|
* @returns {SamplingPriority}
|
|
231
241
|
*/
|
|
232
|
-
#
|
|
242
|
+
#getPriorityByRule (context, rule) {
|
|
233
243
|
context._trace[SAMPLING_RULE_DECISION] = rule.sampleRate
|
|
234
244
|
context._sampling.mechanism = SAMPLING_MECHANISM_RULE
|
|
235
245
|
if (rule.provenance === 'customer') context._sampling.mechanism = SAMPLING_MECHANISM_REMOTE_USER
|
|
236
246
|
if (rule.provenance === 'dynamic') context._sampling.mechanism = SAMPLING_MECHANISM_REMOTE_DYNAMIC
|
|
237
247
|
|
|
238
|
-
return rule.sample() && this._isSampledByRateLimit(context)
|
|
248
|
+
return rule.sample(context) && this._isSampledByRateLimit(context)
|
|
239
249
|
? USER_KEEP
|
|
240
250
|
: USER_REJECT
|
|
241
251
|
}
|
|
@@ -258,19 +268,14 @@ class PrioritySampler {
|
|
|
258
268
|
*
|
|
259
269
|
* @param context {DatadogSpanContext}
|
|
260
270
|
* @returns {SamplingPriority}
|
|
261
|
-
* @private
|
|
262
271
|
*/
|
|
263
|
-
#
|
|
272
|
+
#getPriorityByAgent (context) {
|
|
264
273
|
const key = `service:${context._tags[SERVICE_NAME]},env:${this._env}`
|
|
265
274
|
const sampler = this._samplers[key] || this._samplers[DEFAULT_KEY]
|
|
266
275
|
|
|
267
276
|
context._trace[SAMPLING_AGENT_DECISION] = sampler.rate()
|
|
268
277
|
|
|
269
|
-
|
|
270
|
-
context._sampling.mechanism = SAMPLING_MECHANISM_DEFAULT
|
|
271
|
-
} else {
|
|
272
|
-
context._sampling.mechanism = SAMPLING_MECHANISM_AGENT
|
|
273
|
-
}
|
|
278
|
+
context._sampling.mechanism = sampler === defaultSampler ? SAMPLING_MECHANISM_DEFAULT : SAMPLING_MECHANISM_AGENT
|
|
274
279
|
|
|
275
280
|
return sampler.isSampled(context) ? AUTO_KEEP : AUTO_REJECT
|
|
276
281
|
}
|
|
@@ -278,10 +283,9 @@ class PrioritySampler {
|
|
|
278
283
|
/**
|
|
279
284
|
*
|
|
280
285
|
* @param span {DatadogSpan}
|
|
281
|
-
* @private
|
|
282
286
|
* @returns {void}
|
|
283
287
|
*/
|
|
284
|
-
#
|
|
288
|
+
#addDecisionMaker (span) {
|
|
285
289
|
const context = span.context()
|
|
286
290
|
const trace = context._trace
|
|
287
291
|
const priority = context._sampling.priority
|
|
@@ -297,32 +301,39 @@ class PrioritySampler {
|
|
|
297
301
|
}
|
|
298
302
|
|
|
299
303
|
/**
|
|
300
|
-
*
|
|
301
|
-
* @param
|
|
302
|
-
* @param
|
|
303
|
-
* @param
|
|
304
|
-
* @param provenance {string}
|
|
304
|
+
* @param {Record<string, unknown>[] | Record<string, unknown>} rules - The sampling rules to normalize.
|
|
305
|
+
* @param {number} sampleRate
|
|
306
|
+
* @param {number} rateLimit
|
|
307
|
+
* @param {string} provenance
|
|
305
308
|
* @returns {SamplingRule[]}
|
|
306
|
-
* @private
|
|
307
309
|
*/
|
|
308
|
-
#
|
|
309
|
-
rules =
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
.
|
|
310
|
+
#normalizeRules (rules, sampleRate, rateLimit, provenance) {
|
|
311
|
+
rules = Array.isArray(rules) ? rules.flat() : [rules]
|
|
312
|
+
|
|
313
|
+
rules.push({ sampleRate, maxPerSecond: rateLimit, provenance })
|
|
314
|
+
|
|
315
|
+
const result = []
|
|
316
|
+
for (const rule of rules) {
|
|
317
|
+
const sampleRate = Number.parseFloat(rule.sampleRate)
|
|
318
|
+
// TODO(BridgeAR): Debug logging invalid rules fails our tests.
|
|
319
|
+
// Should we definitely not know about these?
|
|
320
|
+
if (!Number.isNaN(sampleRate)) {
|
|
321
|
+
result.push(SamplingRule.from({ ...rule, sampleRate }))
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return result
|
|
316
325
|
}
|
|
317
326
|
|
|
318
327
|
/**
|
|
319
328
|
*
|
|
320
329
|
* @param span {DatadogSpan}
|
|
321
|
-
* @returns {SamplingRule}
|
|
322
|
-
* @private
|
|
330
|
+
* @returns {SamplingRule|undefined}
|
|
323
331
|
*/
|
|
324
|
-
#
|
|
332
|
+
#findRule (span) {
|
|
325
333
|
for (const rule of this._rules) {
|
|
334
|
+
// Rule is a special object with a .match() property.
|
|
335
|
+
// It has nothing to do with a regular expression.
|
|
336
|
+
// eslint-disable-next-line unicorn/prefer-regexp-test
|
|
326
337
|
if (rule.match(span)) return rule
|
|
327
338
|
}
|
|
328
339
|
}
|
|
@@ -330,7 +341,7 @@ class PrioritySampler {
|
|
|
330
341
|
/**
|
|
331
342
|
*
|
|
332
343
|
* @param span {DatadogSpan}
|
|
333
|
-
* @param product {import('./standalone/product')
|
|
344
|
+
* @param product {import('./standalone/product')}
|
|
334
345
|
*/
|
|
335
346
|
static keepTrace (span, product) {
|
|
336
347
|
span?._prioritySampler?.setPriority(span, USER_KEEP, product)
|
|
@@ -15,26 +15,26 @@ const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
|
|
|
15
15
|
const { tagger } = require('./tagger')
|
|
16
16
|
const { isFalse, isTrue } = require('../util')
|
|
17
17
|
const { getAzureTagsFromMetadata, getAzureAppMetadata } = require('../azure_metadata')
|
|
18
|
+
const { getEnvironmentVariables } = require('../config-helper')
|
|
18
19
|
|
|
19
20
|
class Config {
|
|
20
21
|
constructor (options = {}) {
|
|
21
22
|
const {
|
|
23
|
+
AWS_LAMBDA_FUNCTION_NAME: functionname,
|
|
22
24
|
DD_AGENT_HOST,
|
|
23
25
|
DD_ENV,
|
|
24
26
|
DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED, // used for testing
|
|
25
27
|
DD_PROFILING_CODEHOTSPOTS_ENABLED,
|
|
26
28
|
DD_PROFILING_CPU_ENABLED,
|
|
27
29
|
DD_PROFILING_DEBUG_SOURCE_MAPS,
|
|
30
|
+
DD_PROFILING_DEBUG_UPLOAD_COMPRESSION,
|
|
28
31
|
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
|
|
29
|
-
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED,
|
|
30
|
-
DD_PROFILING_EXPERIMENTAL_CPU_ENABLED,
|
|
31
|
-
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED,
|
|
32
32
|
DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES,
|
|
33
33
|
DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE,
|
|
34
34
|
DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT,
|
|
35
35
|
DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED,
|
|
36
|
-
DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED,
|
|
37
36
|
DD_PROFILING_HEAP_ENABLED,
|
|
37
|
+
DD_PROFILING_HEAP_SAMPLING_INTERVAL,
|
|
38
38
|
DD_PROFILING_PPROF_PREFIX,
|
|
39
39
|
DD_PROFILING_PROFILERS,
|
|
40
40
|
DD_PROFILING_SOURCE_MAP,
|
|
@@ -48,13 +48,12 @@ class Config {
|
|
|
48
48
|
DD_TRACE_AGENT_PORT,
|
|
49
49
|
DD_TRACE_AGENT_URL,
|
|
50
50
|
DD_VERSION
|
|
51
|
-
} =
|
|
51
|
+
} = getEnvironmentVariables()
|
|
52
52
|
|
|
53
53
|
const env = coalesce(options.env, DD_ENV)
|
|
54
54
|
const service = options.service || DD_SERVICE || 'node'
|
|
55
55
|
const host = os.hostname()
|
|
56
56
|
const version = coalesce(options.version, DD_VERSION)
|
|
57
|
-
const functionname = process.env.AWS_LAMBDA_FUNCTION_NAME
|
|
58
57
|
// Must be longer than one minute so pad with five seconds
|
|
59
58
|
const flushInterval = coalesce(options.interval, Number(DD_PROFILING_UPLOAD_PERIOD) * 1000, 65 * 1000)
|
|
60
59
|
const uploadTimeout = coalesce(options.uploadTimeout,
|
|
@@ -84,16 +83,6 @@ class Config {
|
|
|
84
83
|
}
|
|
85
84
|
|
|
86
85
|
this.logger = ensureLogger(options.logger)
|
|
87
|
-
const logger = this.logger
|
|
88
|
-
function logExperimentalVarDeprecation (shortVarName) {
|
|
89
|
-
const deprecatedEnvVarName = `DD_PROFILING_EXPERIMENTAL_${shortVarName}`
|
|
90
|
-
const v = process.env[deprecatedEnvVarName]
|
|
91
|
-
// not null, undefined, or NaN -- same logic as koalas.hasValue
|
|
92
|
-
// eslint-disable-next-line no-self-compare
|
|
93
|
-
if (v != null && v === v) {
|
|
94
|
-
logger.warn(`${deprecatedEnvVarName} is deprecated. Use DD_PROFILING_${shortVarName} instead.`)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
86
|
// Profiler sampling contexts are not available on Windows, so features
|
|
98
87
|
// depending on those (code hotspots and endpoint collection) need to default
|
|
99
88
|
// to false on Windows.
|
|
@@ -117,9 +106,7 @@ class Config {
|
|
|
117
106
|
this.sourceMap = sourceMap
|
|
118
107
|
this.debugSourceMaps = isTrue(coalesce(options.debugSourceMaps, DD_PROFILING_DEBUG_SOURCE_MAPS, false))
|
|
119
108
|
this.endpointCollectionEnabled = isTrue(coalesce(options.endpointCollection,
|
|
120
|
-
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
|
|
121
|
-
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED, samplingContextsAvailable))
|
|
122
|
-
logExperimentalVarDeprecation('ENDPOINT_COLLECTION_ENABLED')
|
|
109
|
+
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED, samplingContextsAvailable))
|
|
123
110
|
checkOptionWithSamplingContextAllowed(this.endpointCollectionEnabled, 'Endpoint collection')
|
|
124
111
|
|
|
125
112
|
this.pprofPrefix = pprofPrefix
|
|
@@ -163,34 +150,63 @@ class Config {
|
|
|
163
150
|
exportCommand
|
|
164
151
|
}
|
|
165
152
|
|
|
166
|
-
const profilers = options.profilers
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
DD_PROFILING_PROFILERS
|
|
172
|
-
})
|
|
153
|
+
const profilers = options.profilers || getProfilers({
|
|
154
|
+
DD_PROFILING_HEAP_ENABLED,
|
|
155
|
+
DD_PROFILING_WALLTIME_ENABLED,
|
|
156
|
+
DD_PROFILING_PROFILERS
|
|
157
|
+
})
|
|
173
158
|
|
|
174
159
|
this.timelineEnabled = isTrue(coalesce(options.timelineEnabled,
|
|
175
|
-
DD_PROFILING_TIMELINE_ENABLED,
|
|
176
|
-
DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED, samplingContextsAvailable))
|
|
177
|
-
logExperimentalVarDeprecation('TIMELINE_ENABLED')
|
|
160
|
+
DD_PROFILING_TIMELINE_ENABLED, samplingContextsAvailable))
|
|
178
161
|
checkOptionWithSamplingContextAllowed(this.timelineEnabled, 'Timeline view')
|
|
179
162
|
this.timelineSamplingEnabled = isTrue(coalesce(options.timelineSamplingEnabled,
|
|
180
163
|
DD_INTERNAL_PROFILING_TIMELINE_SAMPLING_ENABLED, true))
|
|
181
164
|
|
|
182
165
|
this.codeHotspotsEnabled = isTrue(coalesce(options.codeHotspotsEnabled,
|
|
183
|
-
DD_PROFILING_CODEHOTSPOTS_ENABLED,
|
|
184
|
-
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED, samplingContextsAvailable))
|
|
185
|
-
logExperimentalVarDeprecation('CODEHOTSPOTS_ENABLED')
|
|
166
|
+
DD_PROFILING_CODEHOTSPOTS_ENABLED, samplingContextsAvailable))
|
|
186
167
|
checkOptionWithSamplingContextAllowed(this.codeHotspotsEnabled, 'Code hotspots')
|
|
187
168
|
|
|
188
169
|
this.cpuProfilingEnabled = isTrue(coalesce(options.cpuProfilingEnabled,
|
|
189
170
|
DD_PROFILING_CPU_ENABLED,
|
|
190
|
-
|
|
191
|
-
logExperimentalVarDeprecation('CPU_ENABLED')
|
|
171
|
+
samplingContextsAvailable))
|
|
192
172
|
checkOptionWithSamplingContextAllowed(this.cpuProfilingEnabled, 'CPU profiling')
|
|
193
173
|
|
|
174
|
+
this.heapSamplingInterval = coalesce(options.heapSamplingInterval,
|
|
175
|
+
Number(DD_PROFILING_HEAP_SAMPLING_INTERVAL))
|
|
176
|
+
const uploadCompression0 = coalesce(options.uploadCompression, DD_PROFILING_DEBUG_UPLOAD_COMPRESSION, 'on')
|
|
177
|
+
let [uploadCompression, level0] = uploadCompression0.split('-')
|
|
178
|
+
if (!['on', 'off', 'gzip', 'zstd'].includes(uploadCompression)) {
|
|
179
|
+
this.logger.warn(`Invalid profile upload compression method "${uploadCompression0}". Will use "on".`)
|
|
180
|
+
uploadCompression = 'on'
|
|
181
|
+
}
|
|
182
|
+
let level = level0 ? Number.parseInt(level0, 10) : undefined
|
|
183
|
+
if (level !== undefined) {
|
|
184
|
+
if (['on', 'off'].includes(uploadCompression)) {
|
|
185
|
+
this.logger.warn(`Compression levels are not supported for "${uploadCompression}".`)
|
|
186
|
+
level = undefined
|
|
187
|
+
} else if (Number.isNaN(level)) {
|
|
188
|
+
this.logger.warn(
|
|
189
|
+
`Invalid compression level "${level0}". Will use default level.`)
|
|
190
|
+
level = undefined
|
|
191
|
+
} else if (level < 1) {
|
|
192
|
+
this.logger.warn(`Invalid compression level ${level}. Will use 1.`)
|
|
193
|
+
level = 1
|
|
194
|
+
} else {
|
|
195
|
+
const maxLevel = { gzip: 9, zstd: 22 }[uploadCompression]
|
|
196
|
+
if (level > maxLevel) {
|
|
197
|
+
this.logger.warn(`Invalid compression level ${level}. Will use ${maxLevel}.`)
|
|
198
|
+
level = maxLevel
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Default to gzip
|
|
204
|
+
if (uploadCompression === 'on') {
|
|
205
|
+
uploadCompression = 'gzip'
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
this.uploadCompression = { method: uploadCompression, level }
|
|
209
|
+
|
|
194
210
|
this.profilers = ensureProfilers(profilers, this)
|
|
195
211
|
}
|
|
196
212
|
}
|
|
@@ -307,7 +323,7 @@ function ensureProfilers (profilers, options) {
|
|
|
307
323
|
}
|
|
308
324
|
|
|
309
325
|
// Filter out any invalid profilers
|
|
310
|
-
return profilers.filter(
|
|
326
|
+
return profilers.filter(Boolean)
|
|
311
327
|
}
|
|
312
328
|
|
|
313
329
|
function ensureLogger (logger) {
|
|
@@ -8,6 +8,7 @@ const { ConsoleLogger } = require('./loggers/console')
|
|
|
8
8
|
const { tagger } = require('./tagger')
|
|
9
9
|
const fs = require('fs')
|
|
10
10
|
const { fileURLToPath } = require('url')
|
|
11
|
+
const { getEnvironmentVariable } = require('../config-helper')
|
|
11
12
|
|
|
12
13
|
const logger = new ConsoleLogger()
|
|
13
14
|
const timeoutMs = 15 * 1000
|
|
@@ -15,25 +16,24 @@ const timeoutMs = 15 * 1000
|
|
|
15
16
|
function exporterFromURL (url) {
|
|
16
17
|
if (url.protocol === 'file:') {
|
|
17
18
|
return new FileExporter({ pprofPrefix: fileURLToPath(url) })
|
|
18
|
-
} else {
|
|
19
|
-
const injectionEnabled = (process.env.DD_INJECTION_ENABLED || '').split(',')
|
|
20
|
-
const libraryInjected = injectionEnabled.length > 0
|
|
21
|
-
const profilingEnabled = (process.env.DD_PROFILING_ENABLED || '').toLowerCase()
|
|
22
|
-
const activation = ['true', '1'].includes(profilingEnabled)
|
|
23
|
-
? 'manual'
|
|
24
|
-
: profilingEnabled === 'auto'
|
|
25
|
-
? 'auto'
|
|
26
|
-
: injectionEnabled.includes('profiling')
|
|
27
|
-
? 'injection'
|
|
28
|
-
: 'unknown'
|
|
29
|
-
return new AgentExporter({
|
|
30
|
-
url,
|
|
31
|
-
logger,
|
|
32
|
-
uploadTimeout: timeoutMs,
|
|
33
|
-
libraryInjected,
|
|
34
|
-
activation
|
|
35
|
-
})
|
|
36
19
|
}
|
|
20
|
+
const injectionEnabled = (getEnvironmentVariable('DD_INJECTION_ENABLED') ?? '').split(',')
|
|
21
|
+
const libraryInjected = injectionEnabled.length > 0
|
|
22
|
+
const profilingEnabled = (getEnvironmentVariable('DD_PROFILING_ENABLED') ?? '').toLowerCase()
|
|
23
|
+
const activation = ['true', '1'].includes(profilingEnabled)
|
|
24
|
+
? 'manual'
|
|
25
|
+
: profilingEnabled === 'auto'
|
|
26
|
+
? 'auto'
|
|
27
|
+
: injectionEnabled.includes('profiling')
|
|
28
|
+
? 'injection'
|
|
29
|
+
: 'unknown'
|
|
30
|
+
return new AgentExporter({
|
|
31
|
+
url,
|
|
32
|
+
logger,
|
|
33
|
+
uploadTimeout: timeoutMs,
|
|
34
|
+
libraryInjected,
|
|
35
|
+
activation
|
|
36
|
+
})
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
async function exportProfile (urls, tags, profileType, profile) {
|
|
@@ -46,7 +46,7 @@ async function exportProfile (urls, tags, profileType, profile) {
|
|
|
46
46
|
|
|
47
47
|
const encodedProfile = await encode(heap.convertProfile(profile, undefined, mapper))
|
|
48
48
|
const start = new Date()
|
|
49
|
-
|
|
49
|
+
await Promise.all(urls.map(async (url) => {
|
|
50
50
|
const exporter = exporterFromURL(url)
|
|
51
51
|
|
|
52
52
|
await exporter.export({
|
|
@@ -57,7 +57,7 @@ async function exportProfile (urls, tags, profileType, profile) {
|
|
|
57
57
|
end: start,
|
|
58
58
|
tags
|
|
59
59
|
})
|
|
60
|
-
}
|
|
60
|
+
}))
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/** Expected command line arguments are:
|
|
@@ -150,7 +150,7 @@ class AgentExporter extends EventSerializer {
|
|
|
150
150
|
'DD-EVP-ORIGIN-VERSION': version,
|
|
151
151
|
...form.getHeaders()
|
|
152
152
|
},
|
|
153
|
-
timeout: this._backoffTime *
|
|
153
|
+
timeout: this._backoffTime * 2 ** attempt
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
docker.inject(options.headers)
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
const os = require('os')
|
|
2
2
|
const perf = require('perf_hooks').performance
|
|
3
3
|
const version = require('../../../../../package.json').version
|
|
4
|
+
const { getEnvironmentVariable } = require('../../config-helper')
|
|
4
5
|
|
|
5
6
|
const libuvThreadPoolSize = (() => {
|
|
6
|
-
const ss =
|
|
7
|
+
const ss = getEnvironmentVariable('UV_THREADPOOL_SIZE')
|
|
7
8
|
if (ss === undefined) {
|
|
8
9
|
// Backend will apply the default size based on Node version.
|
|
9
|
-
return
|
|
10
|
+
return
|
|
10
11
|
}
|
|
11
12
|
// libuv uses atoi to parse the value, which is almost the same as parseInt, except that parseInt
|
|
12
13
|
// will return NaN on invalid input, while atoi will return 0. This is handled at return.
|
|
13
|
-
const s = parseInt(ss)
|
|
14
|
-
// We
|
|
14
|
+
const s = Number.parseInt(ss)
|
|
15
|
+
// We don't interpret the value further here in the library. Backend will interpret the number
|
|
15
16
|
// based on Node version. In all currently known Node versions, 0 results in 1 worker thread,
|
|
16
17
|
// negative values (because they're assigned to an unsigned int) become very high positive values,
|
|
17
18
|
// and the value is finally capped at 1024.
|
|
18
|
-
return isNaN(s) ? 0 : s
|
|
19
|
+
return Number.isNaN(s) ? 0 : s
|
|
19
20
|
})()
|
|
20
21
|
|
|
21
22
|
class EventSerializer {
|
|
@@ -87,7 +88,7 @@ class EventSerializer {
|
|
|
87
88
|
// We'll keep it like this as we want cross-engine consistency. We
|
|
88
89
|
// also aren't changing the format of the existing tag as we don't want
|
|
89
90
|
// to break it.
|
|
90
|
-
version: process.version.
|
|
91
|
+
version: process.version.slice(1)
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
})
|
|
@@ -6,8 +6,9 @@ const { threadId } = require('worker_threads')
|
|
|
6
6
|
const writeFile = promisify(fs.writeFile)
|
|
7
7
|
const { EventSerializer } = require('./event_serializer')
|
|
8
8
|
|
|
9
|
+
const pad = (n) => String(n).padStart(2, '0')
|
|
10
|
+
|
|
9
11
|
function formatDateTime (t) {
|
|
10
|
-
const pad = (n) => String(n).padStart(2, '0')
|
|
11
12
|
return `${t.getUTCFullYear()}${pad(t.getUTCMonth() + 1)}${pad(t.getUTCDate())}` +
|
|
12
13
|
`T${pad(t.getUTCHours())}${pad(t.getUTCMinutes())}${pad(t.getUTCSeconds())}Z`
|
|
13
14
|
}
|
|
@@ -6,8 +6,9 @@ const SpaceProfiler = require('./profilers/space')
|
|
|
6
6
|
const { AgentExporter } = require('./exporters/agent')
|
|
7
7
|
const { FileExporter } = require('./exporters/file')
|
|
8
8
|
const { ConsoleLogger } = require('./loggers/console')
|
|
9
|
+
const { getEnvironmentVariable } = require('../config-helper')
|
|
9
10
|
|
|
10
|
-
const profiler =
|
|
11
|
+
const profiler = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') ? new ServerlessProfiler() : new Profiler()
|
|
11
12
|
|
|
12
13
|
module.exports = {
|
|
13
14
|
profiler,
|
|
@@ -8,6 +8,9 @@ const { isWebServerSpan, endpointNameFromTags, getStartedSpans } = require('./we
|
|
|
8
8
|
const dc = require('dc-polyfill')
|
|
9
9
|
const crashtracker = require('../crashtracking')
|
|
10
10
|
|
|
11
|
+
const { promisify } = require('util')
|
|
12
|
+
const zlib = require('zlib')
|
|
13
|
+
|
|
11
14
|
const profileSubmittedChannel = dc.channel('datadog:profiling:profile-submitted')
|
|
12
15
|
const spanFinishedChannel = dc.channel('dd-trace:span:finish')
|
|
13
16
|
|
|
@@ -83,9 +86,37 @@ class Profiler extends EventEmitter {
|
|
|
83
86
|
this._logger.debug(() => {
|
|
84
87
|
return mapper.infoMap.size === 0
|
|
85
88
|
? 'Found no source maps'
|
|
86
|
-
: `Found source maps for following files: [${
|
|
89
|
+
: `Found source maps for following files: [${[...mapper.infoMap.keys()].join(', ')}]`
|
|
87
90
|
})
|
|
88
91
|
}
|
|
92
|
+
|
|
93
|
+
const clevel = config.uploadCompression.level
|
|
94
|
+
switch (config.uploadCompression.method) {
|
|
95
|
+
case 'gzip':
|
|
96
|
+
this._compressionFn = promisify(zlib.gzip)
|
|
97
|
+
if (clevel !== undefined) {
|
|
98
|
+
this._compressionOptions = {
|
|
99
|
+
level: clevel
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
break
|
|
103
|
+
case 'zstd':
|
|
104
|
+
if (typeof zlib.zstdCompress === 'function') {
|
|
105
|
+
this._compressionFn = promisify(zlib.zstdCompress)
|
|
106
|
+
if (clevel !== undefined) {
|
|
107
|
+
this._compressionOptions = {
|
|
108
|
+
params: {
|
|
109
|
+
[zlib.constants.ZSTD_c_compressionLevel]: clevel
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
const zstdCompress = require('@datadog/libdatadog').load('datadog-js-zstd').zstd_compress
|
|
115
|
+
const level = clevel ?? 0 // 0 is zstd default compression level
|
|
116
|
+
this._compressionFn = (buffer) => Promise.resolve(Buffer.from(zstdCompress(buffer, level)))
|
|
117
|
+
}
|
|
118
|
+
break
|
|
119
|
+
}
|
|
89
120
|
} catch (err) {
|
|
90
121
|
this._logError(err)
|
|
91
122
|
}
|
|
@@ -195,7 +226,7 @@ class Profiler extends EventEmitter {
|
|
|
195
226
|
const encodedProfiles = {}
|
|
196
227
|
|
|
197
228
|
try {
|
|
198
|
-
if (
|
|
229
|
+
if (this._config.profilers.length === 0) {
|
|
199
230
|
throw new Error('No profile types configured.')
|
|
200
231
|
}
|
|
201
232
|
|
|
@@ -215,24 +246,31 @@ class Profiler extends EventEmitter {
|
|
|
215
246
|
this._capture(this._timeoutInterval, endDate)
|
|
216
247
|
}
|
|
217
248
|
|
|
249
|
+
let hasEncoded = false
|
|
250
|
+
|
|
218
251
|
// encode and export asynchronously
|
|
219
|
-
|
|
252
|
+
await Promise.all(profiles.map(async ({ profiler, profile }) => {
|
|
220
253
|
try {
|
|
221
|
-
|
|
254
|
+
const encoded = await profiler.encode(profile)
|
|
255
|
+
const compressed = encoded instanceof Buffer && this._compressionFn !== undefined
|
|
256
|
+
? await this._compressionFn(encoded, this._compressionOptions)
|
|
257
|
+
: encoded
|
|
258
|
+
encodedProfiles[profiler.type] = compressed
|
|
222
259
|
this._logger.debug(() => {
|
|
223
260
|
const profileJson = JSON.stringify(profile, (key, value) => {
|
|
224
261
|
return typeof value === 'bigint' ? value.toString() : value
|
|
225
262
|
})
|
|
226
263
|
return `Collected ${profiler.type} profile: ` + profileJson
|
|
227
264
|
})
|
|
265
|
+
hasEncoded = true
|
|
228
266
|
} catch (err) {
|
|
229
267
|
// If encoding one of the profile types fails, we should still try to
|
|
230
268
|
// encode and submit the other profile types.
|
|
231
269
|
this._logError(err)
|
|
232
270
|
}
|
|
233
|
-
}
|
|
271
|
+
}))
|
|
234
272
|
|
|
235
|
-
if (
|
|
273
|
+
if (hasEncoded) {
|
|
236
274
|
await this._submit(encodedProfiles, startDate, endDate, snapshotKind)
|
|
237
275
|
profileSubmittedChannel.publish()
|
|
238
276
|
this._logger.debug('Submitted profiles')
|