dd-trace 5.7.0 → 5.9.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 -1
- package/ci/init.js +3 -3
- package/index.d.ts +35 -0
- package/package.json +4 -5
- package/packages/datadog-esbuild/index.js +2 -2
- package/packages/datadog-instrumentations/src/apollo-server.js +1 -1
- package/packages/datadog-instrumentations/src/apollo.js +103 -0
- package/packages/datadog-instrumentations/src/aws-sdk.js +4 -1
- package/packages/datadog-instrumentations/src/cassandra-driver.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber.js +6 -2
- package/packages/datadog-instrumentations/src/fs.js +0 -1
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +57 -56
- package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -2
- package/packages/datadog-instrumentations/src/http/client.js +1 -0
- package/packages/datadog-instrumentations/src/jest.js +12 -13
- package/packages/datadog-instrumentations/src/kafkajs.js +2 -1
- package/packages/datadog-instrumentations/src/ldapjs.js +2 -1
- package/packages/datadog-instrumentations/src/mocha.js +1 -1
- package/packages/datadog-instrumentations/src/mongodb-core.js +4 -6
- package/packages/datadog-instrumentations/src/net.js +1 -1
- package/packages/datadog-instrumentations/src/passport-utils.js +1 -0
- package/packages/datadog-instrumentations/src/playwright.js +158 -7
- package/packages/datadog-instrumentations/src/rhea.js +5 -2
- package/packages/datadog-instrumentations/src/tedious.js +1 -1
- package/packages/datadog-plugin-apollo/src/gateway/execute.js +12 -0
- package/packages/datadog-plugin-apollo/src/gateway/fetch.js +36 -0
- package/packages/datadog-plugin-apollo/src/gateway/index.js +36 -0
- package/packages/datadog-plugin-apollo/src/gateway/plan.js +12 -0
- package/packages/datadog-plugin-apollo/src/gateway/postprocessing.js +12 -0
- package/packages/datadog-plugin-apollo/src/gateway/request.js +124 -0
- package/packages/datadog-plugin-apollo/src/gateway/validate.js +25 -0
- package/packages/datadog-plugin-apollo/src/index.js +15 -0
- package/packages/datadog-plugin-aws-sdk/src/base.js +3 -3
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -2
- package/packages/datadog-plugin-child_process/src/index.js +1 -1
- package/packages/datadog-plugin-couchbase/src/index.js +2 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +1 -0
- package/packages/datadog-plugin-fetch/src/index.js +1 -1
- package/packages/datadog-plugin-graphql/src/resolve.js +1 -1
- package/packages/datadog-plugin-grpc/src/client.js +2 -2
- package/packages/datadog-plugin-grpc/src/server.js +2 -2
- package/packages/datadog-plugin-http/src/client.js +2 -2
- package/packages/datadog-plugin-http2/src/client.js +4 -3
- package/packages/datadog-plugin-jest/src/index.js +1 -0
- package/packages/datadog-plugin-kafkajs/src/consumer.js +1 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +1 -1
- package/packages/datadog-plugin-next/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/index.js +4 -4
- package/packages/datadog-plugin-playwright/src/index.js +16 -3
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -1
- package/packages/datadog-plugin-rhea/src/producer.js +1 -1
- package/packages/datadog-plugin-router/src/index.js +1 -1
- package/packages/datadog-plugin-tedious/src/index.js +1 -1
- package/packages/dd-trace/src/appsec/blocking.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +17 -17
- package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +132 -132
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +2 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +3 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +4 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/namespaces.js +27 -18
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +7 -4
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -1
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +1 -0
- package/packages/dd-trace/src/config.js +13 -13
- package/packages/dd-trace/src/datastreams/pathway.js +1 -1
- package/packages/dd-trace/src/datastreams/processor.js +15 -15
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +2 -2
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +1 -1
- package/packages/dd-trace/src/exporters/common/request.js +1 -0
- package/packages/dd-trace/src/exporters/span-stats/writer.js +0 -1
- package/packages/dd-trace/src/external-logger/src/index.js +5 -5
- package/packages/dd-trace/src/opentelemetry/span.js +2 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -1
- package/packages/dd-trace/src/opentracing/span.js +1 -1
- package/packages/dd-trace/src/plugin_manager.js +1 -2
- package/packages/dd-trace/src/plugins/apollo.js +52 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +2 -1
- package/packages/dd-trace/src/plugins/composite.js +4 -4
- package/packages/dd-trace/src/plugins/database.js +1 -0
- package/packages/dd-trace/src/plugins/index.js +44 -43
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/tracing.js +9 -6
- package/packages/dd-trace/src/plugins/util/test.js +2 -1
- package/packages/dd-trace/src/plugins/util/web.js +4 -4
- package/packages/dd-trace/src/profiling/config.js +1 -1
- package/packages/dd-trace/src/profiling/loggers/console.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +79 -82
- package/packages/dd-trace/src/proxy.js +2 -0
- package/packages/dd-trace/src/runtime_metrics.js +8 -5
- package/packages/dd-trace/src/serverless.js +3 -2
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +24 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +0 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +24 -0
- package/packages/dd-trace/src/span_processor.js +2 -2
- package/packages/dd-trace/src/span_stats.js +1 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +4 -5
- package/packages/dd-trace/src/telemetry/index.js +12 -13
- package/packages/dd-trace/src/telemetry/send-data.js +0 -1
- package/packages/dd-trace/src/util.js +7 -7
|
@@ -15,7 +15,7 @@ const startTCPCh = channel('apm:net:tcp:start')
|
|
|
15
15
|
const finishTCPCh = channel('apm:net:tcp:finish')
|
|
16
16
|
const errorTCPCh = channel('apm:net:tcp:error')
|
|
17
17
|
|
|
18
|
-
const connectionCh = channel(
|
|
18
|
+
const connectionCh = channel('apm:net:tcp:connection')
|
|
19
19
|
|
|
20
20
|
const names = ['net', 'node:net']
|
|
21
21
|
|
|
@@ -10,6 +10,7 @@ function wrapVerifiedAndPublish (username, password, verified, type) {
|
|
|
10
10
|
return verified
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
// eslint-disable-next-line n/handle-callback-err
|
|
13
14
|
return shimmer.wrap(verified, function (err, user, info) {
|
|
14
15
|
const credentials = { type, username }
|
|
15
16
|
passportVerifyChannel.publish({ credentials, user })
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
const semver = require('semver')
|
|
2
|
+
|
|
1
3
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
2
4
|
const shimmer = require('../../datadog-shimmer')
|
|
3
|
-
const { parseAnnotations } = require('../../dd-trace/src/plugins/util/test')
|
|
5
|
+
const { parseAnnotations, getTestSuitePath } = require('../../dd-trace/src/plugins/util/test')
|
|
6
|
+
const log = require('../../dd-trace/src/log')
|
|
4
7
|
|
|
5
8
|
const testStartCh = channel('ci:playwright:test:start')
|
|
6
9
|
const testFinishCh = channel('ci:playwright:test:finish')
|
|
@@ -8,6 +11,9 @@ const testFinishCh = channel('ci:playwright:test:finish')
|
|
|
8
11
|
const testSessionStartCh = channel('ci:playwright:session:start')
|
|
9
12
|
const testSessionFinishCh = channel('ci:playwright:session:finish')
|
|
10
13
|
|
|
14
|
+
const libraryConfigurationCh = channel('ci:playwright:library-configuration')
|
|
15
|
+
const knownTestsCh = channel('ci:playwright:known-tests')
|
|
16
|
+
|
|
11
17
|
const testSuiteStartCh = channel('ci:playwright:test-suite:start')
|
|
12
18
|
const testSuiteFinishCh = channel('ci:playwright:test-suite:finish')
|
|
13
19
|
|
|
@@ -16,6 +22,8 @@ const testSuiteToAr = new Map()
|
|
|
16
22
|
const testSuiteToTestStatuses = new Map()
|
|
17
23
|
const testSuiteToErrors = new Map()
|
|
18
24
|
|
|
25
|
+
let applyRepeatEachIndex = null
|
|
26
|
+
|
|
19
27
|
let startedSuites = []
|
|
20
28
|
|
|
21
29
|
const STATUS_TO_TEST_STATUS = {
|
|
@@ -26,6 +34,44 @@ const STATUS_TO_TEST_STATUS = {
|
|
|
26
34
|
}
|
|
27
35
|
|
|
28
36
|
let remainingTestsByFile = {}
|
|
37
|
+
let isEarlyFlakeDetectionEnabled = false
|
|
38
|
+
let earlyFlakeDetectionNumRetries = 0
|
|
39
|
+
let knownTests = {}
|
|
40
|
+
let rootDir = ''
|
|
41
|
+
const MINIMUM_SUPPORTED_VERSION_EFD = '1.38.0'
|
|
42
|
+
|
|
43
|
+
function isNewTest (test) {
|
|
44
|
+
const testSuite = getTestSuitePath(test._requireFile, rootDir)
|
|
45
|
+
const testsForSuite = knownTests?.playwright?.[testSuite] || []
|
|
46
|
+
|
|
47
|
+
return !testsForSuite.includes(test.title)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getSuiteType (test, type) {
|
|
51
|
+
let suite = test.parent
|
|
52
|
+
while (suite && suite._type !== type) {
|
|
53
|
+
suite = suite.parent
|
|
54
|
+
}
|
|
55
|
+
return suite
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Copy of Suite#_deepClone but with a function to filter tests
|
|
59
|
+
function deepCloneSuite (suite, filterTest) {
|
|
60
|
+
const copy = suite._clone()
|
|
61
|
+
for (const entry of suite._entries) {
|
|
62
|
+
if (entry.constructor.name === 'Suite') {
|
|
63
|
+
copy._addSuite(deepCloneSuite(entry, filterTest))
|
|
64
|
+
} else {
|
|
65
|
+
if (filterTest(entry)) {
|
|
66
|
+
const copiedTest = entry._clone()
|
|
67
|
+
copiedTest._ddIsNew = true
|
|
68
|
+
copiedTest._ddIsEfdRetry = true
|
|
69
|
+
copy._addTest(copiedTest)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return copy
|
|
74
|
+
}
|
|
29
75
|
|
|
30
76
|
function getTestsBySuiteFromTestGroups (testGroups) {
|
|
31
77
|
return testGroups.reduce((acc, { requireFile, tests }) => {
|
|
@@ -153,8 +199,11 @@ function getTestSuiteError (testSuiteAbsolutePath) {
|
|
|
153
199
|
function testBeginHandler (test, browserName) {
|
|
154
200
|
const {
|
|
155
201
|
_requireFile: testSuiteAbsolutePath,
|
|
156
|
-
title: testName,
|
|
157
|
-
|
|
202
|
+
title: testName,
|
|
203
|
+
_type,
|
|
204
|
+
location: {
|
|
205
|
+
line: testSourceLine
|
|
206
|
+
}
|
|
158
207
|
} = test
|
|
159
208
|
|
|
160
209
|
if (_type === 'beforeAll' || _type === 'afterAll') {
|
|
@@ -198,7 +247,14 @@ function testEndHandler (test, annotations, testStatus, error, isTimeout) {
|
|
|
198
247
|
const testResult = results[results.length - 1]
|
|
199
248
|
const testAsyncResource = testToAr.get(test)
|
|
200
249
|
testAsyncResource.runInAsyncScope(() => {
|
|
201
|
-
testFinishCh.publish({
|
|
250
|
+
testFinishCh.publish({
|
|
251
|
+
testStatus,
|
|
252
|
+
steps: testResult.steps,
|
|
253
|
+
error,
|
|
254
|
+
extraTags: annotationTags,
|
|
255
|
+
isNew: test._ddIsNew,
|
|
256
|
+
isEfdRetry: test._ddIsEfdRetry
|
|
257
|
+
})
|
|
202
258
|
})
|
|
203
259
|
|
|
204
260
|
if (testSuiteToTestStatuses.has(testSuiteAbsolutePath)) {
|
|
@@ -309,14 +365,56 @@ function dispatcherHookNew (dispatcherExport, runWrapper) {
|
|
|
309
365
|
|
|
310
366
|
function runnerHook (runnerExport, playwrightVersion) {
|
|
311
367
|
shimmer.wrap(runnerExport.Runner.prototype, 'runAllTests', runAllTests => async function () {
|
|
368
|
+
let onDone
|
|
369
|
+
|
|
312
370
|
const testSessionAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
313
|
-
|
|
371
|
+
|
|
372
|
+
rootDir = getRootDir(this)
|
|
314
373
|
|
|
315
374
|
const processArgv = process.argv.slice(2).join(' ')
|
|
316
375
|
const command = `playwright ${processArgv}`
|
|
317
376
|
testSessionAsyncResource.runInAsyncScope(() => {
|
|
318
377
|
testSessionStartCh.publish({ command, frameworkVersion: playwrightVersion, rootDir })
|
|
319
378
|
})
|
|
379
|
+
|
|
380
|
+
const configurationPromise = new Promise((resolve) => {
|
|
381
|
+
onDone = resolve
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
testSessionAsyncResource.runInAsyncScope(() => {
|
|
385
|
+
libraryConfigurationCh.publish({ onDone })
|
|
386
|
+
})
|
|
387
|
+
|
|
388
|
+
try {
|
|
389
|
+
const { err, libraryConfig } = await configurationPromise
|
|
390
|
+
if (!err) {
|
|
391
|
+
isEarlyFlakeDetectionEnabled = libraryConfig.isEarlyFlakeDetectionEnabled
|
|
392
|
+
earlyFlakeDetectionNumRetries = libraryConfig.earlyFlakeDetectionNumRetries
|
|
393
|
+
}
|
|
394
|
+
} catch (e) {
|
|
395
|
+
log.error(e)
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (isEarlyFlakeDetectionEnabled && semver.gte(playwrightVersion, MINIMUM_SUPPORTED_VERSION_EFD)) {
|
|
399
|
+
const knownTestsPromise = new Promise((resolve) => {
|
|
400
|
+
onDone = resolve
|
|
401
|
+
})
|
|
402
|
+
testSessionAsyncResource.runInAsyncScope(() => {
|
|
403
|
+
knownTestsCh.publish({ onDone })
|
|
404
|
+
})
|
|
405
|
+
|
|
406
|
+
try {
|
|
407
|
+
const { err, knownTests: receivedKnownTests } = await knownTestsPromise
|
|
408
|
+
if (!err) {
|
|
409
|
+
knownTests = receivedKnownTests
|
|
410
|
+
} else {
|
|
411
|
+
isEarlyFlakeDetectionEnabled = false
|
|
412
|
+
}
|
|
413
|
+
} catch (err) {
|
|
414
|
+
log.error(err)
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
320
418
|
const projects = getProjectsFromRunner(this)
|
|
321
419
|
|
|
322
420
|
const runAllTestsReturn = await runAllTests.apply(this, arguments)
|
|
@@ -334,12 +432,15 @@ function runnerHook (runnerExport, playwrightVersion) {
|
|
|
334
432
|
|
|
335
433
|
const sessionStatus = runAllTestsReturn.status || runAllTestsReturn
|
|
336
434
|
|
|
337
|
-
let onDone
|
|
338
435
|
const flushWait = new Promise(resolve => {
|
|
339
436
|
onDone = resolve
|
|
340
437
|
})
|
|
341
438
|
testSessionAsyncResource.runInAsyncScope(() => {
|
|
342
|
-
testSessionFinishCh.publish({
|
|
439
|
+
testSessionFinishCh.publish({
|
|
440
|
+
status: STATUS_TO_TEST_STATUS[sessionStatus],
|
|
441
|
+
isEarlyFlakeDetectionEnabled,
|
|
442
|
+
onDone
|
|
443
|
+
})
|
|
343
444
|
})
|
|
344
445
|
await flushWait
|
|
345
446
|
|
|
@@ -394,3 +495,53 @@ addHook({
|
|
|
394
495
|
file: 'lib/runner/dispatcher.js',
|
|
395
496
|
versions: ['>=1.38.0']
|
|
396
497
|
}, (dispatcher) => dispatcherHookNew(dispatcher, dispatcherRunWrapperNew))
|
|
498
|
+
|
|
499
|
+
// Hook used for early flake detection. EFD only works from >=1.38.0
|
|
500
|
+
addHook({
|
|
501
|
+
name: 'playwright',
|
|
502
|
+
file: 'lib/common/suiteUtils.js',
|
|
503
|
+
versions: [`>=${MINIMUM_SUPPORTED_VERSION_EFD}`]
|
|
504
|
+
}, suiteUtilsPackage => {
|
|
505
|
+
// We grab `applyRepeatEachIndex` to use it later
|
|
506
|
+
// `applyRepeatEachIndex` needs to be applied to a cloned suite
|
|
507
|
+
applyRepeatEachIndex = suiteUtilsPackage.applyRepeatEachIndex
|
|
508
|
+
return suiteUtilsPackage
|
|
509
|
+
})
|
|
510
|
+
|
|
511
|
+
// Hook used for early flake detection. EFD only works from >=1.38.0
|
|
512
|
+
addHook({
|
|
513
|
+
name: 'playwright',
|
|
514
|
+
file: 'lib/runner/loadUtils.js',
|
|
515
|
+
versions: [`>=${MINIMUM_SUPPORTED_VERSION_EFD}`]
|
|
516
|
+
}, (loadUtilsPackage) => {
|
|
517
|
+
const oldCreateRootSuite = loadUtilsPackage.createRootSuite
|
|
518
|
+
|
|
519
|
+
async function newCreateRootSuite () {
|
|
520
|
+
const rootSuite = await oldCreateRootSuite.apply(this, arguments)
|
|
521
|
+
if (!isEarlyFlakeDetectionEnabled) {
|
|
522
|
+
return rootSuite
|
|
523
|
+
}
|
|
524
|
+
const newTests = rootSuite
|
|
525
|
+
.allTests()
|
|
526
|
+
.filter(isNewTest)
|
|
527
|
+
|
|
528
|
+
newTests.forEach(newTest => {
|
|
529
|
+
newTest._ddIsNew = true
|
|
530
|
+
if (newTest.expectedStatus !== 'skipped') {
|
|
531
|
+
const fileSuite = getSuiteType(newTest, 'file')
|
|
532
|
+
const projectSuite = getSuiteType(newTest, 'project')
|
|
533
|
+
for (let repeatEachIndex = 0; repeatEachIndex < earlyFlakeDetectionNumRetries; repeatEachIndex++) {
|
|
534
|
+
const copyFileSuite = deepCloneSuite(fileSuite, isNewTest)
|
|
535
|
+
applyRepeatEachIndex(projectSuite._fullProject, copyFileSuite, repeatEachIndex + 1)
|
|
536
|
+
projectSuite._addSuite(copyFileSuite)
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
})
|
|
540
|
+
|
|
541
|
+
return rootSuite
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
loadUtilsPackage.createRootSuite = newCreateRootSuite
|
|
545
|
+
|
|
546
|
+
return loadUtilsPackage
|
|
547
|
+
})
|
|
@@ -45,7 +45,9 @@ addHook({ name: 'rhea', versions: ['>=1'], file: 'lib/link.js' }, obj => {
|
|
|
45
45
|
const { host, port } = getHostAndPort(this.connection)
|
|
46
46
|
|
|
47
47
|
const targetAddress = this.options && this.options.target &&
|
|
48
|
-
this.options.target.address
|
|
48
|
+
this.options.target.address
|
|
49
|
+
? this.options.target.address
|
|
50
|
+
: undefined
|
|
49
51
|
|
|
50
52
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
51
53
|
return asyncResource.runInAsyncScope(() => {
|
|
@@ -187,7 +189,8 @@ function patchCircularBuffer (proto, Session) {
|
|
|
187
189
|
if (shouldPop) {
|
|
188
190
|
const remoteState = entry.remote_state
|
|
189
191
|
const state = remoteState && remoteState.constructor
|
|
190
|
-
? entry.remote_state.constructor.composite_type
|
|
192
|
+
? entry.remote_state.constructor.composite_type
|
|
193
|
+
: undefined
|
|
191
194
|
asyncResource.runInAsyncScope(() => {
|
|
192
195
|
exports.beforeFinish(entry, state)
|
|
193
196
|
finishSendCh.publish()
|
|
@@ -7,7 +7,7 @@ const {
|
|
|
7
7
|
} = require('./helpers/instrument')
|
|
8
8
|
const shimmer = require('../../datadog-shimmer')
|
|
9
9
|
|
|
10
|
-
addHook({ name: 'tedious', versions: [
|
|
10
|
+
addHook({ name: 'tedious', versions: ['>=1.0.0'] }, tedious => {
|
|
11
11
|
const startCh = channel('apm:tedious:request:start')
|
|
12
12
|
const finishCh = channel('apm:tedious:request:finish')
|
|
13
13
|
const errorCh = channel('apm:tedious:request:error')
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
4
|
+
|
|
5
|
+
class ApolloGatewayExecutePlugin extends ApolloBasePlugin {
|
|
6
|
+
static get operation () { return 'execute' }
|
|
7
|
+
static get prefix () {
|
|
8
|
+
return 'tracing:apm:apollo:gateway:execute'
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = ApolloGatewayExecutePlugin
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { storage } = require('../../../datadog-core')
|
|
4
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
5
|
+
|
|
6
|
+
class ApolloGatewayFetchPlugin extends ApolloBasePlugin {
|
|
7
|
+
static get operation () { return 'fetch' }
|
|
8
|
+
static get prefix () {
|
|
9
|
+
return 'tracing:apm:apollo:gateway:fetch'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
bindStart (ctx) {
|
|
13
|
+
const store = storage.getStore()
|
|
14
|
+
const childOf = store ? store.span : null
|
|
15
|
+
|
|
16
|
+
const spanData = {
|
|
17
|
+
childOf,
|
|
18
|
+
service: this.getServiceName(),
|
|
19
|
+
type: this.constructor.type,
|
|
20
|
+
meta: {}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const serviceName = ctx?.attributes?.service
|
|
24
|
+
|
|
25
|
+
if (serviceName) { spanData.meta.serviceName = serviceName }
|
|
26
|
+
|
|
27
|
+
const span = this.startSpan(this.getOperationName(), spanData, false)
|
|
28
|
+
|
|
29
|
+
ctx.parentStore = store
|
|
30
|
+
ctx.currentStore = { ...store, span }
|
|
31
|
+
|
|
32
|
+
return ctx.currentStore
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = ApolloGatewayFetchPlugin
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { storage } = require('../../../datadog-core')
|
|
4
|
+
const CompositePlugin = require('../../../dd-trace/src/plugins/composite')
|
|
5
|
+
const ApolloGatewayExecutePlugin = require('./execute')
|
|
6
|
+
const ApolloGatewayPostProcessingPlugin = require('./postprocessing')
|
|
7
|
+
const ApolloGatewayRequestPlugin = require('./request')
|
|
8
|
+
const ApolloGatewayPlanPlugin = require('./plan')
|
|
9
|
+
const ApolloGatewayValidatePlugin = require('./validate')
|
|
10
|
+
const ApolloGatewayFetchPlugin = require('./fetch')
|
|
11
|
+
|
|
12
|
+
class ApolloGatewayPlugin extends CompositePlugin {
|
|
13
|
+
static get id () { return 'gateway' }
|
|
14
|
+
static get plugins () {
|
|
15
|
+
return {
|
|
16
|
+
execute: ApolloGatewayExecutePlugin,
|
|
17
|
+
postprocessing: ApolloGatewayPostProcessingPlugin,
|
|
18
|
+
request: ApolloGatewayRequestPlugin,
|
|
19
|
+
plan: ApolloGatewayPlanPlugin,
|
|
20
|
+
fetch: ApolloGatewayFetchPlugin,
|
|
21
|
+
validate: ApolloGatewayValidatePlugin
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
constructor (...args) {
|
|
26
|
+
super(...args)
|
|
27
|
+
this.addSub('apm:apollo:gateway:general:error', (ctx) => {
|
|
28
|
+
const store = storage.getStore()
|
|
29
|
+
const span = store?.span
|
|
30
|
+
if (!span) return
|
|
31
|
+
span.setTag('error', ctx.error)
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = ApolloGatewayPlugin
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
4
|
+
|
|
5
|
+
class ApolloGatewayPlanPlugin extends ApolloBasePlugin {
|
|
6
|
+
static get operation () { return 'plan' }
|
|
7
|
+
static get prefix () {
|
|
8
|
+
return 'tracing:apm:apollo:gateway:plan'
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = ApolloGatewayPlanPlugin
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
4
|
+
|
|
5
|
+
class ApolloGatewayPostProcessingPlugin extends ApolloBasePlugin {
|
|
6
|
+
static get operation () { return 'postprocessing' }
|
|
7
|
+
static get prefix () {
|
|
8
|
+
return 'tracing:apm:apollo:gateway:postprocessing'
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = ApolloGatewayPostProcessingPlugin
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { storage } = require('../../../datadog-core')
|
|
4
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
5
|
+
|
|
6
|
+
let tools
|
|
7
|
+
|
|
8
|
+
const OPERATION_DEFINITION = 'OperationDefinition'
|
|
9
|
+
const FRAGMENT_DEFINITION = 'FragmentDefinition'
|
|
10
|
+
|
|
11
|
+
class ApolloGatewayRequestPlugin extends ApolloBasePlugin {
|
|
12
|
+
static get operation () { return 'request' }
|
|
13
|
+
static get prefix () {
|
|
14
|
+
return 'tracing:apm:apollo:gateway:request'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
bindStart (ctx) {
|
|
18
|
+
const store = storage.getStore()
|
|
19
|
+
const childOf = store ? store.span : null
|
|
20
|
+
const spanData = {
|
|
21
|
+
childOf,
|
|
22
|
+
service: this.serviceName(
|
|
23
|
+
{ id: `${this.constructor.id}.${this.constructor.operation}`, pluginConfig: this.config }),
|
|
24
|
+
type: this.constructor.type,
|
|
25
|
+
kind: this.constructor.kind,
|
|
26
|
+
meta: {}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { requestContext, gateway } = ctx
|
|
30
|
+
|
|
31
|
+
if (requestContext?.operationName) {
|
|
32
|
+
spanData.meta['graphql.operation.name'] = requestContext.operationName
|
|
33
|
+
}
|
|
34
|
+
if ((this.config.source || gateway?.config?.telemetry?.includeDocument) && requestContext?.source) {
|
|
35
|
+
spanData.meta['graphql.source'] = requestContext.source
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const operationContext =
|
|
39
|
+
buildOperationContext(gateway.schema, requestContext.document, requestContext.request.operationName)
|
|
40
|
+
|
|
41
|
+
if (operationContext?.operation?.operation) {
|
|
42
|
+
const document = requestContext?.document
|
|
43
|
+
const type = operationContext?.operation?.operation
|
|
44
|
+
const name = operationContext?.operation?.name && operationContext?.operation?.name?.value
|
|
45
|
+
|
|
46
|
+
spanData.resource = getSignature(document, name, type, this?.config?.signature)
|
|
47
|
+
spanData.meta['graphql.operation.type'] = type
|
|
48
|
+
}
|
|
49
|
+
const span = this.startSpan(this.operationName({ id: `${this.constructor.id}.${this.constructor.operation}` }),
|
|
50
|
+
spanData, false)
|
|
51
|
+
|
|
52
|
+
ctx.parentStore = store
|
|
53
|
+
ctx.currentStore = { ...store, span }
|
|
54
|
+
return ctx.currentStore
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
asyncStart (ctx) {
|
|
58
|
+
const errors = ctx?.result?.errors
|
|
59
|
+
// apollo gateway catches certain errors and returns them in the result object
|
|
60
|
+
// we want to capture these errors as spans
|
|
61
|
+
if (errors instanceof Array &&
|
|
62
|
+
errors[errors.length - 1] && errors[errors.length - 1].stack && errors[errors.length - 1].message) {
|
|
63
|
+
ctx.currentStore.span.setTag('error', errors[errors.length - 1])
|
|
64
|
+
}
|
|
65
|
+
ctx.currentStore.span.finish()
|
|
66
|
+
return ctx.parentStore
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function buildOperationContext (schema, operationDocument, operationName) {
|
|
71
|
+
let operation
|
|
72
|
+
let operationCount = 0
|
|
73
|
+
const fragments = Object.create(null)
|
|
74
|
+
try {
|
|
75
|
+
operationDocument.definitions.forEach(definition => {
|
|
76
|
+
switch (definition.kind) {
|
|
77
|
+
case OPERATION_DEFINITION:
|
|
78
|
+
operationCount++
|
|
79
|
+
if (!operationName && operationCount > 1) {
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
if (
|
|
83
|
+
!operationName ||
|
|
84
|
+
(definition.name && definition.name.value === operationName)
|
|
85
|
+
) {
|
|
86
|
+
operation = definition
|
|
87
|
+
}
|
|
88
|
+
break
|
|
89
|
+
case FRAGMENT_DEFINITION:
|
|
90
|
+
fragments[definition.name.value] = definition
|
|
91
|
+
break
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
} catch (e) {
|
|
95
|
+
// safety net
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
schema,
|
|
100
|
+
operation,
|
|
101
|
+
fragments
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function getSignature (document, operationName, operationType, calculate) {
|
|
106
|
+
if (calculate !== false && tools !== false) {
|
|
107
|
+
try {
|
|
108
|
+
try {
|
|
109
|
+
tools = tools || require('../../../datadog-plugin-graphql/src/tools')
|
|
110
|
+
} catch (e) {
|
|
111
|
+
tools = false
|
|
112
|
+
throw e
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return tools.defaultEngineReportingSignature(document, operationName)
|
|
116
|
+
} catch (e) {
|
|
117
|
+
// safety net
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return [operationType, operationName].filter(val => val).join(' ')
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
module.exports = ApolloGatewayRequestPlugin
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
4
|
+
|
|
5
|
+
class ApolloGatewayValidatePlugin extends ApolloBasePlugin {
|
|
6
|
+
static get operation () { return 'validate' }
|
|
7
|
+
static get prefix () {
|
|
8
|
+
return 'tracing:apm:apollo:gateway:validate'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
end (ctx) {
|
|
12
|
+
const result = ctx.result
|
|
13
|
+
const span = ctx.currentStore?.span
|
|
14
|
+
|
|
15
|
+
if (!span) return
|
|
16
|
+
|
|
17
|
+
if (result instanceof Array &&
|
|
18
|
+
result[result.length - 1] && result[result.length - 1].stack && result[result.length - 1].message) {
|
|
19
|
+
span.setTag('error', result[result.length - 1])
|
|
20
|
+
}
|
|
21
|
+
span.finish()
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = ApolloGatewayValidatePlugin
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
4
|
+
const ApolloGatewayPlugin = require('./gateway')
|
|
5
|
+
|
|
6
|
+
class ApolloPlugin extends CompositePlugin {
|
|
7
|
+
static get id () { return 'apollo' }
|
|
8
|
+
static get plugins () {
|
|
9
|
+
return {
|
|
10
|
+
gateway: ApolloGatewayPlugin
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
module.exports = ApolloPlugin
|
|
@@ -37,10 +37,10 @@ class BaseAwsSdkPlugin extends ClientPlugin {
|
|
|
37
37
|
'service.name': this.serviceName(),
|
|
38
38
|
'aws.operation': operation,
|
|
39
39
|
'aws.region': awsRegion,
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
region: awsRegion,
|
|
41
|
+
aws_service: awsService,
|
|
42
42
|
'aws.service': awsService,
|
|
43
|
-
|
|
43
|
+
component: 'aws-sdk'
|
|
44
44
|
}
|
|
45
45
|
if (this.requestTags) this.requestTags.set(request, tags)
|
|
46
46
|
|
|
@@ -13,7 +13,7 @@ class CloudwatchLogs extends BaseAwsSdkPlugin {
|
|
|
13
13
|
return Object.assign(tags, {
|
|
14
14
|
'resource.name': `${operation} ${params.logGroupName}`,
|
|
15
15
|
'aws.cloudwatch.logs.log_group_name': params.logGroupName,
|
|
16
|
-
|
|
16
|
+
loggroupname: params.logGroupName
|
|
17
17
|
})
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -14,7 +14,7 @@ class DynamoDb extends BaseAwsSdkPlugin {
|
|
|
14
14
|
Object.assign(tags, {
|
|
15
15
|
'resource.name': `${operation} ${params.TableName}`,
|
|
16
16
|
'aws.dynamodb.table_name': params.TableName,
|
|
17
|
-
|
|
17
|
+
tablename: params.TableName
|
|
18
18
|
})
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -30,7 +30,7 @@ class DynamoDb extends BaseAwsSdkPlugin {
|
|
|
30
30
|
Object.assign(tags, {
|
|
31
31
|
'resource.name': `${operation} ${tableName}`,
|
|
32
32
|
'aws.dynamodb.table_name': tableName,
|
|
33
|
-
|
|
33
|
+
tablename: tableName
|
|
34
34
|
})
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -13,7 +13,7 @@ class Redshift extends BaseAwsSdkPlugin {
|
|
|
13
13
|
return Object.assign(tags, {
|
|
14
14
|
'resource.name': `${operation} ${params.ClusterIdentifier}`,
|
|
15
15
|
'aws.redshift.cluster_identifier': params.ClusterIdentifier,
|
|
16
|
-
|
|
16
|
+
clusteridentifier: params.ClusterIdentifier
|
|
17
17
|
})
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -23,7 +23,7 @@ class Sns extends BaseAwsSdkPlugin {
|
|
|
23
23
|
return {
|
|
24
24
|
'resource.name': `${operation} ${params.TopicArn || response.data.TopicArn}`,
|
|
25
25
|
'aws.sns.topic_arn': TopicArn,
|
|
26
|
-
|
|
26
|
+
topicname: topicName
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// TODO: should arn be sanitized or quantized in some way here,
|