dd-trace 5.66.0 → 5.68.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 +0 -3
- package/README.md +0 -2
- package/ci/init.js +52 -54
- package/ext/exporters.d.ts +2 -1
- package/ext/exporters.js +2 -1
- package/index.d.ts +85 -2
- package/initialize.mjs +1 -1
- package/package.json +8 -11
- package/packages/datadog-esbuild/index.js +56 -0
- package/packages/datadog-instrumentations/src/aws-sdk.js +42 -4
- package/packages/datadog-instrumentations/src/azure-functions.js +1 -1
- package/packages/datadog-instrumentations/src/azure-service-bus.js +1 -1
- package/packages/datadog-instrumentations/src/cassandra-driver.js +2 -2
- package/packages/datadog-instrumentations/src/connect.js +6 -2
- package/packages/datadog-instrumentations/src/cucumber.js +31 -6
- package/packages/datadog-instrumentations/src/express.js +5 -6
- package/packages/datadog-instrumentations/src/fastify.js +3 -3
- package/packages/datadog-instrumentations/src/helpers/hook.js +28 -15
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +11 -2
- package/packages/datadog-instrumentations/src/helpers/register.js +10 -3
- package/packages/datadog-instrumentations/src/http2/client.js +1 -0
- package/packages/datadog-instrumentations/src/http2/server.js +0 -1
- package/packages/datadog-instrumentations/src/ioredis.js +12 -1
- package/packages/datadog-instrumentations/src/jest.js +48 -36
- package/packages/datadog-instrumentations/src/limitd-client.js +2 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +15 -7
- package/packages/datadog-instrumentations/src/mocha/utils.js +3 -0
- package/packages/datadog-instrumentations/src/mongoose.js +2 -1
- package/packages/datadog-instrumentations/src/oracledb.js +19 -13
- package/packages/datadog-instrumentations/src/pg.js +9 -5
- package/packages/datadog-instrumentations/src/pino.js +18 -6
- package/packages/datadog-instrumentations/src/playwright.js +15 -1
- package/packages/datadog-instrumentations/src/sequelize.js +1 -1
- package/packages/datadog-instrumentations/src/vitest.js +155 -62
- package/packages/datadog-plugin-ai/src/tracing.js +3 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +23 -8
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/tracing.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +101 -2
- package/packages/datadog-plugin-aws-sdk/src/util.js +1 -1
- package/packages/datadog-plugin-cucumber/src/index.js +4 -56
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +6 -2
- package/packages/datadog-plugin-cypress/src/support.js +4 -0
- package/packages/datadog-plugin-express/src/code_origin.js +2 -2
- package/packages/datadog-plugin-fastify/src/code_origin.js +1 -2
- package/packages/datadog-plugin-jest/src/index.js +0 -21
- package/packages/datadog-plugin-mocha/src/index.js +3 -57
- package/packages/datadog-plugin-mongodb-core/src/index.js +20 -7
- package/packages/datadog-plugin-playwright/src/index.js +11 -5
- package/packages/datadog-plugin-vitest/src/index.js +5 -1
- package/packages/datadog-plugin-ws/src/close.js +1 -1
- package/packages/datadog-plugin-ws/src/producer.js +6 -1
- package/packages/datadog-plugin-ws/src/receiver.js +6 -1
- package/packages/dd-trace/src/appsec/iast/security-controls/parser.js +1 -1
- package/packages/dd-trace/src/appsec/telemetry/waf.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -4
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +11 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +10 -1
- package/packages/dd-trace/src/config.js +69 -304
- package/packages/dd-trace/src/config_defaults.js +186 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +2 -1
- package/packages/dd-trace/src/datastreams/fnv.js +2 -2
- package/packages/dd-trace/src/datastreams/writer.js +3 -2
- package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -1
- package/packages/dd-trace/src/dogstatsd.js +4 -3
- package/packages/dd-trace/src/encode/0.4.js +1 -5
- package/packages/dd-trace/src/exporter.js +1 -0
- package/packages/dd-trace/src/exporters/agent/index.js +3 -2
- package/packages/dd-trace/src/exporters/agent/writer.js +1 -1
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +3 -2
- package/packages/dd-trace/src/exporters/common/request.js +2 -1
- package/packages/dd-trace/src/exporters/span-stats/index.js +3 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +2 -0
- package/packages/dd-trace/src/llmobs/index.js +7 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +4 -3
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -1
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +40 -13
- package/packages/dd-trace/src/llmobs/plugins/openai.js +7 -1
- package/packages/dd-trace/src/llmobs/sdk.js +28 -0
- package/packages/dd-trace/src/llmobs/span_processor.js +124 -28
- package/packages/dd-trace/src/llmobs/tagger.js +8 -0
- package/packages/dd-trace/src/llmobs/telemetry.js +9 -2
- package/packages/dd-trace/src/log/index.js +28 -17
- package/packages/dd-trace/src/log/log.js +29 -5
- package/packages/dd-trace/src/log/writer.js +5 -5
- package/packages/dd-trace/src/noop/span.js +1 -0
- package/packages/dd-trace/src/opentelemetry/span.js +14 -3
- package/packages/dd-trace/src/opentracing/span.js +18 -4
- package/packages/dd-trace/src/plugin_manager.js +20 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +97 -3
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/util/git-cache.js +129 -0
- package/packages/dd-trace/src/plugins/util/git.js +40 -26
- package/packages/dd-trace/src/plugins/util/test.js +37 -27
- package/packages/dd-trace/src/plugins/util/web.js +1 -1
- package/packages/dd-trace/src/profiler.js +4 -1
- package/packages/dd-trace/src/profiling/config.js +73 -42
- package/packages/dd-trace/src/profiling/profiler.js +3 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -8
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -0
- package/packages/dd-trace/src/profiling/profilers/wall.js +196 -117
- package/packages/dd-trace/src/remote_config/capabilities.js +5 -0
- package/packages/dd-trace/src/remote_config/manager.js +3 -2
- package/packages/dd-trace/src/startup-log.js +2 -1
- package/packages/dd-trace/src/supported-configurations.json +3 -0
- package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
- package/register.js +1 -1
|
@@ -21,12 +21,6 @@ const {
|
|
|
21
21
|
TEST_EARLY_FLAKE_ABORT_REASON,
|
|
22
22
|
TEST_IS_NEW,
|
|
23
23
|
TEST_IS_RETRY,
|
|
24
|
-
TEST_SUITE_ID,
|
|
25
|
-
TEST_SESSION_ID,
|
|
26
|
-
TEST_COMMAND,
|
|
27
|
-
TEST_MODULE,
|
|
28
|
-
TEST_MODULE_ID,
|
|
29
|
-
TEST_SUITE,
|
|
30
24
|
CUCUMBER_IS_PARALLEL,
|
|
31
25
|
TEST_RETRY_REASON,
|
|
32
26
|
TEST_MANAGEMENT_ENABLED,
|
|
@@ -55,25 +49,11 @@ const {
|
|
|
55
49
|
TEST_BROWSER_DRIVER,
|
|
56
50
|
TELEMETRY_TEST_SESSION
|
|
57
51
|
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
58
|
-
const id = require('../../dd-trace/src/id')
|
|
59
52
|
|
|
60
53
|
const BREAKPOINT_HIT_GRACE_PERIOD_MS = 200
|
|
61
54
|
const BREAKPOINT_SET_GRACE_PERIOD_MS = 200
|
|
62
55
|
const isCucumberWorker = !!getEnvironmentVariable('CUCUMBER_WORKER_ID')
|
|
63
56
|
|
|
64
|
-
function getTestSuiteTags (testSuiteSpan) {
|
|
65
|
-
const suiteTags = {
|
|
66
|
-
[TEST_SUITE_ID]: testSuiteSpan.context().toSpanId(),
|
|
67
|
-
[TEST_SESSION_ID]: testSuiteSpan.context().toTraceId(),
|
|
68
|
-
[TEST_COMMAND]: testSuiteSpan.context()._tags[TEST_COMMAND],
|
|
69
|
-
[TEST_MODULE]: 'cucumber'
|
|
70
|
-
}
|
|
71
|
-
if (testSuiteSpan.context()._parentId) {
|
|
72
|
-
suiteTags[TEST_MODULE_ID] = testSuiteSpan.context()._parentId.toString(10)
|
|
73
|
-
}
|
|
74
|
-
return suiteTags
|
|
75
|
-
}
|
|
76
|
-
|
|
77
57
|
class CucumberPlugin extends CiPlugin {
|
|
78
58
|
static id = 'cucumber'
|
|
79
59
|
|
|
@@ -82,8 +62,6 @@ class CucumberPlugin extends CiPlugin {
|
|
|
82
62
|
|
|
83
63
|
this.sourceRoot = process.cwd()
|
|
84
64
|
|
|
85
|
-
this.testSuiteSpanByPath = {}
|
|
86
|
-
|
|
87
65
|
this.addSub('ci:cucumber:session:finish', ({
|
|
88
66
|
status,
|
|
89
67
|
isSuitesSkipped,
|
|
@@ -185,7 +163,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
185
163
|
},
|
|
186
164
|
integrationName: this.constructor.id
|
|
187
165
|
})
|
|
188
|
-
this.
|
|
166
|
+
this._testSuiteSpansByTestSuite.set(testSuitePath, testSuiteSpan)
|
|
189
167
|
|
|
190
168
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'suite')
|
|
191
169
|
if (this.libraryConfig?.isCodeCoverageEnabled) {
|
|
@@ -194,7 +172,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
194
172
|
})
|
|
195
173
|
|
|
196
174
|
this.addSub('ci:cucumber:test-suite:finish', ({ status, testSuitePath }) => {
|
|
197
|
-
const testSuiteSpan = this.
|
|
175
|
+
const testSuiteSpan = this._testSuiteSpansByTestSuite.get(testSuitePath)
|
|
198
176
|
testSuiteSpan.setTag(TEST_STATUS, status)
|
|
199
177
|
testSuiteSpan.finish()
|
|
200
178
|
this.telemetry.ciVisEvent(TELEMETRY_EVENT_FINISHED, 'suite')
|
|
@@ -207,7 +185,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
207
185
|
if (!coverageFiles.length) {
|
|
208
186
|
this.telemetry.count(TELEMETRY_CODE_COVERAGE_EMPTY)
|
|
209
187
|
}
|
|
210
|
-
const testSuiteSpan = this.
|
|
188
|
+
const testSuiteSpan = this._testSuiteSpansByTestSuite.get(testSuitePath)
|
|
211
189
|
|
|
212
190
|
const relativeCoverageFiles = [...coverageFiles, suiteFile]
|
|
213
191
|
.map(filename => getTestSuitePath(filename, this.repositoryRoot))
|
|
@@ -303,36 +281,6 @@ class CucumberPlugin extends CiPlugin {
|
|
|
303
281
|
return ctx.currentStore
|
|
304
282
|
})
|
|
305
283
|
|
|
306
|
-
this.addSub('ci:cucumber:worker-report:trace', (traces) => {
|
|
307
|
-
const formattedTraces = JSON.parse(traces).map(trace =>
|
|
308
|
-
trace.map(span => ({
|
|
309
|
-
...span,
|
|
310
|
-
span_id: id(span.span_id),
|
|
311
|
-
trace_id: id(span.trace_id),
|
|
312
|
-
parent_id: id(span.parent_id)
|
|
313
|
-
}))
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
// We have to update the test session, test module and test suite ids
|
|
317
|
-
// before we export them in the main process
|
|
318
|
-
formattedTraces.forEach(trace => {
|
|
319
|
-
trace.forEach(span => {
|
|
320
|
-
if (span.name === 'cucumber.test') {
|
|
321
|
-
const testSuite = span.meta[TEST_SUITE]
|
|
322
|
-
const testSuiteSpan = this.testSuiteSpanByPath[testSuite]
|
|
323
|
-
|
|
324
|
-
const testSuiteTags = getTestSuiteTags(testSuiteSpan)
|
|
325
|
-
span.meta = {
|
|
326
|
-
...span.meta,
|
|
327
|
-
...testSuiteTags
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
})
|
|
331
|
-
|
|
332
|
-
this.tracer._exporter.export(trace)
|
|
333
|
-
})
|
|
334
|
-
})
|
|
335
|
-
|
|
336
284
|
this.addSub('ci:cucumber:test:finish', ({
|
|
337
285
|
span,
|
|
338
286
|
isStep,
|
|
@@ -501,7 +449,7 @@ class CucumberPlugin extends CiPlugin {
|
|
|
501
449
|
}
|
|
502
450
|
|
|
503
451
|
startTestSpan (testName, testSuite, extraTags) {
|
|
504
|
-
const testSuiteSpan = this.
|
|
452
|
+
const testSuiteSpan = this._testSuiteSpansByTestSuite.get(testSuite)
|
|
505
453
|
return super.startTestSpan(
|
|
506
454
|
testName,
|
|
507
455
|
testSuite,
|
|
@@ -482,8 +482,12 @@ class CypressPlugin {
|
|
|
482
482
|
this.isEarlyFlakeDetectionEnabled = false
|
|
483
483
|
this.isKnownTestsEnabled = false
|
|
484
484
|
} else {
|
|
485
|
-
|
|
486
|
-
|
|
485
|
+
if (knownTestsResponse.knownTests[TEST_FRAMEWORK_NAME]) {
|
|
486
|
+
this.knownTestsByTestSuite = knownTestsResponse.knownTests[TEST_FRAMEWORK_NAME]
|
|
487
|
+
} else {
|
|
488
|
+
this.isEarlyFlakeDetectionEnabled = false
|
|
489
|
+
this.isKnownTestsEnabled = false
|
|
490
|
+
}
|
|
487
491
|
}
|
|
488
492
|
}
|
|
489
493
|
|
|
@@ -26,6 +26,10 @@ function safeGetRum (window) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function isNewTest (test) {
|
|
29
|
+
// If for whatever reason the worker does not receive valid known tests, we don't consider it as new
|
|
30
|
+
if (!Array.isArray(knownTestsForSuite)) {
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
29
33
|
return !knownTestsForSuite.includes(test.fullTitle())
|
|
30
34
|
}
|
|
31
35
|
|
|
@@ -15,7 +15,7 @@ class ExpressCodeOriginForSpansPlugin extends Plugin {
|
|
|
15
15
|
this.addSub('apm:express:middleware:enter', ({ req, layer }) => {
|
|
16
16
|
const tags = layerTags.get(layer)
|
|
17
17
|
if (!tags) return
|
|
18
|
-
web.getContext(req)
|
|
18
|
+
web.getContext(req)?.span?.addTags(tags)
|
|
19
19
|
})
|
|
20
20
|
|
|
21
21
|
this.addSub('apm:express:route:added', ({ topOfStackFunc, layer }) => {
|
|
@@ -26,7 +26,7 @@ class ExpressCodeOriginForSpansPlugin extends Plugin {
|
|
|
26
26
|
this.addSub('apm:router:middleware:enter', ({ req, layer }) => {
|
|
27
27
|
const tags = layerTags.get(layer)
|
|
28
28
|
if (!tags) return
|
|
29
|
-
web.getContext(req)
|
|
29
|
+
web.getContext(req)?.span?.addTags(tags)
|
|
30
30
|
})
|
|
31
31
|
|
|
32
32
|
this.addSub('apm:router:route:added', ({ topOfStackFunc, layer }) => {
|
|
@@ -15,8 +15,7 @@ class FastifyCodeOriginForSpansPlugin extends Plugin {
|
|
|
15
15
|
this.addSub('apm:fastify:request:handle', ({ req, routeConfig }) => {
|
|
16
16
|
const tags = routeConfig?.[kCodeOriginForSpansTagsSym]
|
|
17
17
|
if (!tags) return
|
|
18
|
-
|
|
19
|
-
context.span?.addTags(tags)
|
|
18
|
+
web.getContext(req)?.span?.addTags(tags)
|
|
20
19
|
})
|
|
21
20
|
|
|
22
21
|
this.addSub('apm:fastify:route:added', ({ routeOptions, onRoute }) => {
|
|
@@ -261,21 +261,6 @@ class JestPlugin extends CiPlugin {
|
|
|
261
261
|
}
|
|
262
262
|
})
|
|
263
263
|
|
|
264
|
-
this.addSub('ci:jest:worker-report:trace', traces => {
|
|
265
|
-
const formattedTraces = JSON.parse(traces).map(trace =>
|
|
266
|
-
trace.map(span => ({
|
|
267
|
-
...span,
|
|
268
|
-
span_id: id(span.span_id),
|
|
269
|
-
trace_id: id(span.trace_id),
|
|
270
|
-
parent_id: id(span.parent_id)
|
|
271
|
-
}))
|
|
272
|
-
)
|
|
273
|
-
|
|
274
|
-
formattedTraces.forEach(trace => {
|
|
275
|
-
this.tracer._exporter.export(trace)
|
|
276
|
-
})
|
|
277
|
-
})
|
|
278
|
-
|
|
279
264
|
this.addSub('ci:jest:worker-report:coverage', data => {
|
|
280
265
|
const formattedCoverages = JSON.parse(data).map(coverage => ({
|
|
281
266
|
sessionId: id(coverage.sessionId),
|
|
@@ -287,12 +272,6 @@ class JestPlugin extends CiPlugin {
|
|
|
287
272
|
})
|
|
288
273
|
})
|
|
289
274
|
|
|
290
|
-
this.addSub('ci:jest:worker-report:logs', (logsPayloads) => {
|
|
291
|
-
JSON.parse(logsPayloads).forEach(({ testConfiguration, logMessage }) => {
|
|
292
|
-
this.tracer._exporter.exportDiLogs(testConfiguration, logMessage)
|
|
293
|
-
})
|
|
294
|
-
})
|
|
295
|
-
|
|
296
275
|
this.addSub('ci:jest:test-suite:finish', ({ status, errorMessage, error }) => {
|
|
297
276
|
this.testSuiteSpan.setTag(TEST_STATUS, status)
|
|
298
277
|
if (error) {
|
|
@@ -22,12 +22,6 @@ const {
|
|
|
22
22
|
TEST_IS_RETRY,
|
|
23
23
|
TEST_EARLY_FLAKE_ENABLED,
|
|
24
24
|
TEST_EARLY_FLAKE_ABORT_REASON,
|
|
25
|
-
TEST_SESSION_ID,
|
|
26
|
-
TEST_MODULE_ID,
|
|
27
|
-
TEST_MODULE,
|
|
28
|
-
TEST_SUITE_ID,
|
|
29
|
-
TEST_COMMAND,
|
|
30
|
-
TEST_SUITE,
|
|
31
25
|
MOCHA_IS_PARALLEL,
|
|
32
26
|
TEST_IS_RUM_ACTIVE,
|
|
33
27
|
TEST_BROWSER_DRIVER,
|
|
@@ -54,32 +48,15 @@ const {
|
|
|
54
48
|
TELEMETRY_CODE_COVERAGE_NUM_FILES,
|
|
55
49
|
TELEMETRY_TEST_SESSION
|
|
56
50
|
} = require('../../dd-trace/src/ci-visibility/telemetry')
|
|
57
|
-
const id = require('../../dd-trace/src/id')
|
|
58
|
-
const log = require('../../dd-trace/src/log')
|
|
59
51
|
|
|
60
52
|
const BREAKPOINT_SET_GRACE_PERIOD_MS = 200
|
|
61
53
|
|
|
62
|
-
function getTestSuiteLevelVisibilityTags (testSuiteSpan) {
|
|
63
|
-
const testSuiteSpanContext = testSuiteSpan.context()
|
|
64
|
-
const suiteTags = {
|
|
65
|
-
[TEST_SUITE_ID]: testSuiteSpanContext.toSpanId(),
|
|
66
|
-
[TEST_SESSION_ID]: testSuiteSpanContext.toTraceId(),
|
|
67
|
-
[TEST_COMMAND]: testSuiteSpanContext._tags[TEST_COMMAND],
|
|
68
|
-
[TEST_MODULE]: 'mocha'
|
|
69
|
-
}
|
|
70
|
-
if (testSuiteSpanContext._parentId) {
|
|
71
|
-
suiteTags[TEST_MODULE_ID] = testSuiteSpanContext._parentId.toString(10)
|
|
72
|
-
}
|
|
73
|
-
return suiteTags
|
|
74
|
-
}
|
|
75
|
-
|
|
76
54
|
class MochaPlugin extends CiPlugin {
|
|
77
55
|
static id = 'mocha'
|
|
78
56
|
|
|
79
57
|
constructor (...args) {
|
|
80
58
|
super(...args)
|
|
81
59
|
|
|
82
|
-
this._testSuites = new Map()
|
|
83
60
|
this._testTitleToParams = {}
|
|
84
61
|
this.sourceRoot = process.cwd()
|
|
85
62
|
|
|
@@ -88,7 +65,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
88
65
|
return
|
|
89
66
|
}
|
|
90
67
|
const testSuite = getTestSuitePath(suiteFile, this.sourceRoot)
|
|
91
|
-
const testSuiteSpan = this.
|
|
68
|
+
const testSuiteSpan = this._testSuiteSpansByTestSuite.get(testSuite)
|
|
92
69
|
|
|
93
70
|
if (!coverageFiles.length) {
|
|
94
71
|
this.telemetry.count(TELEMETRY_CODE_COVERAGE_EMPTY)
|
|
@@ -163,7 +140,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
163
140
|
const store = storage('legacy').getStore()
|
|
164
141
|
ctx.parentStore = store
|
|
165
142
|
ctx.currentStore = { ...store, testSuiteSpan }
|
|
166
|
-
this.
|
|
143
|
+
this._testSuiteSpansByTestSuite.set(testSuite, testSuiteSpan)
|
|
167
144
|
})
|
|
168
145
|
|
|
169
146
|
this.addSub('ci:mocha:test-suite:finish', ({ testSuiteSpan, status }) => {
|
|
@@ -436,37 +413,6 @@ class MochaPlugin extends CiPlugin {
|
|
|
436
413
|
this.tracer._exporter.flush()
|
|
437
414
|
})
|
|
438
415
|
|
|
439
|
-
this.addSub('ci:mocha:worker-report:trace', (traces) => {
|
|
440
|
-
const formattedTraces = JSON.parse(traces).map(trace =>
|
|
441
|
-
trace.map(span => {
|
|
442
|
-
const formattedSpan = {
|
|
443
|
-
...span,
|
|
444
|
-
span_id: id(span.span_id),
|
|
445
|
-
trace_id: id(span.trace_id),
|
|
446
|
-
parent_id: id(span.parent_id)
|
|
447
|
-
}
|
|
448
|
-
if (formattedSpan.name === 'mocha.test') {
|
|
449
|
-
const testSuite = span.meta[TEST_SUITE]
|
|
450
|
-
const testSuiteSpan = this._testSuites.get(testSuite)
|
|
451
|
-
if (!testSuiteSpan) {
|
|
452
|
-
log.warn('Test suite span not found for test span with test suite', testSuite)
|
|
453
|
-
return formattedSpan
|
|
454
|
-
}
|
|
455
|
-
const suiteTags = getTestSuiteLevelVisibilityTags(testSuiteSpan)
|
|
456
|
-
formattedSpan.meta = {
|
|
457
|
-
...formattedSpan.meta,
|
|
458
|
-
...suiteTags
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
return formattedSpan
|
|
462
|
-
})
|
|
463
|
-
)
|
|
464
|
-
|
|
465
|
-
formattedTraces.forEach(trace => {
|
|
466
|
-
this.tracer._exporter.export(trace)
|
|
467
|
-
})
|
|
468
|
-
})
|
|
469
|
-
|
|
470
416
|
this.addBind('ci:mocha:global:run', (ctx) => {
|
|
471
417
|
return ctx.currentStore
|
|
472
418
|
})
|
|
@@ -522,7 +468,7 @@ class MochaPlugin extends CiPlugin {
|
|
|
522
468
|
}
|
|
523
469
|
|
|
524
470
|
const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.sourceRoot)
|
|
525
|
-
const testSuiteSpan = this.
|
|
471
|
+
const testSuiteSpan = this._testSuiteSpansByTestSuite.get(testSuite)
|
|
526
472
|
|
|
527
473
|
extraTags[TEST_SOURCE_FILE] = this.repositoryRoot !== this.sourceRoot && !!this.repositoryRoot
|
|
528
474
|
? getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const { isTrue } = require('../../dd-trace/src/util')
|
|
4
4
|
const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
5
|
-
const coalesce = require('koalas')
|
|
6
5
|
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
7
6
|
|
|
8
7
|
class MongodbCorePlugin extends DatabasePlugin {
|
|
@@ -17,16 +16,13 @@ class MongodbCorePlugin extends DatabasePlugin {
|
|
|
17
16
|
|
|
18
17
|
const heartbeatFromEnv = getEnvironmentVariable('DD_TRACE_MONGODB_HEARTBEAT_ENABLED')
|
|
19
18
|
|
|
20
|
-
this.config.heartbeatEnabled =
|
|
21
|
-
|
|
22
|
-
heartbeatFromEnv && isTrue(heartbeatFromEnv),
|
|
19
|
+
this.config.heartbeatEnabled = config.heartbeatEnabled ??
|
|
20
|
+
(heartbeatFromEnv && isTrue(heartbeatFromEnv)) ??
|
|
23
21
|
true
|
|
24
|
-
)
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
bindStart (ctx) {
|
|
28
25
|
const { ns, ops, options = {}, name } = ctx
|
|
29
|
-
|
|
30
26
|
// heartbeat commands can be disabled if this.config.heartbeatEnabled is false
|
|
31
27
|
if (!this.config.heartbeatEnabled && isHeartbeat(ops, this.config)) {
|
|
32
28
|
return
|
|
@@ -90,11 +86,28 @@ function sanitizeBigInt (data) {
|
|
|
90
86
|
return JSON.stringify(data, (_key, value) => typeof value === 'bigint' ? value.toString() : value)
|
|
91
87
|
}
|
|
92
88
|
|
|
89
|
+
function extractQuery (statements) {
|
|
90
|
+
if (statements.length === 1 && statements[0].q) return statements[0].q
|
|
91
|
+
|
|
92
|
+
const extractedQueries = []
|
|
93
|
+
for (let i = 0; i < statements.length; i++) {
|
|
94
|
+
if (statements[i].q) {
|
|
95
|
+
extractedQueries.push(limitDepth(statements[i].q))
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return extractedQueries
|
|
100
|
+
}
|
|
101
|
+
|
|
93
102
|
function getQuery (cmd) {
|
|
94
|
-
if (!cmd || typeof cmd !== 'object'
|
|
103
|
+
if (!cmd || (typeof cmd !== 'object' && !Array.isArray(cmd))) return
|
|
104
|
+
|
|
105
|
+
if (Array.isArray(cmd)) return sanitizeBigInt(extractQuery(cmd))
|
|
95
106
|
if (cmd.query) return sanitizeBigInt(limitDepth(cmd.query))
|
|
96
107
|
if (cmd.filter) return sanitizeBigInt(limitDepth(cmd.filter))
|
|
97
108
|
if (cmd.pipeline) return sanitizeBigInt(limitDepth(cmd.pipeline))
|
|
109
|
+
if (cmd.deletes) return sanitizeBigInt(extractQuery(cmd.deletes))
|
|
110
|
+
if (cmd.updates) return sanitizeBigInt(extractQuery(cmd.updates))
|
|
98
111
|
}
|
|
99
112
|
|
|
100
113
|
function getResource (plugin, ns, query, operationName) {
|
|
@@ -17,6 +17,7 @@ const {
|
|
|
17
17
|
TEST_IS_NEW,
|
|
18
18
|
TEST_IS_RETRY,
|
|
19
19
|
TEST_EARLY_FLAKE_ENABLED,
|
|
20
|
+
TEST_EARLY_FLAKE_ABORT_REASON,
|
|
20
21
|
TELEMETRY_TEST_SESSION,
|
|
21
22
|
TEST_RETRY_REASON,
|
|
22
23
|
TEST_MANAGEMENT_IS_QUARANTINED,
|
|
@@ -53,7 +54,7 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
53
54
|
constructor (...args) {
|
|
54
55
|
super(...args)
|
|
55
56
|
|
|
56
|
-
this.
|
|
57
|
+
this._testSuiteSpansByTestSuiteAbsolutePath = new Map()
|
|
57
58
|
this.numFailedTests = 0
|
|
58
59
|
this.numFailedSuites = 0
|
|
59
60
|
|
|
@@ -70,6 +71,7 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
70
71
|
this.addSub('ci:playwright:session:finish', ({
|
|
71
72
|
status,
|
|
72
73
|
isEarlyFlakeDetectionEnabled,
|
|
74
|
+
isEarlyFlakeDetectionFaulty,
|
|
73
75
|
isTestManagementTestsEnabled,
|
|
74
76
|
onDone
|
|
75
77
|
}) => {
|
|
@@ -79,7 +81,9 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
79
81
|
if (isEarlyFlakeDetectionEnabled) {
|
|
80
82
|
this.testSessionSpan.setTag(TEST_EARLY_FLAKE_ENABLED, 'true')
|
|
81
83
|
}
|
|
82
|
-
|
|
84
|
+
if (isEarlyFlakeDetectionFaulty) {
|
|
85
|
+
this.testSessionSpan.setTag(TEST_EARLY_FLAKE_ABORT_REASON, 'faulty')
|
|
86
|
+
}
|
|
83
87
|
if (this.numFailedSuites > 0) {
|
|
84
88
|
let errorMessage = `Test suites failed: ${this.numFailedSuites}.`
|
|
85
89
|
if (this.numFailedTests > 0) {
|
|
@@ -142,7 +146,7 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
142
146
|
ctx.parentStore = store
|
|
143
147
|
ctx.currentStore = { ...store, testSuiteSpan }
|
|
144
148
|
|
|
145
|
-
this.
|
|
149
|
+
this._testSuiteSpansByTestSuiteAbsolutePath.set(testSuiteAbsolutePath, testSuiteSpan)
|
|
146
150
|
|
|
147
151
|
return ctx.currentStore
|
|
148
152
|
})
|
|
@@ -247,7 +251,9 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
247
251
|
formattedSpan.meta[TEST_COMMAND] = this.command
|
|
248
252
|
formattedSpan.meta[TEST_MODULE] = this.constructor.id
|
|
249
253
|
// MISSING _trace.startTime and _trace.ticks - because by now the suite is already serialized
|
|
250
|
-
const testSuite = this.
|
|
254
|
+
const testSuite = this._testSuiteSpansByTestSuiteAbsolutePath.get(
|
|
255
|
+
formattedSpan.meta.test_suite_absolute_path
|
|
256
|
+
)
|
|
251
257
|
if (testSuite) {
|
|
252
258
|
formattedSpan.meta[TEST_SUITE_ID] = testSuite.context().toSpanId()
|
|
253
259
|
}
|
|
@@ -391,7 +397,7 @@ class PlaywrightPlugin extends CiPlugin {
|
|
|
391
397
|
|
|
392
398
|
// TODO: this runs both in worker and main process (main process: skipped tests that do not go through _runTest)
|
|
393
399
|
startTestSpan (testName, testSuiteAbsolutePath, testSuite, testSourceFile, testSourceLine, browserName) {
|
|
394
|
-
const testSuiteSpan = this.
|
|
400
|
+
const testSuiteSpan = this._testSuiteSpansByTestSuiteAbsolutePath.get(testSuiteAbsolutePath)
|
|
395
401
|
|
|
396
402
|
const extraTags = {
|
|
397
403
|
[TEST_SOURCE_START]: testSourceLine
|
|
@@ -55,8 +55,12 @@ class VitestPlugin extends CiPlugin {
|
|
|
55
55
|
this.taskToFinishTime = new WeakMap()
|
|
56
56
|
|
|
57
57
|
this.addSub('ci:vitest:test:is-new', ({ knownTests, testSuiteAbsolutePath, testName, onDone }) => {
|
|
58
|
+
// if for whatever reason the worker does not receive valid known tests, we don't consider it as new
|
|
59
|
+
if (!knownTests.vitest) {
|
|
60
|
+
return onDone(false)
|
|
61
|
+
}
|
|
58
62
|
const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.repositoryRoot)
|
|
59
|
-
const testsForThisTestSuite = knownTests[testSuite] || []
|
|
63
|
+
const testsForThisTestSuite = knownTests.vitest[testSuite] || []
|
|
60
64
|
onDone(!testsForThisTestSuite.includes(testName))
|
|
61
65
|
})
|
|
62
66
|
|
|
@@ -60,7 +60,7 @@ class WSClosePlugin extends TracingPlugin {
|
|
|
60
60
|
end (ctx) {
|
|
61
61
|
if (!Object.hasOwn(ctx, 'result')) return
|
|
62
62
|
|
|
63
|
-
if (ctx.socket.spanContext) ctx.span.addLink(ctx.socket.spanContext)
|
|
63
|
+
if (ctx.socket.spanContext) ctx.span.addLink({ context: ctx.socket.spanContext })
|
|
64
64
|
|
|
65
65
|
ctx.span.finish()
|
|
66
66
|
}
|
|
@@ -50,7 +50,12 @@ class WSProducerPlugin extends TracingPlugin {
|
|
|
50
50
|
end (ctx) {
|
|
51
51
|
if (!Object.hasOwn(ctx, 'result')) return
|
|
52
52
|
|
|
53
|
-
if (ctx.socket.spanContext)
|
|
53
|
+
if (ctx.socket.spanContext) {
|
|
54
|
+
ctx.span.addLink({
|
|
55
|
+
context: ctx.socket.spanContext,
|
|
56
|
+
attributes: { 'dd.kind': 'resuming' },
|
|
57
|
+
})
|
|
58
|
+
}
|
|
54
59
|
|
|
55
60
|
ctx.span.finish()
|
|
56
61
|
return ctx.parentStore
|
|
@@ -60,7 +60,12 @@ class WSReceiverPlugin extends TracingPlugin {
|
|
|
60
60
|
end (ctx) {
|
|
61
61
|
if (!Object.hasOwn(ctx, 'result')) return
|
|
62
62
|
|
|
63
|
-
if (ctx.socket.spanContext)
|
|
63
|
+
if (ctx.socket.spanContext) {
|
|
64
|
+
ctx.span.addLink({
|
|
65
|
+
context: ctx.socket.spanContext,
|
|
66
|
+
attributes: { 'dd.kind': 'executed_by' },
|
|
67
|
+
})
|
|
68
|
+
}
|
|
64
69
|
|
|
65
70
|
ctx.span.finish()
|
|
66
71
|
return ctx.parentStore
|
|
@@ -15,7 +15,7 @@ const validTypes = new Set([INPUT_VALIDATOR_TYPE, SANITIZER_TYPE])
|
|
|
15
15
|
function parse (securityControlsConfiguration) {
|
|
16
16
|
const controls = new Map()
|
|
17
17
|
|
|
18
|
-
securityControlsConfiguration?.
|
|
18
|
+
securityControlsConfiguration?.replaceAll(/[\r\n\t\v\f]*/g, '')
|
|
19
19
|
.split(SECURITY_CONTROL_DELIMITER)
|
|
20
20
|
.map(parseControl)
|
|
21
21
|
.filter(control => !!control)
|
|
@@ -96,7 +96,7 @@ function incrementWafInit (wafVersion, rulesVersion, success) {
|
|
|
96
96
|
appsecMetrics.count('waf.init', { ...versionsTags, success }).inc()
|
|
97
97
|
|
|
98
98
|
if (!success) {
|
|
99
|
-
appsecMetrics.count('waf.config_errors', versionsTags).inc()
|
|
99
|
+
appsecMetrics.count('waf.config_errors', { ...versionsTags, action: 'init' }).inc()
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -107,7 +107,7 @@ function incrementWafUpdates (wafVersion, rulesVersion, success) {
|
|
|
107
107
|
|
|
108
108
|
function incrementWafConfigErrors (wafVersion, rulesVersion) {
|
|
109
109
|
const versionsTags = getVersionsTags(wafVersion, rulesVersion)
|
|
110
|
-
appsecMetrics.count('waf.config_errors', versionsTags).inc()
|
|
110
|
+
appsecMetrics.count('waf.config_errors', { ...versionsTags, action: 'update' }).inc()
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
function incrementWafRequests (store) {
|
|
@@ -287,11 +287,11 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
287
287
|
this._export(formattedCoverage, this._coverageWriter, '_coverageTimer')
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
formatLogMessage (
|
|
290
|
+
formatLogMessage (testEnvironmentMetadata, logMessage) {
|
|
291
291
|
const {
|
|
292
292
|
[GIT_REPOSITORY_URL]: gitRepositoryUrl,
|
|
293
293
|
[GIT_COMMIT_SHA]: gitCommitSha
|
|
294
|
-
} =
|
|
294
|
+
} = testEnvironmentMetadata
|
|
295
295
|
|
|
296
296
|
const { service, env, version } = this._config
|
|
297
297
|
|
|
@@ -315,14 +315,14 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
// DI logs
|
|
318
|
-
exportDiLogs (
|
|
318
|
+
exportDiLogs (testEnvironmentMetadata, logMessage) {
|
|
319
319
|
// TODO: could we lose logs if it's not initialized?
|
|
320
320
|
if (!this._config.isTestDynamicInstrumentationEnabled || !this._isInitialized || !this._canForwardLogs) {
|
|
321
321
|
return
|
|
322
322
|
}
|
|
323
323
|
|
|
324
324
|
this._export(
|
|
325
|
-
this.formatLogMessage(
|
|
325
|
+
this.formatLogMessage(testEnvironmentMetadata, logMessage),
|
|
326
326
|
this._logsWriter,
|
|
327
327
|
'_logsTimer'
|
|
328
328
|
)
|
|
@@ -7,7 +7,9 @@ const {
|
|
|
7
7
|
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE,
|
|
8
8
|
MOCHA_WORKER_TRACE_PAYLOAD_CODE,
|
|
9
9
|
JEST_WORKER_LOGS_PAYLOAD_CODE,
|
|
10
|
-
PLAYWRIGHT_WORKER_TRACE_PAYLOAD_CODE
|
|
10
|
+
PLAYWRIGHT_WORKER_TRACE_PAYLOAD_CODE,
|
|
11
|
+
VITEST_WORKER_TRACE_PAYLOAD_CODE,
|
|
12
|
+
VITEST_WORKER_LOGS_PAYLOAD_CODE
|
|
11
13
|
} = require('../../../plugins/util/test')
|
|
12
14
|
const { getEnvironmentVariable } = require('../../../config-helper')
|
|
13
15
|
|
|
@@ -24,6 +26,9 @@ function getInterprocessTraceCode () {
|
|
|
24
26
|
if (getEnvironmentVariable('DD_PLAYWRIGHT_WORKER')) {
|
|
25
27
|
return PLAYWRIGHT_WORKER_TRACE_PAYLOAD_CODE
|
|
26
28
|
}
|
|
29
|
+
if (getEnvironmentVariable('TINYPOOL_WORKER_ID')) {
|
|
30
|
+
return VITEST_WORKER_TRACE_PAYLOAD_CODE
|
|
31
|
+
}
|
|
27
32
|
return null
|
|
28
33
|
}
|
|
29
34
|
|
|
@@ -39,6 +44,9 @@ function getInterprocessLogsCode () {
|
|
|
39
44
|
if (getEnvironmentVariable('JEST_WORKER_ID')) {
|
|
40
45
|
return JEST_WORKER_LOGS_PAYLOAD_CODE
|
|
41
46
|
}
|
|
47
|
+
if (getEnvironmentVariable('TINYPOOL_WORKER_ID')) {
|
|
48
|
+
return VITEST_WORKER_LOGS_PAYLOAD_CODE
|
|
49
|
+
}
|
|
42
50
|
return null
|
|
43
51
|
}
|
|
44
52
|
|
|
@@ -66,8 +74,8 @@ class TestWorkerCiVisibilityExporter {
|
|
|
66
74
|
this._coverageWriter.append(formattedCoverage)
|
|
67
75
|
}
|
|
68
76
|
|
|
69
|
-
exportDiLogs (
|
|
70
|
-
this._logsWriter.append({
|
|
77
|
+
exportDiLogs (testEnvironmentMetadata, logMessage) {
|
|
78
|
+
this._logsWriter.append({ testEnvironmentMetadata, logMessage })
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
// TODO: add to other writers
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const { JSONEncoder } = require('../../encode/json-encoder')
|
|
3
|
+
const { getEnvironmentVariable } = require('../../../config-helper')
|
|
3
4
|
|
|
4
5
|
class Writer {
|
|
5
6
|
constructor (interprocessCode) {
|
|
@@ -34,9 +35,17 @@ class Writer {
|
|
|
34
35
|
// See cucumber code:
|
|
35
36
|
// https://github.com/cucumber/cucumber-js/blob/5ce371870b677fe3d1a14915dc535688946f734c/src/runtime/parallel/run_worker.ts#L13
|
|
36
37
|
if (process.send) { // it only works if process.send is available
|
|
37
|
-
|
|
38
|
+
const isVitestWorker = !!getEnvironmentVariable('TINYPOOL_WORKER_ID')
|
|
39
|
+
|
|
40
|
+
const payload = isVitestWorker
|
|
41
|
+
? { __tinypool_worker_message__: true, interprocessCode: this._interprocessCode, data }
|
|
42
|
+
: [this._interprocessCode, data]
|
|
43
|
+
|
|
44
|
+
process.send(payload, () => {
|
|
38
45
|
onDone()
|
|
39
46
|
})
|
|
47
|
+
} else {
|
|
48
|
+
onDone()
|
|
40
49
|
}
|
|
41
50
|
}
|
|
42
51
|
}
|