dd-trace 5.81.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/index.d.ts +7 -0
- package/loader-hook.mjs +7 -2
- package/package.json +13 -18
- package/packages/datadog-core/src/utils/src/parse-tags.js +1 -1
- package/packages/datadog-esbuild/index.js +8 -7
- package/packages/datadog-esbuild/src/utils.js +14 -2
- 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 +2 -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 +1 -1
- 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/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 +3 -3
- package/packages/datadog-instrumentations/src/graphql.js +1 -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 +4 -1
- package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/register.js +6 -4
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/bullmq.json +106 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +2 -1
- 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/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/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 +1 -1
- 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 +1 -1
- 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/selenium.js +1 -1
- 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 +3 -2
- 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-confluentinc-kafka-javascript/src/index.js +1 -1
- package/packages/datadog-plugin-cypress/src/plugin.js +1 -1
- 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 +1 -1
- package/packages/datadog-plugin-graphql/src/resolve.js +1 -1
- 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-kafkajs/src/index.js +1 -1
- package/packages/datadog-plugin-langchain/src/index.js +1 -1
- 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-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 +3 -3
- 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/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.js +10 -14
- 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 +3 -3
- 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 -3
- 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 +6 -0
- 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/config/remote_config.js +34 -0
- package/packages/dd-trace/src/config.js +29 -28
- package/packages/dd-trace/src/config_defaults.js +2 -1
- 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/index.js +1 -1
- package/packages/dd-trace/src/datastreams/pathway.js +7 -7
- package/packages/dd-trace/src/datastreams/processor.js +2 -2
- 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/config.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/index.js +7 -2
- package/packages/dd-trace/src/debugger/devtools_client/send.js +3 -3
- package/packages/dd-trace/src/debugger/devtools_client/session.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +5 -5
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/status.js +2 -2
- package/packages/dd-trace/src/debugger/index.js +1 -1
- 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 +6 -1
- 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/id.js +1 -1
- 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 +1 -1
- package/packages/dd-trace/src/llmobs/constants/tags.js +7 -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/util.js +2 -2
- 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/openai/constants.js +16 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +16 -1
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +22 -10
- package/packages/dd-trace/src/llmobs/plugins/vertexai.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +15 -22
- package/packages/dd-trace/src/llmobs/span_processor.js +9 -13
- 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/logger.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +4 -4
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +9 -8
- package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +3 -3
- package/packages/dd-trace/src/opentelemetry/metrics/meter.js +2 -2
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +4 -4
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +36 -11
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +11 -10
- package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +1 -1
- package/packages/dd-trace/src/opentelemetry/span.js +2 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +3 -3
- 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 +6 -2
- package/packages/dd-trace/src/plugin_manager.js +1 -1
- 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 +5 -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 +24 -24
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +8 -5
- package/packages/dd-trace/src/priority_sampler.js +15 -16
- package/packages/dd-trace/src/process-tags/index.js +31 -29
- package/packages/dd-trace/src/profiling/config.js +32 -21
- 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 +2 -2
- package/packages/dd-trace/src/profiling/profilers/wall.js +4 -4
- package/packages/dd-trace/src/proxy.js +12 -18
- 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/v1/messaging.js +8 -0
- package/packages/dd-trace/src/span_format.js +1 -1
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/span_stats.js +6 -4
- 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 +3 -0
- package/packages/dd-trace/src/telemetry/dependencies.js +3 -3
- 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 +11 -6
- package/packages/dd-trace/src/tracer.js +3 -3
- package/packages/dd-trace/src/tracer_metadata.js +19 -15
- package/packages/dd-trace/src/remote_config/manager.js +0 -368
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { URL } = require('url')
|
|
4
|
+
|
|
3
5
|
const ClientPlugin = require('../../dd-trace/src/plugins/client')
|
|
4
6
|
const { storage } = require('../../datadog-core')
|
|
5
7
|
const tags = require('../../../ext/tags')
|
|
@@ -9,7 +11,6 @@ const HTTP_HEADERS = formats.HTTP_HEADERS
|
|
|
9
11
|
const urlFilter = require('../../dd-trace/src/plugins/util/urlfilter')
|
|
10
12
|
const log = require('../../dd-trace/src/log')
|
|
11
13
|
const { CLIENT_PORT_KEY, COMPONENT, ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../dd-trace/src/constants')
|
|
12
|
-
const { URL } = require('url')
|
|
13
14
|
|
|
14
15
|
const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
|
|
15
16
|
const HTTP_REQUEST_HEADERS = tags.HTTP_REQUEST_HEADERS
|
|
@@ -1,16 +1,36 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const HttpClientPlugin = require('./client')
|
|
3
|
+
const PushSubscriptionPlugin = require('../../datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription')
|
|
5
4
|
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
5
|
+
const { enableGCPPubSubPushSubscription } = require('../../dd-trace/src/serverless')
|
|
6
|
+
const log = require('../../dd-trace/src/log')
|
|
7
|
+
const HttpClientPlugin = require('./client')
|
|
8
|
+
const HttpServerPlugin = require('./server')
|
|
6
9
|
|
|
10
|
+
/**
|
|
11
|
+
* HTTP Plugin loads server/client plugins with optional GCP Pub/Sub Push support.
|
|
12
|
+
* Plugin order is critical: PushSubscriptionPlugin must load FIRST to intercept
|
|
13
|
+
* Pub/Sub push requests and activate delivery spans before HTTP spans are created.
|
|
14
|
+
*/
|
|
7
15
|
class HttpPlugin extends CompositePlugin {
|
|
8
16
|
static id = 'http'
|
|
9
17
|
static get plugins () {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
18
|
+
const plugins = {}
|
|
19
|
+
|
|
20
|
+
// Load push subscription plugin first (if enabled) for GCP Cloud Run
|
|
21
|
+
if (enableGCPPubSubPushSubscription()) {
|
|
22
|
+
try {
|
|
23
|
+
plugins['pubsub-push-subscription'] = PushSubscriptionPlugin
|
|
24
|
+
log.debug('Loaded GCP Pub/Sub Push Subscription plugin for HTTP requests')
|
|
25
|
+
} catch (e) {
|
|
26
|
+
log.debug(`Failed to load GCP Pub/Sub Push Subscription plugin: ${e.message}`)
|
|
27
|
+
}
|
|
13
28
|
}
|
|
29
|
+
|
|
30
|
+
plugins.server = HttpServerPlugin
|
|
31
|
+
plugins.client = HttpClientPlugin
|
|
32
|
+
|
|
33
|
+
return plugins
|
|
14
34
|
}
|
|
15
35
|
}
|
|
16
36
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const URL = require('url').URL
|
|
4
|
+
|
|
3
5
|
const { storage } = require('../../datadog-core')
|
|
4
6
|
const ClientPlugin = require('../../dd-trace/src/plugins/client')
|
|
5
|
-
|
|
6
|
-
const URL = require('url').URL
|
|
7
7
|
const log = require('../../dd-trace/src/log')
|
|
8
8
|
const tags = require('../../../ext/tags')
|
|
9
9
|
const kinds = require('../../../ext/kinds')
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
3
4
|
const Http2ServerPlugin = require('./server')
|
|
4
5
|
const Http2ClientPlugin = require('./client')
|
|
5
|
-
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
6
6
|
|
|
7
7
|
class Http2Plugin extends CompositePlugin {
|
|
8
8
|
static id = 'http2'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
3
4
|
const ProducerPlugin = require('./producer')
|
|
4
5
|
const ConsumerPlugin = require('./consumer')
|
|
5
6
|
const BatchConsumerPlugin = require('./batch-consumer')
|
|
6
|
-
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
7
7
|
|
|
8
8
|
class KafkajsPlugin extends CompositePlugin {
|
|
9
9
|
static id = 'kafkajs'
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const langChainTracingPlugins = require('./tracing')
|
|
4
3
|
const langChainLLMObsPlugins = require('../../dd-trace/src/llmobs/plugins/langchain')
|
|
5
4
|
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
5
|
+
const langChainTracingPlugins = require('./tracing')
|
|
6
6
|
|
|
7
7
|
const plugins = {}
|
|
8
8
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
// TODO: support https://moleculer.services/docs/0.13/actions.html#Streaming
|
|
4
4
|
|
|
5
|
+
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
5
6
|
const MoleculerServerPlugin = require('./server')
|
|
6
7
|
const MoleculerClientPlugin = require('./client')
|
|
7
|
-
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
8
8
|
|
|
9
9
|
class MoleculerPlugin extends CompositePlugin {
|
|
10
10
|
static id = 'moleculer'
|
|
@@ -204,8 +204,12 @@ function isBinary (val) {
|
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
function isHeartbeat (ops, config) {
|
|
207
|
-
// Check if it's a heartbeat command
|
|
208
|
-
return
|
|
207
|
+
// Check if it's a heartbeat command https://github.com/mongodb/specifications/blob/master/source/mongodb-handshake/handshake.md
|
|
208
|
+
return (
|
|
209
|
+
ops &&
|
|
210
|
+
typeof ops === 'object' &&
|
|
211
|
+
(ops.hello === 1 || ops.helloOk === true || ops.ismaster === 1 || ops.isMaster === 1)
|
|
212
|
+
)
|
|
209
213
|
}
|
|
210
214
|
|
|
211
215
|
module.exports = MongodbCorePlugin
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
4
|
-
const OpenAiTracingPlugin = require('./tracing')
|
|
5
4
|
const OpenAiLLMObsPlugin = require('../../dd-trace/src/llmobs/plugins/openai')
|
|
5
|
+
const OpenAiTracingPlugin = require('./tracing')
|
|
6
6
|
|
|
7
7
|
class OpenAiPlugin extends CompositePlugin {
|
|
8
8
|
static id = 'openai'
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {Record<string, unknown>} JsonObject
|
|
5
|
+
*
|
|
6
|
+
* @typedef {{ function: { arguments: string } }} ToolCall
|
|
7
|
+
* @typedef {{ content?: string, tool_calls?: ToolCall[] }} ChatDelta
|
|
8
|
+
*
|
|
9
|
+
* @typedef {{
|
|
10
|
+
* index: number,
|
|
11
|
+
* finish_reason?: string | null,
|
|
12
|
+
* text?: string,
|
|
13
|
+
* delta?: ChatDelta
|
|
14
|
+
* }} StreamChoice
|
|
15
|
+
*
|
|
16
|
+
* @typedef {JsonObject & { choices: StreamChoice[], usage?: unknown }} StreamChunk
|
|
17
|
+
* @typedef {JsonObject & { choices: Array<StreamChoice | undefined>, usage?: unknown }} StreamResponseBody
|
|
18
|
+
*
|
|
19
|
+
* @typedef {JsonObject & { status?: string }} ResponsesApiResponse
|
|
20
|
+
* @typedef {JsonObject & { response?: ResponsesApiResponse }} ResponsesApiChunk
|
|
21
|
+
*/
|
|
22
|
+
|
|
3
23
|
/**
|
|
4
24
|
* Combines legacy OpenAI streamed chunks into a single object.
|
|
5
25
|
* These legacy chunks are returned as buffers instead of individual objects.
|
|
6
26
|
* @param {readonly Uint8Array[]} chunks
|
|
7
|
-
* @returns {
|
|
27
|
+
* @returns {JsonObject[]}
|
|
8
28
|
*/
|
|
9
29
|
function convertBuffersToObjects (chunks) {
|
|
10
30
|
return Buffer
|
|
@@ -21,10 +41,10 @@ function convertBuffersToObjects (chunks) {
|
|
|
21
41
|
* The shared logic will add a new choice index entry if it doesn't exist, and otherwise
|
|
22
42
|
* hand off to a onChoice handler to add that choice to the previously stored choice.
|
|
23
43
|
*
|
|
24
|
-
* @param {
|
|
44
|
+
* @param {StreamChunk[]} chunks
|
|
25
45
|
* @param {number} n
|
|
26
|
-
* @param {
|
|
27
|
-
* @returns {
|
|
46
|
+
* @param {(newChoice: StreamChoice, existingChoice: StreamChoice) => void} onChoice
|
|
47
|
+
* @returns {StreamResponseBody}
|
|
28
48
|
*/
|
|
29
49
|
function constructResponseFromStreamedChunks (chunks, n, onChoice) {
|
|
30
50
|
const body = { ...chunks[0], choices: Array.from({ length: n }) }
|
|
@@ -54,9 +74,9 @@ function constructResponseFromStreamedChunks (chunks, n, onChoice) {
|
|
|
54
74
|
/**
|
|
55
75
|
* Constructs the entire response from a stream of OpenAI completion chunks,
|
|
56
76
|
* mainly combining the text choices of each chunk into a single string per choice.
|
|
57
|
-
* @param {
|
|
77
|
+
* @param {StreamChunk[]} chunks
|
|
58
78
|
* @param {number} n the number of choices to expect in the response
|
|
59
|
-
* @returns {
|
|
79
|
+
* @returns {StreamResponseBody}
|
|
60
80
|
*/
|
|
61
81
|
function constructCompletionResponseFromStreamedChunks (chunks, n) {
|
|
62
82
|
return constructResponseFromStreamedChunks(chunks, n, (choice, oldChoice) => {
|
|
@@ -74,9 +94,9 @@ function constructCompletionResponseFromStreamedChunks (chunks, n) {
|
|
|
74
94
|
/**
|
|
75
95
|
* Constructs the entire response from a stream of OpenAI chat completion chunks,
|
|
76
96
|
* mainly combining the text choices of each chunk into a single string per choice.
|
|
77
|
-
* @param {
|
|
97
|
+
* @param {StreamChunk[]} chunks
|
|
78
98
|
* @param {number} n the number of choices to expect in the response
|
|
79
|
-
* @returns {
|
|
99
|
+
* @returns {StreamResponseBody}
|
|
80
100
|
*/
|
|
81
101
|
function constructChatCompletionResponseFromStreamedChunks (chunks, n) {
|
|
82
102
|
return constructResponseFromStreamedChunks(chunks, n, (choice, oldChoice) => {
|
|
@@ -110,8 +130,8 @@ function constructChatCompletionResponseFromStreamedChunks (chunks, n) {
|
|
|
110
130
|
/**
|
|
111
131
|
* Constructs the entire response from a stream of OpenAI responses chunks.
|
|
112
132
|
* The responses API uses event-based streaming with delta chunks.
|
|
113
|
-
* @param {
|
|
114
|
-
* @returns {
|
|
133
|
+
* @param {ResponsesApiChunk[]} chunks
|
|
134
|
+
* @returns {ResponsesApiResponse|undefined}
|
|
115
135
|
*/
|
|
116
136
|
function constructResponseResponseFromStreamedChunks (chunks) {
|
|
117
137
|
// The responses API streams events with different types:
|
|
@@ -4,10 +4,10 @@ const path = require('path')
|
|
|
4
4
|
|
|
5
5
|
const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
|
|
6
6
|
const { storage } = require('../../datadog-core')
|
|
7
|
-
const services = require('./services')
|
|
8
7
|
const Sampler = require('../../dd-trace/src/sampler')
|
|
9
8
|
const { MEASURED } = require('../../../ext/tags')
|
|
10
9
|
|
|
10
|
+
const { DD_MAJOR } = require('../../../version')
|
|
11
11
|
const {
|
|
12
12
|
convertBuffersToObjects,
|
|
13
13
|
constructCompletionResponseFromStreamedChunks,
|
|
@@ -15,7 +15,7 @@ const {
|
|
|
15
15
|
constructResponseResponseFromStreamedChunks
|
|
16
16
|
} = require('./stream-helpers')
|
|
17
17
|
|
|
18
|
-
const
|
|
18
|
+
const services = require('./services')
|
|
19
19
|
|
|
20
20
|
class OpenAiTracingPlugin extends TracingPlugin {
|
|
21
21
|
static id = 'openai'
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
3
4
|
const ProducerPlugin = require('./producer')
|
|
4
5
|
const ConsumerPlugin = require('./consumer')
|
|
5
|
-
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
6
6
|
|
|
7
7
|
class RheaPlugin extends CompositePlugin {
|
|
8
8
|
static id = 'rhea'
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const TracingPlugin = require('../../dd-trace/src/plugins/tracing.js')
|
|
4
|
+
const {
|
|
5
|
+
WEBSOCKET_PTR_KIND,
|
|
6
|
+
SPAN_POINTER_DIRECTION,
|
|
7
|
+
SPAN_POINTER_DIRECTION_NAME
|
|
8
|
+
} = require('../../dd-trace/src/constants')
|
|
9
|
+
const {
|
|
10
|
+
incrementWebSocketCounter,
|
|
11
|
+
buildWebSocketSpanPointerHash,
|
|
12
|
+
hasDistributedTracingContext
|
|
13
|
+
} = require('./util')
|
|
4
14
|
|
|
5
15
|
class WSClosePlugin extends TracingPlugin {
|
|
6
16
|
static get id () { return 'ws' }
|
|
@@ -10,11 +20,9 @@ class WSClosePlugin extends TracingPlugin {
|
|
|
10
20
|
|
|
11
21
|
bindStart (ctx) {
|
|
12
22
|
const {
|
|
13
|
-
traceWebsocketMessagesEnabled,
|
|
14
23
|
traceWebsocketMessagesInheritSampling,
|
|
15
24
|
traceWebsocketMessagesSeparateTraces
|
|
16
25
|
} = this.config
|
|
17
|
-
if (!traceWebsocketMessagesEnabled) return
|
|
18
26
|
|
|
19
27
|
const { code, data, socket, isPeerClose } = ctx
|
|
20
28
|
if (!socket?.spanContext) return
|
|
@@ -60,7 +68,52 @@ class WSClosePlugin extends TracingPlugin {
|
|
|
60
68
|
end (ctx) {
|
|
61
69
|
if (!Object.hasOwn(ctx, 'result') || !ctx.span) return
|
|
62
70
|
|
|
63
|
-
if (ctx.socket.spanContext)
|
|
71
|
+
if (ctx.socket.spanContext) {
|
|
72
|
+
const linkAttributes = {}
|
|
73
|
+
|
|
74
|
+
// Determine link kind based on whether this is peer close (incoming) or self close (outgoing)
|
|
75
|
+
const isIncoming = ctx.isPeerClose
|
|
76
|
+
linkAttributes['dd.kind'] = isIncoming ? 'executed_by' : 'resuming'
|
|
77
|
+
|
|
78
|
+
// Add span pointer for context propagation
|
|
79
|
+
if (this.config.traceWebsocketMessagesEnabled && ctx.socket.handshakeSpan) {
|
|
80
|
+
const handshakeSpan = ctx.socket.handshakeSpan
|
|
81
|
+
|
|
82
|
+
// Only add span pointers if distributed tracing is enabled and handshake has distributed context
|
|
83
|
+
if (hasDistributedTracingContext(handshakeSpan, ctx.socket)) {
|
|
84
|
+
const counterType = isIncoming ? 'receiveCounter' : 'sendCounter'
|
|
85
|
+
const counter = incrementWebSocketCounter(ctx.socket, counterType)
|
|
86
|
+
const handshakeContext = handshakeSpan.context()
|
|
87
|
+
|
|
88
|
+
const ptrHash = buildWebSocketSpanPointerHash(
|
|
89
|
+
handshakeContext._traceId,
|
|
90
|
+
handshakeContext._spanId,
|
|
91
|
+
counter,
|
|
92
|
+
true, // isServer
|
|
93
|
+
isIncoming
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
const directionName = isIncoming
|
|
97
|
+
? SPAN_POINTER_DIRECTION_NAME.UPSTREAM
|
|
98
|
+
: SPAN_POINTER_DIRECTION_NAME.DOWNSTREAM
|
|
99
|
+
const direction = isIncoming
|
|
100
|
+
? SPAN_POINTER_DIRECTION.UPSTREAM
|
|
101
|
+
: SPAN_POINTER_DIRECTION.DOWNSTREAM
|
|
102
|
+
|
|
103
|
+
// Add span pointer attributes to link
|
|
104
|
+
linkAttributes['link.name'] = directionName
|
|
105
|
+
linkAttributes['dd.kind'] = 'span-pointer'
|
|
106
|
+
linkAttributes['ptr.kind'] = WEBSOCKET_PTR_KIND
|
|
107
|
+
linkAttributes['ptr.dir'] = direction
|
|
108
|
+
linkAttributes['ptr.hash'] = ptrHash
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
ctx.span.addLink({
|
|
113
|
+
context: ctx.socket.spanContext,
|
|
114
|
+
attributes: linkAttributes
|
|
115
|
+
})
|
|
116
|
+
}
|
|
64
117
|
|
|
65
118
|
ctx.span.finish()
|
|
66
119
|
}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const TracingPlugin = require('../../dd-trace/src/plugins/tracing.js')
|
|
4
|
+
const {
|
|
5
|
+
WEBSOCKET_PTR_KIND,
|
|
6
|
+
SPAN_POINTER_DIRECTION,
|
|
7
|
+
SPAN_POINTER_DIRECTION_NAME
|
|
8
|
+
} = require('../../dd-trace/src/constants')
|
|
9
|
+
const {
|
|
10
|
+
incrementWebSocketCounter,
|
|
11
|
+
buildWebSocketSpanPointerHash,
|
|
12
|
+
hasDistributedTracingContext
|
|
13
|
+
} = require('./util')
|
|
4
14
|
|
|
5
15
|
class WSProducerPlugin extends TracingPlugin {
|
|
6
16
|
static get id () { return 'ws' }
|
|
@@ -9,9 +19,6 @@ class WSProducerPlugin extends TracingPlugin {
|
|
|
9
19
|
static get kind () { return 'producer' }
|
|
10
20
|
|
|
11
21
|
bindStart (ctx) {
|
|
12
|
-
const messagesEnabled = this.config.traceWebsocketMessagesEnabled
|
|
13
|
-
if (!messagesEnabled) return
|
|
14
|
-
|
|
15
22
|
const { byteLength, socket, binary } = ctx
|
|
16
23
|
if (!socket.spanContext) return
|
|
17
24
|
|
|
@@ -51,9 +58,37 @@ class WSProducerPlugin extends TracingPlugin {
|
|
|
51
58
|
if (!Object.hasOwn(ctx, 'result') || !ctx.span) return
|
|
52
59
|
|
|
53
60
|
if (ctx.socket.spanContext) {
|
|
61
|
+
const linkAttributes = { 'dd.kind': 'resuming' }
|
|
62
|
+
|
|
63
|
+
// Add span pointer for context propagation
|
|
64
|
+
if (this.config.traceWebsocketMessagesEnabled && ctx.socket.handshakeSpan) {
|
|
65
|
+
const handshakeSpan = ctx.socket.handshakeSpan
|
|
66
|
+
|
|
67
|
+
// Only add span pointers if distributed tracing is enabled and handshake has distributed context
|
|
68
|
+
if (hasDistributedTracingContext(handshakeSpan, ctx.socket)) {
|
|
69
|
+
const counter = incrementWebSocketCounter(ctx.socket, 'sendCounter')
|
|
70
|
+
const handshakeContext = handshakeSpan.context()
|
|
71
|
+
|
|
72
|
+
const ptrHash = buildWebSocketSpanPointerHash(
|
|
73
|
+
handshakeContext._traceId,
|
|
74
|
+
handshakeContext._spanId,
|
|
75
|
+
counter,
|
|
76
|
+
true, // isServer
|
|
77
|
+
false // isIncoming (this is outgoing)
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
// Add span pointer attributes to link
|
|
81
|
+
linkAttributes['link.name'] = SPAN_POINTER_DIRECTION_NAME.DOWNSTREAM
|
|
82
|
+
linkAttributes['dd.kind'] = 'span-pointer'
|
|
83
|
+
linkAttributes['ptr.kind'] = WEBSOCKET_PTR_KIND
|
|
84
|
+
linkAttributes['ptr.dir'] = SPAN_POINTER_DIRECTION.DOWNSTREAM
|
|
85
|
+
linkAttributes['ptr.hash'] = ptrHash
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
54
89
|
ctx.span.addLink({
|
|
55
90
|
context: ctx.socket.spanContext,
|
|
56
|
-
attributes:
|
|
91
|
+
attributes: linkAttributes,
|
|
57
92
|
})
|
|
58
93
|
}
|
|
59
94
|
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const TracingPlugin = require('../../dd-trace/src/plugins/tracing.js')
|
|
4
|
+
const {
|
|
5
|
+
WEBSOCKET_PTR_KIND,
|
|
6
|
+
SPAN_POINTER_DIRECTION,
|
|
7
|
+
SPAN_POINTER_DIRECTION_NAME
|
|
8
|
+
} = require('../../dd-trace/src/constants')
|
|
9
|
+
const {
|
|
10
|
+
incrementWebSocketCounter,
|
|
11
|
+
buildWebSocketSpanPointerHash,
|
|
12
|
+
hasDistributedTracingContext
|
|
13
|
+
} = require('./util')
|
|
4
14
|
|
|
5
15
|
class WSReceiverPlugin extends TracingPlugin {
|
|
6
16
|
static get id () { return 'ws' }
|
|
@@ -10,11 +20,9 @@ class WSReceiverPlugin extends TracingPlugin {
|
|
|
10
20
|
|
|
11
21
|
bindStart (ctx) {
|
|
12
22
|
const {
|
|
13
|
-
traceWebsocketMessagesEnabled,
|
|
14
23
|
traceWebsocketMessagesInheritSampling,
|
|
15
24
|
traceWebsocketMessagesSeparateTraces
|
|
16
25
|
} = this.config
|
|
17
|
-
if (!traceWebsocketMessagesEnabled) return
|
|
18
26
|
|
|
19
27
|
const { byteLength, socket, binary } = ctx
|
|
20
28
|
if (!socket.spanContext) return
|
|
@@ -61,9 +69,37 @@ class WSReceiverPlugin extends TracingPlugin {
|
|
|
61
69
|
if (!Object.hasOwn(ctx, 'result') || !ctx.span) return
|
|
62
70
|
|
|
63
71
|
if (ctx.socket.spanContext) {
|
|
72
|
+
const linkAttributes = { 'dd.kind': 'executed_by' }
|
|
73
|
+
|
|
74
|
+
// Add span pointer for context propagation
|
|
75
|
+
if (this.config.traceWebsocketMessagesEnabled && ctx.socket.handshakeSpan) {
|
|
76
|
+
const handshakeSpan = ctx.socket.handshakeSpan
|
|
77
|
+
|
|
78
|
+
// Only add span pointers if distributed tracing is enabled and handshake has distributed context
|
|
79
|
+
if (hasDistributedTracingContext(handshakeSpan, ctx.socket)) {
|
|
80
|
+
const counter = incrementWebSocketCounter(ctx.socket, 'receiveCounter')
|
|
81
|
+
const handshakeContext = handshakeSpan.context()
|
|
82
|
+
|
|
83
|
+
const ptrHash = buildWebSocketSpanPointerHash(
|
|
84
|
+
handshakeContext._traceId,
|
|
85
|
+
handshakeContext._spanId,
|
|
86
|
+
counter,
|
|
87
|
+
true, // isServer
|
|
88
|
+
true // isIncoming
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
// Add span pointer attributes to link
|
|
92
|
+
linkAttributes['link.name'] = SPAN_POINTER_DIRECTION_NAME.UPSTREAM
|
|
93
|
+
linkAttributes['dd.kind'] = 'span-pointer'
|
|
94
|
+
linkAttributes['ptr.kind'] = WEBSOCKET_PTR_KIND
|
|
95
|
+
linkAttributes['ptr.dir'] = SPAN_POINTER_DIRECTION.UPSTREAM
|
|
96
|
+
linkAttributes['ptr.hash'] = ptrHash
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
64
100
|
ctx.span.addLink({
|
|
65
101
|
context: ctx.socket.spanContext,
|
|
66
|
-
attributes:
|
|
102
|
+
attributes: linkAttributes,
|
|
67
103
|
})
|
|
68
104
|
}
|
|
69
105
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const TracingPlugin = require('../../dd-trace/src/plugins/tracing.js')
|
|
4
4
|
const tags = require('../../../ext/tags.js')
|
|
5
|
+
const { FORMAT_HTTP_HEADERS } = require('../../../ext/formats')
|
|
6
|
+
const { initWebSocketMessageCounters } = require('./util')
|
|
5
7
|
|
|
6
8
|
const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
|
|
7
9
|
|
|
@@ -28,9 +30,13 @@ class WSServerPlugin extends TracingPlugin {
|
|
|
28
30
|
|
|
29
31
|
ctx.args = { options }
|
|
30
32
|
|
|
33
|
+
// Extract distributed tracing context from request headers
|
|
34
|
+
const childOf = this.tracer.extract(FORMAT_HTTP_HEADERS, req.headers)
|
|
35
|
+
|
|
31
36
|
const service = this.serviceName({ pluginConfig: this.config })
|
|
32
37
|
const span = this.startSpan(this.operationName(), {
|
|
33
38
|
service,
|
|
39
|
+
childOf,
|
|
34
40
|
meta: {
|
|
35
41
|
'span.type': 'websocket',
|
|
36
42
|
'http.upgraded': 'websocket',
|
|
@@ -38,7 +44,6 @@ class WSServerPlugin extends TracingPlugin {
|
|
|
38
44
|
'http.url': uri,
|
|
39
45
|
'resource.name': `${options.method} ${route}`,
|
|
40
46
|
'span.kind': 'server'
|
|
41
|
-
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
}, ctx)
|
|
@@ -46,6 +51,13 @@ class WSServerPlugin extends TracingPlugin {
|
|
|
46
51
|
|
|
47
52
|
ctx.socket.spanContext = ctx.span._spanContext
|
|
48
53
|
ctx.socket.spanContext.spanTags = ctx.span._spanContext._tags
|
|
54
|
+
// Store the handshake span for use in message span pointers
|
|
55
|
+
ctx.socket.handshakeSpan = ctx.span
|
|
56
|
+
// Store the request headers for distributed tracing check
|
|
57
|
+
ctx.socket.requestHeaders = req.headers
|
|
58
|
+
|
|
59
|
+
// Initialize message counters for span pointers
|
|
60
|
+
initWebSocketMessageCounters(ctx.socket)
|
|
49
61
|
|
|
50
62
|
return ctx.currentStore
|
|
51
63
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// WeakMap to store message counters per socket without mutating the socket object
|
|
4
|
+
const socketCounters = new WeakMap()
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Initializes WebSocket message counters for a socket.
|
|
8
|
+
* @param {object} socket - The WebSocket socket object
|
|
9
|
+
*/
|
|
10
|
+
function initWebSocketMessageCounters (socket) {
|
|
11
|
+
if (!socketCounters.has(socket)) {
|
|
12
|
+
socketCounters.set(socket, {
|
|
13
|
+
receiveCounter: 0,
|
|
14
|
+
sendCounter: 0
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Increments and returns the WebSocket message counter.
|
|
21
|
+
* @param {object} socket - The WebSocket socket object
|
|
22
|
+
* @param {string} counterType - Either 'receiveCounter' or 'sendCounter'
|
|
23
|
+
* @returns {number} The incremented counter value
|
|
24
|
+
*/
|
|
25
|
+
function incrementWebSocketCounter (socket, counterType) {
|
|
26
|
+
if (!socketCounters.has(socket)) {
|
|
27
|
+
initWebSocketMessageCounters(socket)
|
|
28
|
+
}
|
|
29
|
+
const counters = socketCounters.get(socket)
|
|
30
|
+
counters[counterType]++
|
|
31
|
+
return counters[counterType]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Builds a WebSocket span pointer hash.
|
|
36
|
+
*
|
|
37
|
+
* Format: <prefix><128 bit hex trace id><64 bit hex span id><32 bit hex counter>
|
|
38
|
+
* Prefix: 'S' for server outgoing or client incoming, 'C' for server incoming or client outgoing
|
|
39
|
+
*
|
|
40
|
+
* @param {bigint} handshakeTraceId - The trace ID from the handshake span (as a BigInt)
|
|
41
|
+
* @param {bigint} handshakeSpanId - The span ID from the handshake span (as a BigInt)
|
|
42
|
+
* @param {number} counter - The message counter
|
|
43
|
+
* @param {boolean} isServer - Whether this is a server (true) or client (false)
|
|
44
|
+
* @param {boolean} isIncoming - Whether this is an incoming message (true) or outgoing (false)
|
|
45
|
+
* @returns {string} The span pointer hash
|
|
46
|
+
*/
|
|
47
|
+
function buildWebSocketSpanPointerHash (handshakeTraceId, handshakeSpanId, counter, isServer, isIncoming) {
|
|
48
|
+
// Determine prefix based on server/client and incoming/outgoing
|
|
49
|
+
// Server outgoing or client incoming: 'S'
|
|
50
|
+
// Server incoming or client outgoing: 'C'
|
|
51
|
+
const prefix = (isServer && !isIncoming) || (!isServer && isIncoming) ? 'S' : 'C'
|
|
52
|
+
|
|
53
|
+
// Pad trace ID to 32 hex chars (128 bits)
|
|
54
|
+
const traceIdHex = handshakeTraceId.toString(16).padStart(32, '0')
|
|
55
|
+
|
|
56
|
+
// Pad span ID to 16 hex chars (64 bits)
|
|
57
|
+
const spanIdHex = handshakeSpanId.toString(16).padStart(16, '0')
|
|
58
|
+
|
|
59
|
+
// Pad counter to 8 hex chars (32 bits)
|
|
60
|
+
const counterHex = counter.toString(16).padStart(8, '0')
|
|
61
|
+
|
|
62
|
+
return `${prefix}${traceIdHex}${spanIdHex}${counterHex}`
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Checks if the handshake span has extracted distributed tracing context.
|
|
67
|
+
* A websocket server must not set the span pointer if the handshake has not extracted a context.
|
|
68
|
+
*
|
|
69
|
+
* A span has distributed tracing context if it has a parent context that was
|
|
70
|
+
* extracted from headers (remote parent).
|
|
71
|
+
*
|
|
72
|
+
* @param {object} span - The handshake span
|
|
73
|
+
* @param {object} socket - The WebSocket socket object
|
|
74
|
+
* @returns {boolean} True if the span has distributed tracing context
|
|
75
|
+
*/
|
|
76
|
+
function hasDistributedTracingContext (span, socket) {
|
|
77
|
+
if (!span) return false
|
|
78
|
+
const context = span.context()
|
|
79
|
+
if (!context) return false
|
|
80
|
+
|
|
81
|
+
// Check if this span has a parent. If the parent was extracted from remote headers,
|
|
82
|
+
// then this span is part of a distributed trace.
|
|
83
|
+
// We check if the span has a parent by looking at _parentId.
|
|
84
|
+
// In the JavaScript tracer, when a context is extracted from headers and a child span
|
|
85
|
+
// is created, the child will have _parentId set to the extracted parent's span ID.
|
|
86
|
+
//
|
|
87
|
+
// For testing purposes, we also check if Datadog trace headers are present in the socket's
|
|
88
|
+
// upgrade request, which indicates distributed tracing context was sent by the client.
|
|
89
|
+
if (context._parentId !== null) {
|
|
90
|
+
return true
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Fallback check: look for distributed tracing headers in the stored request headers
|
|
94
|
+
if (socket && socket.requestHeaders) {
|
|
95
|
+
const headers = socket.requestHeaders
|
|
96
|
+
return !!(headers['x-datadog-trace-id'] || headers.traceparent)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return false
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = {
|
|
103
|
+
initWebSocketMessageCounters,
|
|
104
|
+
incrementWebSocketCounter,
|
|
105
|
+
buildWebSocketSpanPointerHash,
|
|
106
|
+
hasDistributedTracingContext
|
|
107
|
+
}
|
|
@@ -91,7 +91,7 @@ function wrapFunction (original, wrapper) {
|
|
|
91
91
|
* @param {Record<string | symbol, unknown> | Function | undefined} target - The target
|
|
92
92
|
* object.
|
|
93
93
|
* @param {string | symbol} name - The property key of the method to wrap.
|
|
94
|
-
* @param {(original: Function) => (...args: unknown[]) =>
|
|
94
|
+
* @param {(original: Function) => (...args: unknown[]) => unknown} wrapper - The wrapper function.
|
|
95
95
|
* @param {{ replaceGetter?: boolean }} [options] - If `replaceGetter` is set to
|
|
96
96
|
* true, the getter is accessed and the getter is replaced with one that just
|
|
97
97
|
* returns the earlier retrieved value. Use with care! This may only be done in
|
|
@@ -214,7 +214,7 @@ function wrap (target, name, wrapper, options) {
|
|
|
214
214
|
* Record<string | symbol, unknown> |
|
|
215
215
|
* Function} targets - The target objects.
|
|
216
216
|
* @param {Array<string | symbol> | string | symbol} names - The property keys of the methods to wrap.
|
|
217
|
-
* @param {(original: Function) => (...args: unknown[]) =>
|
|
217
|
+
* @param {(original: Function) => (...args: unknown[]) => unknown} wrapper - The wrapper function.
|
|
218
218
|
*/
|
|
219
219
|
function massWrap (targets, names, wrapper) {
|
|
220
220
|
targets = toArray(targets)
|