dd-trace 2.4.1 → 2.6.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/ci/init.js +6 -0
- package/ci/jest/env.js +16 -3
- package/ext/exporters.d.ts +2 -1
- package/ext/exporters.js +2 -1
- package/index.d.ts +17 -1
- package/package.json +5 -4
- package/packages/datadog-instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/amqplib.js +1 -1
- package/packages/datadog-instrumentations/src/cypress.js +8 -0
- package/packages/datadog-instrumentations/src/http/client.js +10 -10
- package/packages/datadog-instrumentations/src/jest.js +170 -0
- package/packages/datadog-plugin-aws-sdk/src/helpers.js +4 -4
- package/packages/datadog-plugin-aws-sdk/src/index.js +1 -1
- package/packages/datadog-plugin-cucumber/src/index.js +16 -16
- package/packages/datadog-plugin-cypress/src/index.js +10 -5
- package/packages/datadog-plugin-cypress/src/plugin.js +18 -17
- package/packages/datadog-plugin-elasticsearch/src/index.js +4 -2
- package/packages/datadog-plugin-fs/src/index.js +2 -0
- package/packages/datadog-plugin-http/src/client.js +4 -1
- package/packages/datadog-plugin-http/src/server.js +7 -10
- package/packages/datadog-plugin-jest/src/index.js +101 -3
- package/packages/datadog-plugin-jest/src/util.js +1 -29
- package/packages/datadog-plugin-mocha/src/index.js +14 -15
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +29 -12
- package/packages/dd-trace/src/appsec/index.js +7 -3
- package/packages/dd-trace/src/appsec/recommended.json +119 -210
- package/packages/dd-trace/src/appsec/reporter.js +29 -3
- package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +32 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +51 -0
- package/packages/dd-trace/src/config.js +33 -4
- package/packages/dd-trace/src/encode/0.4.js +0 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +193 -0
- package/packages/dd-trace/src/encode/tags-processors.js +116 -0
- package/packages/dd-trace/src/exporter.js +3 -0
- package/packages/dd-trace/src/exporters/agent/index.js +1 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +7 -32
- package/packages/dd-trace/src/exporters/{agent → common}/docker.js +0 -0
- package/packages/dd-trace/src/exporters/common/request.js +83 -0
- package/packages/dd-trace/src/exporters/common/writer.js +36 -0
- package/packages/dd-trace/src/exporters/{agent/scheduler.js → scheduler.js} +0 -0
- package/packages/dd-trace/src/format.js +9 -5
- package/packages/dd-trace/src/instrumenter.js +3 -0
- package/packages/dd-trace/src/pkg.js +11 -6
- package/packages/dd-trace/src/plugins/util/test.js +79 -1
- package/packages/dd-trace/src/plugins/util/web.js +11 -10
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/cpu.js +1 -1
- package/packages/dd-trace/src/proxy.js +2 -0
- package/packages/dd-trace/src/span_processor.js +4 -1
- package/packages/dd-trace/src/telemetry.js +187 -0
- package/scripts/install_plugin_modules.js +1 -0
- package/packages/datadog-plugin-jest/src/jest-environment.js +0 -272
- package/packages/datadog-plugin-jest/src/jest-jasmine2.js +0 -185
- package/packages/dd-trace/src/exporters/agent/request.js +0 -86
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -7,6 +7,7 @@ require,@types/node,MIT,Copyright Authors
|
|
|
7
7
|
require,crypto-randomuuid,MIT,Copyright 2021 Node.js Foundation and contributors
|
|
8
8
|
require,diagnostics_channel,MIT,Copyright 2021 Simon D.
|
|
9
9
|
require,form-data,MIT,Copyright 2012 Felix Geisendörfer and contributors
|
|
10
|
+
require,ignore,MIT,Copyright 2013 Kael Zhang and contributors
|
|
10
11
|
require,import-in-the-middle,Apache license 2.0,Copyright 2021 Datadog Inc.
|
|
11
12
|
require,koalas,MIT,Copyright 2013-2017 Brian Woodward
|
|
12
13
|
require,limiter,MIT,Copyright 2011 John Hurliman
|
package/ci/init.js
CHANGED
|
@@ -11,6 +11,12 @@ const options = {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
if (process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED && (process.env.DATADOG_API_KEY || process.env.DD_API_KEY)) {
|
|
15
|
+
options.experimental = {
|
|
16
|
+
exporter: 'datadog'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
// TODO: remove this in a later major version since we now recommend using
|
|
15
21
|
// `NODE_OPTIONS='-r dd-trace/ci/init'`.
|
|
16
22
|
try {
|
package/ci/jest/env.js
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
const tracer = require('../../packages/dd-trace')
|
|
2
2
|
const { ORIGIN_KEY } = require('../../packages/dd-trace/src/constants')
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const options = {
|
|
5
5
|
startupLogs: false,
|
|
6
|
-
flushInterval: 400000,
|
|
7
6
|
tags: {
|
|
8
7
|
[ORIGIN_KEY]: 'ciapp-test'
|
|
9
8
|
}
|
|
10
|
-
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED && (process.env.DATADOG_API_KEY || process.env.DD_API_KEY)) {
|
|
12
|
+
tracer.init({
|
|
13
|
+
...options,
|
|
14
|
+
experimental: {
|
|
15
|
+
exporter: 'datadog'
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
} else {
|
|
19
|
+
tracer.init({
|
|
20
|
+
...options,
|
|
21
|
+
flushInterval: 400000
|
|
22
|
+
})
|
|
23
|
+
}
|
|
11
24
|
|
|
12
25
|
tracer.use('fs', false)
|
|
13
26
|
|
package/ext/exporters.d.ts
CHANGED
package/ext/exporters.js
CHANGED
package/index.d.ts
CHANGED
|
@@ -428,7 +428,23 @@ export declare interface TracerOptions {
|
|
|
428
428
|
* Controls the maximum amount of traces sampled by AppSec attacks, per second.
|
|
429
429
|
* @default 100
|
|
430
430
|
*/
|
|
431
|
-
rateLimit?: number
|
|
431
|
+
rateLimit?: number,
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Controls the maximum amount of time in microseconds the WAF is allowed to run synchronously for.
|
|
435
|
+
* @default 5000
|
|
436
|
+
*/
|
|
437
|
+
wafTimeout?: number,
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Specifies a regex that will redact sensitive data by its key in attack reports.
|
|
441
|
+
*/
|
|
442
|
+
obfuscatorKeyRegex?: string,
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Specifies a regex that will redact sensitive data by its value in attack reports.
|
|
446
|
+
*/
|
|
447
|
+
obfuscatorValueRegex?: string
|
|
432
448
|
};
|
|
433
449
|
}
|
|
434
450
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -61,14 +61,15 @@
|
|
|
61
61
|
"node": ">=12"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@datadog/native-appsec": "^
|
|
65
|
-
"@datadog/native-metrics": "^1.
|
|
66
|
-
"@datadog/pprof": "^0.
|
|
64
|
+
"@datadog/native-appsec": "^1.1.1",
|
|
65
|
+
"@datadog/native-metrics": "^1.2.0",
|
|
66
|
+
"@datadog/pprof": "^0.4.0",
|
|
67
67
|
"@datadog/sketches-js": "^1.0.4",
|
|
68
68
|
"@types/node": ">=12",
|
|
69
69
|
"crypto-randomuuid": "^1.0.0",
|
|
70
70
|
"diagnostics_channel": "^1.1.0",
|
|
71
71
|
"form-data": "^3.0.0",
|
|
72
|
+
"ignore": "^5.2.0",
|
|
72
73
|
"import-in-the-middle": "^1.2.1",
|
|
73
74
|
"koalas": "^1.0.2",
|
|
74
75
|
"limiter": "^1.1.4",
|
|
@@ -38,7 +38,7 @@ addHook({ name: 'amqplib', file: 'lib/channel.js', versions: ['>=0.5'] }, channe
|
|
|
38
38
|
|
|
39
39
|
function instrument (send, channel, args, method, fields, message) {
|
|
40
40
|
if (!startCh.hasSubscribers) {
|
|
41
|
-
return send.apply(
|
|
41
|
+
return send.apply(channel, args)
|
|
42
42
|
}
|
|
43
43
|
startCh.publish({ channel, method, fields, message })
|
|
44
44
|
|
|
@@ -50,6 +50,7 @@ function patch (http, methodName) {
|
|
|
50
50
|
|
|
51
51
|
const ar = new AsyncResource('bound-anonymous-fn')
|
|
52
52
|
|
|
53
|
+
let finished = false
|
|
53
54
|
let callback = args.callback
|
|
54
55
|
|
|
55
56
|
if (callback) {
|
|
@@ -60,34 +61,33 @@ function patch (http, methodName) {
|
|
|
60
61
|
const req = ar.bind(request).call(this, options, callback)
|
|
61
62
|
const emit = req.emit
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
finished = true
|
|
68
|
-
asyncEndClientCh.publish({ req, res })
|
|
69
|
-
}
|
|
64
|
+
const finish = (req, res) => {
|
|
65
|
+
if (!finished) {
|
|
66
|
+
finished = true
|
|
67
|
+
asyncEndClientCh.publish({ req, res })
|
|
70
68
|
}
|
|
69
|
+
}
|
|
71
70
|
|
|
71
|
+
req.emit = function (eventName, arg) {
|
|
72
72
|
ar.runInAsyncScope(() => {
|
|
73
73
|
switch (eventName) {
|
|
74
74
|
case 'response': {
|
|
75
75
|
const res = arg
|
|
76
|
-
const listener = ar.bind(() => finish(
|
|
76
|
+
const listener = ar.bind(() => finish(req, res))
|
|
77
77
|
res.on('end', listener)
|
|
78
78
|
res.on('error', listener)
|
|
79
79
|
break
|
|
80
80
|
}
|
|
81
81
|
case 'connect':
|
|
82
82
|
case 'upgrade':
|
|
83
|
-
finish(
|
|
83
|
+
finish(req, arg)
|
|
84
84
|
break
|
|
85
85
|
case 'error':
|
|
86
86
|
errorClientCh.publish(arg)
|
|
87
87
|
case 'abort': // deprecated and replaced by `close` in node 17
|
|
88
88
|
case 'timeout':
|
|
89
89
|
case 'close':
|
|
90
|
-
finish(
|
|
90
|
+
finish(req)
|
|
91
91
|
}
|
|
92
92
|
})
|
|
93
93
|
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
4
|
+
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
|
|
6
|
+
const testStartCh = channel('ci:jest:test:start')
|
|
7
|
+
const testSkippedCh = channel('ci:jest:test:skip')
|
|
8
|
+
const testRunEndCh = channel('ci:jest:test:end')
|
|
9
|
+
const testErrCh = channel('ci:jest:test:err')
|
|
10
|
+
const testSuiteEnd = channel('ci:jest:test-suite:end')
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
getTestSuitePath,
|
|
14
|
+
getTestParametersString
|
|
15
|
+
} = require('../../dd-trace/src/plugins/util/test')
|
|
16
|
+
|
|
17
|
+
const { getFormattedJestTestParameters } = require('../../datadog-plugin-jest/src/util')
|
|
18
|
+
|
|
19
|
+
const specStatusToTestStatus = {
|
|
20
|
+
'pending': 'skip',
|
|
21
|
+
'disabled': 'skip',
|
|
22
|
+
'todo': 'skip',
|
|
23
|
+
'passed': 'pass',
|
|
24
|
+
'failed': 'fail'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const asyncResources = new WeakMap()
|
|
28
|
+
const originalTestFns = new WeakMap()
|
|
29
|
+
|
|
30
|
+
// based on https://github.com/facebook/jest/blob/main/packages/jest-circus/src/formatNodeAssertErrors.ts#L41
|
|
31
|
+
function formatJestError (errors) {
|
|
32
|
+
let error
|
|
33
|
+
if (Array.isArray(errors)) {
|
|
34
|
+
const [originalError, asyncError] = errors
|
|
35
|
+
if (originalError === null || !originalError.stack) {
|
|
36
|
+
error = asyncError
|
|
37
|
+
error.message = originalError
|
|
38
|
+
} else {
|
|
39
|
+
error = originalError
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
error = errors
|
|
43
|
+
}
|
|
44
|
+
return error
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getWrappedEnvironment (BaseEnvironment) {
|
|
48
|
+
return class DatadogEnvironment extends BaseEnvironment {
|
|
49
|
+
constructor (config, context) {
|
|
50
|
+
super(config, context)
|
|
51
|
+
this.testSuite = getTestSuitePath(context.testPath, config.rootDir)
|
|
52
|
+
this.nameToParams = {}
|
|
53
|
+
this.global._ddtrace = global._ddtrace
|
|
54
|
+
}
|
|
55
|
+
async teardown () {
|
|
56
|
+
super.teardown().finally(() => {
|
|
57
|
+
testSuiteEnd.publish()
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async handleTestEvent (event, state) {
|
|
62
|
+
if (super.handleTestEvent) {
|
|
63
|
+
await super.handleTestEvent(event, state)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let context
|
|
67
|
+
if (this.getVmContext) {
|
|
68
|
+
context = this.getVmContext()
|
|
69
|
+
} else {
|
|
70
|
+
context = this.context
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const setNameToParams = (name, params) => { this.nameToParams[name] = params }
|
|
74
|
+
|
|
75
|
+
if (event.name === 'setup') {
|
|
76
|
+
shimmer.wrap(this.global.test, 'each', each => function () {
|
|
77
|
+
const testParameters = getFormattedJestTestParameters(arguments)
|
|
78
|
+
const eachBind = each.apply(this, arguments)
|
|
79
|
+
return function () {
|
|
80
|
+
const [testName] = arguments
|
|
81
|
+
setNameToParams(testName, testParameters)
|
|
82
|
+
return eachBind.apply(this, arguments)
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
if (event.name === 'test_start') {
|
|
87
|
+
const testParameters = getTestParametersString(this.nameToParams, event.test.name)
|
|
88
|
+
|
|
89
|
+
// Async resource for this test is created here
|
|
90
|
+
// It is used later on by the test_done handler
|
|
91
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
92
|
+
asyncResources.set(event.test, asyncResource)
|
|
93
|
+
asyncResource.runInAsyncScope(() => {
|
|
94
|
+
testStartCh.publish({
|
|
95
|
+
name: context.expect.getState().currentTestName,
|
|
96
|
+
suite: this.testSuite,
|
|
97
|
+
runner: 'jest-circus',
|
|
98
|
+
testParameters
|
|
99
|
+
})
|
|
100
|
+
originalTestFns.set(event.test, event.test.fn)
|
|
101
|
+
event.test.fn = asyncResource.bind(event.test.fn)
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
if (event.name === 'test_done') {
|
|
105
|
+
const asyncResource = asyncResources.get(event.test)
|
|
106
|
+
asyncResource.runInAsyncScope(() => {
|
|
107
|
+
let status = 'pass'
|
|
108
|
+
if (event.test.errors && event.test.errors.length) {
|
|
109
|
+
status = 'fail'
|
|
110
|
+
const formattedError = formatJestError(event.test.errors[0])
|
|
111
|
+
testErrCh.publish(formattedError)
|
|
112
|
+
}
|
|
113
|
+
testRunEndCh.publish(status)
|
|
114
|
+
// restore in case it is retried
|
|
115
|
+
event.test.fn = originalTestFns.get(event.test)
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
if (event.name === 'test_skip' || event.name === 'test_todo') {
|
|
119
|
+
testSkippedCh.publish({
|
|
120
|
+
name: context.expect.getState().currentTestName,
|
|
121
|
+
suite: this.testSuite,
|
|
122
|
+
runner: 'jest-circus'
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
addHook({
|
|
130
|
+
name: 'jest-environment-node',
|
|
131
|
+
versions: ['>=24.8.0']
|
|
132
|
+
}, getWrappedEnvironment)
|
|
133
|
+
|
|
134
|
+
addHook({
|
|
135
|
+
name: 'jest-environment-jsdom',
|
|
136
|
+
versions: ['>=24.8.0']
|
|
137
|
+
}, getWrappedEnvironment)
|
|
138
|
+
|
|
139
|
+
addHook({
|
|
140
|
+
name: 'jest-jasmine2',
|
|
141
|
+
versions: ['>=24.8.0'],
|
|
142
|
+
file: 'build/jasmineAsyncInstall.js'
|
|
143
|
+
}, (jasmineAsyncInstallExport) => {
|
|
144
|
+
return function (globalConfig, globalInput) {
|
|
145
|
+
globalInput._ddtrace = global._ddtrace
|
|
146
|
+
shimmer.wrap(globalInput.jasmine.Spec.prototype, 'execute', execute => function (onComplete) {
|
|
147
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
148
|
+
asyncResource.runInAsyncScope(() => {
|
|
149
|
+
const testSuite = getTestSuitePath(this.result.testPath, globalConfig.rootDir)
|
|
150
|
+
testStartCh.publish({
|
|
151
|
+
name: this.getFullName(),
|
|
152
|
+
suite: testSuite,
|
|
153
|
+
runner: 'jest-jasmine2'
|
|
154
|
+
})
|
|
155
|
+
const spec = this
|
|
156
|
+
const callback = asyncResource.bind(function () {
|
|
157
|
+
if (spec.result.failedExpectations && spec.result.failedExpectations.length) {
|
|
158
|
+
const formattedError = formatJestError(spec.result.failedExpectations[0].error)
|
|
159
|
+
testErrCh.publish(formattedError)
|
|
160
|
+
}
|
|
161
|
+
testRunEndCh.publish(specStatusToTestStatus[spec.result.status])
|
|
162
|
+
onComplete.apply(this, arguments)
|
|
163
|
+
})
|
|
164
|
+
arguments[0] = callback
|
|
165
|
+
execute.apply(this, arguments)
|
|
166
|
+
})
|
|
167
|
+
})
|
|
168
|
+
return jasmineAsyncInstallExport.default(globalConfig, globalInput)
|
|
169
|
+
}
|
|
170
|
+
})
|
|
@@ -19,7 +19,7 @@ function getService (Service) {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
const helpers = {
|
|
22
|
-
finish (span, err) {
|
|
22
|
+
finish (config, span, response, err) {
|
|
23
23
|
if (err) {
|
|
24
24
|
span.setTag('error', err)
|
|
25
25
|
|
|
@@ -28,6 +28,8 @@ const helpers = {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
config.hooks.request(span, response)
|
|
32
|
+
|
|
31
33
|
span.finish()
|
|
32
34
|
},
|
|
33
35
|
|
|
@@ -43,14 +45,12 @@ const helpers = {
|
|
|
43
45
|
: true
|
|
44
46
|
},
|
|
45
47
|
|
|
46
|
-
addResponseTags (span, response, serviceName
|
|
48
|
+
addResponseTags (span, response, serviceName) {
|
|
47
49
|
if (!span) return
|
|
48
50
|
|
|
49
51
|
if (response.request) {
|
|
50
52
|
this.addServicesTags(span, response, serviceName)
|
|
51
53
|
}
|
|
52
|
-
|
|
53
|
-
config.hooks.request(span, response)
|
|
54
54
|
},
|
|
55
55
|
|
|
56
56
|
addServicesTags (span, response, serviceName) {
|
|
@@ -36,7 +36,7 @@ function createWrapRequest (tracer, config) {
|
|
|
36
36
|
if (!span) return
|
|
37
37
|
|
|
38
38
|
awsHelpers.addResponseTags(span, response, serviceIdentifier, config, tracer)
|
|
39
|
-
awsHelpers.finish(span, response.error)
|
|
39
|
+
awsHelpers.finish(config, span, response, response.error)
|
|
40
40
|
})
|
|
41
41
|
|
|
42
42
|
analyticsSampler.sample(span, config.measured)
|
|
@@ -5,20 +5,18 @@ const { storage } = require('../../datadog-core')
|
|
|
5
5
|
|
|
6
6
|
const {
|
|
7
7
|
CI_APP_ORIGIN,
|
|
8
|
-
TEST_TYPE,
|
|
9
|
-
TEST_NAME,
|
|
10
|
-
TEST_SUITE,
|
|
11
8
|
TEST_SKIP_REASON,
|
|
12
|
-
TEST_FRAMEWORK_VERSION,
|
|
13
9
|
ERROR_MESSAGE,
|
|
14
10
|
TEST_STATUS,
|
|
11
|
+
TEST_CODE_OWNERS,
|
|
15
12
|
finishAllTraceSpans,
|
|
16
13
|
getTestEnvironmentMetadata,
|
|
17
|
-
getTestSuitePath
|
|
14
|
+
getTestSuitePath,
|
|
15
|
+
getCodeOwnersFileEntries,
|
|
16
|
+
getCodeOwnersForFilename,
|
|
17
|
+
getTestCommonTags
|
|
18
18
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
19
|
-
const {
|
|
20
|
-
const { SAMPLING_RULE_DECISION } = require('../../dd-trace/src/constants')
|
|
21
|
-
const { AUTO_KEEP } = require('../../../ext/priority')
|
|
19
|
+
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
22
20
|
|
|
23
21
|
class CucumberPlugin extends Plugin {
|
|
24
22
|
static get name () {
|
|
@@ -30,26 +28,28 @@ class CucumberPlugin extends Plugin {
|
|
|
30
28
|
|
|
31
29
|
const testEnvironmentMetadata = getTestEnvironmentMetadata('cucumber', this.config)
|
|
32
30
|
const sourceRoot = process.cwd()
|
|
31
|
+
const codeOwnersEntries = getCodeOwnersFileEntries(sourceRoot)
|
|
33
32
|
|
|
34
33
|
this.addSub('ci:cucumber:run:start', ({ pickleName, pickleUri }) => {
|
|
35
34
|
const store = storage.getStore()
|
|
36
35
|
const childOf = store ? store.span : store
|
|
37
36
|
const testSuite = getTestSuitePath(pickleUri, sourceRoot)
|
|
38
37
|
|
|
38
|
+
const commonTags = getTestCommonTags(pickleName, testSuite, this.tracer._version)
|
|
39
|
+
|
|
40
|
+
const codeOwners = getCodeOwnersForFilename(testSuite, codeOwnersEntries)
|
|
41
|
+
if (codeOwners) {
|
|
42
|
+
commonTags[TEST_CODE_OWNERS] = codeOwners
|
|
43
|
+
}
|
|
44
|
+
|
|
39
45
|
const span = this.tracer.startSpan('cucumber.test', {
|
|
40
46
|
childOf,
|
|
41
47
|
tags: {
|
|
42
|
-
|
|
43
|
-
[RESOURCE_NAME]: pickleName,
|
|
44
|
-
[TEST_TYPE]: 'test',
|
|
45
|
-
[TEST_NAME]: pickleName,
|
|
46
|
-
[TEST_SUITE]: testSuite,
|
|
47
|
-
[SAMPLING_RULE_DECISION]: 1,
|
|
48
|
-
[SAMPLING_PRIORITY]: AUTO_KEEP,
|
|
49
|
-
[TEST_FRAMEWORK_VERSION]: this.tracer._version,
|
|
48
|
+
...commonTags,
|
|
50
49
|
...testEnvironmentMetadata
|
|
51
50
|
}
|
|
52
51
|
})
|
|
52
|
+
|
|
53
53
|
span.context()._trace.origin = CI_APP_ORIGIN
|
|
54
54
|
this.enter(span, store)
|
|
55
55
|
})
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
2
|
+
|
|
3
|
+
// Cypress plugin does not patch any library. This is just a placeholder to
|
|
4
|
+
// follow the structure of the plugins
|
|
5
|
+
class CypressPlugin extends Plugin {
|
|
6
|
+
static get name () {
|
|
7
|
+
return 'cypress'
|
|
5
8
|
}
|
|
6
|
-
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = CypressPlugin
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
const {
|
|
2
|
-
TEST_TYPE,
|
|
3
|
-
TEST_NAME,
|
|
4
|
-
TEST_SUITE,
|
|
5
2
|
TEST_STATUS,
|
|
6
|
-
TEST_FRAMEWORK_VERSION,
|
|
7
3
|
TEST_IS_RUM_ACTIVE,
|
|
4
|
+
TEST_CODE_OWNERS,
|
|
8
5
|
getTestEnvironmentMetadata,
|
|
9
6
|
CI_APP_ORIGIN,
|
|
10
|
-
getTestParentSpan
|
|
7
|
+
getTestParentSpan,
|
|
8
|
+
getCodeOwnersFileEntries,
|
|
9
|
+
getCodeOwnersForFilename,
|
|
10
|
+
getTestCommonTags
|
|
11
11
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
12
12
|
|
|
13
|
-
const {
|
|
14
|
-
const { SAMPLING_PRIORITY, SPAN_TYPE, RESOURCE_NAME } = require('../../../ext/tags')
|
|
15
|
-
const { AUTO_KEEP } = require('../../../ext/priority')
|
|
13
|
+
const { ORIGIN_KEY } = require('../../dd-trace/src/constants')
|
|
16
14
|
|
|
17
15
|
const CYPRESS_STATUS_TO_TEST_STATUS = {
|
|
18
16
|
passed: 'pass',
|
|
@@ -24,21 +22,20 @@ const CYPRESS_STATUS_TO_TEST_STATUS = {
|
|
|
24
22
|
function getTestSpanMetadata (tracer, testName, testSuite, cypressConfig) {
|
|
25
23
|
const childOf = getTestParentSpan(tracer)
|
|
26
24
|
|
|
25
|
+
const commonTags = getTestCommonTags(testName, testSuite, cypressConfig.version)
|
|
26
|
+
|
|
27
27
|
return {
|
|
28
28
|
childOf,
|
|
29
|
-
|
|
30
|
-
[TEST_TYPE]: 'test',
|
|
31
|
-
[TEST_NAME]: testName,
|
|
32
|
-
[TEST_SUITE]: testSuite,
|
|
33
|
-
[SAMPLING_RULE_DECISION]: 1,
|
|
34
|
-
[SAMPLING_PRIORITY]: AUTO_KEEP,
|
|
35
|
-
[TEST_FRAMEWORK_VERSION]: cypressConfig.version
|
|
29
|
+
...commonTags
|
|
36
30
|
}
|
|
37
31
|
}
|
|
38
32
|
|
|
39
33
|
module.exports = (on, config) => {
|
|
40
34
|
const tracer = require('../../dd-trace')
|
|
41
35
|
const testEnvironmentMetadata = getTestEnvironmentMetadata('cypress')
|
|
36
|
+
|
|
37
|
+
const codeOwnersEntries = getCodeOwnersFileEntries()
|
|
38
|
+
|
|
42
39
|
let activeSpan = null
|
|
43
40
|
on('after:run', () => {
|
|
44
41
|
return new Promise(resolve => {
|
|
@@ -55,12 +52,16 @@ module.exports = (on, config) => {
|
|
|
55
52
|
...testSpanMetadata
|
|
56
53
|
} = getTestSpanMetadata(tracer, testName, testSuite, config)
|
|
57
54
|
|
|
55
|
+
const codeOwners = getCodeOwnersForFilename(testSuite, codeOwnersEntries)
|
|
56
|
+
|
|
57
|
+
if (codeOwners) {
|
|
58
|
+
testSpanMetadata[TEST_CODE_OWNERS] = codeOwners
|
|
59
|
+
}
|
|
60
|
+
|
|
58
61
|
if (!activeSpan) {
|
|
59
62
|
activeSpan = tracer.startSpan('cypress.test', {
|
|
60
63
|
childOf,
|
|
61
64
|
tags: {
|
|
62
|
-
[SPAN_TYPE]: 'test',
|
|
63
|
-
[RESOURCE_NAME]: resource,
|
|
64
65
|
[ORIGIN_KEY]: CI_APP_ORIGIN,
|
|
65
66
|
...testSpanMetadata,
|
|
66
67
|
...testEnvironmentMetadata
|
|
@@ -13,8 +13,6 @@ class ElasticsearchPlugin extends Plugin {
|
|
|
13
13
|
super(...args)
|
|
14
14
|
|
|
15
15
|
this.addSub('apm:elasticsearch:query:start', ({ params }) => {
|
|
16
|
-
this.config = normalizeConfig(this.config)
|
|
17
|
-
|
|
18
16
|
const store = storage.getStore()
|
|
19
17
|
const childOf = store ? store.span : store
|
|
20
18
|
const body = getBody(params.body || params.bulkBody)
|
|
@@ -51,6 +49,10 @@ class ElasticsearchPlugin extends Plugin {
|
|
|
51
49
|
span.finish()
|
|
52
50
|
})
|
|
53
51
|
}
|
|
52
|
+
|
|
53
|
+
configure (config) {
|
|
54
|
+
return super.configure(normalizeConfig(config))
|
|
55
|
+
}
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
function normalizeConfig (config) {
|
|
@@ -60,6 +60,7 @@ function createWrapCreateReadStream (config, tracer) {
|
|
|
60
60
|
const tags = makeFSFlagTags('ReadStream', path, options, 'r', config, tracer)
|
|
61
61
|
return tracer.trace('fs.operation', { tags, orphanable }, (span, done) => {
|
|
62
62
|
const stream = createReadStream.apply(this, arguments)
|
|
63
|
+
stream.once('close', done)
|
|
63
64
|
stream.once('end', done)
|
|
64
65
|
stream.once('error', done)
|
|
65
66
|
return stream
|
|
@@ -74,6 +75,7 @@ function createWrapCreateWriteStream (config, tracer) {
|
|
|
74
75
|
const tags = makeFSFlagTags('WriteStream', path, options, 'w', config, tracer)
|
|
75
76
|
return tracer.trace('fs.operation', { tags, orphanable }, (span, done) => {
|
|
76
77
|
const stream = createWriteStream.apply(this, arguments)
|
|
78
|
+
stream.once('close', done)
|
|
77
79
|
stream.once('finish', done)
|
|
78
80
|
stream.once('error', done)
|
|
79
81
|
return stream
|
|
@@ -24,7 +24,6 @@ class HttpClientPlugin extends Plugin {
|
|
|
24
24
|
|
|
25
25
|
this.addSub('apm:http:client:request:start', ({ args, http }) => {
|
|
26
26
|
const store = storage.getStore()
|
|
27
|
-
this.config = normalizeClientConfig(this.config)
|
|
28
27
|
const options = args.options
|
|
29
28
|
const agent = options.agent || options._defaultAgent || http.globalAgent
|
|
30
29
|
const protocol = options.protocol || agent.protocol || 'http:'
|
|
@@ -79,6 +78,10 @@ class HttpClientPlugin extends Plugin {
|
|
|
79
78
|
|
|
80
79
|
this.addSub('apm:http:client:request:error', errorHandler)
|
|
81
80
|
}
|
|
81
|
+
|
|
82
|
+
configure (config) {
|
|
83
|
+
return super.configure(normalizeClientConfig(config))
|
|
84
|
+
}
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
function errorHandler (err) {
|
|
@@ -4,9 +4,6 @@ const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
|
4
4
|
const { storage } = require('../../datadog-core')
|
|
5
5
|
const web = require('../../dd-trace/src/plugins/util/web')
|
|
6
6
|
const { incomingHttpRequestStart } = require('../../dd-trace/src/appsec/gateway/channels')
|
|
7
|
-
const tags = require('../../../ext/tags')
|
|
8
|
-
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
9
|
-
const SERVICE_NAME = tags.SERVICE_NAME
|
|
10
7
|
|
|
11
8
|
class HttpServerPlugin extends Plugin {
|
|
12
9
|
static get name () {
|
|
@@ -18,15 +15,8 @@ class HttpServerPlugin extends Plugin {
|
|
|
18
15
|
|
|
19
16
|
this.addSub('apm:http:server:request:start', ({ req, res }) => {
|
|
20
17
|
const store = storage.getStore()
|
|
21
|
-
this.config = web.normalizeConfig(this.config)
|
|
22
|
-
|
|
23
18
|
const span = web.startSpan(this.tracer, this.config, req, res, 'http.request')
|
|
24
19
|
|
|
25
|
-
if (this.config.service) {
|
|
26
|
-
span.setTag(SERVICE_NAME, this.config.service)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
analyticsSampler.sample(span, this.config.measured, true)
|
|
30
20
|
this.enter(span, store)
|
|
31
21
|
|
|
32
22
|
const context = web.getContext(req)
|
|
@@ -56,9 +46,16 @@ class HttpServerPlugin extends Plugin {
|
|
|
56
46
|
|
|
57
47
|
this.addSub('apm:http:server:request:async-end', ({ req }) => {
|
|
58
48
|
const context = web.getContext(req)
|
|
49
|
+
|
|
50
|
+
if (!context) return // Not created by a http.Server instance.
|
|
51
|
+
|
|
59
52
|
web.wrapRes(context, context.req, context.res, context.res.end)()
|
|
60
53
|
})
|
|
61
54
|
}
|
|
55
|
+
|
|
56
|
+
configure (config) {
|
|
57
|
+
return super.configure(web.normalizeConfig(config))
|
|
58
|
+
}
|
|
62
59
|
}
|
|
63
60
|
|
|
64
61
|
module.exports = HttpServerPlugin
|