dd-trace 3.12.1 → 3.15.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 -0
- package/README.md +5 -5
- package/ci/init.js +3 -1
- package/index.d.ts +100 -1
- package/package.json +5 -4
- package/packages/datadog-instrumentations/src/aws-sdk.js +86 -0
- package/packages/datadog-instrumentations/src/cucumber.js +74 -15
- package/packages/datadog-instrumentations/src/cypress.js +1 -1
- package/packages/datadog-instrumentations/src/fs.js +358 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +24 -23
- package/packages/datadog-instrumentations/src/ldapjs.js +12 -2
- package/packages/datadog-instrumentations/src/mocha.js +10 -7
- package/packages/datadog-instrumentations/src/mongoose.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +7 -1
- package/packages/datadog-instrumentations/src/mysql2.js +7 -1
- package/packages/datadog-instrumentations/src/next.js +2 -1
- package/packages/datadog-instrumentations/src/playwright.js +263 -0
- package/packages/datadog-plugin-aws-sdk/src/base.js +12 -5
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +29 -24
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +31 -16
- package/packages/datadog-plugin-cucumber/src/index.js +42 -11
- package/packages/datadog-plugin-cypress/src/plugin.js +129 -4
- package/packages/datadog-plugin-cypress/src/support.js +5 -0
- package/packages/datadog-plugin-fs/src/index.js +45 -0
- package/packages/datadog-plugin-hapi/src/index.js +5 -1
- package/packages/datadog-plugin-http/src/server.js +1 -1
- package/packages/datadog-plugin-http2/src/server.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +40 -70
- package/packages/datadog-plugin-mocha/src/index.js +44 -64
- package/packages/datadog-plugin-mysql/src/index.js +8 -7
- package/packages/datadog-plugin-playwright/src/index.js +112 -0
- package/packages/datadog-shimmer/src/shimmer.js +28 -11
- package/packages/dd-trace/src/appsec/addresses.js +3 -1
- package/packages/dd-trace/src/appsec/blocking.js +35 -9
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +60 -0
- package/packages/dd-trace/src/appsec/iast/iast-context.js +6 -2
- package/packages/dd-trace/src/appsec/iast/index.js +3 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -2
- package/packages/dd-trace/src/appsec/index.js +5 -5
- package/packages/dd-trace/src/appsec/recommended.json +320 -184
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +3 -0
- package/packages/dd-trace/src/appsec/reporter.js +14 -14
- package/packages/dd-trace/src/appsec/sdk/index.js +41 -0
- package/packages/dd-trace/src/appsec/sdk/noop.js +17 -0
- package/packages/dd-trace/src/appsec/sdk/set_user.js +30 -0
- package/packages/dd-trace/src/appsec/sdk/track_event.js +74 -0
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +73 -0
- package/packages/dd-trace/src/appsec/sdk/utils.js +10 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +1 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +1 -5
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +48 -11
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +7 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +4 -2
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +5 -3
- package/packages/dd-trace/src/config.js +63 -7
- package/packages/dd-trace/src/encode/0.4.js +1 -1
- package/packages/dd-trace/src/encode/0.5.js +1 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +44 -4
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +52 -37
- package/packages/dd-trace/src/encode/tags-processors.js +3 -2
- package/packages/dd-trace/src/exporters/common/request.js +10 -3
- package/packages/dd-trace/src/lambda/handler.js +5 -6
- package/packages/dd-trace/src/log/channels.js +47 -0
- package/packages/dd-trace/src/log/index.js +79 -0
- package/packages/dd-trace/src/log/writer.js +124 -0
- package/packages/dd-trace/src/metrics.js +18 -0
- package/packages/dd-trace/src/noop/proxy.js +5 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +188 -36
- package/packages/dd-trace/src/opentracing/propagation/tracestate.js +99 -0
- package/packages/dd-trace/src/opentracing/span.js +2 -1
- package/packages/dd-trace/src/opentracing/span_context.js +6 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +72 -12
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/util/ci.js +13 -21
- package/packages/dd-trace/src/plugins/util/exec.js +2 -2
- package/packages/dd-trace/src/plugins/util/git.js +16 -1
- package/packages/dd-trace/src/{appsec → plugins/util}/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +53 -10
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -7
- package/packages/dd-trace/src/plugins/util/web.js +11 -0
- package/packages/dd-trace/src/profiler.js +3 -0
- package/packages/dd-trace/src/profiling/config.js +8 -3
- package/packages/dd-trace/src/profiling/exporters/file.js +13 -2
- package/packages/dd-trace/src/profiling/profiler.js +23 -6
- package/packages/dd-trace/src/profiling/profilers/wall.js +1 -0
- package/packages/dd-trace/src/proxy.js +2 -0
- package/packages/dd-trace/src/span_processor.js +1 -1
- package/packages/dd-trace/src/span_sampler.js +68 -52
- package/packages/dd-trace/src/startup-log.js +3 -6
- package/packages/dd-trace/src/telemetry/index.js +23 -2
- package/packages/dd-trace/src/telemetry/send-data.js +4 -1
- package/packages/dd-trace/src/tracer.js +0 -16
- package/scripts/check-proposal-labels.js +71 -0
- package/packages/dd-trace/src/log.js +0 -143
- /package/packages/dd-trace/src/{appsec → plugins/util}/ip_blocklist.js +0 -0
|
@@ -8,7 +8,12 @@ beforeEach(() => {
|
|
|
8
8
|
})
|
|
9
9
|
})
|
|
10
10
|
|
|
11
|
+
before(() => {
|
|
12
|
+
cy.task('dd:testSuiteStart', Cypress.mocha.getRootSuite().file)
|
|
13
|
+
})
|
|
14
|
+
|
|
11
15
|
after(() => {
|
|
16
|
+
cy.task('dd:testSuiteFinish', Cypress.mocha.getRunner().stats)
|
|
12
17
|
cy.window().then(win => {
|
|
13
18
|
win.dispatchEvent(new Event('beforeunload'))
|
|
14
19
|
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
|
|
4
|
+
|
|
5
|
+
class FsPlugin extends TracingPlugin {
|
|
6
|
+
static get name () { return 'fs' }
|
|
7
|
+
static get operation () { return 'operation' }
|
|
8
|
+
|
|
9
|
+
configure (...args) {
|
|
10
|
+
return super.configure(...args)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
start ({ operation, ...params }) {
|
|
14
|
+
if (!this.activeSpan) return this.skip()
|
|
15
|
+
|
|
16
|
+
const lowerOp = operation.toLowerCase()
|
|
17
|
+
const flag = params.flag || params.flags || (params.options && (params.options.flag || params.options.flags))
|
|
18
|
+
const defaultFlag = ((lowerOp.includes('open') || lowerOp.includes('read')) && 'r') ||
|
|
19
|
+
(lowerOp.includes('write') && 'w') ||
|
|
20
|
+
(lowerOp.includes('append') && 'a')
|
|
21
|
+
const fd = params.fd || (typeof params.file === 'number' && params.file)
|
|
22
|
+
const path = params.path || params.prefix || params.filename || (typeof params.file === 'string' && params.file)
|
|
23
|
+
const uid = typeof params.uid === 'number' && params.uid.toString()
|
|
24
|
+
const gid = typeof params.gid === 'number' && params.gid.toString()
|
|
25
|
+
const mode = typeof params.mode === 'number' ? params.mode.toString(8) : params.mode
|
|
26
|
+
|
|
27
|
+
this.startSpan('fs.operation', {
|
|
28
|
+
service: this.config.service,
|
|
29
|
+
resource: operation,
|
|
30
|
+
kind: 'internal',
|
|
31
|
+
meta: {
|
|
32
|
+
'file.descriptor': (typeof fd === 'object' || typeof fd === 'number') ? fd.toString() : '',
|
|
33
|
+
'file.dest': params.dest || params.newPath || (params.target && params.path),
|
|
34
|
+
'file.flag': String(flag || defaultFlag || ''),
|
|
35
|
+
'file.gid': gid || '',
|
|
36
|
+
'file.mode': mode,
|
|
37
|
+
'file.path': path || '',
|
|
38
|
+
'file.src': params.src || params.oldPath || params.existingPath || params.target,
|
|
39
|
+
'file.uid': uid || ''
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = FsPlugin
|
|
@@ -26,7 +26,11 @@ class HapiPlugin extends RouterPlugin {
|
|
|
26
26
|
web.setRoute(req, route)
|
|
27
27
|
})
|
|
28
28
|
|
|
29
|
-
this.addSub(
|
|
29
|
+
this.addSub('apm:hapi:request:error', error => {
|
|
30
|
+
if (!error || !error.isBoom || !this.config.validateStatus(error.output.statusCode)) {
|
|
31
|
+
this.addError(error)
|
|
32
|
+
}
|
|
33
|
+
})
|
|
30
34
|
|
|
31
35
|
this.addSub('apm:hapi:extension:enter', ({ req }) => {
|
|
32
36
|
this.enter(this._requestSpans.get(req))
|
|
@@ -6,18 +6,12 @@ const {
|
|
|
6
6
|
JEST_TEST_RUNNER,
|
|
7
7
|
finishAllTraceSpans,
|
|
8
8
|
getTestEnvironmentMetadata,
|
|
9
|
-
getTestParentSpan,
|
|
10
|
-
getTestSessionCommonTags,
|
|
11
9
|
getTestSuiteCommonTags,
|
|
10
|
+
addIntelligentTestRunnerSpanTags,
|
|
12
11
|
TEST_PARAMETERS,
|
|
13
12
|
getCodeOwnersFileEntries,
|
|
14
|
-
TEST_SESSION_ID,
|
|
15
|
-
TEST_SUITE_ID,
|
|
16
13
|
TEST_COMMAND,
|
|
17
|
-
|
|
18
|
-
TEST_SESSION_CODE_COVERAGE_ENABLED,
|
|
19
|
-
TEST_SESSION_ITR_SKIPPING_ENABLED,
|
|
20
|
-
TEST_CODE_COVERAGE_LINES_TOTAL
|
|
14
|
+
TEST_FRAMEWORK_VERSION
|
|
21
15
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
22
16
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
23
17
|
|
|
@@ -49,22 +43,6 @@ class JestPlugin extends CiPlugin {
|
|
|
49
43
|
this.testEnvironmentMetadata = getTestEnvironmentMetadata('jest', this.config)
|
|
50
44
|
this.codeOwnersEntries = getCodeOwnersFileEntries()
|
|
51
45
|
|
|
52
|
-
this.addSub('ci:jest:session:start', (command) => {
|
|
53
|
-
const store = storage.getStore()
|
|
54
|
-
const childOf = getTestParentSpan(this.tracer)
|
|
55
|
-
const testSessionSpanMetadata = getTestSessionCommonTags(command, this.tracer._version)
|
|
56
|
-
|
|
57
|
-
const testSessionSpan = this.tracer.startSpan('jest.test_session', {
|
|
58
|
-
childOf,
|
|
59
|
-
tags: {
|
|
60
|
-
[COMPONENT]: this.constructor.name,
|
|
61
|
-
...this.testEnvironmentMetadata,
|
|
62
|
-
...testSessionSpanMetadata
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
this.enter(testSessionSpan, store)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
46
|
this.addSub('ci:jest:session:finish', ({
|
|
69
47
|
status,
|
|
70
48
|
isSuitesSkipped,
|
|
@@ -72,18 +50,18 @@ class JestPlugin extends CiPlugin {
|
|
|
72
50
|
isCodeCoverageEnabled,
|
|
73
51
|
testCodeCoverageLinesTotal
|
|
74
52
|
}) => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
testSessionSpan.finish()
|
|
86
|
-
finishAllTraceSpans(testSessionSpan)
|
|
53
|
+
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
54
|
+
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
55
|
+
|
|
56
|
+
addIntelligentTestRunnerSpanTags(
|
|
57
|
+
this.testSessionSpan,
|
|
58
|
+
this.testModuleSpan,
|
|
59
|
+
{ isSuitesSkipped, isSuitesSkippingEnabled, isCodeCoverageEnabled, testCodeCoverageLinesTotal }
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
this.testModuleSpan.finish()
|
|
63
|
+
this.testSessionSpan.finish()
|
|
64
|
+
finishAllTraceSpans(this.testSessionSpan)
|
|
87
65
|
this.tracer._exporter.flush()
|
|
88
66
|
})
|
|
89
67
|
|
|
@@ -91,26 +69,28 @@ class JestPlugin extends CiPlugin {
|
|
|
91
69
|
// This subscriber changes the configuration objects from jest to inject the trace id
|
|
92
70
|
// of the test session to the processes that run the test suites.
|
|
93
71
|
this.addSub('ci:jest:session:configuration', configs => {
|
|
94
|
-
const testSessionSpan = storage.getStore().span
|
|
95
72
|
configs.forEach(config => {
|
|
96
|
-
config._ddTestSessionId = testSessionSpan.context().
|
|
97
|
-
config.
|
|
73
|
+
config._ddTestSessionId = this.testSessionSpan.context().toTraceId()
|
|
74
|
+
config._ddTestModuleId = this.testModuleSpan.context().toSpanId()
|
|
75
|
+
config._ddTestCommand = this.testSessionSpan.context()._tags[TEST_COMMAND]
|
|
98
76
|
})
|
|
99
77
|
})
|
|
100
78
|
|
|
101
|
-
this.addSub('ci:jest:test-suite:start', ({ testSuite, testEnvironmentOptions }) => {
|
|
102
|
-
const {
|
|
103
|
-
|
|
104
|
-
|
|
79
|
+
this.addSub('ci:jest:test-suite:start', ({ testSuite, testEnvironmentOptions, frameworkVersion }) => {
|
|
80
|
+
const {
|
|
81
|
+
_ddTestSessionId: testSessionId,
|
|
82
|
+
_ddTestCommand: testCommand,
|
|
83
|
+
_ddTestModuleId: testModuleId
|
|
84
|
+
} = testEnvironmentOptions
|
|
105
85
|
|
|
106
86
|
const testSessionSpanContext = this.tracer.extract('text_map', {
|
|
107
87
|
'x-datadog-trace-id': testSessionId,
|
|
108
|
-
'x-datadog-parent-id':
|
|
88
|
+
'x-datadog-parent-id': testModuleId
|
|
109
89
|
})
|
|
110
90
|
|
|
111
|
-
const testSuiteMetadata = getTestSuiteCommonTags(testCommand,
|
|
91
|
+
const testSuiteMetadata = getTestSuiteCommonTags(testCommand, frameworkVersion, testSuite)
|
|
112
92
|
|
|
113
|
-
|
|
93
|
+
this.testSuiteSpan = this.tracer.startSpan('jest.test_suite', {
|
|
114
94
|
childOf: testSessionSpanContext,
|
|
115
95
|
tags: {
|
|
116
96
|
[COMPONENT]: this.constructor.name,
|
|
@@ -118,19 +98,17 @@ class JestPlugin extends CiPlugin {
|
|
|
118
98
|
...testSuiteMetadata
|
|
119
99
|
}
|
|
120
100
|
})
|
|
121
|
-
this.enter(testSuiteSpan, store)
|
|
122
101
|
})
|
|
123
102
|
|
|
124
103
|
this.addSub('ci:jest:test-suite:finish', ({ status, errorMessage }) => {
|
|
125
|
-
|
|
126
|
-
testSuiteSpan.setTag(TEST_STATUS, status)
|
|
104
|
+
this.testSuiteSpan.setTag(TEST_STATUS, status)
|
|
127
105
|
if (errorMessage) {
|
|
128
|
-
testSuiteSpan.setTag('error', new Error(errorMessage))
|
|
106
|
+
this.testSuiteSpan.setTag('error', new Error(errorMessage))
|
|
129
107
|
}
|
|
130
|
-
testSuiteSpan.finish()
|
|
108
|
+
this.testSuiteSpan.finish()
|
|
131
109
|
// Suites potentially run in a different process than the session,
|
|
132
110
|
// so calling finishAllTraceSpans on the session span is not enough
|
|
133
|
-
finishAllTraceSpans(testSuiteSpan)
|
|
111
|
+
finishAllTraceSpans(this.testSuiteSpan)
|
|
134
112
|
})
|
|
135
113
|
|
|
136
114
|
/**
|
|
@@ -139,8 +117,7 @@ class JestPlugin extends CiPlugin {
|
|
|
139
117
|
* fetching the ITR config.
|
|
140
118
|
*/
|
|
141
119
|
this.addSub('ci:jest:test-suite:code-coverage', (coverageFiles) => {
|
|
142
|
-
|
|
143
|
-
this.tracer._exporter.exportCoverage({ span: testSuiteSpan, coverageFiles })
|
|
120
|
+
this.tracer._exporter.exportCoverage({ span: this.testSuiteSpan, coverageFiles })
|
|
144
121
|
})
|
|
145
122
|
|
|
146
123
|
this.addSub('ci:jest:test:start', (test) => {
|
|
@@ -159,9 +136,12 @@ class JestPlugin extends CiPlugin {
|
|
|
159
136
|
|
|
160
137
|
this.addSub('ci:jest:test:err', (error) => {
|
|
161
138
|
if (error) {
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
139
|
+
const store = storage.getStore()
|
|
140
|
+
if (store && store.span) {
|
|
141
|
+
const span = store.span
|
|
142
|
+
span.setTag(TEST_STATUS, 'fail')
|
|
143
|
+
span.setTag('error', error)
|
|
144
|
+
}
|
|
165
145
|
}
|
|
166
146
|
})
|
|
167
147
|
|
|
@@ -173,25 +153,15 @@ class JestPlugin extends CiPlugin {
|
|
|
173
153
|
}
|
|
174
154
|
|
|
175
155
|
startTestSpan (test) {
|
|
176
|
-
const
|
|
177
|
-
const store = storage.getStore()
|
|
178
|
-
const testSuiteSpan = store ? store.span : undefined
|
|
179
|
-
if (testSuiteSpan) {
|
|
180
|
-
const testSuiteId = testSuiteSpan.context()._spanId.toString(10)
|
|
181
|
-
suiteTags[TEST_SUITE_ID] = testSuiteId
|
|
182
|
-
suiteTags[TEST_SESSION_ID] = testSuiteSpan.context()._traceId.toString(10)
|
|
183
|
-
suiteTags[TEST_COMMAND] = testSuiteSpan.context()._tags[TEST_COMMAND]
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const { suite, name, runner, testParameters } = test
|
|
156
|
+
const { suite, name, runner, testParameters, frameworkVersion } = test
|
|
187
157
|
|
|
188
158
|
const extraTags = {
|
|
189
159
|
[JEST_TEST_RUNNER]: runner,
|
|
190
160
|
[TEST_PARAMETERS]: testParameters,
|
|
191
|
-
|
|
161
|
+
[TEST_FRAMEWORK_VERSION]: frameworkVersion
|
|
192
162
|
}
|
|
193
163
|
|
|
194
|
-
return super.startTestSpan(name, suite, extraTags)
|
|
164
|
+
return super.startTestSpan(name, suite, this.testSuiteSpan, extraTags)
|
|
195
165
|
}
|
|
196
166
|
}
|
|
197
167
|
|
|
@@ -8,16 +8,9 @@ const {
|
|
|
8
8
|
TEST_PARAMETERS,
|
|
9
9
|
finishAllTraceSpans,
|
|
10
10
|
getTestSuitePath,
|
|
11
|
-
getTestParentSpan,
|
|
12
11
|
getTestParametersString,
|
|
13
|
-
getTestSessionCommonTags,
|
|
14
12
|
getTestSuiteCommonTags,
|
|
15
|
-
|
|
16
|
-
TEST_SESSION_ID,
|
|
17
|
-
TEST_COMMAND,
|
|
18
|
-
TEST_ITR_TESTS_SKIPPED,
|
|
19
|
-
TEST_SESSION_CODE_COVERAGE_ENABLED,
|
|
20
|
-
TEST_SESSION_ITR_SKIPPING_ENABLED
|
|
13
|
+
addIntelligentTestRunnerSpanTags
|
|
21
14
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
22
15
|
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
23
16
|
|
|
@@ -48,30 +41,15 @@ class MochaPlugin extends CiPlugin {
|
|
|
48
41
|
})
|
|
49
42
|
})
|
|
50
43
|
|
|
51
|
-
this.addSub('ci:mocha:session:start', (command) => {
|
|
52
|
-
const childOf = getTestParentSpan(this.tracer)
|
|
53
|
-
const testSessionSpanMetadata = getTestSessionCommonTags(command, this.tracer._version)
|
|
54
|
-
|
|
55
|
-
this.command = command
|
|
56
|
-
this.testSessionSpan = this.tracer.startSpan('mocha.test_session', {
|
|
57
|
-
childOf,
|
|
58
|
-
tags: {
|
|
59
|
-
[COMPONENT]: this.constructor.name,
|
|
60
|
-
...this.testEnvironmentMetadata,
|
|
61
|
-
...testSessionSpanMetadata
|
|
62
|
-
}
|
|
63
|
-
})
|
|
64
|
-
})
|
|
65
|
-
|
|
66
44
|
this.addSub('ci:mocha:test-suite:start', (suite) => {
|
|
67
45
|
const store = storage.getStore()
|
|
68
46
|
const testSuiteMetadata = getTestSuiteCommonTags(
|
|
69
47
|
this.command,
|
|
70
|
-
this.
|
|
48
|
+
this.frameworkVersion,
|
|
71
49
|
getTestSuitePath(suite.file, this.sourceRoot)
|
|
72
50
|
)
|
|
73
51
|
const testSuiteSpan = this.tracer.startSpan('mocha.test_suite', {
|
|
74
|
-
childOf: this.
|
|
52
|
+
childOf: this.testModuleSpan,
|
|
75
53
|
tags: {
|
|
76
54
|
[COMPONENT]: this.constructor.name,
|
|
77
55
|
...this.testEnvironmentMetadata,
|
|
@@ -83,18 +61,24 @@ class MochaPlugin extends CiPlugin {
|
|
|
83
61
|
})
|
|
84
62
|
|
|
85
63
|
this.addSub('ci:mocha:test-suite:finish', (status) => {
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
64
|
+
const store = storage.getStore()
|
|
65
|
+
if (store && store.span) {
|
|
66
|
+
const span = storage.getStore().span
|
|
67
|
+
// the test status of the suite may have been set in ci:mocha:test-suite:error already
|
|
68
|
+
if (!span.context()._tags[TEST_STATUS]) {
|
|
69
|
+
span.setTag(TEST_STATUS, status)
|
|
70
|
+
}
|
|
71
|
+
span.finish()
|
|
90
72
|
}
|
|
91
|
-
span.finish()
|
|
92
73
|
})
|
|
93
74
|
|
|
94
75
|
this.addSub('ci:mocha:test-suite:error', (err) => {
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
76
|
+
const store = storage.getStore()
|
|
77
|
+
if (store && store.span) {
|
|
78
|
+
const span = storage.getStore().span
|
|
79
|
+
span.setTag('error', err)
|
|
80
|
+
span.setTag(TEST_STATUS, 'fail')
|
|
81
|
+
}
|
|
98
82
|
})
|
|
99
83
|
|
|
100
84
|
this.addSub('ci:mocha:test:start', (test) => {
|
|
@@ -105,12 +89,16 @@ class MochaPlugin extends CiPlugin {
|
|
|
105
89
|
})
|
|
106
90
|
|
|
107
91
|
this.addSub('ci:mocha:test:finish', (status) => {
|
|
108
|
-
const
|
|
92
|
+
const store = storage.getStore()
|
|
109
93
|
|
|
110
|
-
|
|
94
|
+
if (store && store.span) {
|
|
95
|
+
const span = storage.getStore().span
|
|
96
|
+
|
|
97
|
+
span.setTag(TEST_STATUS, status)
|
|
111
98
|
|
|
112
|
-
|
|
113
|
-
|
|
99
|
+
span.finish()
|
|
100
|
+
finishAllTraceSpans(span)
|
|
101
|
+
}
|
|
114
102
|
})
|
|
115
103
|
|
|
116
104
|
this.addSub('ci:mocha:test:skip', (test) => {
|
|
@@ -124,8 +112,9 @@ class MochaPlugin extends CiPlugin {
|
|
|
124
112
|
})
|
|
125
113
|
|
|
126
114
|
this.addSub('ci:mocha:test:error', (err) => {
|
|
127
|
-
|
|
128
|
-
|
|
115
|
+
const store = storage.getStore()
|
|
116
|
+
if (err && store && store.span) {
|
|
117
|
+
const span = store.span
|
|
129
118
|
if (err.constructor.name === 'Pending' && !this.forbidPending) {
|
|
130
119
|
span.setTag(TEST_STATUS, 'skip')
|
|
131
120
|
} else {
|
|
@@ -143,10 +132,15 @@ class MochaPlugin extends CiPlugin {
|
|
|
143
132
|
if (this.testSessionSpan) {
|
|
144
133
|
const { isSuitesSkippingEnabled, isCodeCoverageEnabled } = this.itrConfig || {}
|
|
145
134
|
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
146
|
-
this.
|
|
147
|
-
this.testSessionSpan.setTag(TEST_SESSION_ITR_SKIPPING_ENABLED, isSuitesSkippingEnabled ? 'true' : 'false')
|
|
148
|
-
this.testSessionSpan.setTag(TEST_SESSION_CODE_COVERAGE_ENABLED, isCodeCoverageEnabled ? 'true' : 'false')
|
|
135
|
+
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
149
136
|
|
|
137
|
+
addIntelligentTestRunnerSpanTags(
|
|
138
|
+
this.testSessionSpan,
|
|
139
|
+
this.testModuleSpan,
|
|
140
|
+
{ isSuitesSkipped, isSuitesSkippingEnabled, isCodeCoverageEnabled }
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
this.testModuleSpan.finish()
|
|
150
144
|
this.testSessionSpan.finish()
|
|
151
145
|
finishAllTraceSpans(this.testSessionSpan)
|
|
152
146
|
}
|
|
@@ -156,33 +150,19 @@ class MochaPlugin extends CiPlugin {
|
|
|
156
150
|
}
|
|
157
151
|
|
|
158
152
|
startTestSpan (test) {
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
if (testSuiteSpan) {
|
|
162
|
-
const testSuiteId = testSuiteSpan.context()._spanId.toString(10)
|
|
163
|
-
testSuiteTags[TEST_SUITE_ID] = testSuiteId
|
|
164
|
-
}
|
|
153
|
+
const testName = test.fullTitle()
|
|
154
|
+
const { file: testSuiteAbsolutePath, title } = test
|
|
165
155
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
testSuiteTags[TEST_SESSION_ID] = testSessionId
|
|
169
|
-
testSuiteTags[TEST_COMMAND] = this.command
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const { file: testSuiteAbsolutePath } = test
|
|
173
|
-
const fullTestName = test.fullTitle()
|
|
174
|
-
const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.sourceRoot)
|
|
175
|
-
|
|
176
|
-
const extraTags = {
|
|
177
|
-
...testSuiteTags
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const testParametersString = getTestParametersString(this._testNameToParams, test.title)
|
|
156
|
+
const extraTags = {}
|
|
157
|
+
const testParametersString = getTestParametersString(this._testNameToParams, title)
|
|
181
158
|
if (testParametersString) {
|
|
182
159
|
extraTags[TEST_PARAMETERS] = testParametersString
|
|
183
160
|
}
|
|
184
161
|
|
|
185
|
-
|
|
162
|
+
const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.sourceRoot)
|
|
163
|
+
const testSuiteSpan = this._testSuites.get(testSuiteAbsolutePath)
|
|
164
|
+
|
|
165
|
+
return super.startTestSpan(testName, testSuite, testSuiteSpan, extraTags)
|
|
186
166
|
}
|
|
187
167
|
}
|
|
188
168
|
|
|
@@ -6,22 +6,23 @@ class MySQLPlugin extends DatabasePlugin {
|
|
|
6
6
|
static get name () { return 'mysql' }
|
|
7
7
|
static get system () { return 'mysql' }
|
|
8
8
|
|
|
9
|
-
start (
|
|
10
|
-
const service = getServiceName(this.config,
|
|
9
|
+
start (payload) {
|
|
10
|
+
const service = getServiceName(this.config, payload.conf)
|
|
11
11
|
|
|
12
12
|
this.startSpan(`${this.system}.query`, {
|
|
13
13
|
service,
|
|
14
|
-
resource: sql,
|
|
14
|
+
resource: payload.sql,
|
|
15
15
|
type: 'sql',
|
|
16
16
|
kind: 'client',
|
|
17
17
|
meta: {
|
|
18
18
|
'db.type': this.system,
|
|
19
|
-
'db.user':
|
|
20
|
-
'db.name':
|
|
21
|
-
'out.host':
|
|
22
|
-
'out.port':
|
|
19
|
+
'db.user': payload.conf.user,
|
|
20
|
+
'db.name': payload.conf.database,
|
|
21
|
+
'out.host': payload.conf.host,
|
|
22
|
+
'out.port': payload.conf.port
|
|
23
23
|
}
|
|
24
24
|
})
|
|
25
|
+
payload.sql = this.injectDbmQuery(payload.sql, service)
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { storage } = require('../../datadog-core')
|
|
4
|
+
const CiPlugin = require('../../dd-trace/src/plugins/ci_plugin')
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
TEST_STATUS,
|
|
8
|
+
finishAllTraceSpans,
|
|
9
|
+
getTestSuitePath,
|
|
10
|
+
getTestSuiteCommonTags
|
|
11
|
+
} = require('../../dd-trace/src/plugins/util/test')
|
|
12
|
+
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
13
|
+
const { COMPONENT } = require('../../dd-trace/src/constants')
|
|
14
|
+
|
|
15
|
+
class PlaywrightPlugin extends CiPlugin {
|
|
16
|
+
static get name () {
|
|
17
|
+
return 'playwright'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
constructor (...args) {
|
|
21
|
+
super(...args)
|
|
22
|
+
|
|
23
|
+
this._testSuites = new Map()
|
|
24
|
+
|
|
25
|
+
this.addSub('ci:playwright:session:finish', ({ status, onDone }) => {
|
|
26
|
+
this.testModuleSpan.setTag(TEST_STATUS, status)
|
|
27
|
+
this.testSessionSpan.setTag(TEST_STATUS, status)
|
|
28
|
+
|
|
29
|
+
this.testModuleSpan.finish()
|
|
30
|
+
this.testSessionSpan.finish()
|
|
31
|
+
finishAllTraceSpans(this.testSessionSpan)
|
|
32
|
+
this.tracer._exporter.flush(onDone)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
this.addSub('ci:playwright:test-suite:start', (testSuiteAbsolutePath) => {
|
|
36
|
+
const store = storage.getStore()
|
|
37
|
+
const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.rootDir)
|
|
38
|
+
|
|
39
|
+
const testSuiteMetadata = getTestSuiteCommonTags(
|
|
40
|
+
this.command,
|
|
41
|
+
this.frameworkVersion,
|
|
42
|
+
testSuite
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
const testSuiteSpan = this.tracer.startSpan('playwright.test_suite', {
|
|
46
|
+
childOf: this.testModuleSpan,
|
|
47
|
+
tags: {
|
|
48
|
+
[COMPONENT]: this.constructor.name,
|
|
49
|
+
...this.testEnvironmentMetadata,
|
|
50
|
+
...testSuiteMetadata
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
this.enter(testSuiteSpan, store)
|
|
54
|
+
|
|
55
|
+
this._testSuites.set(testSuite, testSuiteSpan)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
this.addSub('ci:playwright:test-suite:finish', (status) => {
|
|
59
|
+
const store = storage.getStore()
|
|
60
|
+
const span = store && store.span
|
|
61
|
+
if (!span) return
|
|
62
|
+
span.setTag(TEST_STATUS, status)
|
|
63
|
+
span.finish()
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
this.addSub('ci:playwright:test:start', ({ testName, testSuiteAbsolutePath }) => {
|
|
67
|
+
const store = storage.getStore()
|
|
68
|
+
const testSuite = getTestSuitePath(testSuiteAbsolutePath, this.rootDir)
|
|
69
|
+
const span = this.startTestSpan(testName, testSuite)
|
|
70
|
+
|
|
71
|
+
this.enter(span, store)
|
|
72
|
+
})
|
|
73
|
+
this.addSub('ci:playwright:test:finish', ({ testStatus, steps, error }) => {
|
|
74
|
+
const store = storage.getStore()
|
|
75
|
+
const span = store && store.span
|
|
76
|
+
if (!span) return
|
|
77
|
+
|
|
78
|
+
span.setTag(TEST_STATUS, testStatus)
|
|
79
|
+
|
|
80
|
+
if (error) {
|
|
81
|
+
span.setTag('error', error)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
steps.forEach(step => {
|
|
85
|
+
const stepStartTime = step.startTime.getTime()
|
|
86
|
+
const stepSpan = this.tracer.startSpan('playwright.step', {
|
|
87
|
+
childOf: span,
|
|
88
|
+
startTime: stepStartTime,
|
|
89
|
+
tags: {
|
|
90
|
+
[COMPONENT]: this.constructor.name,
|
|
91
|
+
'playwright.step': step.title,
|
|
92
|
+
[RESOURCE_NAME]: step.title
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
if (step.error) {
|
|
96
|
+
stepSpan.setTag('error', step.error)
|
|
97
|
+
}
|
|
98
|
+
stepSpan.finish(stepStartTime + step.duration)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
span.finish()
|
|
102
|
+
finishAllTraceSpans(span)
|
|
103
|
+
})
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
startTestSpan (testName, testSuite) {
|
|
107
|
+
const testSuiteSpan = this._testSuites.get(testSuite)
|
|
108
|
+
return super.startTestSpan(testName, testSuite, testSuiteSpan)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = PlaywrightPlugin
|
|
@@ -10,7 +10,11 @@ function copyProperties (original, wrapped) {
|
|
|
10
10
|
const keys = Reflect.ownKeys(props)
|
|
11
11
|
|
|
12
12
|
for (const key of keys) {
|
|
13
|
-
|
|
13
|
+
try {
|
|
14
|
+
Object.defineProperty(wrapped, key, props[key])
|
|
15
|
+
} catch (e) {
|
|
16
|
+
// TODO: figure out how to handle this without a try/catch
|
|
17
|
+
}
|
|
14
18
|
}
|
|
15
19
|
}
|
|
16
20
|
|
|
@@ -33,28 +37,41 @@ function wrapFn (original, delegate) {
|
|
|
33
37
|
|
|
34
38
|
function wrapMethod (target, name, wrapper) {
|
|
35
39
|
assertMethod(target, name)
|
|
36
|
-
assertNotClass(target[name]) // TODO: support constructors of native classes
|
|
37
40
|
assertFunction(wrapper)
|
|
38
41
|
|
|
39
42
|
const original = target[name]
|
|
40
43
|
const wrapped = wrapper(original)
|
|
41
44
|
const descriptor = Object.getOwnPropertyDescriptor(target, name)
|
|
42
45
|
|
|
46
|
+
const attributes = {
|
|
47
|
+
configurable: true,
|
|
48
|
+
...descriptor
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
copyProperties(original, wrapped)
|
|
52
|
+
|
|
43
53
|
if (descriptor) {
|
|
44
54
|
unwrappers.set(wrapped, () => Object.defineProperty(target, name, descriptor))
|
|
55
|
+
|
|
56
|
+
if (descriptor.get || descriptor.set) {
|
|
57
|
+
attributes.get = () => wrapped
|
|
58
|
+
} else {
|
|
59
|
+
attributes.value = wrapped
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// TODO: create a single object for multiple wrapped methods
|
|
63
|
+
if (descriptor.configurable === false) {
|
|
64
|
+
return Object.create(target, {
|
|
65
|
+
[name]: attributes
|
|
66
|
+
})
|
|
67
|
+
}
|
|
45
68
|
} else { // no descriptor means original was on the prototype
|
|
46
69
|
unwrappers.set(wrapped, () => delete target[name])
|
|
70
|
+
attributes.value = wrapped
|
|
71
|
+
attributes.writable = true
|
|
47
72
|
}
|
|
48
73
|
|
|
49
|
-
Object.defineProperty(target, name,
|
|
50
|
-
configurable: true,
|
|
51
|
-
writable: true,
|
|
52
|
-
enumerable: false,
|
|
53
|
-
...descriptor,
|
|
54
|
-
value: wrapped
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
copyProperties(original, wrapped)
|
|
74
|
+
Object.defineProperty(target, name, attributes)
|
|
58
75
|
|
|
59
76
|
return target
|
|
60
77
|
}
|