dd-trace 6.0.0 → 6.2.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/LICENSE-3rdparty.csv +1 -2
- package/index.d.ts +28 -1
- package/initialize.mjs +4 -2
- package/package.json +34 -30
- package/packages/datadog-instrumentations/src/ai.js +45 -0
- package/packages/datadog-instrumentations/src/apollo-server.js +5 -13
- package/packages/datadog-instrumentations/src/child_process.js +3 -3
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +587 -0
- package/packages/datadog-instrumentations/src/cucumber.js +102 -43
- package/packages/datadog-instrumentations/src/cypress-config.js +11 -3
- package/packages/datadog-instrumentations/src/fastify.js +27 -8
- package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +7 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +5 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/ai.js +6 -6
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/claude-agent-sdk.js +17 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/mercurius.js +31 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +19 -5
- package/packages/datadog-instrumentations/src/jest.js +713 -63
- package/packages/datadog-instrumentations/src/mercurius.js +11 -0
- package/packages/datadog-instrumentations/src/mocha/main.js +24 -3
- package/packages/datadog-instrumentations/src/mocha/utils.js +128 -22
- package/packages/datadog-instrumentations/src/mocha/worker.js +13 -0
- package/packages/datadog-instrumentations/src/mongodb.js +74 -0
- package/packages/datadog-instrumentations/src/mongoose.js +4 -5
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +15 -0
- package/packages/datadog-instrumentations/src/playwright.js +13 -9
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +4 -0
- package/packages/datadog-instrumentations/src/vitest-main.js +26 -1
- package/packages/datadog-instrumentations/src/vitest-util.js +2 -0
- package/packages/datadog-instrumentations/src/vitest-worker.js +103 -34
- package/packages/datadog-plugin-ai/src/index.js +1 -1
- package/packages/datadog-plugin-ai/src/tracing.js +66 -3
- package/packages/datadog-plugin-ai/src/utils.js +17 -4
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +1 -0
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/handler.js +1 -0
- package/packages/datadog-plugin-child_process/src/index.js +13 -2
- package/packages/datadog-plugin-claude-agent-sdk/src/index.js +31 -0
- package/packages/datadog-plugin-claude-agent-sdk/src/tracing.js +107 -0
- package/packages/datadog-plugin-claude-agent-sdk/src/util.js +15 -0
- package/packages/datadog-plugin-cucumber/src/index.js +14 -23
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +351 -11
- package/packages/datadog-plugin-cypress/src/index.js +47 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +1 -0
- package/packages/datadog-plugin-graphql/src/execute.js +25 -25
- package/packages/datadog-plugin-graphql/src/index.js +23 -1
- package/packages/datadog-plugin-graphql/src/request.js +104 -0
- package/packages/datadog-plugin-graphql/src/utils.js +186 -2
- package/packages/datadog-plugin-graphql/src/validate.js +25 -2
- package/packages/datadog-plugin-jest/src/index.js +30 -14
- package/packages/datadog-plugin-mocha/src/index.js +39 -14
- package/packages/datadog-plugin-mongodb-core/src/bulk-write.js +43 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +8 -443
- package/packages/datadog-plugin-mongodb-core/src/query.js +452 -0
- package/packages/datadog-plugin-playwright/src/index.js +3 -2
- package/packages/datadog-plugin-vitest/src/index.js +43 -9
- package/packages/dd-trace/src/aiguard/index.js +9 -14
- package/packages/dd-trace/src/aiguard/integrations/index.js +34 -0
- package/packages/dd-trace/src/aiguard/integrations/openai.js +47 -33
- package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +42 -28
- package/packages/dd-trace/src/appsec/graphql.js +9 -6
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +3 -10
- package/packages/dd-trace/src/appsec/lambda.js +8 -8
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +26 -1
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +115 -24
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +3 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +3 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +75 -7
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +156 -0
- package/packages/dd-trace/src/config/generated-config-types.d.ts +10 -0
- package/packages/dd-trace/src/config/supported-configurations.json +37 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +2 -2
- package/packages/dd-trace/src/datastreams/writer.js +14 -2
- package/packages/dd-trace/src/encode/0.4.js +23 -2
- package/packages/dd-trace/src/encode/0.5.js +12 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +11 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +20 -2
- package/packages/dd-trace/src/exporters/common/writer.js +17 -1
- package/packages/dd-trace/src/guardrails/index.js +3 -1
- package/packages/dd-trace/src/guardrails/telemetry.js +40 -3
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +403 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +8 -395
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +27 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +363 -0
- package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/index.js +270 -0
- package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/utils.js +10 -0
- package/packages/dd-trace/src/msgpack/chunk.js +33 -1
- package/packages/dd-trace/src/msgpack/index.js +6 -1
- package/packages/dd-trace/src/opentelemetry/span.js +5 -0
- package/packages/dd-trace/src/plugin_manager.js +16 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +147 -7
- package/packages/dd-trace/src/plugins/index.js +5 -0
- package/packages/dd-trace/src/plugins/util/test.js +4 -0
- package/packages/dd-trace/src/profiling/exporters/agent.js +28 -3
- package/packages/dd-trace/src/service-naming/schemas/v0/graphql.js +6 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/graphql.js +8 -0
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +5 -6
|
@@ -152,6 +152,11 @@ class Span extends BridgeSpanBase {
|
|
|
152
152
|
hostname: _tracer._hostname,
|
|
153
153
|
integrationName: parentTracer?._isOtelLibrary ? 'otel.library' : 'otel',
|
|
154
154
|
tags: {
|
|
155
|
+
// Apply global/resource tags (DD_TAGS, OTEL_RESOURCE_ATTRIBUTES) as
|
|
156
|
+
// defaults, mirroring the native path in opentracing/tracer.js. The
|
|
157
|
+
// explicit service/resource/span.kind below take precedence, and any
|
|
158
|
+
// user-set OTel attributes applied via setAttributes() still win.
|
|
159
|
+
..._tracer._config.tags,
|
|
155
160
|
[SERVICE_NAME]: _tracer._service,
|
|
156
161
|
[RESOURCE_NAME]: spanName,
|
|
157
162
|
[SPAN_KIND]: spanKindNames[kind],
|
|
@@ -169,6 +169,10 @@ module.exports = class PluginManager {
|
|
|
169
169
|
clientIpHeader,
|
|
170
170
|
DD_TRACE_MEMCACHED_COMMAND_ENABLED,
|
|
171
171
|
DD_TRACE_OTEL_SEMANTICS_ENABLED,
|
|
172
|
+
DD_TRACE_GRAPHQL_COLLAPSE,
|
|
173
|
+
DD_TRACE_GRAPHQL_DEPTH,
|
|
174
|
+
DD_TRACE_GRAPHQL_VARIABLES,
|
|
175
|
+
DD_TRACE_GRAPHQL_ERROR_EXTENSIONS,
|
|
172
176
|
DD_TEST_SESSION_NAME,
|
|
173
177
|
DD_AGENTLESS_LOG_SUBMISSION_ENABLED,
|
|
174
178
|
testOptimization,
|
|
@@ -225,6 +229,18 @@ module.exports = class PluginManager {
|
|
|
225
229
|
sharedConfig.middleware = middlewareTracingEnabled
|
|
226
230
|
}
|
|
227
231
|
|
|
232
|
+
// The graphql `DD_TRACE_GRAPHQL_*` options are global on purpose: they feed
|
|
233
|
+
// the plugin config as a base that a programmatic `tracer.use('graphql', …)`
|
|
234
|
+
// overrides, and stay on the Config singleton so remote config and config
|
|
235
|
+
// telemetry observe them. Forwarded only for graphql so other plugins do not
|
|
236
|
+
// carry keys they ignore. The plugin-facing names drop the prefix.
|
|
237
|
+
if (name === 'graphql') {
|
|
238
|
+
sharedConfig.collapse = DD_TRACE_GRAPHQL_COLLAPSE
|
|
239
|
+
sharedConfig.depth = DD_TRACE_GRAPHQL_DEPTH
|
|
240
|
+
sharedConfig.variables = DD_TRACE_GRAPHQL_VARIABLES
|
|
241
|
+
sharedConfig.errorExtensions = DD_TRACE_GRAPHQL_ERROR_EXTENSIONS
|
|
242
|
+
}
|
|
243
|
+
|
|
228
244
|
return sharedConfig
|
|
229
245
|
}
|
|
230
246
|
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// Capture real timers at module load time, before any test can install fake timers.
|
|
4
|
+
const realSetTimeout = setTimeout
|
|
5
|
+
const realClearTimeout = clearTimeout
|
|
6
|
+
|
|
7
|
+
const { threadId } = require('node:worker_threads')
|
|
8
|
+
|
|
3
9
|
const { storage } = require('../../../datadog-core')
|
|
4
10
|
const { COMPONENT } = require('../constants')
|
|
5
11
|
const log = require('../log')
|
|
@@ -12,6 +18,7 @@ const {
|
|
|
12
18
|
} = require('../ci-visibility/telemetry')
|
|
13
19
|
const getDiClient = require('../ci-visibility/dynamic-instrumentation')
|
|
14
20
|
const { DD_MAJOR } = require('../../../../version')
|
|
21
|
+
const { version: tracerVersion } = require('../../../../package.json')
|
|
15
22
|
const id = require('../id')
|
|
16
23
|
const { OS_VERSION, OS_PLATFORM, OS_ARCHITECTURE, RUNTIME_NAME, RUNTIME_VERSION } = require('./util/env')
|
|
17
24
|
const {
|
|
@@ -84,6 +91,9 @@ const {
|
|
|
84
91
|
} = require('./util/test')
|
|
85
92
|
|
|
86
93
|
const legacyStorage = storage('legacy')
|
|
94
|
+
const DI_OPERATION_TIMEOUT_MS = 2000
|
|
95
|
+
const DI_LOGGER_THREAD_ID = threadId === 0 ? `pid:${process.pid}` : `pid:${process.pid};tid:${threadId}`
|
|
96
|
+
const DI_LOGGER_THREAD_NAME = threadId === 0 ? 'MainThread' : `WorkerThread:${threadId}`
|
|
87
97
|
|
|
88
98
|
const FRAMEWORK_TO_TRIMMED_COMMAND = {
|
|
89
99
|
vitest: 'vitest run',
|
|
@@ -108,6 +118,18 @@ const TEST_FRAMEWORKS_TO_SKIP_GIT_METADATA_EXTRACTION = new Set([
|
|
|
108
118
|
'cucumber',
|
|
109
119
|
])
|
|
110
120
|
|
|
121
|
+
function withTimeout (promise, timeoutMs) {
|
|
122
|
+
return new Promise(resolve => {
|
|
123
|
+
const timeoutId = realSetTimeout(resolve, timeoutMs)
|
|
124
|
+
|
|
125
|
+
const done = () => {
|
|
126
|
+
realClearTimeout(timeoutId)
|
|
127
|
+
resolve()
|
|
128
|
+
}
|
|
129
|
+
promise.then(done, done)
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
|
|
111
133
|
function setItrSkippingEnabledTagFromLibraryConfig (plugin, frameworkVersion) {
|
|
112
134
|
const libraryCapabilitiesTags = getDefaultLibraryCapabilitiesTags(plugin.constructor.id, frameworkVersion)
|
|
113
135
|
|
|
@@ -143,6 +165,8 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
143
165
|
super(...args)
|
|
144
166
|
|
|
145
167
|
this.fileLineToProbeId = new Map()
|
|
168
|
+
this.diBreakpointHitPromise = undefined
|
|
169
|
+
this.diBreakpointHitResolvers = []
|
|
146
170
|
this.rootDir = process.cwd() // fallback in case :session:start events are not emitted
|
|
147
171
|
this._testSuiteSpansByTestSuite = new Map()
|
|
148
172
|
this._pendingWorkerTracesByTestSuite = new Map()
|
|
@@ -164,10 +188,6 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
164
188
|
setItrSkippingEnabledTagFromLibraryConfig(this, frameworkVersion)
|
|
165
189
|
}
|
|
166
190
|
|
|
167
|
-
const requestErrorTags = this.testSessionSpan
|
|
168
|
-
? getSessionRequestErrorTags(this.testSessionSpan)
|
|
169
|
-
: Object.fromEntries(this._pendingRequestErrorTags.map(({ tag, value }) => [tag, value]))
|
|
170
|
-
|
|
171
191
|
const libraryCapabilitiesTags = this.getLibraryCapabilitiesTags(frameworkVersion, ctx)
|
|
172
192
|
const metadataTags = {
|
|
173
193
|
test: {
|
|
@@ -175,7 +195,13 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
175
195
|
},
|
|
176
196
|
}
|
|
177
197
|
this.tracer._exporter.addMetadataTags(metadataTags)
|
|
178
|
-
onDone({
|
|
198
|
+
onDone({
|
|
199
|
+
err,
|
|
200
|
+
isTestDynamicInstrumentationEnabled: this.config.isTestDynamicInstrumentationEnabled,
|
|
201
|
+
libraryConfig,
|
|
202
|
+
repositoryRoot: this.repositoryRoot,
|
|
203
|
+
requestErrorTags: this._getCurrentRequestErrorTags(),
|
|
204
|
+
})
|
|
179
205
|
})
|
|
180
206
|
})
|
|
181
207
|
|
|
@@ -307,7 +333,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
307
333
|
this.libraryConfig.isKnownTestsEnabled = false
|
|
308
334
|
}
|
|
309
335
|
}
|
|
310
|
-
onDone({ err, knownTests })
|
|
336
|
+
onDone({ err, knownTests, requestErrorTags: this._getCurrentRequestErrorTags() })
|
|
311
337
|
})
|
|
312
338
|
})
|
|
313
339
|
|
|
@@ -327,7 +353,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
327
353
|
this.libraryConfig.isTestManagementEnabled = false
|
|
328
354
|
}
|
|
329
355
|
}
|
|
330
|
-
onDone({ err, testManagementTests })
|
|
356
|
+
onDone({ err, testManagementTests, requestErrorTags: this._getCurrentRequestErrorTags() })
|
|
331
357
|
})
|
|
332
358
|
})
|
|
333
359
|
|
|
@@ -459,6 +485,18 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
459
485
|
}
|
|
460
486
|
}
|
|
461
487
|
|
|
488
|
+
/**
|
|
489
|
+
* Returns the current request error tags, including tags queued before session creation.
|
|
490
|
+
*
|
|
491
|
+
* @returns {Record<string, string>}
|
|
492
|
+
*/
|
|
493
|
+
_getCurrentRequestErrorTags () {
|
|
494
|
+
if (this.testSessionSpan) {
|
|
495
|
+
return getSessionRequestErrorTags(this.testSessionSpan)
|
|
496
|
+
}
|
|
497
|
+
return Object.fromEntries(this._pendingRequestErrorTags.map(({ tag, value }) => [tag, value]))
|
|
498
|
+
}
|
|
499
|
+
|
|
462
500
|
/**
|
|
463
501
|
* Updates repository-root-dependent state when a worker receives the root from
|
|
464
502
|
* the coordinator process after plugin configuration.
|
|
@@ -776,6 +814,11 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
776
814
|
}
|
|
777
815
|
|
|
778
816
|
onDiBreakpointHit ({ snapshot }) {
|
|
817
|
+
for (const resolve of this.diBreakpointHitResolvers) {
|
|
818
|
+
resolve()
|
|
819
|
+
}
|
|
820
|
+
this.diBreakpointHitResolvers.length = 0
|
|
821
|
+
|
|
779
822
|
if (!this.activeTestSpan || this.activeTestSpan.context()._isFinished) {
|
|
780
823
|
// This is unexpected and is caused by a race condition.
|
|
781
824
|
log.warn('Breakpoint snapshot could not be attached to the active test span')
|
|
@@ -799,8 +842,17 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
799
842
|
)
|
|
800
843
|
|
|
801
844
|
const activeTestSpanContext = this.activeTestSpan.context()
|
|
845
|
+
const topStackFrame = snapshot.stack?.[0]
|
|
802
846
|
|
|
803
847
|
this.tracer._exporter.exportDiLogs(this.testEnvironmentMetadata, {
|
|
848
|
+
message: '',
|
|
849
|
+
logger: {
|
|
850
|
+
name: snapshot.probe.location.file,
|
|
851
|
+
method: topStackFrame?.function || '',
|
|
852
|
+
version: tracerVersion,
|
|
853
|
+
thread_id: DI_LOGGER_THREAD_ID,
|
|
854
|
+
thread_name: DI_LOGGER_THREAD_NAME,
|
|
855
|
+
},
|
|
804
856
|
debugger: { snapshot },
|
|
805
857
|
dd: {
|
|
806
858
|
trace_id: activeTestSpanContext.toTraceId(),
|
|
@@ -809,6 +861,94 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
809
861
|
})
|
|
810
862
|
}
|
|
811
863
|
|
|
864
|
+
/**
|
|
865
|
+
* Wait for a Dynamic Instrumentation operation without blocking test framework progress forever.
|
|
866
|
+
*
|
|
867
|
+
* @param {Promise<void>} promise - Dynamic Instrumentation operation promise.
|
|
868
|
+
* @returns {Promise<void>}
|
|
869
|
+
*/
|
|
870
|
+
waitForDiOperation (promise) {
|
|
871
|
+
return withTimeout(promise, DI_OPERATION_TIMEOUT_MS)
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
* Resolve any prepared breakpoint-hit wait when no caller still needs it.
|
|
876
|
+
*/
|
|
877
|
+
cancelDiBreakpointHitWait () {
|
|
878
|
+
for (const resolve of this.diBreakpointHitResolvers) {
|
|
879
|
+
resolve()
|
|
880
|
+
}
|
|
881
|
+
this.diBreakpointHitResolvers.length = 0
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Wait for a prepared breakpoint hit before resolving any unused waiters.
|
|
886
|
+
*
|
|
887
|
+
* @returns {Promise<void>}
|
|
888
|
+
*/
|
|
889
|
+
waitForPreparedDiBreakpointHit () {
|
|
890
|
+
if (!this.diBreakpointHitPromise) {
|
|
891
|
+
this.cancelDiBreakpointHitWait()
|
|
892
|
+
return Promise.resolve()
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
return this.waitForDiOperation(this.diBreakpointHitPromise).then(
|
|
896
|
+
() => this.cancelDiBreakpointHitWait(),
|
|
897
|
+
() => this.cancelDiBreakpointHitWait()
|
|
898
|
+
)
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* Prepare a wait for the next breakpoint hit before the retried test starts.
|
|
903
|
+
*
|
|
904
|
+
* @returns {Promise<void>}
|
|
905
|
+
*/
|
|
906
|
+
prepareDiBreakpointHitWait () {
|
|
907
|
+
if (!this.di) return Promise.resolve()
|
|
908
|
+
|
|
909
|
+
let resolveHit
|
|
910
|
+
const hitPromise = new Promise(resolve => {
|
|
911
|
+
resolveHit = resolve
|
|
912
|
+
this.diBreakpointHitResolvers.push(resolve)
|
|
913
|
+
})
|
|
914
|
+
|
|
915
|
+
const preparedPromise = hitPromise.finally(() => {
|
|
916
|
+
const resolverIndex = this.diBreakpointHitResolvers.indexOf(resolveHit)
|
|
917
|
+
if (resolverIndex !== -1) {
|
|
918
|
+
this.diBreakpointHitResolvers.splice(resolverIndex, 1)
|
|
919
|
+
}
|
|
920
|
+
if (this.diBreakpointHitPromise === preparedPromise) {
|
|
921
|
+
this.diBreakpointHitPromise = undefined
|
|
922
|
+
}
|
|
923
|
+
})
|
|
924
|
+
|
|
925
|
+
this.diBreakpointHitPromise = preparedPromise
|
|
926
|
+
return this.diBreakpointHitPromise
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/**
|
|
930
|
+
* Wait until the DI worker has posted any breakpoint hits it was already processing.
|
|
931
|
+
*
|
|
932
|
+
* @returns {Promise<void>}
|
|
933
|
+
*/
|
|
934
|
+
waitForDiBreakpointHits () {
|
|
935
|
+
if (!this.di) return Promise.resolve()
|
|
936
|
+
if (this.diBreakpointHitPromise) return this.waitForDiOperation(this.diBreakpointHitPromise)
|
|
937
|
+
|
|
938
|
+
return this.waitForInFlightDiBreakpointHits()
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
/**
|
|
942
|
+
* Wait until the DI worker has posted breakpoint hits it was already processing.
|
|
943
|
+
*
|
|
944
|
+
* @returns {Promise<void>}
|
|
945
|
+
*/
|
|
946
|
+
waitForInFlightDiBreakpointHits () {
|
|
947
|
+
if (!this.di) return Promise.resolve()
|
|
948
|
+
|
|
949
|
+
return this.waitForDiOperation(this.di.waitForInFlightBreakpointHits())
|
|
950
|
+
}
|
|
951
|
+
|
|
812
952
|
removeAllDiProbes () {
|
|
813
953
|
if (this.fileLineToProbeId.size === 0) {
|
|
814
954
|
return Promise.resolve()
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const plugins = {
|
|
4
|
+
get '@anthropic-ai/claude-agent-sdk' () { return require('../../../datadog-plugin-claude-agent-sdk/src') },
|
|
4
5
|
get '@anthropic-ai/sdk' () { return require('../../../datadog-plugin-anthropic/src') },
|
|
5
6
|
get '@apollo/gateway' () { return require('../../../datadog-plugin-apollo/src') },
|
|
6
7
|
get '@aws-sdk/smithy-client' () { return require('../../../datadog-plugin-aws-sdk/src') },
|
|
@@ -46,6 +47,7 @@ const plugins = {
|
|
|
46
47
|
get bunyan () { return require('../../../datadog-plugin-bunyan/src') },
|
|
47
48
|
get 'cassandra-driver' () { return require('../../../datadog-plugin-cassandra-driver/src') },
|
|
48
49
|
get child_process () { return require('../../../datadog-plugin-child_process/src') },
|
|
50
|
+
get 'claude-agent-sdk' () { return require('../../../datadog-plugin-claude-agent-sdk/src') },
|
|
49
51
|
get connect () { return require('../../../datadog-plugin-connect/src') },
|
|
50
52
|
get couchbase () { return require('../../../datadog-plugin-couchbase/src') },
|
|
51
53
|
get cypress () { return require('../../../datadog-plugin-cypress/src') },
|
|
@@ -82,6 +84,9 @@ const plugins = {
|
|
|
82
84
|
get langchain () { return require('../../../datadog-plugin-langchain/src') },
|
|
83
85
|
get mariadb () { return require('../../../datadog-plugin-mariadb/src') },
|
|
84
86
|
get memcached () { return require('../../../datadog-plugin-memcached/src') },
|
|
87
|
+
// mercurius is traced under the graphql plugin: its instrumentation opens the
|
|
88
|
+
// top-level graphql.request span handled by the graphql CompositePlugin.
|
|
89
|
+
get mercurius () { return require('../../../datadog-plugin-graphql/src') },
|
|
85
90
|
get 'microgateway-core' () { return require('../../../datadog-plugin-microgateway-core/src') },
|
|
86
91
|
get mocha () { return require('../../../datadog-plugin-mocha/src') },
|
|
87
92
|
get 'mocha-each' () { return require('../../../datadog-plugin-mocha/src') },
|
|
@@ -95,6 +95,8 @@ const TEST_IS_RUM_ACTIVE = 'test.is_rum_active'
|
|
|
95
95
|
const TEST_CODE_OWNERS = 'test.codeowners'
|
|
96
96
|
const TEST_SOURCE_FILE = 'test.source.file'
|
|
97
97
|
const TEST_SOURCE_START = 'test.source.start'
|
|
98
|
+
const TEST_FAILURE_SCREENSHOT_UPLOADED = 'test.failure_screenshot.uploaded'
|
|
99
|
+
const TEST_FAILURE_SCREENSHOT_UPLOAD_ERROR = 'test.failure_screenshot.upload_error'
|
|
98
100
|
const LIBRARY_VERSION = 'library_version'
|
|
99
101
|
const TEST_COMMAND = 'test.command'
|
|
100
102
|
const TEST_MODULE = 'test.module'
|
|
@@ -433,6 +435,8 @@ module.exports = {
|
|
|
433
435
|
TEST_SKIP_REASON,
|
|
434
436
|
TEST_IS_RUM_ACTIVE,
|
|
435
437
|
TEST_SOURCE_FILE,
|
|
438
|
+
TEST_FAILURE_SCREENSHOT_UPLOADED,
|
|
439
|
+
TEST_FAILURE_SCREENSHOT_UPLOAD_ERROR,
|
|
436
440
|
CI_APP_ORIGIN,
|
|
437
441
|
LIBRARY_VERSION,
|
|
438
442
|
JEST_WORKER_TRACE_PAYLOAD_CODE,
|
|
@@ -42,6 +42,19 @@ function sendRequest (options, form, callback) {
|
|
|
42
42
|
storage('legacy').run({ noop: true }, () => {
|
|
43
43
|
requestCounter.inc()
|
|
44
44
|
const start = perf.now()
|
|
45
|
+
|
|
46
|
+
// Ensure the callback runs at most once per request. The 'timeout' handler
|
|
47
|
+
// below can fire after a response was already received (e.g. on a lingering
|
|
48
|
+
// keep-alive socket, once it goes idle); without this guard that would
|
|
49
|
+
// invoke the callback a second time and corrupt the retry accounting in
|
|
50
|
+
// AgentExporter.export.
|
|
51
|
+
let settled = false
|
|
52
|
+
const done = (err, res) => {
|
|
53
|
+
if (settled) return
|
|
54
|
+
settled = true
|
|
55
|
+
callback(err, res)
|
|
56
|
+
}
|
|
57
|
+
|
|
45
58
|
const req = request(options, res => {
|
|
46
59
|
durationDistribution.track(perf.now() - start)
|
|
47
60
|
countStatusCode(res.statusCode)
|
|
@@ -49,16 +62,28 @@ function sendRequest (options, form, callback) {
|
|
|
49
62
|
statusCodeErrorCounter.inc()
|
|
50
63
|
const error = new Error(`HTTP Error ${res.statusCode}`)
|
|
51
64
|
error.status = res.statusCode
|
|
52
|
-
|
|
65
|
+
done(error)
|
|
53
66
|
} else {
|
|
54
|
-
|
|
67
|
+
done(null, res)
|
|
55
68
|
}
|
|
56
69
|
})
|
|
57
70
|
|
|
58
71
|
req.on('error', (err) => {
|
|
59
72
|
networkErrorCounter.inc()
|
|
60
|
-
|
|
73
|
+
done(err)
|
|
61
74
|
})
|
|
75
|
+
|
|
76
|
+
// `options.timeout` sets the socket's idle timeout, which only emits a
|
|
77
|
+
// 'timeout' event — per the Node docs it does NOT abort the request. Without
|
|
78
|
+
// destroying the socket here, a stalled upload hangs indefinitely: no
|
|
79
|
+
// 'error' fires, so the retry/backoff in AgentExporter.export never runs and
|
|
80
|
+
// the export promise never settles. Destroying the request makes the
|
|
81
|
+
// 'error' handler above run, which drives the retry (see the trace exporter
|
|
82
|
+
// in ../common/request.js, which likewise aborts the request on timeout).
|
|
83
|
+
req.on('timeout', () => {
|
|
84
|
+
req.destroy(new Error(`Profiling agent export timed out after ${options.timeout}ms`))
|
|
85
|
+
})
|
|
86
|
+
|
|
62
87
|
if (form) {
|
|
63
88
|
sizeDistribution.track(form.size())
|
|
64
89
|
form.pipe(req)
|
|
@@ -8,6 +8,12 @@ const graphql = {
|
|
|
8
8
|
opName: () => 'graphql.execute',
|
|
9
9
|
serviceName: identityService,
|
|
10
10
|
},
|
|
11
|
+
// Top-level request span for drivers that funnel through a single entry
|
|
12
|
+
// point (mercurius). Matches the cross-tracer `graphql.request` v0 name.
|
|
13
|
+
request: {
|
|
14
|
+
opName: () => 'graphql.request',
|
|
15
|
+
serviceName: identityService,
|
|
16
|
+
},
|
|
11
17
|
},
|
|
12
18
|
}
|
|
13
19
|
|
|
@@ -8,6 +8,14 @@ const graphql = {
|
|
|
8
8
|
opName: () => 'graphql.server.request',
|
|
9
9
|
serviceName: identityService,
|
|
10
10
|
},
|
|
11
|
+
// Top-level request span for drivers that funnel through a single entry
|
|
12
|
+
// point (mercurius). Matches the cross-tracer `graphql.server.request` v1
|
|
13
|
+
// name. The v1 overlap with the execute span's name above is a known wart
|
|
14
|
+
// tracked for a separate cross-tracer unification (breaking) change.
|
|
15
|
+
request: {
|
|
16
|
+
opName: () => 'graphql.server.request',
|
|
17
|
+
serviceName: identityService,
|
|
18
|
+
},
|
|
11
19
|
},
|
|
12
20
|
}
|
|
13
21
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
const __apm$${T} = this["${T}"]
|
|
9
9
|
this["${T}"] = function () {}
|
|
10
10
|
if (typeof __apm$${T} === 'function') {
|
|
11
|
-
Object.defineProperty(this["${T}"], 'length', {
|
|
11
|
+
Object.defineProperty(this["${T}"], 'length', {
|
|
12
12
|
value: __apm$${T}.length,
|
|
13
13
|
configurable: true
|
|
14
14
|
})
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
if (typeof promise?.then !== 'function') {
|
|
95
95
|
__apm$ctx.result = promise;
|
|
96
96
|
${k}
|
|
97
|
-
return
|
|
97
|
+
return __apm$ctx.result;
|
|
98
98
|
}
|
|
99
99
|
// Mirror Node.js core diagnostics_channel behaviour: for native Promise
|
|
100
100
|
// instances, chain normally (safe since there is no subclass API to
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
${k}
|
|
110
110
|
${w}.asyncStart.publish(__apm$ctx);
|
|
111
111
|
${w}.asyncEnd.publish(__apm$ctx);
|
|
112
|
-
return result;
|
|
112
|
+
return __apm$ctx.result;
|
|
113
113
|
},
|
|
114
114
|
err => {
|
|
115
115
|
__apm$ctx.error = err;
|
|
@@ -151,10 +151,8 @@
|
|
|
151
151
|
|
|
152
152
|
return ${w}.start.runStores(__apm$ctx, () => {
|
|
153
153
|
try {
|
|
154
|
-
|
|
155
|
-
__apm$ctx.result = result;
|
|
154
|
+
__apm$ctx.result = __apm$traced();
|
|
156
155
|
${k}
|
|
157
|
-
return result;
|
|
158
156
|
} catch (err) {
|
|
159
157
|
__apm$ctx.error = err;
|
|
160
158
|
${w}.error.publish(__apm$ctx);
|
|
@@ -163,6 +161,7 @@
|
|
|
163
161
|
__apm$ctx.self ??= this;
|
|
164
162
|
${w}.end.publish(__apm$ctx);
|
|
165
163
|
}
|
|
164
|
+
return __apm$ctx.result;
|
|
166
165
|
});
|
|
167
166
|
}
|
|
168
167
|
`)}function declareIteratorChannel(i,s){let{channelName:k,module:{name:S}}=i,w=formatChannelVariable(k+":next");if(s.body.some(i=>i.declarations?.[0]?.id?.name===w))return;let C=formatChannelVariable(k),T=s.body.findIndex(i=>i.declarations?.[0]?.id?.name===C),_=`const ${w} = tr_ch_apm_tracingChannel("orchestrion:${S}:${k}:next")`;s.body.splice(T+1,0,E(_).body[0])}function generateIterPatch(i,s,k){let{channelName:S}=i,E=formatChannelVariable(S+":next");return declareIteratorChannel(i,k),`
|