dd-trace 5.132.0 → 5.134.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 +9 -14
- package/ci/init.js +1 -2
- package/ci/test-optimization-validation/ci-discovery.js +9 -4
- package/ci/test-optimization-validation/executable.js +1 -5
- package/ci/test-optimization-validation/framework-adapters/cypress.js +1 -4
- package/ci/test-optimization-validation/framework-adapters/vitest.js +1 -1
- package/ci/test-optimization-validation/generated-files.js +6 -4
- package/ci/test-optimization-validation/generated-test-contract.js +7 -3
- package/ci/test-optimization-validation/manifest-scaffold.js +7 -2
- package/ci/test-optimization-validation/manifest-schema.js +6 -7
- package/ci/test-optimization-validation/report-writer.js +6 -2
- package/ci/test-optimization-validation/runner-command.js +2 -4
- package/ci/test-optimization-validation/runner-contract.js +1 -2
- package/ci/test-optimization-validation/scenarios/auto-test-retries.js +1 -15
- package/ci/vitest-no-worker-init-runner-setup.mjs +27 -0
- package/ci/vitest-no-worker-init-setup.mjs +10 -7
- package/index.d.ts +41 -19
- package/initialize.mjs +1 -3
- package/openfeature/rules-based.d.ts +11 -0
- package/openfeature/rules-based.js +7 -0
- package/package.json +25 -22
- package/packages/datadog-core/src/storage.js +16 -0
- package/packages/datadog-esbuild/index.js +18 -12
- package/packages/datadog-instrumentations/index.js +2 -1
- package/packages/datadog-instrumentations/src/aerospike.js +3 -3
- package/packages/datadog-instrumentations/src/ai.js +3 -3
- package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -6
- package/packages/datadog-instrumentations/src/aws-sdk.js +21 -13
- package/packages/datadog-instrumentations/src/cassandra-driver.js +25 -20
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +9 -23
- package/packages/datadog-instrumentations/src/cucumber.js +65 -41
- package/packages/datadog-instrumentations/src/elasticsearch.js +1 -5
- package/packages/datadog-instrumentations/src/electron.js +6 -6
- package/packages/datadog-instrumentations/src/fastify.js +13 -4
- package/packages/datadog-instrumentations/src/fs.js +2 -2
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +9 -5
- package/packages/datadog-instrumentations/src/grpc/client.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +28 -9
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/register.js +45 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +89 -6
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql-jit.js +5 -6
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/jest.js +12 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +48 -31
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/vitest.js +8 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +7 -7
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +5 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +42 -4
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +7 -10
- package/packages/datadog-instrumentations/src/ioredis.js +7 -5
- package/packages/datadog-instrumentations/src/iovalkey.js +7 -5
- package/packages/datadog-instrumentations/src/jest.js +72 -67
- package/packages/datadog-instrumentations/src/knex.js +9 -5
- package/packages/datadog-instrumentations/src/mariadb-bundle.js +3 -3
- package/packages/datadog-instrumentations/src/mocha/common.js +20 -8
- package/packages/datadog-instrumentations/src/mocha/main.js +140 -43
- package/packages/datadog-instrumentations/src/mocha/utils.js +38 -4
- package/packages/datadog-instrumentations/src/mocha/worker.js +1 -2
- package/packages/datadog-instrumentations/src/mongodb-core.js +3 -3
- package/packages/datadog-instrumentations/src/mongoose.js +3 -3
- package/packages/datadog-instrumentations/src/nova-sonic/audio.js +173 -0
- package/packages/datadog-instrumentations/src/nova-sonic/index.js +209 -0
- package/packages/datadog-instrumentations/src/nova-sonic/session.js +492 -0
- package/packages/datadog-instrumentations/src/openai-realtime/index.js +18 -6
- package/packages/datadog-instrumentations/src/openai-realtime/session.js +1 -1
- package/packages/datadog-instrumentations/src/openai.js +7 -0
- package/packages/datadog-instrumentations/src/pino.js +5 -6
- package/packages/datadog-instrumentations/src/playwright.js +2 -0
- package/packages/datadog-instrumentations/src/redis.js +27 -13
- package/packages/datadog-instrumentations/src/router.js +30 -0
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +2 -6
- package/packages/datadog-instrumentations/src/stripe.js +23 -12
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +8 -5
- package/packages/datadog-instrumentations/src/vitest-main.js +16 -18
- package/packages/datadog-instrumentations/src/vitest-util.js +7 -4
- package/packages/datadog-instrumentations/src/vitest-worker.js +1 -2
- package/packages/datadog-instrumentations/src/vitest.js +9 -1
- package/packages/datadog-instrumentations/src/webdriverio.js +5 -8
- package/packages/datadog-instrumentations/src/ws.js +1 -4
- package/packages/datadog-plugin-amqplib/src/client.js +1 -2
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -5
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/handler.js +1 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +5 -8
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +18 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/sonic.js +45 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +9 -3
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -5
- package/packages/datadog-plugin-azure-durable-functions/src/index.js +5 -4
- package/packages/datadog-plugin-azure-functions/src/index.js +5 -3
- package/packages/datadog-plugin-claude-agent-sdk/src/index.js +0 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +4 -5
- package/packages/datadog-plugin-cypress/src/index.js +6 -6
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +1 -2
- package/packages/datadog-plugin-cypress/src/support.js +3 -4
- package/packages/datadog-plugin-express/src/code_origin.js +1 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +1 -2
- package/packages/datadog-plugin-graphql/src/execute.js +5 -5
- package/packages/datadog-plugin-grpc/src/util.js +1 -2
- package/packages/datadog-plugin-kafkajs/src/producer.js +1 -2
- package/packages/datadog-plugin-mocha/src/index.js +7 -10
- package/packages/datadog-plugin-mocha/src/webdriverio-video.js +8 -4
- package/packages/datadog-plugin-mongodb-core/src/query.js +8 -5
- package/packages/datadog-plugin-next/src/index.js +1 -2
- package/packages/datadog-plugin-openai/src/tracing.js +5 -2
- package/packages/datadog-plugin-openai-agents/src/integration.js +6 -2
- package/packages/datadog-plugin-openai-agents/src/processor.js +2 -4
- package/packages/datadog-plugin-postgres/src/index.js +24 -0
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -5
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -4
- package/packages/datadog-plugin-vitest/src/index.js +5 -2
- package/packages/datadog-shimmer/src/shimmer.js +5 -4
- package/packages/datadog-webpack/index.js +55 -43
- package/packages/datadog-webpack/src/loader.js +56 -8
- package/packages/dd-trace/src/aiguard/evaluation.js +143 -1
- package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +2 -4
- package/packages/dd-trace/src/aiguard/messages/utils.js +1 -2
- package/packages/dd-trace/src/aiguard/redaction.js +8 -2
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +3 -2
- package/packages/dd-trace/src/appsec/api_security/sampler.js +2 -6
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -9
- package/packages/dd-trace/src/appsec/handlers/http-request.js +3 -9
- package/packages/dd-trace/src/appsec/handlers/http-response.js +7 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +4 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +1 -4
- package/packages/dd-trace/src/appsec/iast/path-line.js +2 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +7 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -3
- package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +1 -6
- package/packages/dd-trace/src/appsec/lambda.js +1 -3
- package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +37 -27
- package/packages/dd-trace/src/appsec/rasp/lfi.js +9 -5
- package/packages/dd-trace/src/appsec/reporter.js +21 -1
- package/packages/dd-trace/src/appsec/stack_trace.js +4 -4
- package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +3 -6
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +3 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +13 -7
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +1 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +2 -8
- package/packages/dd-trace/src/ci-visibility/resolve-runfile-path.js +54 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +5 -8
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +2 -53
- package/packages/dd-trace/src/config/config-types.d.ts +2 -2
- package/packages/dd-trace/src/config/defaults.js +5 -5
- package/packages/dd-trace/src/config/generated-config-types.d.ts +10 -0
- package/packages/dd-trace/src/config/helper.js +34 -3
- package/packages/dd-trace/src/config/index.js +55 -9
- package/packages/dd-trace/src/config/normalize-service.js +1 -1
- package/packages/dd-trace/src/config/parsers.js +2 -2
- package/packages/dd-trace/src/config/supported-configurations.json +44 -0
- package/packages/dd-trace/src/datastreams/processor.js +3 -2
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -4
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +6 -5
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +5 -5
- package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +4 -6
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -0
- package/packages/dd-trace/src/debugger/guardrail-metrics.js +2 -2
- package/packages/dd-trace/src/debugger/unsupported-runtime.js +16 -0
- package/packages/dd-trace/src/dogstatsd.js +1 -1
- package/packages/dd-trace/src/encode/tags-processors.js +2 -2
- package/packages/dd-trace/src/exporters/common/request.js +1 -5
- package/packages/dd-trace/src/id.js +14 -1
- package/packages/dd-trace/src/lambda/handler.js +179 -19
- package/packages/dd-trace/src/lambda/index.js +15 -1
- package/packages/dd-trace/src/lambda/runtime/patch.js +34 -7
- package/packages/dd-trace/src/llmobs/agent-manifest.js +19 -2
- package/packages/dd-trace/src/llmobs/audio-utils.js +3 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +15 -0
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +15 -0
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +1 -2
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +1 -3
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/nova-sonic.js +92 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +5 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +64 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +38 -0
- package/packages/dd-trace/src/llmobs/prompts/manager.js +5 -7
- package/packages/dd-trace/src/llmobs/prompts/prompt.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +15 -4
- package/packages/dd-trace/src/llmobs/span_processor.js +13 -2
- package/packages/dd-trace/src/llmobs/tagger.js +20 -10
- package/packages/dd-trace/src/llmobs/util.js +11 -6
- package/packages/dd-trace/src/llmobs/writers/base.js +4 -5
- package/packages/dd-trace/src/log/log.js +1 -5
- package/packages/dd-trace/src/openfeature/evaluation-telemetry-opt-out-hook.js +51 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +48 -21
- package/packages/dd-trace/src/openfeature/index.js +6 -0
- package/packages/dd-trace/src/openfeature/writers/util.js +4 -4
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -2
- package/packages/dd-trace/src/opentelemetry/otlp/common.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +24 -24
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +53 -13
- package/packages/dd-trace/src/otel-sampling.js +4 -5
- package/packages/dd-trace/src/otel-thread-ctx.js +79 -13
- package/packages/dd-trace/src/plugin_manager.js +1 -2
- package/packages/dd-trace/src/plugins/database.js +7 -16
- package/packages/dd-trace/src/plugins/tracing.js +0 -1
- package/packages/dd-trace/src/plugins/util/git.js +99 -59
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -5
- package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -1
- package/packages/dd-trace/src/plugins/util/test.js +50 -4
- package/packages/dd-trace/src/plugins/util/web.js +90 -20
- package/packages/dd-trace/src/priority_sampler.js +1 -2
- package/packages/dd-trace/src/profiling/profiler.js +4 -6
- package/packages/dd-trace/src/proxy.js +1 -2
- package/packages/dd-trace/src/ritm.js +4 -2
- package/packages/dd-trace/src/serverless.js +5 -0
- package/packages/dd-trace/src/span_processor.js +13 -17
- package/packages/dd-trace/src/span_stats.js +4 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +1 -3
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +1 -1
- package/packages/dd-trace/src/util.js +37 -4
- package/packages/dd-trace/src/web-tags-cache.js +6 -2
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +8 -8
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
- package/vendor/dist/@datadog/openfeature-node-server/rules-based/LICENSE +201 -0
- package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.d.ts +925 -0
- package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.js +1 -0
- 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
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
// and the OTel ContextManager activates spans via
|
|
21
21
|
// storage('legacy').run({ span: ddSpan }, ...), so the active span
|
|
22
22
|
// our writer reads from legacy storage is the same DatadogSpan in
|
|
23
|
-
// both cases. The
|
|
24
|
-
// _ddContext.toTraceId/toSpanId
|
|
23
|
+
// both cases. The record's trace/span IDs are read from the same
|
|
24
|
+
// Identifier bytes (and _dd.p.tid) behind _ddContext.toTraceId/toSpanId,
|
|
25
|
+
// and the spec pins them byte-for-byte to those methods.
|
|
25
26
|
|
|
26
27
|
const { isMainThread, threadId } = require('worker_threads')
|
|
27
28
|
|
|
@@ -40,6 +41,10 @@ const {
|
|
|
40
41
|
} = require('./profiling/webspan-utils')
|
|
41
42
|
const webTagsCache = require('./web-tags-cache')
|
|
42
43
|
|
|
44
|
+
/** @typedef {import('./opentracing/span')} DatadogSpan */
|
|
45
|
+
/** @typedef {import('./opentracing/span_context')} DatadogSpanContext */
|
|
46
|
+
/** @typedef {InstanceType<typeof import('@datadog/pprof').otelThreadCtx.ThreadContext>} ThreadContext */
|
|
47
|
+
|
|
43
48
|
// OTEP-4947 duplicates are last-wins, so appending a later endpoint value would
|
|
44
49
|
// correctly overwrite an earlier one — but an out-of-process reader sampling the
|
|
45
50
|
// record mid-request would still see the interim value (e.g. a bare `GET`) as
|
|
@@ -124,6 +129,7 @@ function traceFlagsOf (spanContext) {
|
|
|
124
129
|
// waiting on; undefined while the span has no web-server ancestry.
|
|
125
130
|
// Distinguishes a stale announcement from a live one when a nearer
|
|
126
131
|
// web-server span takes over.
|
|
132
|
+
// awaitsOwnEndpoint: this is the request span, waiting on its own endpoint.
|
|
127
133
|
const CachedSym = Symbol('OtelThreadCtx.cached')
|
|
128
134
|
|
|
129
135
|
let started = false
|
|
@@ -131,12 +137,59 @@ let ThreadContext
|
|
|
131
137
|
let getContext
|
|
132
138
|
let clearContext
|
|
133
139
|
|
|
140
|
+
// Reusable: the ThreadContext constructor copies the ids into its own record.
|
|
141
|
+
const traceIdBytes = Buffer.alloc(16)
|
|
142
|
+
const spanIdBytes = new Uint8Array(8)
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Same bytes as decoding toTraceId(true); unexpected shapes fall back to that.
|
|
146
|
+
*
|
|
147
|
+
* @param {DatadogSpanContext} spanContext
|
|
148
|
+
* @returns {Uint8Array}
|
|
149
|
+
*/
|
|
150
|
+
function getTraceIdBytes (spanContext) {
|
|
151
|
+
const low = spanContext._traceId.toBuffer()
|
|
152
|
+
if (low.length === 16) {
|
|
153
|
+
for (let i = 0; i < 16; i++) traceIdBytes[i] = low[i]
|
|
154
|
+
return traceIdBytes
|
|
155
|
+
}
|
|
156
|
+
if (low.length !== 8) return Buffer.from(spanContext.toTraceId(true), 'hex')
|
|
157
|
+
const high = spanContext._trace.tags['_dd.p.tid']
|
|
158
|
+
if (high) {
|
|
159
|
+
// write() stops at the first non-hex character, so only a valid _dd.p.tid fills all 8 bytes.
|
|
160
|
+
if (typeof high !== 'string' || high.length !== 16 || traceIdBytes.write(high, 0, 8, 'hex') !== 8) {
|
|
161
|
+
return Buffer.from(spanContext.toTraceId(true), 'hex')
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
for (let i = 0; i < 8; i++) traceIdBytes[i] = 0
|
|
165
|
+
}
|
|
166
|
+
for (let i = 0; i < 8; i++) traceIdBytes[i + 8] = low[i]
|
|
167
|
+
return traceIdBytes
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* @param {DatadogSpanContext} spanContext
|
|
172
|
+
* @returns {Uint8Array}
|
|
173
|
+
*/
|
|
174
|
+
function getSpanIdBytes (spanContext) {
|
|
175
|
+
const bytes = spanContext._spanId.toBuffer()
|
|
176
|
+
if (bytes.length !== 8) return Buffer.from(spanContext.toSpanId(true), 'hex')
|
|
177
|
+
for (let i = 0; i < 8; i++) spanIdBytes[i] = bytes[i]
|
|
178
|
+
return spanIdBytes
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @param {DatadogSpan} span
|
|
183
|
+
* @returns {ThreadContext | undefined} The span's record, or undefined when the span's trace or span id is malformed.
|
|
184
|
+
*/
|
|
134
185
|
function getOrBuildContext (span) {
|
|
135
186
|
let cached = span[CachedSym]
|
|
136
187
|
if (cached !== undefined && cached.context !== undefined) return cached.context
|
|
137
188
|
const spanContext = span.context()
|
|
138
|
-
const traceId =
|
|
139
|
-
const spanId =
|
|
189
|
+
const traceId = getTraceIdBytes(spanContext)
|
|
190
|
+
const spanId = getSpanIdBytes(spanContext)
|
|
191
|
+
// The native constructor throws on any other id length, and onEnter runs inside user code.
|
|
192
|
+
if (traceId.length !== 16 || spanId.length !== 8) return
|
|
140
193
|
// Local root span: the first entry in the trace's started-spans list, or
|
|
141
194
|
// this span itself when it IS the root. Encoded as 16-char lowercase hex
|
|
142
195
|
// per the libdatadog convention.
|
|
@@ -152,7 +205,7 @@ function getOrBuildContext (span) {
|
|
|
152
205
|
attrs[THREAD_NAME_IDX] = THREAD_NAME
|
|
153
206
|
attrs[THREAD_ID_IDX] = THREAD_ID
|
|
154
207
|
if (cached === undefined) {
|
|
155
|
-
cached = {}
|
|
208
|
+
cached = { context: undefined, webTags: undefined, awaitsOwnEndpoint: false }
|
|
156
209
|
span[CachedSym] = cached
|
|
157
210
|
}
|
|
158
211
|
// The flags are the one part of the record that can still change after
|
|
@@ -163,17 +216,22 @@ function getOrBuildContext (span) {
|
|
|
163
216
|
// built before the decision keeps reading as not sampled.
|
|
164
217
|
cached.context = new ThreadContext(traceId, spanId, traceFlagsOf(spanContext), attrs)
|
|
165
218
|
cached.webTags = webTags
|
|
166
|
-
if (endpoint === undefined) awaitEndpoint(webTags, cached)
|
|
219
|
+
if (endpoint === undefined) awaitEndpoint(span, webTags, cached)
|
|
167
220
|
return cached.context
|
|
168
221
|
}
|
|
169
222
|
|
|
170
223
|
// Enlist a record built without an endpoint, so the resolution announcement for
|
|
171
224
|
// its request fills it in.
|
|
172
|
-
function awaitEndpoint (webTags, cached) {
|
|
225
|
+
function awaitEndpoint (span, webTags, cached) {
|
|
173
226
|
// No web-server span in this span's ancestry, so no endpoint is coming. Should
|
|
174
227
|
// one appear later, webTagsCache announces that separately — see
|
|
175
228
|
// onWebTagsResolved.
|
|
176
229
|
if (webTags === undefined) return
|
|
230
|
+
// The request span waits on its own announcement; only descendants need the shared list.
|
|
231
|
+
if (webTags === span.context().getTags()) {
|
|
232
|
+
cached.awaitsOwnEndpoint = true
|
|
233
|
+
return
|
|
234
|
+
}
|
|
177
235
|
const waiting = pendingEndpoints.get(webTags)
|
|
178
236
|
if (waiting === undefined) {
|
|
179
237
|
pendingEndpoints.set(webTags, [cached])
|
|
@@ -193,12 +251,13 @@ function appendEndpoint (context, endpoint) {
|
|
|
193
251
|
|
|
194
252
|
function onEnter () {
|
|
195
253
|
if (!started) return
|
|
196
|
-
const span = getActiveSpan()
|
|
197
|
-
|
|
198
|
-
|
|
254
|
+
const span = /** @type {DatadogSpan | null | undefined} */ (getActiveSpan())
|
|
255
|
+
const context = span && getOrBuildContext(span)
|
|
256
|
+
if (!context) {
|
|
257
|
+
// Clearing an empty frame would still make pprof install a new AsyncContextFrame.
|
|
258
|
+
if (getContext() !== undefined) clearContext()
|
|
199
259
|
return
|
|
200
260
|
}
|
|
201
|
-
const context = getOrBuildContext(span)
|
|
202
261
|
// Skip if this CPED already holds the same context. Same allocation-churn
|
|
203
262
|
// fix as the wall profiler in dd-trace-js#8638.
|
|
204
263
|
if (getContext() === context) return
|
|
@@ -246,11 +305,18 @@ function onSpanFinished (span) {
|
|
|
246
305
|
function onEndpointResolved (span) {
|
|
247
306
|
if (!started) return
|
|
248
307
|
const webTags = span.context().getTags()
|
|
308
|
+
const own = span[CachedSym]
|
|
309
|
+
const ownWaits = own !== undefined && own.awaitsOwnEndpoint
|
|
249
310
|
const waiting = pendingEndpoints.get(webTags)
|
|
250
|
-
if (waiting === undefined) return
|
|
311
|
+
if (!ownWaits && waiting === undefined) return
|
|
251
312
|
const endpoint = finalEndpoint(webTags)
|
|
252
313
|
// webTagsCache only announces settled endpoints, so this is belt and braces.
|
|
253
314
|
if (endpoint === undefined) return
|
|
315
|
+
if (ownWaits) {
|
|
316
|
+
own.awaitsOwnEndpoint = false
|
|
317
|
+
if (own.context !== undefined && own.webTags === webTags) appendEndpoint(own.context, endpoint)
|
|
318
|
+
}
|
|
319
|
+
if (waiting === undefined) return
|
|
254
320
|
pendingEndpoints.delete(webTags)
|
|
255
321
|
for (const cached of waiting) {
|
|
256
322
|
// A record whose span has since been attributed to a nearer web-server span
|
|
@@ -281,7 +347,7 @@ function onWebTagsResolved (span) {
|
|
|
281
347
|
// ThreadContext would strand every async-context frame holding this one.
|
|
282
348
|
// The work is still nested in the outer request, which makes that the least
|
|
283
349
|
// wrong of the values available.
|
|
284
|
-
awaitEndpoint(webTags, cached)
|
|
350
|
+
awaitEndpoint(span, webTags, cached)
|
|
285
351
|
} else {
|
|
286
352
|
appendEndpoint(cached.context, endpoint)
|
|
287
353
|
}
|
|
@@ -102,8 +102,7 @@ module.exports = class PluginManager {
|
|
|
102
102
|
loadPlugin (name) {
|
|
103
103
|
const Plugin = pluginClasses[name]
|
|
104
104
|
|
|
105
|
-
if (!Plugin) return
|
|
106
|
-
if (!this._tracerConfig) return // TODO: don't wait for tracer to be initialized
|
|
105
|
+
if (!Plugin || !this._tracerConfig) return // TODO: don't wait for tracer to be initialized
|
|
107
106
|
|
|
108
107
|
// Check if this is a Test Optimization plugin and Test Optimization is not enabled
|
|
109
108
|
if (TEST_OPTIMIZATION_PLUGINS.has(name) && !this._tracerConfig.isCiVisibility) {
|
|
@@ -25,7 +25,7 @@ class DatabasePlugin extends StoragePlugin {
|
|
|
25
25
|
// trails ddh — so per-query work shrinks to encoding dddb / dddbs / ddh and concatenating.
|
|
26
26
|
#dbmEnvFragment
|
|
27
27
|
#dbmEndFragment
|
|
28
|
-
// Cache the rendered prefix per `${db.name}\0${out.host}\0${
|
|
28
|
+
// Cache the rendered prefix per `${db.name}\0${out.host}\0${serviceName}`. The triple is
|
|
29
29
|
// connection-stable for a real workload, so the steady state is one `LRUCache.get` plus the
|
|
30
30
|
// optional per-call `,ddprs='...'` suffix.
|
|
31
31
|
#dbmPrefixCache = new LRUCache({ max: DBM_PREFIX_CACHE_MAX })
|
|
@@ -61,23 +61,15 @@ class DatabasePlugin extends StoragePlugin {
|
|
|
61
61
|
this.#dbmPrefixCache.set(cacheKey, prefix)
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
// `dddbs` never follows the peer service: it is always the configured database service, and the
|
|
65
|
+
// peer service is reported through `ddprs` only, and only when it was set explicitly.
|
|
66
|
+
const peerService = peerData?.[PEER_SERVICE_KEY]
|
|
67
|
+
if (peerService && peerData[PEER_SERVICE_SOURCE_KEY] === PEER_SERVICE_KEY) {
|
|
68
|
+
return `${prefix},ddprs='${encode(peerService)}'`
|
|
66
69
|
}
|
|
67
70
|
return prefix
|
|
68
71
|
}
|
|
69
72
|
|
|
70
|
-
/**
|
|
71
|
-
* @param {string} tracerService
|
|
72
|
-
* @param {object} peerData
|
|
73
|
-
*/
|
|
74
|
-
#getDbmServiceName (tracerService, peerData) {
|
|
75
|
-
if (this._tracerConfig.spanComputePeerService) {
|
|
76
|
-
return this.getPeerServiceRemap(peerData)[PEER_SERVICE_KEY] || tracerService
|
|
77
|
-
}
|
|
78
|
-
return tracerService
|
|
79
|
-
}
|
|
80
|
-
|
|
81
73
|
/**
|
|
82
74
|
* @param {import('../../../..').Span} span
|
|
83
75
|
* @param {string} serviceName
|
|
@@ -91,8 +83,7 @@ class DatabasePlugin extends StoragePlugin {
|
|
|
91
83
|
}
|
|
92
84
|
|
|
93
85
|
const peerData = this.getPeerService(span.context().getTags())
|
|
94
|
-
const
|
|
95
|
-
const servicePropagation = this.#createDBMPropagationCommentService(dbmService, span, peerData)
|
|
86
|
+
const servicePropagation = this.#createDBMPropagationCommentService(serviceName, span, peerData)
|
|
96
87
|
|
|
97
88
|
let dbmComment = servicePropagation
|
|
98
89
|
|
|
@@ -267,7 +267,6 @@ class TracingPlugin extends Plugin {
|
|
|
267
267
|
analyticsSampler.sample(span, config.measured)
|
|
268
268
|
|
|
269
269
|
// TODO: Remove this after migration to TracingChannel is done.
|
|
270
|
-
// eslint-disable-next-line unicorn/no-unnecessary-boolean-comparison -- Context objects use the other branch.
|
|
271
270
|
if (enterOrCtx === true) {
|
|
272
271
|
legacyStorage.enterWith({ ...store, span })
|
|
273
272
|
} else if (enterOrCtx) {
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
const os = require('os')
|
|
4
4
|
const path = require('path')
|
|
5
5
|
const fs = require('fs')
|
|
6
|
+
const { execFileSync } = require('node:child_process')
|
|
6
7
|
|
|
7
8
|
const log = require('../../log')
|
|
9
|
+
const { getEnvironmentVariables } = require('../../config/helper')
|
|
8
10
|
const {
|
|
9
11
|
incrementCountMetric,
|
|
10
12
|
distributionMetric,
|
|
@@ -45,12 +47,12 @@ const legacyStorage = storage('legacy')
|
|
|
45
47
|
const GIT_REV_LIST_MAX_BUFFER = 12 * 1024 * 1024 // 12MB
|
|
46
48
|
|
|
47
49
|
function sanitizedExec (
|
|
48
|
-
cmd,
|
|
49
50
|
flags,
|
|
50
51
|
operationMetric,
|
|
51
52
|
durationMetric,
|
|
52
53
|
errorMetric,
|
|
53
|
-
shouldTrim = true
|
|
54
|
+
shouldTrim = true,
|
|
55
|
+
executionOptions
|
|
54
56
|
) {
|
|
55
57
|
return legacyStorage.run({ noop: true }, () => {
|
|
56
58
|
let startTime
|
|
@@ -61,7 +63,14 @@ function sanitizedExec (
|
|
|
61
63
|
startTime = Date.now()
|
|
62
64
|
}
|
|
63
65
|
try {
|
|
64
|
-
|
|
66
|
+
const exec = executionOptions?.uncached ? execFileSync : cachedExec
|
|
67
|
+
/** @type {import('node:child_process').ExecFileSyncOptions} */
|
|
68
|
+
const options = { stdio: 'pipe' }
|
|
69
|
+
if (executionOptions?.timeout) options.timeout = executionOptions.timeout
|
|
70
|
+
if (executionOptions?.localOnly) {
|
|
71
|
+
options.env = { ...getEnvironmentVariables(), GIT_NO_LAZY_FETCH: '1', GIT_ALLOW_PROTOCOL: '' }
|
|
72
|
+
}
|
|
73
|
+
let result = exec('git', flags, options).toString()
|
|
65
74
|
|
|
66
75
|
if (shouldTrim) {
|
|
67
76
|
result = result.replaceAll(/(\r\n|\n|\r)/g, '')
|
|
@@ -80,6 +89,7 @@ function sanitizedExec (
|
|
|
80
89
|
})
|
|
81
90
|
}
|
|
82
91
|
log.error('Git plugin error executing command', err)
|
|
92
|
+
if (executionOptions?.throwOnError) throw err
|
|
83
93
|
return ''
|
|
84
94
|
}
|
|
85
95
|
})
|
|
@@ -104,18 +114,19 @@ function isGitAvailable () {
|
|
|
104
114
|
}
|
|
105
115
|
}
|
|
106
116
|
|
|
107
|
-
function isShallowRepository () {
|
|
117
|
+
function isShallowRepository (uncached = false) {
|
|
108
118
|
return sanitizedExec(
|
|
109
|
-
'git',
|
|
110
119
|
['rev-parse', '--is-shallow-repository'],
|
|
111
120
|
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'check_shallow' } },
|
|
112
121
|
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'check_shallow' } },
|
|
113
|
-
{ name: TELEMETRY_GIT_COMMAND_ERRORS, tags: { command: 'check_shallow' } }
|
|
122
|
+
{ name: TELEMETRY_GIT_COMMAND_ERRORS, tags: { command: 'check_shallow' } },
|
|
123
|
+
true,
|
|
124
|
+
{ uncached }
|
|
114
125
|
) === 'true'
|
|
115
126
|
}
|
|
116
127
|
|
|
117
128
|
function getGitVersion () {
|
|
118
|
-
const gitVersionString = sanitizedExec(
|
|
129
|
+
const gitVersionString = sanitizedExec(['version'])
|
|
119
130
|
const gitVersionMatches = /** @type {RegExpMatch} */ (gitVersionString.match(/git version (\d+)\.(\d+)\.(\d+)/))
|
|
120
131
|
try {
|
|
121
132
|
return {
|
|
@@ -138,8 +149,8 @@ function unshallowRepository (parentOnly = false) {
|
|
|
138
149
|
log.warn('Git version is <2.27, so git unshallow will not proceed')
|
|
139
150
|
return
|
|
140
151
|
}
|
|
141
|
-
const defaultRemoteName = sanitizedExec(
|
|
142
|
-
const revParseHead = sanitizedExec(
|
|
152
|
+
const defaultRemoteName = sanitizedExec(['config', '--default', 'origin', '--get', 'clone.defaultRemoteName'])
|
|
153
|
+
const revParseHead = sanitizedExec(['rev-parse', 'HEAD'])
|
|
143
154
|
|
|
144
155
|
const baseGitOptions = [
|
|
145
156
|
'fetch',
|
|
@@ -167,7 +178,6 @@ function unshallowRepository (parentOnly = false) {
|
|
|
167
178
|
{ command: 'unshallow', errorType: err.code, exitCode: err.status || err.errno }
|
|
168
179
|
)
|
|
169
180
|
const upstreamRemote = sanitizedExec(
|
|
170
|
-
'git',
|
|
171
181
|
['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}']
|
|
172
182
|
)
|
|
173
183
|
flags = [
|
|
@@ -186,7 +196,6 @@ function unshallowRepository (parentOnly = false) {
|
|
|
186
196
|
)
|
|
187
197
|
// We use sanitizedExec here because if this last option fails, we'll give up.
|
|
188
198
|
sanitizedExec(
|
|
189
|
-
'git',
|
|
190
199
|
baseGitOptions,
|
|
191
200
|
null,
|
|
192
201
|
null,
|
|
@@ -199,7 +208,6 @@ function unshallowRepository (parentOnly = false) {
|
|
|
199
208
|
|
|
200
209
|
function getRepositoryUrl () {
|
|
201
210
|
return sanitizedExec(
|
|
202
|
-
'git',
|
|
203
211
|
['config', '--get', 'remote.origin.url'],
|
|
204
212
|
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'get_repository' } },
|
|
205
213
|
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'get_repository' } },
|
|
@@ -228,23 +236,29 @@ function getLatestCommits () {
|
|
|
228
236
|
}
|
|
229
237
|
|
|
230
238
|
function getGitDiff (baseCommit, targetCommit) {
|
|
239
|
+
// Fetch the required snapshots explicitly; a depth-1 metadata fetch does not provide their ancestry.
|
|
240
|
+
for (const commit of targetCommit ? [baseCommit, targetCommit] : [baseCommit]) {
|
|
241
|
+
if (!hasLocalGitObject(commit)) {
|
|
242
|
+
// Use the current checkout state so a stale cache cannot shorten a complete clone.
|
|
243
|
+
fetchHeadCommitSha(commit, isShallowRepository(true))
|
|
244
|
+
}
|
|
245
|
+
}
|
|
231
246
|
const flags = ['diff', '-U0', '--word-diff=porcelain', baseCommit]
|
|
232
247
|
if (targetCommit) {
|
|
233
248
|
flags.push(targetCommit)
|
|
234
249
|
}
|
|
235
250
|
return sanitizedExec(
|
|
236
|
-
'git',
|
|
237
251
|
flags,
|
|
238
252
|
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'diff' } },
|
|
239
253
|
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'diff' } },
|
|
240
254
|
{ name: TELEMETRY_GIT_COMMAND_ERRORS, tags: { command: 'diff' } },
|
|
241
|
-
false // important not to trim or we'll lose the line breaks which we need to detect impacted tests
|
|
255
|
+
false, // important not to trim or we'll lose the line breaks which we need to detect impacted tests
|
|
256
|
+
{ uncached: true }
|
|
242
257
|
)
|
|
243
258
|
}
|
|
244
259
|
|
|
245
260
|
function getGitRemoteName () {
|
|
246
261
|
const upstreamRemote = sanitizedExec(
|
|
247
|
-
'git',
|
|
248
262
|
['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}'],
|
|
249
263
|
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'get_remote_name' } },
|
|
250
264
|
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'get_remote_name' } },
|
|
@@ -256,7 +270,6 @@ function getGitRemoteName () {
|
|
|
256
270
|
}
|
|
257
271
|
|
|
258
272
|
const remotes = sanitizedExec(
|
|
259
|
-
'git',
|
|
260
273
|
['remote'],
|
|
261
274
|
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'get_remote_name' } },
|
|
262
275
|
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'get_remote_name' } },
|
|
@@ -269,7 +282,6 @@ function getGitRemoteName () {
|
|
|
269
282
|
|
|
270
283
|
function getSourceBranch () {
|
|
271
284
|
return sanitizedExec(
|
|
272
|
-
'git',
|
|
273
285
|
['rev-parse', '--abbrev-ref', 'HEAD'],
|
|
274
286
|
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'get_source_branch' } },
|
|
275
287
|
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'get_source_branch' } },
|
|
@@ -315,7 +327,6 @@ function checkAndFetchBranch (branch, remoteName) {
|
|
|
315
327
|
|
|
316
328
|
function getLocalBranches (remoteName) {
|
|
317
329
|
const localBranches = sanitizedExec(
|
|
318
|
-
'git',
|
|
319
330
|
['for-each-ref', '--format=%(refname:short)', `refs/remotes/${remoteName}`],
|
|
320
331
|
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'get_local_branches' } },
|
|
321
332
|
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'get_local_branches' } },
|
|
@@ -331,7 +342,6 @@ function getLocalBranches (remoteName) {
|
|
|
331
342
|
|
|
332
343
|
function getMergeBase (baseBranch, sourceBranch) {
|
|
333
344
|
return sanitizedExec(
|
|
334
|
-
'git',
|
|
335
345
|
['merge-base', baseBranch, sourceBranch],
|
|
336
346
|
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'get_merge_base' } },
|
|
337
347
|
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'get_merge_base' } },
|
|
@@ -341,7 +351,6 @@ function getMergeBase (baseBranch, sourceBranch) {
|
|
|
341
351
|
|
|
342
352
|
function getCounts (sourceBranch, candidateBranch) {
|
|
343
353
|
const counts = sanitizedExec(
|
|
344
|
-
'git',
|
|
345
354
|
['rev-list', '--left-right', '--count', `${candidateBranch}...${sourceBranch}`],
|
|
346
355
|
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'get_counts' } },
|
|
347
356
|
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'get_counts' } },
|
|
@@ -460,7 +469,6 @@ function generatePackFilesForCommits (commitsToUpload) {
|
|
|
460
469
|
|
|
461
470
|
function getRepositoryRoot () {
|
|
462
471
|
return sanitizedExec(
|
|
463
|
-
'git',
|
|
464
472
|
['rev-parse', '--show-toplevel']
|
|
465
473
|
)
|
|
466
474
|
}
|
|
@@ -477,6 +485,7 @@ function getGitMetadata (ciMetadata) {
|
|
|
477
485
|
authorEmail: ciAuthorEmail,
|
|
478
486
|
ciWorkspacePath,
|
|
479
487
|
headCommitSha,
|
|
488
|
+
pullRequestBaseBranchSha,
|
|
480
489
|
} = ciMetadata
|
|
481
490
|
|
|
482
491
|
// With stdio: 'pipe', errors in this command will not be output to the parent process,
|
|
@@ -488,19 +497,36 @@ function getGitMetadata (ciMetadata) {
|
|
|
488
497
|
committerName,
|
|
489
498
|
committerEmail,
|
|
490
499
|
committerDate,
|
|
491
|
-
] = sanitizedExec(
|
|
500
|
+
] = sanitizedExec(['show', '-s', '--format=%an,%ae,%aI,%cn,%ce,%cI']).split(',')
|
|
492
501
|
|
|
493
502
|
const tags = {
|
|
494
503
|
[GIT_COMMIT_MESSAGE]:
|
|
495
|
-
commitMessage || sanitizedExec(
|
|
496
|
-
[GIT_BRANCH]: branch || sanitizedExec(
|
|
497
|
-
[GIT_COMMIT_SHA]: commitSHA || sanitizedExec(
|
|
504
|
+
commitMessage || sanitizedExec(['show', '-s', '--format=%B'], null, null, null, false),
|
|
505
|
+
[GIT_BRANCH]: branch || sanitizedExec(['rev-parse', '--abbrev-ref', 'HEAD']),
|
|
506
|
+
[GIT_COMMIT_SHA]: commitSHA || sanitizedExec(['rev-parse', 'HEAD']),
|
|
498
507
|
[CI_WORKSPACE_PATH]: ciWorkspacePath || getRepositoryRoot(),
|
|
499
508
|
}
|
|
500
509
|
|
|
501
510
|
if (headCommitSha) {
|
|
502
|
-
|
|
503
|
-
|
|
511
|
+
const shallow = isShallowRepository(true)
|
|
512
|
+
const fetchedAtDepthOne = shallow && fetchHeadCommitSha(headCommitSha)
|
|
513
|
+
const headFlags = [
|
|
514
|
+
'show',
|
|
515
|
+
'-s',
|
|
516
|
+
'--format=\'%H","%aI","%an","%ae","%cI","%cn","%ce","%B\'',
|
|
517
|
+
headCommitSha,
|
|
518
|
+
]
|
|
519
|
+
// Only explicit, bounded fetches may contact the remote during head metadata recovery.
|
|
520
|
+
const headOptions = { uncached: true, localOnly: true }
|
|
521
|
+
let headInfo = sanitizedExec(headFlags, null, null, null, false, headOptions)
|
|
522
|
+
if (!headInfo && (fetchedAtDepthOne || !shallow)) {
|
|
523
|
+
fetchHeadCommitSha(headCommitSha, false)
|
|
524
|
+
headInfo = sanitizedExec(headFlags, null, null, null, false, headOptions)
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Prepare a known diff base while the remote is available, including when Git upload is disabled.
|
|
528
|
+
if (shallow && pullRequestBaseBranchSha && !hasLocalGitObject(pullRequestBaseBranchSha)) {
|
|
529
|
+
fetchHeadCommitSha(pullRequestBaseBranchSha)
|
|
504
530
|
}
|
|
505
531
|
|
|
506
532
|
const [
|
|
@@ -512,19 +538,7 @@ function getGitMetadata (ciMetadata) {
|
|
|
512
538
|
headCommitterName,
|
|
513
539
|
headCommitterEmail,
|
|
514
540
|
headCommitMessage,
|
|
515
|
-
] =
|
|
516
|
-
'git',
|
|
517
|
-
[
|
|
518
|
-
'show',
|
|
519
|
-
'-s',
|
|
520
|
-
'--format=\'%H","%aI","%an","%ae","%cI","%cn","%ce","%B\'',
|
|
521
|
-
headCommitSha,
|
|
522
|
-
],
|
|
523
|
-
null,
|
|
524
|
-
null,
|
|
525
|
-
null,
|
|
526
|
-
false
|
|
527
|
-
).split('","')
|
|
541
|
+
] = headInfo.split('","')
|
|
528
542
|
|
|
529
543
|
if (gitHeadCommitSha) {
|
|
530
544
|
tags[GIT_COMMIT_HEAD_AUTHOR_DATE] = headAuthorDate
|
|
@@ -539,7 +553,7 @@ function getGitMetadata (ciMetadata) {
|
|
|
539
553
|
|
|
540
554
|
const entries = [
|
|
541
555
|
GIT_REPOSITORY_URL,
|
|
542
|
-
filterSensitiveInfoFromRepository(repositoryUrl || sanitizedExec(
|
|
556
|
+
filterSensitiveInfoFromRepository(repositoryUrl || sanitizedExec(['ls-remote', '--get-url'])),
|
|
543
557
|
GIT_COMMIT_AUTHOR_DATE, authorDate,
|
|
544
558
|
GIT_COMMIT_AUTHOR_NAME, ciAuthorName || authorName,
|
|
545
559
|
GIT_COMMIT_AUTHOR_EMAIL, ciAuthorEmail || authorEmail,
|
|
@@ -563,7 +577,6 @@ function getGitInformationDiscrepancy () {
|
|
|
563
577
|
const gitRepositoryUrl = getRepositoryUrl()
|
|
564
578
|
|
|
565
579
|
const gitCommitSHA = sanitizedExec(
|
|
566
|
-
'git',
|
|
567
580
|
['rev-parse', 'HEAD'],
|
|
568
581
|
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'get_commit_sha' } },
|
|
569
582
|
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'get_commit_sha' } },
|
|
@@ -573,24 +586,51 @@ function getGitInformationDiscrepancy () {
|
|
|
573
586
|
return { gitRepositoryUrl, gitCommitSHA }
|
|
574
587
|
}
|
|
575
588
|
|
|
576
|
-
|
|
577
|
-
|
|
589
|
+
/** @param {string} sha */
|
|
590
|
+
function hasLocalGitObject (sha) {
|
|
591
|
+
return legacyStorage.run({ noop: true }, () => {
|
|
592
|
+
try {
|
|
593
|
+
execFileSync('git', ['cat-file', '-e', sha], {
|
|
594
|
+
stdio: 'pipe',
|
|
595
|
+
// Older Git versions ignore GIT_NO_LAZY_FETCH, so also disallow transports for this local-only probe.
|
|
596
|
+
env: { ...getEnvironmentVariables(), GIT_NO_LAZY_FETCH: '1', GIT_ALLOW_PROTOCOL: '' },
|
|
597
|
+
})
|
|
598
|
+
return true
|
|
599
|
+
} catch {
|
|
600
|
+
return false
|
|
601
|
+
}
|
|
602
|
+
})
|
|
603
|
+
}
|
|
578
604
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
605
|
+
function fetchHeadCommitSha (headSha, useDepth = true) {
|
|
606
|
+
const remoteName = getGitRemoteName()
|
|
607
|
+
// Existing heads retain the original repair/history behavior; a failed bounded fetch also retries that path.
|
|
608
|
+
const depths = useDepth && !hasLocalGitObject(headSha) ? [true, false] : [false]
|
|
609
|
+
for (const shallow of depths) {
|
|
610
|
+
try {
|
|
611
|
+
sanitizedExec(
|
|
612
|
+
[
|
|
613
|
+
'fetch',
|
|
614
|
+
...(shallow ? ['--depth=1'] : []),
|
|
615
|
+
'--update-shallow',
|
|
616
|
+
'--filter=blob:none',
|
|
617
|
+
'--recurse-submodules=no',
|
|
618
|
+
'--no-write-fetch-head',
|
|
619
|
+
remoteName,
|
|
620
|
+
headSha,
|
|
621
|
+
],
|
|
622
|
+
{ name: TELEMETRY_GIT_COMMAND, tags: { command: 'fetch_head_commit_sha' } },
|
|
623
|
+
{ name: TELEMETRY_GIT_COMMAND_MS, tags: { command: 'fetch_head_commit_sha' } },
|
|
624
|
+
{ name: TELEMETRY_GIT_COMMAND_ERRORS, tags: { command: 'fetch_head_commit_sha' } },
|
|
625
|
+
true,
|
|
626
|
+
{ uncached: true, throwOnError: true, timeout: 5000 }
|
|
627
|
+
)
|
|
628
|
+
return shallow
|
|
629
|
+
} catch {
|
|
630
|
+
// sanitizedExec records the failure; retry without a depth limit if the bounded fetch failed.
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
return false
|
|
594
634
|
}
|
|
595
635
|
|
|
596
636
|
module.exports = {
|
|
@@ -51,11 +51,7 @@ const supportedProxies = {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
function createInferredProxySpan (headers, childOf, tracer, reqCtx, traceCtx, config, startSpanHelper) {
|
|
54
|
-
if (!headers) {
|
|
55
|
-
return null
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (!tracer._config?.inferredProxyServicesEnabled) {
|
|
54
|
+
if (!headers || !tracer._config?.inferredProxyServicesEnabled) {
|
|
59
55
|
return null
|
|
60
56
|
}
|
|
61
57
|
|
|
@@ -12,8 +12,9 @@ const NODE_MODULES_PATTERN_START = `node_modules${sep}`
|
|
|
12
12
|
* current file path ends with the expected path structure from the repo root.
|
|
13
13
|
* This is needed for local and CI where dd-trace-js is not in node_modules.
|
|
14
14
|
* In production, these frames are already filtered by isNodeModulesFrame.
|
|
15
|
+
* Bundled into ESM output, `__filename` is not defined, and dd-trace is not running from its repo.
|
|
15
16
|
*/
|
|
16
|
-
const SHOULD_FILTER_DD_TRACE_INSTRUMENTAION = __filename.endsWith(
|
|
17
|
+
const SHOULD_FILTER_DD_TRACE_INSTRUMENTAION = typeof __filename === 'string' && __filename.endsWith(
|
|
17
18
|
join('packages', 'dd-trace', 'src', 'plugins', 'util', 'stacktrace.js')
|
|
18
19
|
)
|
|
19
20
|
|