dd-trace 6.8.0 → 6.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ci/diagnose.js +27 -25
- package/ci/init.js +6 -6
- package/ci/runbook.md +114 -20
- package/ci/test-optimization-validation/approval-artifacts.js +36 -3
- package/ci/test-optimization-validation/approval.js +78 -22
- package/ci/test-optimization-validation/blocker-category.js +24 -0
- package/ci/test-optimization-validation/ci-discovery.js +23 -17
- package/ci/test-optimization-validation/ci-package-scripts.js +34 -6
- package/ci/test-optimization-validation/ci-remediation.js +1 -1
- package/ci/test-optimization-validation/cli.js +280 -52
- package/ci/test-optimization-validation/command-blocker.js +159 -20
- package/ci/test-optimization-validation/command-output-policy.js +9 -3
- package/ci/test-optimization-validation/command-runner.js +9 -7
- package/ci/test-optimization-validation/environment.js +4 -2
- package/ci/test-optimization-validation/executable.js +15 -13
- package/ci/test-optimization-validation/execution-lock.js +70 -0
- package/ci/test-optimization-validation/framework-adapters/cucumber-validation.json +3 -0
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +657 -5
- package/ci/test-optimization-validation/framework-adapters/vitest.js +517 -0
- package/ci/test-optimization-validation/generated-files.js +38 -28
- package/ci/test-optimization-validation/generated-test-contract.js +8 -4
- package/ci/test-optimization-validation/generated-verifier.js +24 -17
- package/ci/test-optimization-validation/literal-glob.js +52 -0
- package/ci/test-optimization-validation/manifest-loader.js +3 -0
- package/ci/test-optimization-validation/manifest-scaffold.js +300 -50
- package/ci/test-optimization-validation/manifest-schema.js +80 -17
- package/ci/test-optimization-validation/offline-fixtures.js +13 -4
- package/ci/test-optimization-validation/package-check.js +94 -0
- package/ci/test-optimization-validation/plan-writer.js +183 -10
- package/ci/test-optimization-validation/preflight-runner.js +110 -31
- package/ci/test-optimization-validation/project-build-artifact.js +31 -0
- package/ci/test-optimization-validation/redaction.js +18 -27
- package/ci/test-optimization-validation/report-writer.js +182 -48
- package/ci/test-optimization-validation/result-semantics.js +20 -3
- package/ci/test-optimization-validation/runner-command.js +40 -20
- package/ci/test-optimization-validation/runner-contract.js +79 -43
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +59 -5
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +141 -35
- package/ci/test-optimization-validation/scenarios/helpers.js +30 -6
- package/ci/test-optimization-validation/static-diagnosis.js +10 -3
- package/ci/test-optimization-validation/test-output.js +2 -1
- package/ci/test-optimization-validation/validation-blocker.js +21 -0
- package/ci/vitest-no-worker-init-setup.mjs +140 -42
- package/index.d.ts +140 -1
- package/init.js +1 -17
- package/initialize.mjs +11 -0
- package/loader-hook.mjs +6 -4
- package/package.json +8 -5
- package/packages/datadog-core/src/utils/src/parse-tags.js +0 -1
- package/packages/datadog-esbuild/src/utils.js +16 -1
- package/packages/datadog-instrumentations/src/ai.js +61 -34
- package/packages/datadog-instrumentations/src/bluebird.js +6 -6
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +81 -5
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +111 -6
- package/packages/datadog-instrumentations/src/cucumber.js +124 -47
- package/packages/datadog-instrumentations/src/dns.js +21 -2
- package/packages/datadog-instrumentations/src/electron.js +1 -0
- package/packages/datadog-instrumentations/src/fastify.js +3 -1
- package/packages/datadog-instrumentations/src/grpc/client.js +4 -2
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +3 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +629 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +34 -9
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +199 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +20 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +32 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +62 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +83 -1
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +37 -6
- package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +980 -234
- package/packages/datadog-instrumentations/src/mocha/main.js +108 -10
- package/packages/datadog-instrumentations/src/mocha/utils.js +66 -50
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +25 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +12 -18
- package/packages/datadog-instrumentations/src/mysql.js +46 -16
- package/packages/datadog-instrumentations/src/mysql2.js +119 -18
- package/packages/datadog-instrumentations/src/next.js +155 -23
- package/packages/datadog-instrumentations/src/openai.js +14 -0
- package/packages/datadog-instrumentations/src/path-to-regexp.js +67 -1
- package/packages/datadog-instrumentations/src/pg.js +209 -11
- package/packages/datadog-instrumentations/src/playwright.js +173 -79
- package/packages/datadog-instrumentations/src/promise-js.js +4 -4
- package/packages/datadog-instrumentations/src/promise.js +3 -3
- package/packages/datadog-instrumentations/src/router.js +195 -19
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +85 -13
- package/packages/datadog-instrumentations/src/vitest-main.js +528 -72
- package/packages/datadog-instrumentations/src/vitest-util.js +106 -12
- package/packages/datadog-instrumentations/src/vitest-worker.js +382 -40
- package/packages/datadog-instrumentations/src/webdriverio.js +212 -22
- package/packages/datadog-instrumentations/src/when.js +3 -3
- package/packages/datadog-instrumentations/src/ws.js +5 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +12 -6
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +59 -48
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -5
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -5
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -3
- package/packages/datadog-plugin-cucumber/src/index.js +5 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +51 -47
- package/packages/datadog-plugin-cypress/src/support.js +7 -4
- package/packages/datadog-plugin-electron/src/net.js +10 -4
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +31 -17
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +6 -22
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -3
- package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -3
- package/packages/datadog-plugin-kafkajs/src/producer.js +5 -3
- package/packages/datadog-plugin-kafkajs/src/utils.js +65 -7
- package/packages/datadog-plugin-mocha/src/index.js +832 -4
- package/packages/datadog-plugin-mysql/src/index.js +37 -0
- package/packages/datadog-plugin-next/src/index.js +51 -21
- package/packages/datadog-plugin-openai/src/tracing.js +4 -0
- package/packages/datadog-plugin-openai-agents/src/integration.js +278 -69
- package/packages/datadog-plugin-openai-agents/src/processor.js +16 -4
- package/packages/datadog-plugin-pg/src/index.js +66 -1
- package/packages/datadog-plugin-playwright/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +103 -27
- package/packages/datadog-plugin-ws/src/util.js +2 -1
- package/packages/datadog-shimmer/src/shimmer.js +6 -2
- package/packages/dd-trace/src/aiguard/sdk.js +3 -0
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +453 -0
- package/packages/dd-trace/src/appsec/{blocking.js → blocking/index.js} +26 -6
- package/packages/dd-trace/src/appsec/handlers/auth.js +62 -0
- package/packages/dd-trace/src/appsec/handlers/http-request.js +228 -0
- package/packages/dd-trace/src/appsec/handlers/http-response.js +78 -0
- package/packages/dd-trace/src/appsec/handlers/http-shared.js +24 -0
- package/packages/dd-trace/src/appsec/handlers/payments.js +104 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +48 -476
- package/packages/dd-trace/src/appsec/sdk/track_event.js +9 -0
- package/packages/dd-trace/src/carrier.js +356 -0
- package/packages/dd-trace/src/ci-visibility/coverage-report-discovery.js +46 -14
- package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +89 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +27 -13
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +17 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +21 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +22 -7
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +9 -14
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +21 -5
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +1 -1
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +5 -1
- package/packages/dd-trace/src/config/generated-config-types.d.ts +5 -0
- package/packages/dd-trace/src/config/helper.js +2 -0
- package/packages/dd-trace/src/config/index.js +16 -5
- package/packages/dd-trace/src/config/remote_config.js +1 -1
- package/packages/dd-trace/src/config/supported-configurations.json +18 -0
- package/packages/dd-trace/src/datastreams/context.js +6 -1
- package/packages/dd-trace/src/datastreams/manager.js +5 -1
- package/packages/dd-trace/src/datastreams/pathway.js +23 -22
- package/packages/dd-trace/src/datastreams/processor.js +3 -2
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
- package/packages/dd-trace/src/guardrails/apply-pm2-env.js +16 -0
- package/packages/dd-trace/src/guardrails/log.js +1 -10
- package/packages/dd-trace/src/llmobs/constants/tags.js +5 -0
- package/packages/dd-trace/src/llmobs/eval-metric.js +249 -0
- package/packages/dd-trace/src/llmobs/experiments/index.js +33 -25
- package/packages/dd-trace/src/llmobs/experiments/util.js +4 -2
- package/packages/dd-trace/src/llmobs/index.js +34 -2
- package/packages/dd-trace/src/llmobs/noop.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +5 -5
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +149 -68
- package/packages/dd-trace/src/llmobs/span_processor.js +16 -0
- package/packages/dd-trace/src/llmobs/tagger.js +96 -0
- package/packages/dd-trace/src/llmobs/telemetry.js +18 -0
- package/packages/dd-trace/src/llmobs/util.js +78 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +3 -0
- package/packages/dd-trace/src/llmobs/writers/util.js +2 -0
- package/packages/dd-trace/src/log/channels.js +1 -9
- package/packages/dd-trace/src/log/levels.js +12 -0
- package/packages/dd-trace/src/openfeature/writers/exposures.js +1 -1
- package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/meter.js +8 -4
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -1
- package/packages/dd-trace/src/opentelemetry/span.js +4 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +126 -120
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +4 -8
- package/packages/dd-trace/src/plugin_manager.js +2 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +21 -5
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +6 -0
- package/packages/dd-trace/src/plugins/util/git.js +6 -4
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +2 -2
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
- package/packages/{datadog-plugin-jest/src/util.js → dd-trace/src/plugins/util/jest.js} +3 -62
- package/packages/dd-trace/src/plugins/util/stacktrace.js +3 -0
- package/packages/dd-trace/src/plugins/util/test.js +397 -74
- package/packages/dd-trace/src/plugins/util/url.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +76 -3
- package/packages/dd-trace/src/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +2 -2
- package/packages/dd-trace/src/proxy.js +1 -0
- package/packages/dd-trace/src/ritm.js +5 -0
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +4 -2
- package/packages/dd-trace/src/sampling_rule.js +4 -2
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +1 -1
- package/packages/dd-trace/src/telemetry/logs/index.js +3 -0
- package/packages/dd-trace/src/telemetry/telemetry.js +1 -1
- package/vendor/dist/pprof-format/index.js +1 -1
- package/version.js +10 -8
- /package/packages/dd-trace/src/appsec/{blocked_templates.js → blocking/templates.js} +0 -0
package/initialize.mjs
CHANGED
|
@@ -20,6 +20,7 @@ import { isMainThread } from 'worker_threads'
|
|
|
20
20
|
|
|
21
21
|
import {
|
|
22
22
|
iitmExclusionRegExp,
|
|
23
|
+
initialize as hookInitialize,
|
|
23
24
|
load as hookLoad,
|
|
24
25
|
resolve as hookResolve,
|
|
25
26
|
} from './loader-hook.mjs?initialize'
|
|
@@ -66,7 +67,17 @@ const [NODE_MAJOR, NODE_MINOR] = process.versions.node.split('.').map(Number)
|
|
|
66
67
|
|
|
67
68
|
const brokenLoaders = NODE_MAJOR === 18 && NODE_MINOR === 0
|
|
68
69
|
|
|
70
|
+
// Node calls `initialize` only through `module.register`, never for `--loader`; without it
|
|
71
|
+
// import-in-the-middle keeps its default matcher and proxies every application module. Loaders
|
|
72
|
+
// before Node 18.19 share the application thread, where `loader-hook.mjs` builds no matcher.
|
|
73
|
+
let needsHookInitialize = !isMainThread && !brokenLoaders
|
|
74
|
+
|
|
69
75
|
export async function load (url, context, nextLoad) {
|
|
76
|
+
if (needsHookInitialize) {
|
|
77
|
+
needsHookInitialize = false
|
|
78
|
+
hookInitialize()
|
|
79
|
+
}
|
|
80
|
+
|
|
70
81
|
const loadHook = (brokenLoaders || iitmExclusionRegExp.test(url)) ? nextLoad : hookLoad
|
|
71
82
|
return insertInit(await loadHook(url, context, nextLoad), url, context)
|
|
72
83
|
}
|
package/loader-hook.mjs
CHANGED
|
@@ -16,7 +16,6 @@ const require = Module.createRequire(import.meta.url)
|
|
|
16
16
|
const isInitializeMainThread = isMainThread && import.meta.url.endsWith('?initialize')
|
|
17
17
|
let syncImportInTheMiddleHook
|
|
18
18
|
|
|
19
|
-
let getValueFromEnvSources
|
|
20
19
|
let regexpEscape
|
|
21
20
|
|
|
22
21
|
// Substrings of resolved URLs that import-in-the-middle must never wrap: re-export
|
|
@@ -32,13 +31,12 @@ const includeModuleNames = new Set()
|
|
|
32
31
|
let moduleNameAlternation = ''
|
|
33
32
|
|
|
34
33
|
if (!isInitializeMainThread) {
|
|
34
|
+
require('./packages/dd-trace/src/guardrails/apply-pm2-env.js')
|
|
35
35
|
const regexpEscapeModule = require('./vendor/dist/escape-string-regexp/index.js')
|
|
36
36
|
const hooks = require('./packages/datadog-instrumentations/src/helpers/hooks.js')
|
|
37
|
-
const configHelper = require('./packages/dd-trace/src/config/helper.js')
|
|
38
37
|
const { isRelativeRequire } = require('./packages/datadog-instrumentations/src/helpers/shared-utils.js')
|
|
39
38
|
|
|
40
39
|
regexpEscape = regexpEscapeModule.default
|
|
41
|
-
getValueFromEnvSources = configHelper.getValueFromEnvSources
|
|
42
40
|
|
|
43
41
|
for (const moduleName of Object.keys(hooks)) {
|
|
44
42
|
// Relative hooks resolve outside node_modules and are not instrumented here.
|
|
@@ -63,7 +61,11 @@ function prepareImportInTheMiddleOptions (data = {}) {
|
|
|
63
61
|
// A consumer-owned shouldInclude predicate takes over the wrapping decision, so
|
|
64
62
|
// iitm ignores the include/exclude arrays. Building the matcher here keeps the
|
|
65
63
|
// synchronous and asynchronous loaders on one matching implementation.
|
|
66
|
-
|
|
64
|
+
// Lazily required and read without its registered default so a loader worker
|
|
65
|
+
// never loads the configuration defaults table. The default is unset regardless.
|
|
66
|
+
const { getValueFromEnvSources } = require('./packages/dd-trace/src/config/helper.js')
|
|
67
|
+
|
|
68
|
+
data.shouldInclude = createShouldInclude(getValueFromEnvSources('DD_IAST_SECURITY_CONTROLS_CONFIGURATION', true))
|
|
67
69
|
|
|
68
70
|
return data
|
|
69
71
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.10.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -15,16 +15,19 @@
|
|
|
15
15
|
"generate:electron-package": "node scripts/generate-electron-package.js",
|
|
16
16
|
"verify:config:types": "node scripts/generate-config-types.js --check",
|
|
17
17
|
"verify:electron-package": "node scripts/generate-electron-package.js --check",
|
|
18
|
+
"generate:rewriter:targets": "node scripts/generate-rewriter-targets.js",
|
|
19
|
+
"verify:rewriter:targets": "node scripts/generate-rewriter-targets.js --check",
|
|
18
20
|
"generate:supported-integrations": "node scripts/generate-supported-integrations.js",
|
|
19
21
|
"verify:supported-integrations": "node scripts/generate-supported-integrations.js --check",
|
|
20
22
|
"type:check": "tsc --noEmit -p tsconfig.dev.json",
|
|
21
23
|
"type:doc:build": "cd docs && yarn && yarn build",
|
|
22
24
|
"type:doc:test": "cd docs && yarn && yarn test",
|
|
23
|
-
"lint": "node scripts/check_licenses.js && node scripts/check-no-coverage-artifacts.js && node scripts/check-no-mcr-images.js && node scripts/check-docker-image-shas.js && eslint . --concurrency=auto --max-warnings 0 && npm run lint:codeowners:ci && npm run verify-exercised-tests",
|
|
25
|
+
"lint": "node scripts/check_licenses.js && node scripts/check-no-coverage-artifacts.js && node scripts/check-no-mcr-images.js && node scripts/check-docker-image-shas.js && eslint . --concurrency=auto --max-warnings 0 && npm run verify:carrier-fields && npm run lint:codeowners:ci && npm run verify-exercised-tests",
|
|
24
26
|
"lint:fix": "node scripts/check_licenses.js && node scripts/check-no-coverage-artifacts.js && node scripts/check-no-mcr-images.js && node scripts/check-docker-image-shas.js && eslint . --concurrency=auto --max-warnings 0 --fix",
|
|
27
|
+
"verify:carrier-fields": "node scripts/verify-carrier-fields.mjs",
|
|
25
28
|
"lint:inspect": "npx @eslint/config-inspector@latest",
|
|
26
29
|
"lint:codeowners": "codeowners-audit",
|
|
27
|
-
"lint:codeowners:ci": "codeowners-audit --glob='**/*.spec.js' --glob='benchmark/sirun/**' --glob='.agents/**' --glob='.claude/**' --glob='integration-tests/**'",
|
|
30
|
+
"lint:codeowners:ci": "codeowners-audit --glob='**/*.spec.js' --glob='benchmark/sirun/**' --glob='.agents/**' --glob='.claude/**' --glob='integration-tests/**' --glob='packages/dd-trace/src/guardrails/**'",
|
|
28
31
|
"lint:editorconfig": "docker build -q -t ec .github/editorconfig-checker && docker run --rm --volume=$PWD:/check ec",
|
|
29
32
|
"release:proposal": "node scripts/release/proposal",
|
|
30
33
|
"services": "node ./scripts/install_plugin_modules && node packages/dd-trace/test/setup/services",
|
|
@@ -37,7 +40,7 @@
|
|
|
37
40
|
"test:appsec:plugins:ci": "yarn services && node scripts/c8-ci.js test:appsec:plugins",
|
|
38
41
|
"test:debugger": "mocha \"packages/dd-trace/test/debugger/**/*.spec.js\"",
|
|
39
42
|
"test:debugger:ci": "node scripts/c8-ci.js test:debugger",
|
|
40
|
-
"test:eslint-rules": "node eslint-rules/*.test.mjs",
|
|
43
|
+
"test:eslint-rules": "node scripts/run-eslint-rule-tests.mjs eslint-rules/*.test.mjs",
|
|
41
44
|
"test:trace:core": "node scripts/mocha-parallel-files.js --expose-gc --timeout 30000 -- \"packages/dd-trace/test/*.spec.js\" \"packages/dd-trace/test/{agent,ci-visibility,config,crashtracking,datastreams,encode,exporters,msgpack,opentelemetry,opentracing,payload-tagging,plugins,remote_config,service-naming,standalone,telemetry,external-logger}/**/*.spec.js\"",
|
|
42
45
|
"test:trace:core:ci": "node scripts/c8-ci.js test:trace:core",
|
|
43
46
|
"test:trace:guardrails": "mocha \"packages/dd-trace/test/guardrails/**/*.spec.js\"",
|
|
@@ -217,7 +220,7 @@
|
|
|
217
220
|
"eslint-plugin-n": "^18.2.1",
|
|
218
221
|
"eslint-plugin-promise": "^7.3.0",
|
|
219
222
|
"eslint-plugin-sonarjs": "^4.2.0",
|
|
220
|
-
"eslint-plugin-unicorn": "^
|
|
223
|
+
"eslint-plugin-unicorn": "^73.0.0",
|
|
221
224
|
"express": "^5.1.0",
|
|
222
225
|
"glob": "^10.4.5",
|
|
223
226
|
"globals": "^17.7.0",
|
|
@@ -85,10 +85,25 @@ function getSource (url, { format }) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
/**
|
|
89
|
+
* @typedef {[typeof LOAD_OPERATION, URL, object] | [typeof RESOLVE_OPERATION, string, object]} GetExportsOperation
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @typedef {{ done: false, value: GetExportsOperation } | { done: true, value: Set<string> }} GetExportsResult
|
|
94
|
+
*/
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @typedef {{
|
|
98
|
+
* next: (value?: unknown) => GetExportsResult,
|
|
99
|
+
* throw: (error?: unknown) => GetExportsResult,
|
|
100
|
+
* }} GetExportsGenerator
|
|
101
|
+
*/
|
|
102
|
+
|
|
88
103
|
/**
|
|
89
104
|
* Drives the generator returned by import-in-the-middle >=3.1.0 export discovery.
|
|
90
105
|
*
|
|
91
|
-
* @param {
|
|
106
|
+
* @param {GetExportsGenerator} exportsGenerator Generator returned by getExports
|
|
92
107
|
* @param {(url: URL, context: object) => { source: string, format: string }} getSource
|
|
93
108
|
* Function that loads module source
|
|
94
109
|
* @returns {Set<string>}
|
|
@@ -116,6 +116,66 @@ function wrapModelWithLifecycle (model) {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Wraps an OTel span without changing its method receivers.
|
|
121
|
+
*
|
|
122
|
+
* OTel spans may use private fields, so methods must run against the original
|
|
123
|
+
* span. A per-invocation wrapper also preserves `ctx` without mutating the AI
|
|
124
|
+
* SDK's shared no-op span.
|
|
125
|
+
*
|
|
126
|
+
* @param {import('@opentelemetry/api').Span} span
|
|
127
|
+
* @param {object} ctx
|
|
128
|
+
* @returns {import('@opentelemetry/api').Span}
|
|
129
|
+
*/
|
|
130
|
+
function createDelegatingSpan (span, ctx) {
|
|
131
|
+
return {
|
|
132
|
+
spanContext () {
|
|
133
|
+
return span.spanContext.apply(span, arguments)
|
|
134
|
+
},
|
|
135
|
+
setAttribute () {
|
|
136
|
+
span.setAttribute.apply(span, arguments)
|
|
137
|
+
return this
|
|
138
|
+
},
|
|
139
|
+
setAttributes (attributes) {
|
|
140
|
+
vercelAiSpanSetAttributesChannel.publish({ ctx, attributes })
|
|
141
|
+
span.setAttributes.apply(span, arguments)
|
|
142
|
+
return this
|
|
143
|
+
},
|
|
144
|
+
addEvent () {
|
|
145
|
+
span.addEvent.apply(span, arguments)
|
|
146
|
+
return this
|
|
147
|
+
},
|
|
148
|
+
addLink () {
|
|
149
|
+
span.addLink.apply(span, arguments)
|
|
150
|
+
return this
|
|
151
|
+
},
|
|
152
|
+
addLinks () {
|
|
153
|
+
span.addLinks.apply(span, arguments)
|
|
154
|
+
return this
|
|
155
|
+
},
|
|
156
|
+
setStatus () {
|
|
157
|
+
span.setStatus.apply(span, arguments)
|
|
158
|
+
return this
|
|
159
|
+
},
|
|
160
|
+
updateName () {
|
|
161
|
+
span.updateName.apply(span, arguments)
|
|
162
|
+
return this
|
|
163
|
+
},
|
|
164
|
+
isRecording () {
|
|
165
|
+
return span.isRecording.apply(span, arguments)
|
|
166
|
+
},
|
|
167
|
+
recordException (exception) {
|
|
168
|
+
ctx.error = exception
|
|
169
|
+
vercelAiTracingChannel.error.publish(ctx)
|
|
170
|
+
return span.recordException.apply(span, arguments)
|
|
171
|
+
},
|
|
172
|
+
end () {
|
|
173
|
+
vercelAiTracingChannel.asyncEnd.publish(ctx)
|
|
174
|
+
return span.end.apply(span, arguments)
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
119
179
|
function wrapTracer (tracer) {
|
|
120
180
|
if (tracers.has(tracer)) {
|
|
121
181
|
return
|
|
@@ -136,40 +196,7 @@ function wrapTracer (tracer) {
|
|
|
136
196
|
|
|
137
197
|
args[args.length - 1] = shimmer.wrapFunction(cb, function (originalCb) {
|
|
138
198
|
return function (span) {
|
|
139
|
-
|
|
140
|
-
// Object.create (and Proxy) cannot cross private-field brand checks — any span
|
|
141
|
-
// method that reads a private field (e.g. BridgeSpanBase#statusCode) would throw
|
|
142
|
-
// "Cannot read private member" on a prototype clone. Every method here calls
|
|
143
|
-
// through to the real span instance so private fields always resolve correctly.
|
|
144
|
-
const freshSpan = {
|
|
145
|
-
spanContext () { return span.spanContext() },
|
|
146
|
-
setAttribute (key, value) { span.setAttribute(key, value); return freshSpan },
|
|
147
|
-
setAttributes (attributes) {
|
|
148
|
-
vercelAiSpanSetAttributesChannel.publish({ ctx, attributes })
|
|
149
|
-
span.setAttributes(attributes)
|
|
150
|
-
return freshSpan
|
|
151
|
-
},
|
|
152
|
-
addEvent (name, attributesOrStartTime, startTime) {
|
|
153
|
-
span.addEvent(name, attributesOrStartTime, startTime)
|
|
154
|
-
return freshSpan
|
|
155
|
-
},
|
|
156
|
-
addLink (link, attrs) { span.addLink(link, attrs); return freshSpan },
|
|
157
|
-
addLinks (links) { span.addLinks(links); return freshSpan },
|
|
158
|
-
setStatus (status) { span.setStatus(status); return freshSpan },
|
|
159
|
-
updateName (spanName) { span.updateName(spanName); return freshSpan },
|
|
160
|
-
isRecording () { return span.isRecording() },
|
|
161
|
-
recordException (exception, timeInput) {
|
|
162
|
-
ctx.error = exception
|
|
163
|
-
vercelAiTracingChannel.error.publish(ctx)
|
|
164
|
-
span.recordException(exception, timeInput)
|
|
165
|
-
},
|
|
166
|
-
end (...endArgs) {
|
|
167
|
-
vercelAiTracingChannel.asyncEnd.publish(ctx)
|
|
168
|
-
span.end(...endArgs)
|
|
169
|
-
},
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return originalCb.call(this, freshSpan)
|
|
199
|
+
return originalCb.call(this, createDelegatingSpan(span, ctx))
|
|
173
200
|
}
|
|
174
201
|
})
|
|
175
202
|
|
|
@@ -15,12 +15,12 @@ function createGetNewLibraryCopyWrap (originalLib) {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
addHook({ name: 'bluebird', versions: ['>=2.0.2'] },
|
|
19
|
-
shimmer.wrap(
|
|
20
|
-
return
|
|
18
|
+
addHook({ name: 'bluebird', versions: ['>=2.0.2'] }, LibraryPromise => {
|
|
19
|
+
shimmer.wrap(LibraryPromise.prototype, '_then', wrapThen)
|
|
20
|
+
return LibraryPromise
|
|
21
21
|
})
|
|
22
22
|
|
|
23
|
-
addHook({ name: 'bluebird', versions: ['^2.11.0', '^3.4.1'] },
|
|
24
|
-
shimmer.wrap(
|
|
25
|
-
return
|
|
23
|
+
addHook({ name: 'bluebird', versions: ['^2.11.0', '^3.4.1'] }, LibraryPromise => {
|
|
24
|
+
shimmer.wrap(LibraryPromise, 'getNewLibraryCopy', createGetNewLibraryCopyWrap(LibraryPromise))
|
|
25
|
+
return LibraryPromise
|
|
26
26
|
})
|
|
@@ -13,6 +13,66 @@ const LOCAL_LIFECYCLE_LOOKAHEAD = 4
|
|
|
13
13
|
|
|
14
14
|
const chunkEmitTimes = new WeakMap()
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {{ session_id?: string } & Record<string, unknown>} Chunk
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {{
|
|
22
|
+
* id: string,
|
|
23
|
+
* name?: string,
|
|
24
|
+
* input?: unknown,
|
|
25
|
+
* output?: unknown,
|
|
26
|
+
* error?: unknown,
|
|
27
|
+
* isInterrupt?: boolean,
|
|
28
|
+
* sessionId?: string,
|
|
29
|
+
* hookStartTime?: number,
|
|
30
|
+
* hookFinishTime?: number,
|
|
31
|
+
* }} ToolState
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @typedef {{ taskStartedChunk?: Chunk, toolResultIndex?: number }} ToolLifecycle
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @typedef {(startIndex: number, toolUseId: string) => ToolLifecycle} GetLifecycle
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {{
|
|
44
|
+
* tools: Map<string, ToolState>,
|
|
45
|
+
* subagents: Map<string, Record<string, unknown>>,
|
|
46
|
+
* prompt?: string,
|
|
47
|
+
* model?: string,
|
|
48
|
+
* resume?: string,
|
|
49
|
+
* maxTurns?: number,
|
|
50
|
+
* permissionMode?: string,
|
|
51
|
+
* sessionId?: string,
|
|
52
|
+
* source?: string,
|
|
53
|
+
* cwd?: string,
|
|
54
|
+
* transcriptPath?: string,
|
|
55
|
+
* agentType?: string,
|
|
56
|
+
* endReason?: string,
|
|
57
|
+
* stopReason?: string,
|
|
58
|
+
* lastAssistantMessage?: string,
|
|
59
|
+
* }} SessionContext
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @typedef {{
|
|
64
|
+
* stepIndex: number,
|
|
65
|
+
* startTime?: number,
|
|
66
|
+
* finishTime?: number,
|
|
67
|
+
* parentToolUseId?: string,
|
|
68
|
+
* sessionId?: string,
|
|
69
|
+
* chunks?: Chunk[],
|
|
70
|
+
* llmStartIdx?: number,
|
|
71
|
+
* llmEndIdx?: number,
|
|
72
|
+
* toolOutputs?: unknown[],
|
|
73
|
+
* }} StepContext
|
|
74
|
+
*/
|
|
75
|
+
|
|
16
76
|
function hasDownstreamSubscribers () {
|
|
17
77
|
return queryChannel.asyncEnd.hasSubscribers ||
|
|
18
78
|
queryChannel.error.hasSubscribers ||
|
|
@@ -287,10 +347,12 @@ function getToolResultContent (chunk, toolUseId) {
|
|
|
287
347
|
}
|
|
288
348
|
|
|
289
349
|
/**
|
|
290
|
-
*
|
|
291
|
-
* @param {Array<Record<string, unknown>>} chunks
|
|
350
|
+
* @param {Chunk[]} chunks
|
|
292
351
|
* @param {number} startIndex
|
|
293
352
|
* @param {string} toolUseId
|
|
353
|
+
* @param {SessionContext | null | undefined} sessionCtx
|
|
354
|
+
* @param {GetLifecycle} getLifecycle
|
|
355
|
+
* @param {ToolLifecycle} lifecycle
|
|
294
356
|
* @returns {number} index in chunks where the next step should start iteration
|
|
295
357
|
*/
|
|
296
358
|
function processTool (chunks, startIndex, toolUseId, sessionCtx, getLifecycle, lifecycle) {
|
|
@@ -342,9 +404,14 @@ function processTool (chunks, startIndex, toolUseId, sessionCtx, getLifecycle, l
|
|
|
342
404
|
}
|
|
343
405
|
|
|
344
406
|
/**
|
|
345
|
-
*
|
|
346
|
-
* @param {Array<Record<string, unknown>>} chunks
|
|
407
|
+
* @param {Chunk[]} chunks
|
|
347
408
|
* @param {number} startIndex
|
|
409
|
+
* @param {number | undefined} stepStartTime
|
|
410
|
+
* @param {string | null | undefined} parentToolUseId
|
|
411
|
+
* @param {string | undefined} initialPrompt
|
|
412
|
+
* @param {StepContext | null | undefined} stepCtx
|
|
413
|
+
* @param {SessionContext | null | undefined} sessionCtx
|
|
414
|
+
* @param {GetLifecycle} getLifecycle
|
|
348
415
|
* @returns {number} index in chunks where the next step should start iteration
|
|
349
416
|
*/
|
|
350
417
|
function processStep (
|
|
@@ -447,7 +514,16 @@ function processStep (
|
|
|
447
514
|
}
|
|
448
515
|
|
|
449
516
|
/**
|
|
450
|
-
* @param {
|
|
517
|
+
* @param {Chunk[]} chunks
|
|
518
|
+
* @param {{
|
|
519
|
+
* sessionCtx?: SessionContext,
|
|
520
|
+
* session_id?: string,
|
|
521
|
+
* cwd?: string,
|
|
522
|
+
* permissionMode?: string,
|
|
523
|
+
* output?: unknown,
|
|
524
|
+
* arguments?: Array<{ prompt?: string }>,
|
|
525
|
+
* runInContext?: (fn: () => number) => number,
|
|
526
|
+
* }} agentCtx
|
|
451
527
|
*/
|
|
452
528
|
function processChunks (chunks, agentCtx) {
|
|
453
529
|
let chunkIndex = 0
|
|
@@ -29,6 +29,17 @@ const channels = {
|
|
|
29
29
|
|
|
30
30
|
const disabledHeaderWeakSet = new WeakSet()
|
|
31
31
|
|
|
32
|
+
const EMPTY_CARRIER = Object.create(null)
|
|
33
|
+
/** @type {string[]} */
|
|
34
|
+
const NO_MERGEABLE_KEYS = []
|
|
35
|
+
|
|
36
|
+
/** @typedef {string | Buffer} NativeHeaderValue */
|
|
37
|
+
/** @typedef {Array<Record<string, NativeHeaderValue>>} NativeHeaders */
|
|
38
|
+
/** @typedef {Record<string, NativeHeaderValue | NativeHeaderValue[]>} NativeHeaderCarrier */
|
|
39
|
+
|
|
40
|
+
/** @type {NativeHeaders} */
|
|
41
|
+
const EMPTY_NATIVE_HEADERS = []
|
|
42
|
+
|
|
32
43
|
// we need to store the offset per partition per topic for the consumer to track offsets for DSM
|
|
33
44
|
const latestConsumerOffsets = new Map()
|
|
34
45
|
|
|
@@ -60,17 +71,47 @@ function instrumentBaseModule (module) {
|
|
|
60
71
|
}
|
|
61
72
|
|
|
62
73
|
const brokers = this.globalConfig?.['bootstrap.servers']
|
|
74
|
+
const nativeHeaders = Array.isArray(headers) ? headers : EMPTY_NATIVE_HEADERS
|
|
75
|
+
|
|
76
|
+
let carrier
|
|
77
|
+
let forwardCallerHeaders = false
|
|
78
|
+
let applicationValues = EMPTY_CARRIER
|
|
79
|
+
let headerKeys = NO_MERGEABLE_KEYS
|
|
80
|
+
if (nativeHeaders.length !== 0) {
|
|
81
|
+
// `__proto__` is a legal Kafka header key and propagation never
|
|
82
|
+
// writes it, so only the seeded carrier needs a null prototype.
|
|
83
|
+
const candidateCarrier = Object.create(null)
|
|
84
|
+
const candidateValues = Object.create(null)
|
|
85
|
+
const candidateKeys = seedNativeHeaderCarrier(nativeHeaders, candidateCarrier, candidateValues)
|
|
86
|
+
if (candidateKeys === undefined) {
|
|
87
|
+
forwardCallerHeaders = true
|
|
88
|
+
} else if (candidateKeys.length !== 0) {
|
|
89
|
+
carrier = candidateCarrier
|
|
90
|
+
applicationValues = candidateValues
|
|
91
|
+
headerKeys = candidateKeys
|
|
92
|
+
}
|
|
93
|
+
}
|
|
63
94
|
|
|
64
95
|
const ctx = {
|
|
65
96
|
topic,
|
|
66
|
-
messages: [{
|
|
97
|
+
messages: [{
|
|
98
|
+
key,
|
|
99
|
+
value: message,
|
|
100
|
+
headers: carrier,
|
|
101
|
+
}],
|
|
67
102
|
bootstrapServers: brokers,
|
|
68
103
|
}
|
|
69
104
|
|
|
70
105
|
return channels.producerStart.runStores(ctx, () => {
|
|
71
106
|
try {
|
|
72
|
-
const
|
|
73
|
-
|
|
107
|
+
const producedHeaders = forwardCallerHeaders
|
|
108
|
+
? nativeHeaders
|
|
109
|
+
: mergeNativeHeaders(
|
|
110
|
+
nativeHeaders, headerKeys, applicationValues, ctx.messages[0].headers ?? EMPTY_CARRIER
|
|
111
|
+
)
|
|
112
|
+
const result = produce.apply(this, [
|
|
113
|
+
topic, partition, message, key, timestamp, opaque, producedHeaders,
|
|
114
|
+
])
|
|
74
115
|
|
|
75
116
|
ctx.result = result
|
|
76
117
|
channels.producerCommit.publish(ctx)
|
|
@@ -432,7 +473,71 @@ function getLatestOffsets () {
|
|
|
432
473
|
return [...latestConsumerOffsets.values()]
|
|
433
474
|
}
|
|
434
475
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
476
|
+
/**
|
|
477
|
+
* `Producer::NodeProduce` reads the first *enumerable* own key of each entry and
|
|
478
|
+
* validates the value itself. A `null` or `undefined` entry aborts the process
|
|
479
|
+
* there, so those are the only entries we refuse to hand back to it.
|
|
480
|
+
*
|
|
481
|
+
* @param {NativeHeaders} headers Caller-owned.
|
|
482
|
+
* @param {NativeHeaderCarrier} carrier
|
|
483
|
+
* @param {NativeHeaderCarrier} applicationValues
|
|
484
|
+
* @returns {string[] | undefined} `undefined` when the binding has to reject the
|
|
485
|
+
* array itself; empty when it cannot consume the array at all.
|
|
486
|
+
* @see https://github.com/confluentinc/confluent-kafka-javascript/blob/v1.9.1/src/producer.cc
|
|
487
|
+
*/
|
|
488
|
+
function seedNativeHeaderCarrier (headers, carrier, applicationValues) {
|
|
489
|
+
const keys = new Array(headers.length)
|
|
490
|
+
for (let i = 0; i < headers.length; i++) {
|
|
491
|
+
const header = headers[i]
|
|
492
|
+
if (header === null || header === undefined) return NO_MERGEABLE_KEYS
|
|
493
|
+
|
|
494
|
+
const key = Object.keys(header)[0]
|
|
495
|
+
if (key === undefined) return
|
|
496
|
+
|
|
497
|
+
keys[i] = key
|
|
498
|
+
const value = header[key]
|
|
499
|
+
if (typeof value !== 'string' && !Buffer.isBuffer(value)) return
|
|
500
|
+
|
|
501
|
+
if (i === 0) {
|
|
502
|
+
carrier[key] = value
|
|
503
|
+
applicationValues[key] = value
|
|
504
|
+
continue
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const previousValue = carrier[key]
|
|
508
|
+
if (previousValue === undefined) {
|
|
509
|
+
carrier[key] = value
|
|
510
|
+
} else if (Array.isArray(previousValue)) {
|
|
511
|
+
previousValue.push(value)
|
|
512
|
+
} else {
|
|
513
|
+
carrier[key] = [previousValue, value]
|
|
514
|
+
}
|
|
515
|
+
applicationValues[key] = carrier[key]
|
|
516
|
+
}
|
|
517
|
+
return keys
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* @param {NativeHeaders} headers Caller-owned; surviving entries are forwarded
|
|
522
|
+
* by reference, never copied or mutated.
|
|
523
|
+
* @param {string[]} headerKeys Parallel to `headers`.
|
|
524
|
+
* @param {NativeHeaderCarrier} applicationValues Carrier contents before
|
|
525
|
+
* propagation ran.
|
|
526
|
+
* @param {NativeHeaderCarrier} carrier
|
|
527
|
+
*/
|
|
528
|
+
function mergeNativeHeaders (headers, headerKeys, applicationValues, carrier) {
|
|
529
|
+
const merged = []
|
|
530
|
+
for (let i = 0; i < headerKeys.length; i++) {
|
|
531
|
+
const key = headerKeys[i]
|
|
532
|
+
if (carrier[key] === applicationValues[key]) {
|
|
533
|
+
merged.push(headers[i])
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
for (const key of Object.keys(carrier)) {
|
|
538
|
+
if (carrier[key] !== applicationValues[key]) {
|
|
539
|
+
merged.push({ [key]: carrier[key] })
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
return merged
|
|
438
543
|
}
|