dd-trace 5.108.0 → 5.110.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/init.js +4 -3
- package/index.d.ts +88 -25
- package/loader-hook.mjs +88 -2
- package/package.json +19 -14
- package/packages/datadog-esbuild/index.js +26 -0
- package/packages/datadog-esbuild/src/utils.js +46 -3
- package/packages/datadog-instrumentations/src/ai.js +43 -48
- package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js-context-methods.js +18 -0
- package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +111 -0
- package/packages/datadog-instrumentations/src/aws-sdk.js +3 -1
- package/packages/datadog-instrumentations/src/connect.js +4 -3
- package/packages/datadog-instrumentations/src/electron.js +1 -1
- package/packages/datadog-instrumentations/src/fastify.js +4 -12
- package/packages/datadog-instrumentations/src/graphql.js +17 -6
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +81 -8
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +27 -2
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +65 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +6 -4
- package/packages/datadog-instrumentations/src/helpers/require-optional-peer.js +17 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/aws-durable-execution-sdk-js.js +31 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +18 -2
- package/packages/datadog-instrumentations/src/http/client.js +12 -2
- package/packages/datadog-instrumentations/src/ioredis.js +0 -1
- package/packages/datadog-instrumentations/src/iovalkey.js +1 -2
- package/packages/datadog-instrumentations/src/koa.js +3 -2
- package/packages/datadog-instrumentations/src/mariadb.js +4 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +3 -3
- package/packages/datadog-instrumentations/src/next.js +44 -10
- package/packages/datadog-instrumentations/src/openai.js +77 -18
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +7 -6
- package/packages/datadog-instrumentations/src/playwright.js +1 -1
- package/packages/datadog-instrumentations/src/redis.js +0 -1
- package/packages/datadog-instrumentations/src/restify.js +4 -3
- package/packages/datadog-instrumentations/src/router.js +18 -5
- package/packages/datadog-instrumentations/src/selenium.js +1 -2
- package/packages/datadog-instrumentations/src/tedious.js +28 -0
- package/packages/datadog-instrumentations/src/vitest.js +323 -7
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +2 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/checkpoint.js +31 -0
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/client.js +55 -0
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +114 -0
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/handler.js +128 -0
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/index.js +19 -0
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +224 -0
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +43 -0
- package/packages/datadog-plugin-aws-sdk/src/base.js +14 -16
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +43 -6
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +100 -37
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +108 -99
- package/packages/datadog-plugin-bullmq/src/filter.js +35 -0
- package/packages/datadog-plugin-bullmq/src/producer.js +84 -4
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +9 -1
- package/packages/datadog-plugin-fs/src/index.js +1 -0
- package/packages/datadog-plugin-http/src/client.js +8 -3
- package/packages/datadog-plugin-http2/src/client.js +5 -2
- package/packages/datadog-plugin-mysql/src/index.js +7 -2
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +2 -2
- package/packages/datadog-plugin-redis/src/index.js +1 -2
- package/packages/datadog-plugin-undici/src/index.js +5 -2
- package/packages/datadog-plugin-vitest/src/index.js +11 -2
- package/packages/datadog-webpack/index.js +17 -1
- package/packages/datadog-webpack/src/optional-peer-loader.js +17 -0
- package/packages/dd-trace/src/aiguard/channels.js +0 -1
- package/packages/dd-trace/src/aiguard/index.js +11 -49
- package/packages/dd-trace/src/aiguard/integrations/evaluate.js +46 -0
- package/packages/dd-trace/src/aiguard/integrations/openai.js +66 -0
- package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +78 -0
- package/packages/{datadog-instrumentations/src/helpers/ai-messages.js → dd-trace/src/aiguard/messages/openai.js} +85 -193
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +185 -0
- package/packages/dd-trace/src/aiguard/sdk.js +13 -1
- package/packages/dd-trace/src/appsec/api_security/index.js +55 -0
- package/packages/dd-trace/src/appsec/api_security/sampler.js +147 -0
- package/packages/dd-trace/src/appsec/channels.js +1 -0
- package/packages/dd-trace/src/appsec/downstream_requests.js +111 -58
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +54 -12
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +5 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +29 -4
- package/packages/dd-trace/src/appsec/index.js +10 -6
- package/packages/dd-trace/src/appsec/rasp/ssrf.js +19 -11
- package/packages/dd-trace/src/appsec/reporter.js +1 -0
- package/packages/dd-trace/src/appsec/telemetry/api_security.js +34 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +26 -0
- package/packages/dd-trace/src/ci-visibility/requests/request.js +1 -17
- package/packages/dd-trace/src/config/defaults.js +22 -3
- package/packages/dd-trace/src/config/generated-config-types.d.ts +538 -1
- package/packages/dd-trace/src/config/helper.js +133 -33
- package/packages/dd-trace/src/config/index.js +4 -1
- package/packages/dd-trace/src/config/parsers.js +19 -1
- package/packages/dd-trace/src/config/supported-configurations.json +45 -5
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +49 -35
- package/packages/dd-trace/src/debugger/devtools_client/index.js +31 -66
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +83 -0
- package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -0
- package/packages/dd-trace/src/debugger/index.js +5 -0
- package/packages/dd-trace/src/debugger/probe_sampler.js +112 -0
- package/packages/dd-trace/src/debugger/probe_sampler_constants.js +19 -0
- package/packages/dd-trace/src/dogstatsd.js +15 -8
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +77 -26
- package/packages/dd-trace/src/exporters/agentless/index.js +7 -5
- package/packages/dd-trace/src/exporters/agentless/intake.js +43 -0
- package/packages/dd-trace/src/exporters/agentless/writer.js +5 -4
- package/packages/dd-trace/src/exporters/common/request.js +1 -20
- package/packages/dd-trace/src/exporters/common/url.js +34 -0
- package/packages/dd-trace/src/exporters/span-stats/writer.js +1 -3
- package/packages/dd-trace/src/guardrails/index.js +8 -5
- package/packages/dd-trace/src/index.js +6 -4
- package/packages/dd-trace/src/llmobs/constants/tags.js +6 -0
- package/packages/dd-trace/src/llmobs/index.js +16 -5
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +3 -3
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +5 -1
- package/packages/dd-trace/src/llmobs/sdk.js +5 -3
- package/packages/dd-trace/src/llmobs/span_processor.js +4 -0
- package/packages/dd-trace/src/llmobs/tagger.js +55 -0
- package/packages/dd-trace/src/llmobs/telemetry.js +1 -0
- package/packages/dd-trace/src/log/index.js +18 -20
- package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -1
- package/packages/dd-trace/src/opentelemetry/bridge-span-base.js +5 -4
- package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +2 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +4 -3
- package/packages/dd-trace/src/opentelemetry/metrics/time.js +19 -0
- package/packages/dd-trace/src/opentelemetry/otlp/common.proto +2 -2
- package/packages/dd-trace/src/opentelemetry/otlp/logs.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/logs_service.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/metrics.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/metrics_service.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +11 -4
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +29 -13
- package/packages/dd-trace/src/opentelemetry/span.js +14 -3
- package/packages/dd-trace/src/opentelemetry/span_context.js +1 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +2 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +3 -2
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +26 -13
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +3 -3
- package/packages/dd-trace/src/opentracing/span_context.js +17 -0
- package/packages/dd-trace/src/plugin_manager.js +7 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +36 -3
- package/packages/dd-trace/src/plugins/index.js +3 -0
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +276 -0
- package/packages/dd-trace/src/plugins/util/test.js +80 -0
- package/packages/dd-trace/src/plugins/util/url.js +68 -1
- package/packages/dd-trace/src/plugins/util/web.js +19 -36
- package/packages/dd-trace/src/priority_sampler.js +1 -13
- package/packages/dd-trace/src/profiling/config.js +129 -198
- package/packages/dd-trace/src/profiling/constants.js +4 -7
- package/packages/dd-trace/src/profiling/exporter_cli.js +10 -10
- package/packages/dd-trace/src/profiling/exporters/agent.js +23 -16
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +45 -14
- package/packages/dd-trace/src/profiling/exporters/file.js +16 -5
- package/packages/dd-trace/src/profiling/oom.js +71 -0
- package/packages/dd-trace/src/profiling/profiler.js +35 -23
- package/packages/dd-trace/src/profiling/profilers/events.js +14 -7
- package/packages/dd-trace/src/profiling/profilers/space.js +27 -18
- package/packages/dd-trace/src/profiling/profilers/wall.js +35 -25
- package/packages/dd-trace/src/ritm.js +4 -2
- package/packages/dd-trace/src/serverless.js +1 -2
- package/packages/dd-trace/src/service-naming/schemas/util.js +36 -5
- package/packages/dd-trace/src/service-naming/schemas/v0/serverless.js +12 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/serverless.js +12 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +5 -3
- package/packages/dd-trace/src/span_format.js +2 -1
- package/packages/dd-trace/src/span_processor.js +6 -0
- package/packages/dd-trace/src/telemetry/send-data.js +12 -10
- package/packages/dd-trace/src/tracer.js +15 -1
- package/packages/dd-trace/src/util.js +14 -0
- package/register.js +58 -1
- 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/pprof-format/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/openai-ai-guard.js +0 -284
- package/packages/dd-trace/src/appsec/api_security_sampler.js +0 -117
|
@@ -137,14 +137,17 @@ function normalizeLinkContext (context) {
|
|
|
137
137
|
* Mirrors `http.response.status_code` onto `http.status_code` (DD's special tag used by APM
|
|
138
138
|
* trace metrics and client-side stats); both names end up on the span.
|
|
139
139
|
*
|
|
140
|
+
* When OTel trace semantics are enabled, the behavior is disabled.
|
|
141
|
+
*
|
|
140
142
|
* @param {import('../opentracing/span')} ddSpan
|
|
141
143
|
* @param {string} key
|
|
142
144
|
* @param {unknown} value
|
|
145
|
+
* @param {boolean} [otelTraceSemanticsEnabled]
|
|
143
146
|
*/
|
|
144
|
-
function setOtelAttribute (ddSpan, key, value) {
|
|
147
|
+
function setOtelAttribute (ddSpan, key, value, otelTraceSemanticsEnabled) {
|
|
145
148
|
if (!isWritable(ddSpan)) return
|
|
146
149
|
|
|
147
|
-
if (key === 'http.response.status_code') {
|
|
150
|
+
if (!otelTraceSemanticsEnabled && key === 'http.response.status_code') {
|
|
148
151
|
ddSpan.setTag('http.status_code', String(value))
|
|
149
152
|
}
|
|
150
153
|
|
|
@@ -155,14 +158,17 @@ function setOtelAttribute (ddSpan, key, value) {
|
|
|
155
158
|
* Same `http.status_code` mirror as `setOtelAttribute`; does not mutate the caller's
|
|
156
159
|
* `attributes` object.
|
|
157
160
|
*
|
|
161
|
+
* When OTel trace semantics are enabled, the behavior is disabled.
|
|
162
|
+
*
|
|
158
163
|
* @param {import('../opentracing/span')} ddSpan
|
|
159
164
|
* @param {Record<string, unknown>} attributes
|
|
165
|
+
* @param {boolean} [otelTraceSemanticsEnabled]
|
|
160
166
|
*/
|
|
161
|
-
function setOtelAttributes (ddSpan, attributes) {
|
|
167
|
+
function setOtelAttributes (ddSpan, attributes, otelTraceSemanticsEnabled) {
|
|
162
168
|
if (!isWritable(ddSpan)) return
|
|
163
169
|
|
|
164
170
|
ddSpan.addTags(attributes)
|
|
165
|
-
if ('http.response.status_code' in attributes) {
|
|
171
|
+
if (!otelTraceSemanticsEnabled && 'http.response.status_code' in attributes) {
|
|
166
172
|
ddSpan.setTag('http.status_code', String(attributes['http.response.status_code']))
|
|
167
173
|
}
|
|
168
174
|
}
|
|
@@ -223,16 +229,19 @@ function addOtelEvent (ddSpan, name, attributesOrStartTime, startTime) {
|
|
|
223
229
|
* @param {import('../opentracing/span')} ddSpan
|
|
224
230
|
* @param {ExceptionLike} exception
|
|
225
231
|
* @param {TimeInput} [timeInput]
|
|
232
|
+
* @param {boolean} [otelTraceSemanticsEnabled]
|
|
226
233
|
*/
|
|
227
|
-
function recordException (ddSpan, exception, timeInput) {
|
|
234
|
+
function recordException (ddSpan, exception, timeInput, otelTraceSemanticsEnabled) {
|
|
228
235
|
if (!isWritable(ddSpan)) return
|
|
229
236
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
237
|
+
if (!otelTraceSemanticsEnabled) {
|
|
238
|
+
ddSpan.addTags({
|
|
239
|
+
[ERROR_TYPE]: exception.name,
|
|
240
|
+
[ERROR_MESSAGE]: exception.message,
|
|
241
|
+
[ERROR_STACK]: exception.stack,
|
|
242
|
+
[IGNORE_OTEL_ERROR]: ddSpan.context().getTag(IGNORE_OTEL_ERROR) ?? true,
|
|
243
|
+
})
|
|
244
|
+
}
|
|
236
245
|
|
|
237
246
|
const attributes = {}
|
|
238
247
|
if (exception.message) attributes['exception.message'] = exception.message
|
|
@@ -251,13 +260,20 @@ function recordException (ddSpan, exception, timeInput) {
|
|
|
251
260
|
* @param {import('../opentracing/span')} ddSpan
|
|
252
261
|
* @param {number} currentCode 0 = UNSET, 1 = OK, 2 = ERROR.
|
|
253
262
|
* @param {{ code?: number, message?: string }} [status]
|
|
263
|
+
* @param {boolean} [otelTraceSemanticsEnabled]
|
|
254
264
|
* @returns {number} The new status code to track on the caller.
|
|
255
265
|
*/
|
|
256
|
-
function applyOtelStatus (ddSpan, currentCode, status) {
|
|
266
|
+
function applyOtelStatus (ddSpan, currentCode, status, otelTraceSemanticsEnabled) {
|
|
257
267
|
if (!isWritable(ddSpan)) return currentCode
|
|
258
268
|
|
|
259
269
|
const code = status?.code
|
|
260
|
-
if (!code || currentCode === 1)
|
|
270
|
+
if (!code || currentCode === 1) {
|
|
271
|
+
if (otelTraceSemanticsEnabled) {
|
|
272
|
+
ddSpan.context().deleteTag(ERROR_MESSAGE)
|
|
273
|
+
ddSpan.context().deleteTag(IGNORE_OTEL_ERROR)
|
|
274
|
+
}
|
|
275
|
+
return currentCode
|
|
276
|
+
}
|
|
261
277
|
|
|
262
278
|
if (code === 2) {
|
|
263
279
|
ddSpan.addTags({
|
|
@@ -15,7 +15,7 @@ const kinds = require('../../../../ext/kinds')
|
|
|
15
15
|
const id = require('../id')
|
|
16
16
|
const BridgeSpanBase = require('./bridge-span-base')
|
|
17
17
|
const SpanContext = require('./span_context')
|
|
18
|
-
const { setOtelOperationName } = require('./span-helpers')
|
|
18
|
+
const { setOtelOperationName, setOtelResource } = require('./span-helpers')
|
|
19
19
|
|
|
20
20
|
const spanKindNames = {
|
|
21
21
|
[api.SpanKind.INTERNAL]: kinds.INTERNAL,
|
|
@@ -118,6 +118,8 @@ function spanNameMapper (spanName, kind, attributes) {
|
|
|
118
118
|
* surface; the underlying DD span carries the lifecycle.
|
|
119
119
|
*/
|
|
120
120
|
class Span extends BridgeSpanBase {
|
|
121
|
+
#otelName
|
|
122
|
+
|
|
121
123
|
/**
|
|
122
124
|
* @param {import('./tracer')} parentTracer
|
|
123
125
|
* @param {import('@opentelemetry/api').Context} context
|
|
@@ -159,12 +161,15 @@ class Span extends BridgeSpanBase {
|
|
|
159
161
|
|
|
160
162
|
super(ddSpan)
|
|
161
163
|
|
|
164
|
+
this._otelTraceSemanticsEnabled = _tracer._config.DD_TRACE_OTEL_SEMANTICS_ENABLED
|
|
165
|
+
|
|
162
166
|
if (attributes) {
|
|
163
167
|
this.setAttributes(attributes)
|
|
164
168
|
}
|
|
165
169
|
|
|
166
170
|
this._parentTracer = parentTracer
|
|
167
171
|
this._context = context
|
|
172
|
+
this.#otelName = spanName || this._ddSpan.context()._name
|
|
168
173
|
|
|
169
174
|
// NOTE: Need to grab the value before setting it on the span because the
|
|
170
175
|
// math for computing opentracing timestamps is apparently lossy...
|
|
@@ -192,7 +197,7 @@ class Span extends BridgeSpanBase {
|
|
|
192
197
|
}
|
|
193
198
|
|
|
194
199
|
get name () {
|
|
195
|
-
return this
|
|
200
|
+
return this.#otelName
|
|
196
201
|
}
|
|
197
202
|
|
|
198
203
|
spanContext () {
|
|
@@ -223,7 +228,13 @@ class Span extends BridgeSpanBase {
|
|
|
223
228
|
* @param {string} name
|
|
224
229
|
*/
|
|
225
230
|
updateName (name) {
|
|
226
|
-
|
|
231
|
+
if (this.ended) return this
|
|
232
|
+
this.#otelName = name
|
|
233
|
+
if (this._otelTraceSemanticsEnabled) {
|
|
234
|
+
setOtelResource(this._ddSpan, name)
|
|
235
|
+
} else {
|
|
236
|
+
setOtelOperationName(this._ddSpan, name)
|
|
237
|
+
}
|
|
227
238
|
return this
|
|
228
239
|
}
|
|
229
240
|
|
|
@@ -59,7 +59,8 @@ function createOtlpTraceExporter (config) {
|
|
|
59
59
|
config.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
|
|
60
60
|
config.OTEL_EXPORTER_OTLP_TRACES_HEADERS,
|
|
61
61
|
config.OTEL_EXPORTER_OTLP_TRACES_TIMEOUT,
|
|
62
|
-
buildResourceAttributes(config)
|
|
62
|
+
buildResourceAttributes(config),
|
|
63
|
+
config.DD_TRACE_OTEL_SEMANTICS_ENABLED
|
|
63
64
|
)
|
|
64
65
|
}
|
|
65
66
|
|
|
@@ -36,10 +36,11 @@ class OtlpHttpTraceExporter extends OtlpHttpExporterBase {
|
|
|
36
36
|
* corresponding `OTEL_EXPORTER_OTLP_*_HEADERS` env by the MAP parser.
|
|
37
37
|
* @param {number} timeout - Request timeout in milliseconds
|
|
38
38
|
* @param {import('@opentelemetry/api').Attributes} resourceAttributes - Resource attributes
|
|
39
|
+
* @param {boolean} otelTraceSemanticsEnabled - When true, do not emit Datadog-only attributes as span attributes
|
|
39
40
|
*/
|
|
40
|
-
constructor (url, headers, timeout, resourceAttributes) {
|
|
41
|
+
constructor (url, headers, timeout, resourceAttributes, otelTraceSemanticsEnabled) {
|
|
41
42
|
super(url, headers, timeout, 'http/json', 'traces')
|
|
42
|
-
this.#transformer = new OtlpTraceTransformer(resourceAttributes)
|
|
43
|
+
this.#transformer = new OtlpTraceTransformer(resourceAttributes, otelTraceSemanticsEnabled)
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
/**
|
|
@@ -74,6 +74,9 @@ const EXCLUDED_META_KEYS = new Set([
|
|
|
74
74
|
TRACE_ID_128,
|
|
75
75
|
])
|
|
76
76
|
|
|
77
|
+
// DD-only error tags that should not appear as attributes when OTel trace semantics are enabled.
|
|
78
|
+
const DD_ERROR_META_KEYS = new Set(['error.message'])
|
|
79
|
+
|
|
77
80
|
/**
|
|
78
81
|
* OtlpTraceTransformer transforms DD-formatted spans to OTLP trace JSON format.
|
|
79
82
|
*
|
|
@@ -87,13 +90,17 @@ const EXCLUDED_META_KEYS = new Set([
|
|
|
87
90
|
* @augments OtlpTransformerBase
|
|
88
91
|
*/
|
|
89
92
|
class OtlpTraceTransformer extends OtlpTransformerBase {
|
|
93
|
+
#otelTraceSemanticsEnabled
|
|
94
|
+
|
|
90
95
|
/**
|
|
91
96
|
* Creates a new OtlpTraceTransformer instance.
|
|
92
97
|
*
|
|
93
98
|
* @param {import('@opentelemetry/api').Attributes} resourceAttributes - Resource attributes
|
|
99
|
+
* @param {boolean} [otelTraceSemanticsEnabled] - When true, do not emit Datadog-only attributes as span attributes
|
|
94
100
|
*/
|
|
95
|
-
constructor (resourceAttributes) {
|
|
101
|
+
constructor (resourceAttributes, otelTraceSemanticsEnabled) {
|
|
96
102
|
super(resourceAttributes, 'http/json', 'traces')
|
|
103
|
+
this.#otelTraceSemanticsEnabled = otelTraceSemanticsEnabled
|
|
97
104
|
}
|
|
98
105
|
|
|
99
106
|
/**
|
|
@@ -184,24 +191,30 @@ class OtlpTraceTransformer extends OtlpTransformerBase {
|
|
|
184
191
|
#buildAttributes (span) {
|
|
185
192
|
const attributes = []
|
|
186
193
|
|
|
187
|
-
// Add top-level DD span fields as OTLP attributes
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
194
|
+
// Add top-level DD span fields as OTLP attributes.
|
|
195
|
+
// When OTel trace semantics are enabled, these Datadog-only concepts
|
|
196
|
+
// are not added to the span attributes so the output conforms to pure
|
|
197
|
+
// OpenTelemetry semantics.
|
|
198
|
+
if (!this.#otelTraceSemanticsEnabled) {
|
|
199
|
+
if (span.service) {
|
|
200
|
+
attributes.push({ key: 'service.name', value: { stringValue: span.service } })
|
|
201
|
+
}
|
|
202
|
+
if (span.name) {
|
|
203
|
+
attributes.push({ key: 'operation.name', value: { stringValue: span.name } })
|
|
204
|
+
}
|
|
205
|
+
if (span.resource) {
|
|
206
|
+
attributes.push({ key: 'resource.name', value: { stringValue: span.resource } })
|
|
207
|
+
}
|
|
208
|
+
if (span.type) {
|
|
209
|
+
attributes.push({ key: 'span.type', value: { stringValue: span.type } })
|
|
210
|
+
}
|
|
199
211
|
}
|
|
200
212
|
|
|
201
213
|
// Add meta string tags, skipping keys that map to dedicated OTLP fields
|
|
202
214
|
if (span.meta) {
|
|
203
215
|
for (const [key, value] of Object.entries(span.meta)) {
|
|
204
216
|
if (EXCLUDED_META_KEYS.has(key)) continue
|
|
217
|
+
if (this.#otelTraceSemanticsEnabled && DD_ERROR_META_KEYS.has(key)) continue
|
|
205
218
|
attributes.push({ key, value: { stringValue: value } })
|
|
206
219
|
}
|
|
207
220
|
}
|
|
@@ -371,8 +371,8 @@ class TextMapPropagator {
|
|
|
371
371
|
|
|
372
372
|
_hasTraceIdConflict (w3cSpanContext, firstSpanContext) {
|
|
373
373
|
return w3cSpanContext !== undefined &&
|
|
374
|
-
|
|
375
|
-
|
|
374
|
+
firstSpanContext.toTraceId(true) === w3cSpanContext.toTraceId(true) &&
|
|
375
|
+
firstSpanContext.toSpanId() !== w3cSpanContext.toSpanId()
|
|
376
376
|
}
|
|
377
377
|
|
|
378
378
|
_hasParentIdInTags (spanContext) {
|
|
@@ -875,7 +875,7 @@ class TextMapPropagator {
|
|
|
875
875
|
(!tracestateSamplingPriority || tracestateSamplingPriority >= 0)) {
|
|
876
876
|
samplingPriority = AUTO_REJECT
|
|
877
877
|
} else if (traceparentSampled === 1 &&
|
|
878
|
-
|
|
878
|
+
(!tracestateSamplingPriority || tracestateSamplingPriority < 0)) {
|
|
879
879
|
samplingPriority = AUTO_KEEP
|
|
880
880
|
}
|
|
881
881
|
}
|
|
@@ -63,6 +63,7 @@ class DatadogSpanContext {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
toTraceparent () {
|
|
66
|
+
this._ensureSamplingPriority()
|
|
66
67
|
const flags = this._sampling.priority >= AUTO_KEEP ? '01' : '00'
|
|
67
68
|
const traceId = this.toTraceId(true)
|
|
68
69
|
const spanId = this.toSpanId(true)
|
|
@@ -70,6 +71,22 @@ class DatadogSpanContext {
|
|
|
70
71
|
return `${version}-${traceId}-${spanId}-${flags}`
|
|
71
72
|
}
|
|
72
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Materialize the lazy priority-sampling decision for this trace, the same
|
|
76
|
+
* way {@link DatadogTracer#inject} does before propagation. The auto priority
|
|
77
|
+
* is otherwise computed at flush time, so the W3C sampled flag reads "drop"
|
|
78
|
+
* for a freshly started, not-yet-flushed span — see
|
|
79
|
+
* https://github.com/DataDog/dd-trace-js/issues/2547.
|
|
80
|
+
*
|
|
81
|
+
* The root span is only used to reach the priority sampler; `this` is passed
|
|
82
|
+
* to `sample()` so a manual sampling tag set directly on this context is
|
|
83
|
+
* honored, matching what `inject(this)` would decide.
|
|
84
|
+
*/
|
|
85
|
+
_ensureSamplingPriority () {
|
|
86
|
+
if (this._sampling.priority !== undefined) return
|
|
87
|
+
this._trace.started[0]?._prioritySampler?.sample(this)
|
|
88
|
+
}
|
|
89
|
+
|
|
73
90
|
/**
|
|
74
91
|
* Set a tag value.
|
|
75
92
|
* @param {string} key - Tag key
|
|
@@ -60,7 +60,11 @@ function maybeEnable (Plugin) {
|
|
|
60
60
|
|
|
61
61
|
function getEnabled (Plugin) {
|
|
62
62
|
const envName = `DD_TRACE_${Plugin.id.toUpperCase()}_ENABLED`
|
|
63
|
-
|
|
63
|
+
// skipDefault: only an explicitly configured value should drive enablement here. A registered
|
|
64
|
+
// default of `false` (e.g. an experimental plugin like `nats`) must not be read as an explicit
|
|
65
|
+
// "disabled via configuration option" — that path both logs a misleading line and nulls the
|
|
66
|
+
// plugin class, bypassing the experimental opt-in handled by `loadPlugin`.
|
|
67
|
+
return getValueFromEnvSources(normalizePluginEnvName(envName), true)
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
// TODO this must always be a singleton.
|
|
@@ -164,6 +168,7 @@ module.exports = class PluginManager {
|
|
|
164
168
|
clientIpEnabled,
|
|
165
169
|
clientIpHeader,
|
|
166
170
|
DD_TRACE_MEMCACHED_COMMAND_ENABLED,
|
|
171
|
+
DD_TRACE_OTEL_SEMANTICS_ENABLED,
|
|
167
172
|
DD_TEST_SESSION_NAME,
|
|
168
173
|
DD_AGENTLESS_LOG_SUBMISSION_ENABLED,
|
|
169
174
|
isTestDynamicInstrumentationEnabled,
|
|
@@ -181,6 +186,7 @@ module.exports = class PluginManager {
|
|
|
181
186
|
dbmPropagationMode,
|
|
182
187
|
dsmEnabled,
|
|
183
188
|
DD_TRACE_MEMCACHED_COMMAND_ENABLED,
|
|
189
|
+
DD_TRACE_OTEL_SEMANTICS_ENABLED,
|
|
184
190
|
site,
|
|
185
191
|
url,
|
|
186
192
|
headers: headerTags || [],
|
|
@@ -31,6 +31,7 @@ const Plugin = require('./plugin')
|
|
|
31
31
|
const { getRepositoryRoot } = require('./util/git')
|
|
32
32
|
const {
|
|
33
33
|
getTestEnvironmentMetadata,
|
|
34
|
+
getTestLevelsMetadataTags,
|
|
34
35
|
getTestSessionName,
|
|
35
36
|
getCodeOwnersFileEntries,
|
|
36
37
|
getTestParentSpan,
|
|
@@ -44,6 +45,7 @@ const {
|
|
|
44
45
|
TEST_MODULE_ID,
|
|
45
46
|
TEST_SESSION_ID,
|
|
46
47
|
TEST_COMMAND,
|
|
48
|
+
TEST_LEVELS_METADATA,
|
|
47
49
|
TEST_MODULE,
|
|
48
50
|
TEST_SESSION_NAME,
|
|
49
51
|
getTestSuiteCommonTags,
|
|
@@ -219,7 +221,13 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
219
221
|
this.testEnvironmentMetadata
|
|
220
222
|
)
|
|
221
223
|
|
|
222
|
-
const metadataTags = {
|
|
224
|
+
const metadataTags = {
|
|
225
|
+
[TEST_LEVELS_METADATA]: {
|
|
226
|
+
[TEST_COMMAND]: command,
|
|
227
|
+
[TEST_SESSION_NAME]: testSessionName,
|
|
228
|
+
...getTestLevelsMetadataTags(this.testEnvironmentMetadata),
|
|
229
|
+
},
|
|
230
|
+
}
|
|
223
231
|
// tracer might not be initialized correctly
|
|
224
232
|
if (this.tracer._exporter.addMetadataTags) {
|
|
225
233
|
this.tracer._exporter.addMetadataTags(metadataTags)
|
|
@@ -442,6 +450,28 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
442
450
|
}
|
|
443
451
|
}
|
|
444
452
|
|
|
453
|
+
/**
|
|
454
|
+
* Updates repository-root-dependent state when a worker receives the root from
|
|
455
|
+
* the coordinator process after plugin configuration.
|
|
456
|
+
*
|
|
457
|
+
* @param {string|undefined} repositoryRoot - Repository root discovered by the coordinator process.
|
|
458
|
+
* @param {Array<{ pattern: string, owners: string[] }>|null|undefined} codeOwnersEntries
|
|
459
|
+
* Parsed CODEOWNERS entries discovered by the coordinator process.
|
|
460
|
+
* @returns {void}
|
|
461
|
+
*/
|
|
462
|
+
_setRepositoryRoot (repositoryRoot, codeOwnersEntries) {
|
|
463
|
+
if (codeOwnersEntries !== undefined) {
|
|
464
|
+
this.codeOwnersEntries = codeOwnersEntries
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (!repositoryRoot || repositoryRoot === this.repositoryRoot) return
|
|
468
|
+
|
|
469
|
+
this.repositoryRoot = repositoryRoot
|
|
470
|
+
if (codeOwnersEntries === undefined) {
|
|
471
|
+
this.codeOwnersEntries = getCodeOwnersFileEntries(this.repositoryRoot)
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
445
475
|
/**
|
|
446
476
|
* Returns request error tags from the test session span for propagation to module, suite and test spans.
|
|
447
477
|
* @returns {Record<string, string>}
|
|
@@ -610,6 +640,8 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
610
640
|
const workerTestFramework = WORKER_EXPORTER_TO_TEST_FRAMEWORK[exporter]
|
|
611
641
|
this.shouldSkipGitMetadataExtraction = workerTestFramework &&
|
|
612
642
|
TEST_FRAMEWORKS_TO_SKIP_GIT_METADATA_EXTRACTION.has(workerTestFramework)
|
|
643
|
+
const shouldDeferCodeOwnersEntries = workerTestFramework === 'vitest'
|
|
644
|
+
const shouldDeferRepositoryRoot = workerTestFramework === 'vitest'
|
|
613
645
|
|
|
614
646
|
this.testEnvironmentMetadata = getTestEnvironmentMetadata(
|
|
615
647
|
this.constructor.id,
|
|
@@ -635,9 +667,10 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
635
667
|
[GIT_COMMIT_HEAD_MESSAGE]: commitHeadMessage,
|
|
636
668
|
} = this.testEnvironmentMetadata
|
|
637
669
|
|
|
638
|
-
this.repositoryRoot = repositoryRoot ||
|
|
670
|
+
this.repositoryRoot = repositoryRoot ||
|
|
671
|
+
(shouldDeferRepositoryRoot ? process.cwd() : getRepositoryRoot() || process.cwd())
|
|
639
672
|
|
|
640
|
-
this.codeOwnersEntries = getCodeOwnersFileEntries(this.repositoryRoot)
|
|
673
|
+
this.codeOwnersEntries = shouldDeferCodeOwnersEntries ? null : getCodeOwnersFileEntries(this.repositoryRoot)
|
|
641
674
|
|
|
642
675
|
this.ciProviderName = ciProviderName
|
|
643
676
|
|
|
@@ -8,6 +8,7 @@ const plugins = {
|
|
|
8
8
|
get '@azure/event-hubs' () { return require('../../../datadog-plugin-azure-event-hubs/src') },
|
|
9
9
|
get '@azure/functions' () { return require('../../../datadog-plugin-azure-functions/src') },
|
|
10
10
|
get '@modelcontextprotocol/sdk' () { return require('../../../datadog-plugin-modelcontextprotocol-sdk/src') },
|
|
11
|
+
get '@aws/durable-execution-sdk-js' () { return require('../../../datadog-plugin-aws-durable-execution-sdk-js/src') },
|
|
11
12
|
get 'durable-functions' () { return require('../../../datadog-plugin-azure-durable-functions/src') },
|
|
12
13
|
get '@azure/service-bus' () { return require('../../../datadog-plugin-azure-service-bus/src') },
|
|
13
14
|
get '@cucumber/cucumber' () { return require('../../../datadog-plugin-cucumber/src') },
|
|
@@ -55,6 +56,7 @@ const plugins = {
|
|
|
55
56
|
get express () { return require('../../../datadog-plugin-express/src') },
|
|
56
57
|
get fastify () { return require('../../../datadog-plugin-fastify/src') },
|
|
57
58
|
get 'find-my-way' () { return require('../../../datadog-plugin-find-my-way/src') },
|
|
59
|
+
get fs () { return require('../../../datadog-plugin-fs/src') },
|
|
58
60
|
get 'global:fetch' () { return require('../../../datadog-plugin-fetch/src') },
|
|
59
61
|
get graphql () { return require('../../../datadog-plugin-graphql/src') },
|
|
60
62
|
get grpc () { return require('../../../datadog-plugin-grpc/src') },
|
|
@@ -97,6 +99,7 @@ const plugins = {
|
|
|
97
99
|
get net () { return require('../../../datadog-plugin-net/src') },
|
|
98
100
|
get next () { return require('../../../datadog-plugin-next/src') },
|
|
99
101
|
get 'node:dns' () { return require('../../../datadog-plugin-dns/src') },
|
|
102
|
+
get 'node:fs' () { return require('../../../datadog-plugin-fs/src') },
|
|
100
103
|
get 'node:http' () { return require('../../../datadog-plugin-http/src') },
|
|
101
104
|
get 'node:http2' () { return require('../../../datadog-plugin-http2/src') },
|
|
102
105
|
get 'node:https' () { return require('../../../datadog-plugin-http/src') },
|