dd-trace 6.3.0 → 6.5.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/README.electron.md +7 -0
- package/README.md +17 -0
- package/ci/diagnose.js +2100 -0
- package/ci/init.js +23 -2
- package/ci/runbook.md +198 -0
- package/ci/test-optimization-validation/approval-artifacts.js +143 -0
- package/ci/test-optimization-validation/approval.js +299 -0
- package/ci/test-optimization-validation/artifact-id.js +20 -0
- package/ci/test-optimization-validation/bounded-json.js +121 -0
- package/ci/test-optimization-validation/ci-command-candidate.js +83 -0
- package/ci/test-optimization-validation/ci-discovery.js +181 -0
- package/ci/test-optimization-validation/ci-remediation.js +210 -0
- package/ci/test-optimization-validation/cli.js +903 -0
- package/ci/test-optimization-validation/command-blocker.js +81 -0
- package/ci/test-optimization-validation/command-output-policy.js +206 -0
- package/ci/test-optimization-validation/command-runner.js +707 -0
- package/ci/test-optimization-validation/command-suitability.js +471 -0
- package/ci/test-optimization-validation/executable-approval.js +48 -0
- package/ci/test-optimization-validation/executable.js +480 -0
- package/ci/test-optimization-validation/generated-file-policy.js +63 -0
- package/ci/test-optimization-validation/generated-files.js +351 -0
- package/ci/test-optimization-validation/generated-verifier.js +196 -0
- package/ci/test-optimization-validation/init-probe-preload.js +163 -0
- package/ci/test-optimization-validation/init-probe.js +246 -0
- package/ci/test-optimization-validation/late-initialization.js +63 -0
- package/ci/test-optimization-validation/local-command.js +163 -0
- package/ci/test-optimization-validation/manifest-loader.js +133 -0
- package/ci/test-optimization-validation/manifest-scaffold.js +738 -0
- package/ci/test-optimization-validation/manifest-schema.js +862 -0
- package/ci/test-optimization-validation/offline-fixtures.js +327 -0
- package/ci/test-optimization-validation/offline-output.js +406 -0
- package/ci/test-optimization-validation/payload-normalizer.js +72 -0
- package/ci/test-optimization-validation/plan-writer.js +1120 -0
- package/ci/test-optimization-validation/preflight-runner.js +114 -0
- package/ci/test-optimization-validation/redaction.js +331 -0
- package/ci/test-optimization-validation/report-writer.js +1508 -0
- package/ci/test-optimization-validation/safe-files.js +203 -0
- package/ci/test-optimization-validation/scenarios/auto-test-retries.js +159 -0
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +657 -0
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +780 -0
- package/ci/test-optimization-validation/scenarios/early-flake-detection.js +141 -0
- package/ci/test-optimization-validation/scenarios/helpers.js +539 -0
- package/ci/test-optimization-validation/scenarios/test-management.js +218 -0
- package/ci/test-optimization-validation/setup-runner.js +97 -0
- package/ci/test-optimization-validation/static-diagnosis.js +159 -0
- package/ci/test-optimization-validation/test-output.js +129 -0
- package/ci/test-optimization-validation-manifest.schema.json +1 -0
- package/ci/validate-test-optimization.js +3 -0
- package/ext/exporters.js +1 -0
- package/index.d.ts +121 -8
- package/index.electron.js +3 -0
- package/init.js +18 -0
- package/initialize.mjs +1 -1
- package/loader-hook.mjs +28 -18
- package/openfeature.d.ts +1 -0
- package/openfeature.js +4 -0
- package/package.json +15 -8
- package/packages/datadog-instrumentations/src/ai.js +37 -26
- package/packages/datadog-instrumentations/src/child_process.js +1 -1
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber-worker-threads.js +9 -3
- package/packages/datadog-instrumentations/src/cucumber.js +24 -10
- package/packages/datadog-instrumentations/src/cypress-config.js +398 -52
- package/packages/datadog-instrumentations/src/express.js +20 -2
- package/packages/datadog-instrumentations/src/fastify.js +7 -11
- package/packages/datadog-instrumentations/src/grpc/server.js +18 -0
- package/packages/datadog-instrumentations/src/helpers/hook.js +27 -6
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +8 -8
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +28 -2
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +8 -8
- package/packages/datadog-instrumentations/src/http2/server.js +143 -17
- package/packages/datadog-instrumentations/src/jest.js +36 -4
- package/packages/datadog-instrumentations/src/mariadb.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +0 -2
- package/packages/datadog-instrumentations/src/mocha/utils.js +0 -4
- package/packages/datadog-instrumentations/src/mongodb.js +3 -3
- package/packages/datadog-instrumentations/src/mongoose.js +3 -3
- package/packages/datadog-instrumentations/src/mquery.js +2 -2
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +24 -0
- package/packages/datadog-instrumentations/src/nyc.js +0 -2
- package/packages/datadog-instrumentations/src/oracledb.js +2 -2
- package/packages/datadog-instrumentations/src/pg.js +2 -2
- package/packages/datadog-instrumentations/src/playwright.js +159 -22
- package/packages/datadog-instrumentations/src/process.js +3 -0
- package/packages/datadog-instrumentations/src/router.js +191 -106
- package/packages/datadog-instrumentations/src/selenium.js +52 -26
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +2 -2
- package/packages/datadog-instrumentations/src/vitest-main.js +0 -2
- package/packages/datadog-instrumentations/src/ws.js +2 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +2 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +41 -16
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +21 -21
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +14 -8
- package/packages/datadog-plugin-aws-sdk/src/util.js +2 -24
- package/packages/datadog-plugin-cucumber/src/index.js +1 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +24 -62
- package/packages/datadog-plugin-cypress/src/index.js +6 -1
- package/packages/datadog-plugin-cypress/src/support.js +92 -26
- package/packages/datadog-plugin-electron/src/ipc.js +1 -1
- package/packages/datadog-plugin-graphql/src/execute.js +177 -59
- package/packages/datadog-plugin-graphql/src/parse.js +22 -1
- package/packages/datadog-plugin-graphql/src/request.js +32 -1
- package/packages/datadog-plugin-graphql/src/utils.js +42 -0
- package/packages/datadog-plugin-graphql/src/validate.js +15 -3
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-http2/src/server.js +38 -6
- package/packages/datadog-plugin-jest/src/util.js +21 -6
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -1
- package/packages/datadog-plugin-langchain/src/handlers/language_models.js +2 -1
- package/packages/datadog-plugin-langchain/src/tokens.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +177 -64
- package/packages/datadog-plugin-router/src/index.js +11 -2
- package/packages/datadog-plugin-selenium/src/index.js +5 -36
- package/packages/datadog-plugin-vitest/src/index.js +4 -2
- package/packages/datadog-plugin-ws/src/close.js +2 -1
- package/packages/datadog-plugin-ws/src/producer.js +2 -1
- package/packages/datadog-plugin-ws/src/receiver.js +2 -1
- package/packages/datadog-plugin-ws/src/server.js +2 -1
- package/packages/dd-trace/index.electron.js +3 -0
- package/packages/dd-trace/index.js +2 -37
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +3 -1
- package/packages/dd-trace/src/azure_metadata.js +2 -1
- package/packages/dd-trace/src/bootstrap.js +39 -0
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +93 -28
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +160 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +288 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/payload-projection.js +84 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +369 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/writer.js +60 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +55 -5
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +22 -6
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +5 -0
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +62 -7
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +9 -2
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +6 -2
- package/packages/dd-trace/src/ci-visibility/rum.js +7 -0
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +4 -0
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +137 -9
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +173 -9
- package/packages/dd-trace/src/ci-visibility/test-screenshot.js +90 -0
- package/packages/dd-trace/src/config/generated-config-types.d.ts +20 -0
- package/packages/dd-trace/src/config/helper.js +1 -0
- package/packages/dd-trace/src/config/index.js +10 -0
- package/packages/dd-trace/src/config/supported-configurations.json +83 -0
- package/packages/dd-trace/src/constants.js +7 -0
- package/packages/dd-trace/src/datastreams/pathway.js +6 -4
- package/packages/dd-trace/src/exporter.js +2 -0
- package/packages/dd-trace/src/exporters/common/client-library-headers.js +21 -0
- package/packages/dd-trace/src/exporters/common/request.js +59 -30
- package/packages/dd-trace/src/exporters/common/url.js +15 -1
- package/packages/dd-trace/src/feature-registry.js +29 -0
- package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
- package/packages/dd-trace/src/llmobs/experiments/client.js +113 -0
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +154 -0
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +283 -0
- package/packages/dd-trace/src/llmobs/experiments/index.js +152 -0
- package/packages/dd-trace/src/llmobs/experiments/noop.js +30 -0
- package/packages/dd-trace/src/llmobs/experiments/result.js +34 -0
- package/packages/dd-trace/src/llmobs/index.js +10 -2
- package/packages/dd-trace/src/llmobs/noop.js +6 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +20 -3
- package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +2 -2
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +8 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +48 -14
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +43 -0
- package/packages/dd-trace/src/llmobs/sdk.js +17 -0
- package/packages/dd-trace/src/llmobs/tagger.js +79 -7
- package/packages/dd-trace/src/llmobs/telemetry.js +2 -1
- package/packages/dd-trace/src/llmobs/util.js +32 -0
- package/packages/dd-trace/src/noop/proxy.js +5 -4
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +322 -0
- package/packages/dd-trace/src/openfeature/configuration_source.js +90 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +14 -23
- package/packages/dd-trace/src/openfeature/index.js +0 -2
- package/packages/dd-trace/src/openfeature/noop.js +1 -28
- package/packages/dd-trace/src/openfeature/register.js +35 -0
- package/packages/dd-trace/src/openfeature/remote_config.js +15 -18
- package/packages/dd-trace/src/openfeature/require-provider.js +18 -0
- package/packages/dd-trace/src/opentelemetry/span-ending-hook.js +10 -0
- package/packages/dd-trace/src/opentelemetry/span.js +5 -0
- package/packages/dd-trace/src/opentracing/propagation/log.js +11 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +80 -14
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +10 -1
- package/packages/dd-trace/src/opentracing/tracer.js +7 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +20 -6
- package/packages/dd-trace/src/plugins/util/git.js +3 -2
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +29 -5
- package/packages/dd-trace/src/plugins/util/test.js +65 -8
- package/packages/dd-trace/src/plugins/util/web.js +12 -0
- package/packages/dd-trace/src/proxy.js +99 -10
- package/packages/dd-trace/src/span_processor.js +5 -0
- package/packages/dd-trace/src/standalone/index.js +0 -36
- package/packages/dd-trace/src/telemetry/send-data.js +2 -2
- package/packages/dd-trace/src/util.js +26 -0
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +1 -1
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/vendor/dist/shell-quote/index.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/require-optional-peer.js +0 -17
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const NoopProxy = require('./noop/proxy')
|
|
4
|
+
const { features } = require('./feature-registry')
|
|
4
5
|
const DatadogTracer = require('./tracer')
|
|
5
6
|
const getConfig = require('./config')
|
|
7
|
+
const { getEnvironmentVariable } = require('./config/helper')
|
|
6
8
|
const runtimeMetrics = require('./runtime_metrics')
|
|
7
9
|
const log = require('./log')
|
|
8
10
|
const { setStartupLogPluginManager, startupLog } = require('./startup-log')
|
|
@@ -13,6 +15,7 @@ const PluginManager = require('./plugin_manager')
|
|
|
13
15
|
const NoopDogStatsDClient = require('./noop/dogstatsd')
|
|
14
16
|
const { IS_SERVERLESS } = require('./serverless')
|
|
15
17
|
const processTags = require('./process-tags')
|
|
18
|
+
const { isTrue } = require('./util')
|
|
16
19
|
const {
|
|
17
20
|
setBaggageItem,
|
|
18
21
|
getBaggageItem,
|
|
@@ -21,6 +24,24 @@ const {
|
|
|
21
24
|
removeAllBaggageItems,
|
|
22
25
|
} = require('./baggage')
|
|
23
26
|
|
|
27
|
+
const VALIDATION_MANIFEST_ENV = '_DD_TEST_OPTIMIZATION_VALIDATION_MANIFEST_FILE'
|
|
28
|
+
const VALIDATION_MODE_ENV = '_DD_TEST_OPTIMIZATION_VALIDATION_MODE'
|
|
29
|
+
const VALIDATION_OUTPUT_ENV = '_DD_TEST_OPTIMIZATION_VALIDATION_OUTPUT_DIR'
|
|
30
|
+
const ORDINARY_TRACING_DISABLED_MESSAGE =
|
|
31
|
+
'Ordinary dd-trace application tracing initialization is disabled during offline Test Optimization validation. ' +
|
|
32
|
+
'The CI test process must initialize through dd-trace/ci/init.'
|
|
33
|
+
const OFFLINE_VALIDATION_EXPORTERS = new Set([
|
|
34
|
+
'ci_validation',
|
|
35
|
+
'cucumber_worker',
|
|
36
|
+
'jest_worker',
|
|
37
|
+
'mocha_worker',
|
|
38
|
+
'playwright_worker',
|
|
39
|
+
'vitest_worker',
|
|
40
|
+
])
|
|
41
|
+
const FEATURE_STATE_NOOP = 0
|
|
42
|
+
const FEATURE_STATE_LAZY = 1
|
|
43
|
+
const FEATURE_STATE_ACTIVE = 2
|
|
44
|
+
|
|
24
45
|
class LazyModule {
|
|
25
46
|
constructor (provider) {
|
|
26
47
|
this.provider = provider
|
|
@@ -69,6 +90,9 @@ function defineLazily (obj, property, getClass, ...args) {
|
|
|
69
90
|
}
|
|
70
91
|
|
|
71
92
|
class Tracer extends NoopProxy {
|
|
93
|
+
/** @type {Record<string, number> | undefined} */
|
|
94
|
+
#featureStates
|
|
95
|
+
|
|
72
96
|
constructor () {
|
|
73
97
|
super()
|
|
74
98
|
|
|
@@ -91,7 +115,10 @@ class Tracer extends NoopProxy {
|
|
|
91
115
|
iast: new LazyModule(() => require('./appsec/iast')),
|
|
92
116
|
llmobs: new LazyModule(() => require('./llmobs')),
|
|
93
117
|
rewriter: new LazyModule(() => require('./appsec/iast/taint-tracking/rewriter')),
|
|
94
|
-
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
for (const feature of Object.values(features)) {
|
|
121
|
+
this._modules[feature.name] = new LazyModule(feature.factory)
|
|
95
122
|
}
|
|
96
123
|
}
|
|
97
124
|
|
|
@@ -103,6 +130,11 @@ class Tracer extends NoopProxy {
|
|
|
103
130
|
|
|
104
131
|
this._initialized = true
|
|
105
132
|
|
|
133
|
+
if (isOfflineTestOptimizationValidation() && !isOfflineValidationExporter(options)) {
|
|
134
|
+
process.stderr.write(`${ORDINARY_TRACING_DISABLED_MESSAGE}\n`)
|
|
135
|
+
return this
|
|
136
|
+
}
|
|
137
|
+
|
|
106
138
|
try {
|
|
107
139
|
const config = getConfig(options) // TODO: support dynamic code config
|
|
108
140
|
|
|
@@ -114,7 +146,11 @@ class Tracer extends NoopProxy {
|
|
|
114
146
|
propagationHash.configure(config)
|
|
115
147
|
|
|
116
148
|
if (config.DD_CRASHTRACKING_ENABLED) {
|
|
117
|
-
|
|
149
|
+
try {
|
|
150
|
+
require('./crashtracking').start(config)
|
|
151
|
+
} catch (e) {
|
|
152
|
+
log.warn('Crashtracking is not available in this environment', e)
|
|
153
|
+
}
|
|
118
154
|
}
|
|
119
155
|
|
|
120
156
|
if (config.DD_HEAP_SNAPSHOT_COUNT > 0) {
|
|
@@ -123,7 +159,7 @@ class Tracer extends NoopProxy {
|
|
|
123
159
|
|
|
124
160
|
telemetry.start(config, this._pluginManager)
|
|
125
161
|
|
|
126
|
-
if (config.dogstatsd) {
|
|
162
|
+
if (config.dogstatsd && !isOfflineTestOptimizationValidation()) {
|
|
127
163
|
// Custom Metrics
|
|
128
164
|
lazyProxy(this, 'dogstatsd', () => require('./dogstatsd').CustomMetrics, config)
|
|
129
165
|
}
|
|
@@ -176,8 +212,9 @@ class Tracer extends NoopProxy {
|
|
|
176
212
|
DynamicInstrumentation.start(config, rc)
|
|
177
213
|
}
|
|
178
214
|
|
|
179
|
-
const
|
|
180
|
-
|
|
215
|
+
for (const feature of Object.values(features)) {
|
|
216
|
+
feature.remoteConfig?.(rc, config, this)
|
|
217
|
+
}
|
|
181
218
|
}
|
|
182
219
|
|
|
183
220
|
if (config.profiling.DD_PROFILING_ENABLED === 'true') {
|
|
@@ -266,6 +303,36 @@ class Tracer extends NoopProxy {
|
|
|
266
303
|
}
|
|
267
304
|
}
|
|
268
305
|
|
|
306
|
+
/**
|
|
307
|
+
* @param {(typeof features)[string]} feature
|
|
308
|
+
* @param {import('./config/config-base')} config
|
|
309
|
+
*/
|
|
310
|
+
#enableFeature (feature, config) {
|
|
311
|
+
const states = this.#featureStates ??= {}
|
|
312
|
+
const state = states[feature.name] ?? FEATURE_STATE_NOOP
|
|
313
|
+
|
|
314
|
+
if (state === FEATURE_STATE_ACTIVE || state === FEATURE_STATE_LAZY) return
|
|
315
|
+
states[feature.name] = FEATURE_STATE_LAZY
|
|
316
|
+
|
|
317
|
+
Reflect.defineProperty(this, feature.name, {
|
|
318
|
+
get: () => {
|
|
319
|
+
const Provider = feature.provider()
|
|
320
|
+
const provider = new Provider(this._tracer, config)
|
|
321
|
+
|
|
322
|
+
this._modules[feature.name].enable(config)
|
|
323
|
+
Reflect.defineProperty(this, feature.name, {
|
|
324
|
+
value: provider,
|
|
325
|
+
configurable: true,
|
|
326
|
+
enumerable: true,
|
|
327
|
+
})
|
|
328
|
+
states[feature.name] = FEATURE_STATE_ACTIVE
|
|
329
|
+
return provider
|
|
330
|
+
},
|
|
331
|
+
configurable: true,
|
|
332
|
+
enumerable: true,
|
|
333
|
+
})
|
|
334
|
+
}
|
|
335
|
+
|
|
269
336
|
/**
|
|
270
337
|
* @param {import('./config/config-base')} config - Tracer configuration
|
|
271
338
|
*/
|
|
@@ -287,14 +354,12 @@ class Tracer extends NoopProxy {
|
|
|
287
354
|
lazyProxy(this, 'llmobs', () => require('./llmobs/sdk'), this._tracer, this._modules.llmobs, config)
|
|
288
355
|
|
|
289
356
|
if (config.experimental?.aiguard?.enabled) {
|
|
290
|
-
this._modules.aiguard.enable(this._tracer, config)
|
|
291
357
|
lazyProxy(this, 'aiguard', () => require('./aiguard/sdk'), this._tracer, config)
|
|
292
358
|
}
|
|
293
359
|
this._tracingInitialized = true
|
|
294
360
|
}
|
|
295
|
-
if (config.experimental
|
|
296
|
-
this._modules.
|
|
297
|
-
lazyProxy(this, 'openfeature', () => require('./openfeature/flagging_provider'), this._tracer, config)
|
|
361
|
+
if (config.experimental?.aiguard?.enabled) {
|
|
362
|
+
this._modules.aiguard.enable(this._tracer, config)
|
|
298
363
|
}
|
|
299
364
|
if (config.iast.enabled) {
|
|
300
365
|
this._modules.iast.enable(config, this._tracer)
|
|
@@ -305,7 +370,10 @@ class Tracer extends NoopProxy {
|
|
|
305
370
|
this._modules.aiguard.disable()
|
|
306
371
|
this._modules.iast.disable()
|
|
307
372
|
this._modules.llmobs.disable()
|
|
308
|
-
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
for (const feature of Object.values(features)) {
|
|
376
|
+
if (feature.isEnabled(config)) this.#enableFeature(feature, config)
|
|
309
377
|
}
|
|
310
378
|
|
|
311
379
|
if (this._tracingInitialized) {
|
|
@@ -388,4 +456,25 @@ class Tracer extends NoopProxy {
|
|
|
388
456
|
}
|
|
389
457
|
}
|
|
390
458
|
|
|
459
|
+
/**
|
|
460
|
+
* Checks the private filesystem-only Test Optimization validation mode.
|
|
461
|
+
*
|
|
462
|
+
* @returns {boolean} whether network-capable tracer side channels must stay disabled
|
|
463
|
+
*/
|
|
464
|
+
function isOfflineTestOptimizationValidation () {
|
|
465
|
+
return isTrue(getEnvironmentVariable(VALIDATION_MODE_ENV)) &&
|
|
466
|
+
Boolean(getEnvironmentVariable(VALIDATION_MANIFEST_ENV)) &&
|
|
467
|
+
Boolean(getEnvironmentVariable(VALIDATION_OUTPUT_ENV))
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Checks whether initialization selected a filesystem-only Test Optimization exporter.
|
|
472
|
+
*
|
|
473
|
+
* @param {import('../../../index').TracerOptions} [options] tracer initialization options
|
|
474
|
+
* @returns {boolean} whether the selected exporter is safe for offline validation
|
|
475
|
+
*/
|
|
476
|
+
function isOfflineValidationExporter (options) {
|
|
477
|
+
return OFFLINE_VALIDATION_EXPORTERS.has(options?.experimental?.exporter)
|
|
478
|
+
}
|
|
479
|
+
|
|
391
480
|
module.exports = Tracer
|
|
@@ -6,6 +6,7 @@ const SpanSampler = require('./span_sampler')
|
|
|
6
6
|
const GitMetadataTagger = require('./git_metadata_tagger')
|
|
7
7
|
const processTags = require('./process-tags')
|
|
8
8
|
const { applyHttpOtelSemantics } = require('./plugins/util/http-otel-semantics')
|
|
9
|
+
const { APM_TRACING_ENABLED_KEY } = require('./constants')
|
|
9
10
|
|
|
10
11
|
const startedSpans = new WeakSet()
|
|
11
12
|
const finishedSpans = new WeakSet()
|
|
@@ -54,12 +55,16 @@ class SpanProcessor {
|
|
|
54
55
|
this._gitMetadataTagger.tagGitMetadata(spanContext)
|
|
55
56
|
|
|
56
57
|
let isFirstSpanInChunk = true
|
|
58
|
+
const stampApmDisabled = this._config.apmTracingEnabled === false
|
|
57
59
|
|
|
58
60
|
for (const span of started) {
|
|
59
61
|
if (span._duration === undefined) {
|
|
60
62
|
active.push(span)
|
|
61
63
|
} else {
|
|
62
64
|
const formattedSpan = spanFormat(span, isFirstSpanInChunk, this._processTags)
|
|
65
|
+
if (isFirstSpanInChunk && stampApmDisabled) {
|
|
66
|
+
formattedSpan.metrics[APM_TRACING_ENABLED_KEY] = 0
|
|
67
|
+
}
|
|
63
68
|
isFirstSpanInChunk = false
|
|
64
69
|
// Span stats read Datadog HTTP tag names from the formatted span, so
|
|
65
70
|
// record them before the OTel rename — an export-only transform.
|
|
@@ -2,60 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
const { channel } = require('dc-polyfill')
|
|
4
4
|
const { USER_KEEP } = require('../../../../ext/priority')
|
|
5
|
-
const TraceState = require('../opentracing/propagation/tracestate')
|
|
6
|
-
const { APM_TRACING_ENABLED_KEY } = require('../constants')
|
|
7
5
|
const TraceSourcePrioritySampler = require('./tracesource_priority_sampler')
|
|
8
6
|
const { hasTraceSourcePropagationTag } = require('./tracesource')
|
|
9
7
|
|
|
10
|
-
const startCh = channel('dd-trace:span:start')
|
|
11
|
-
const injectCh = channel('dd-trace:span:inject')
|
|
12
8
|
const extractCh = channel('dd-trace:span:extract')
|
|
13
9
|
|
|
14
10
|
/**
|
|
15
11
|
* @param {import('../config/config-base')} config - Tracer configuration
|
|
16
12
|
*/
|
|
17
13
|
function configure (config) {
|
|
18
|
-
if (startCh.hasSubscribers) startCh.unsubscribe(onSpanStart)
|
|
19
|
-
if (injectCh.hasSubscribers) injectCh.unsubscribe(onSpanInject)
|
|
20
14
|
if (extractCh.hasSubscribers) extractCh.unsubscribe(onSpanExtract)
|
|
21
15
|
|
|
22
16
|
if (config.apmTracingEnabled !== false) return
|
|
23
17
|
|
|
24
|
-
startCh.subscribe(onSpanStart)
|
|
25
|
-
injectCh.subscribe(onSpanInject)
|
|
26
18
|
extractCh.subscribe(onSpanExtract)
|
|
27
19
|
|
|
28
20
|
return new TraceSourcePrioritySampler(config.env)
|
|
29
21
|
}
|
|
30
22
|
|
|
31
|
-
function onSpanStart ({ span, fields }) {
|
|
32
|
-
const context = span.context?.()
|
|
33
|
-
if (!context) return
|
|
34
|
-
|
|
35
|
-
const { parent } = fields
|
|
36
|
-
if (!parent || parent._isRemote) {
|
|
37
|
-
context.setTag(APM_TRACING_ENABLED_KEY, 0)
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function onSpanInject ({ spanContext, carrier }) {
|
|
42
|
-
if (!spanContext?._trace?.tags || !carrier) return
|
|
43
|
-
|
|
44
|
-
// do not inject trace and sampling if there is no _dd.p.ts
|
|
45
|
-
if (!hasTraceSourcePropagationTag(spanContext._trace.tags)) {
|
|
46
|
-
for (const key in carrier) {
|
|
47
|
-
const lKey = key.toLowerCase()
|
|
48
|
-
if (lKey.startsWith('x-datadog') || lKey.startsWith('x-b3') || lKey === 'traceparent') {
|
|
49
|
-
delete carrier[key]
|
|
50
|
-
} else if (lKey === 'tracestate') {
|
|
51
|
-
const tracestate = TraceState.fromString(carrier[key])
|
|
52
|
-
tracestate.forVendor('dd', state => state.clear())
|
|
53
|
-
carrier[key] = tracestate.toString()
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
23
|
function onSpanExtract ({ spanContext = {} }) {
|
|
60
24
|
if (!spanContext._trace?.tags || !spanContext._sampling) return
|
|
61
25
|
|
|
@@ -77,11 +77,11 @@ let agentTelemetry = true
|
|
|
77
77
|
*/
|
|
78
78
|
function getHeaders (config, application, reqType) {
|
|
79
79
|
const headers = {
|
|
80
|
+
'DD-Client-Library-Language': application.language_name,
|
|
81
|
+
'DD-Client-Library-Version': application.tracer_version,
|
|
80
82
|
'content-type': 'application/json',
|
|
81
83
|
'dd-telemetry-api-version': 'v2',
|
|
82
84
|
'dd-telemetry-request-type': reqType,
|
|
83
|
-
'dd-client-library-language': application.language_name,
|
|
84
|
-
'dd-client-library-version': application.tracer_version,
|
|
85
85
|
'dd-session-id': config.tags['runtime-id'],
|
|
86
86
|
}
|
|
87
87
|
if (config.DD_ROOT_JS_SESSION_ID) {
|
|
@@ -77,6 +77,31 @@ function globMatch (pattern, subject) {
|
|
|
77
77
|
return true
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Return the segment at {index} when splitting {string} on {separator}, without
|
|
82
|
+
* allocating the intermediate array. Equivalent to
|
|
83
|
+
* `string.split(separator, index + 1)[index]`, but `split` with a limit forces
|
|
84
|
+
* V8 off its constant-limit fast path (per-call ToUint32 plus an array
|
|
85
|
+
* allocation), making it 60-170% slower than this scan for the small inputs
|
|
86
|
+
* tracer code splits (paths, request lines, version strings).
|
|
87
|
+
*
|
|
88
|
+
* @param {string} string
|
|
89
|
+
* @param {string} separator
|
|
90
|
+
* @param {number} index
|
|
91
|
+
* @param {string} [fallback] returned when fewer than {index} + 1 segments exist
|
|
92
|
+
* @returns {string | undefined}
|
|
93
|
+
*/
|
|
94
|
+
function getSegment (string, separator, index, fallback) {
|
|
95
|
+
let start = 0
|
|
96
|
+
for (let i = 0; i < index; i++) {
|
|
97
|
+
const next = string.indexOf(separator, start)
|
|
98
|
+
if (next === -1) return fallback
|
|
99
|
+
start = next + separator.length
|
|
100
|
+
}
|
|
101
|
+
const end = string.indexOf(separator, start)
|
|
102
|
+
return end === -1 ? string.slice(start) : string.slice(start, end)
|
|
103
|
+
}
|
|
104
|
+
|
|
80
105
|
function calculateDDBasePath (dirname) {
|
|
81
106
|
const dirSteps = dirname.split(path.sep)
|
|
82
107
|
const packagesIndex = dirSteps.lastIndexOf('packages')
|
|
@@ -110,6 +135,7 @@ module.exports = {
|
|
|
110
135
|
isFalse,
|
|
111
136
|
isError,
|
|
112
137
|
globMatch,
|
|
138
|
+
getSegment,
|
|
113
139
|
ddBasePath: globalThis.__DD_ESBUILD_BASEPATH || calculateDDBasePath(__dirname),
|
|
114
140
|
normalizePluginEnvName,
|
|
115
141
|
formatKnuthRate,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{var i={"./@apm-js-collab/code-transformer/index.js"(i,s,k){"use strict";i.exports=k("./@apm-js-collab/code-transformer/lib/index.js")},"./@apm-js-collab/code-transformer/lib/index.js"(i,s,k){"use strict";let{InstrumentationMatcher:S}=k("./@apm-js-collab/code-transformer/lib/matcher.js");i.exports={create:function(i,s){return new S(i,s)}}},"./@apm-js-collab/code-transformer/lib/matcher.js"(i,s,k){"use strict";let S=k("./semifies/index.js"),{Transformer:E}=k("./@apm-js-collab/code-transformer/lib/transformer.js");let InstrumentationMatcher=class InstrumentationMatcher{#e=[];#t=null;#r={};#n={};constructor(i,s){this.#e=i,this.#t=s||"diagnostics_channel"}free(){this.#r={}}addTransform(i,s){this.#n[i]=s}getTransformer(i,s,k){k=k.replace(/\\/g,"/");let w=`${i}/${k}@${s}`;if(this.#r[w])return this.#r[w];let C=this.#e.filter(({module:E})=>E.name===i&&E.filePath===k&&S(s,E.versionRange));if(0!==C.length)return this.#r[w]=new E(i,s,k,C,this.#t,this.#n),this.#r[w]}};i.exports={InstrumentationMatcher}},"./@apm-js-collab/code-transformer/lib/transformer.js"(i,s,k){"use strict";let S,E,w=k("./esquery/dist/esquery.min.js"),{parse:C}=k("./meriyah/dist/meriyah.cjs"),{generate:T}=k("./astring/dist/astring.js"),_=k("./@apm-js-collab/code-transformer/lib/transforms.js");let Transformer=class Transformer{#a=null;#o=null;#i=null;#e=[];#t=null;#n={};constructor(i,s,k,S,E,w={}){this.#a=i,this.#o=s,this.#i=k,this.#e=S,this.#t=E,this.#n=w}free(){}get moduleName(){return this.#a}get filePath(){return this.#i}transform(i,s,_){let O;if(Buffer.isBuffer(i)&&(i=i.toString()),!i)return{code:i};let N={},D=0;for(let k of this.#e){let{astQuery:S,functionQuery:E={}}=k;if(!O){let k={loc:!0,ranges:!0,raw:!0,module:"esm"===s};try{O=C(i,k)}catch{O=C(i,{...k,module:!k.module})}"esm"===s&&(N=this.#s(O))}let T=this.#l(E,N),_=S||this.#c(T),q={...k,dcModule:this.#t,moduleType:s,moduleVersion:this.#o,functionQuery:T};q.operator=this.#u(q),w.traverse(O,w.parse(_),(...i)=>{D++,this.#p(q,...i)})}if(0===D&&this.#e.length>0){let i=this.#e.map(({functionQuery:
|
|
1
|
+
(()=>{var i={"./@apm-js-collab/code-transformer/index.js"(i,s,k){"use strict";i.exports=k("./@apm-js-collab/code-transformer/lib/index.js")},"./@apm-js-collab/code-transformer/lib/index.js"(i,s,k){"use strict";let{InstrumentationMatcher:S}=k("./@apm-js-collab/code-transformer/lib/matcher.js");i.exports={create:function(i,s){return new S(i,s)}}},"./@apm-js-collab/code-transformer/lib/matcher.js"(i,s,k){"use strict";let S=k("./semifies/index.js"),{Transformer:E}=k("./@apm-js-collab/code-transformer/lib/transformer.js");let InstrumentationMatcher=class InstrumentationMatcher{#e=[];#t=null;#r={};#n={};constructor(i,s){this.#e=i,this.#t=s||"diagnostics_channel"}free(){this.#r={}}addTransform(i,s){this.#n[i]=s}getTransformer(i,s,k){k=k.replace(/\\/g,"/");let w=`${i}/${k}@${s}`;if(this.#r[w])return this.#r[w];let C=this.#e.filter(({module:E})=>E.name===i&&("string"==typeof E.filePath?E.filePath===k:E.filePath.test(k))&&S(s,E.versionRange));if(0!==C.length)return this.#r[w]=new E(i,s,k,C,this.#t,this.#n),this.#r[w]}};i.exports={InstrumentationMatcher}},"./@apm-js-collab/code-transformer/lib/transformer.js"(i,s,k){"use strict";let S,E,w=k("./esquery/dist/esquery.min.js"),{parse:C}=k("./meriyah/dist/meriyah.cjs"),{generate:T}=k("./astring/dist/astring.js"),_=k("./@apm-js-collab/code-transformer/lib/transforms.js");let Transformer=class Transformer{#a=null;#o=null;#i=null;#e=[];#t=null;#n={};constructor(i,s,k,S,E,w={}){this.#a=i,this.#o=s,this.#i=k,this.#e=S,this.#t=E,this.#n=w}free(){}get moduleName(){return this.#a}get filePath(){return this.#i}transform(i,s,_){let O;if(Buffer.isBuffer(i)&&(i=i.toString()),!i)return{code:i};let N={},D=0;for(let k of this.#e){let{astQuery:S,functionQuery:E={}}=k;if(!O){let k={loc:!0,ranges:!0,raw:!0,module:"esm"===s};try{O=C(i,k)}catch{O=C(i,{...k,module:!k.module})}"esm"===s&&(N=this.#s(O))}let T=this.#l(E,N),_=S||this.#c(T),q={...k,dcModule:this.#t,moduleType:s,moduleVersion:this.#o,functionQuery:T};q.operator=this.#u(q),w.traverse(O,w.parse(_),(...i)=>{D++,this.#p(q,...i)})}if(0===D&&this.#e.length>0){let i=this.#e.map(({astQuery:i,functionQuery:s={}})=>{if(i)return i;let k=this.#l(s,N),S=s.methodName||s.privateMethodName||s.functionName||s.expressionName||"constructor",E=s.className||s.functionName||s.expressionName,w=k.className||k.functionName||k.expressionName;return E&&E!==w?`${E} (local name: ${w})`:S});throw Error(`Failed to find injection points for: ${JSON.stringify(i)}`)}if(O){let i;S??=k("./@apm-js-collab/code-transformer/node_modules/source-map/source-map.js").SourceMapConsumer,E??=k("./@apm-js-collab/code-transformer/node_modules/source-map/source-map.js").SourceMapGenerator;let s=`${this.#a}/${this.#i}`;if(_){let k=new S(_);k.file=s,i=E.fromSourceMap(k)}else i=new E({file:s});return{code:T(O,{sourceMap:i}),map:i.toString()}}return{code:i}}#p(i,...s){let k=this.#n[i.operator]??_[i.operator],{index:S=0}=i.functionQuery,[E]=s,w=E.init?.type||E.type;if("ClassDeclaration"===w||"ClassExpression"===w||"VariableDeclarator"!==E.type&&(i.functionIndex=++i.functionIndex||0,null===S||S===i.functionIndex))k(i,...s)}#u({transform:i,functionQuery:{kind:s}}){if(i)return i;switch(s){case"Async":return"tracePromise";case"Auto":return"traceAuto";case"Callback":return"traceCallback";default:return"traceSync"}}#s(i){let s={};for(let k of i.body)if("ExportNamedDeclaration"===k.type&&!k.source){for(let i of k.specifiers)if(i.exported&&i.local){let k=i.exported.name??i.exported.value,S=i.local.name??i.local.value;k&&S&&(s[k]=S)}}return s}#l(i,s){if(!i.isExportAlias)return i;let{functionName:k,expressionName:S,className:E}=i;return k&&s[k]?{...i,functionName:s[k]}:S&&s[S]?{...i,expressionName:s[S]}:E&&s[E]?{...i,className:s[E]}:i}#c(i){let{functionName:s,expressionName:k,className:S,objectName:E,propertyName:w}=i,C=i.privateMethodName?"PrivateIdentifier":"Identifier",T=[],_=i.methodName||i.privateMethodName;if(S?(_??="constructor",T.push(`[id.name="${S}"]`,`[id.name="${S}"] > ClassExpression`,`[id.name="${S}"] > ClassBody > [key.name="${_}"][key.type=${C}] > [async]`,`[id.name="${S}"] > ClassExpression > ClassBody > [key.name="${_}"][key.type=${C}] > [async]`)):_&&T.push(`ClassBody > [key.name="${_}"][key.type=${C}] > [async]`,`Property[key.name="${_}"][key.type=${C}] > [async]`),s?T.push(`FunctionDeclaration[id.name="${s}"][async]`):k&&T.push(`FunctionExpression[id.name="${k}"][async]`,`ArrowFunctionExpression[id.name="${k}"][async]`,`VariableDeclarator[id.name="${k}"] > FunctionExpression[async]`,`VariableDeclarator[id.name="${k}"] > ArrowFunctionExpression[async]`,`AssignmentExpression[left.property.name="${k}"] > FunctionExpression[async]`,`AssignmentExpression[left.property.name="${k}"] > ArrowFunctionExpression[async]`,`AssignmentExpression[left.name="${k}"] > FunctionExpression[async]`,`AssignmentExpression[left.name="${k}"] > ArrowFunctionExpression[async]`),E||w){if(!E||!w)throw Error(`functionQuery: 'objectName' and 'propertyName' must be used together (got objectName=${E}, propertyName=${w})`);let i="this"===E?"left.object.type=ThisExpression":`left.object.name="${E}"`;T.push(`AssignmentExpression[${i}][left.property.name="${w}"] > [async]`)}return T.join(", ")}};i.exports={Transformer}},"./@apm-js-collab/code-transformer/lib/transforms.js"(i,s,k){"use strict";let S=k("./esquery/dist/esquery.min.js"),{parse:E}=k("./meriyah/dist/meriyah.cjs"),tracingChannelPredicate=i=>i.declarations?.[0]?.id?.properties?.[0]?.value?.name==="tr_ch_apm_tracingChannel",w=/[^\w]/g,formatChannelVariable=i=>`tr_ch_apm$${i.replace(w,"_")}`,C=i.exports={tracingChannelImport({dcModule:i,moduleType:s},k){if(k.body.some(tracingChannelPredicate))return;let S={module:"esm"===s},w=k.body.findIndex(i=>"use strict"===i.directive),C="esm"===s?`import tr_ch_apm_dc from "${i}"`:`const tr_ch_apm_dc = require("${i}")`,T=`const tr_ch_apm_hasSubscribers = ch => ch.start.hasSubscribers
|
|
2
2
|
|| ch.end.hasSubscribers
|
|
3
3
|
|| ch.asyncStart.hasSubscribers
|
|
4
4
|
|| ch.asyncEnd.hasSubscribers
|