dd-trace 2.20.1 → 2.21.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/package.json +2 -2
- package/packages/datadog-instrumentations/src/jest.js +11 -1
- package/packages/datadog-plugin-http/src/client.js +9 -1
- package/packages/datadog-plugin-http2/src/client.js +18 -1
- package/packages/datadog-plugin-jest/src/index.js +2 -0
- package/packages/datadog-plugin-oracledb/src/index.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +5 -4
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +5 -4
- package/packages/dd-trace/src/config.js +16 -11
- package/packages/dd-trace/src/plugin_manager.js +3 -1
- package/packages/dd-trace/src/proxy.js +0 -3
- package/packages/dd-trace/src/span_processor.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.21.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"node": ">=12"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@datadog/native-appsec": "
|
|
61
|
+
"@datadog/native-appsec": "1.3.0",
|
|
62
62
|
"@datadog/native-metrics": "^1.5.0",
|
|
63
63
|
"@datadog/pprof": "^1.1.1",
|
|
64
64
|
"@datadog/sketches-js": "^2.1.0",
|
|
@@ -263,6 +263,9 @@ function jestAdapterWrapper (jestAdapter) {
|
|
|
263
263
|
const adapter = jestAdapter.default ? jestAdapter.default : jestAdapter
|
|
264
264
|
const newAdapter = shimmer.wrap(adapter, function () {
|
|
265
265
|
const environment = arguments[2]
|
|
266
|
+
if (!environment) {
|
|
267
|
+
return adapter.apply(this, arguments)
|
|
268
|
+
}
|
|
266
269
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
267
270
|
return asyncResource.runInAsyncScope(() => {
|
|
268
271
|
testSuiteStartCh.publish({
|
|
@@ -280,7 +283,9 @@ function jestAdapterWrapper (jestAdapter) {
|
|
|
280
283
|
testSuiteFinishCh.publish({ status, errorMessage })
|
|
281
284
|
if (environment.global.__coverage__) {
|
|
282
285
|
const coverageFiles = extractCoverageInformation(environment.global.__coverage__, environment.rootDir)
|
|
283
|
-
if (coverageFiles.length
|
|
286
|
+
if (coverageFiles.length &&
|
|
287
|
+
environment.testEnvironmentOptions &&
|
|
288
|
+
environment.testEnvironmentOptions._ddTestCodeCoverageEnabled) {
|
|
284
289
|
testSuiteCodeCoverageCh.publish([...coverageFiles, environment.testSuite])
|
|
285
290
|
}
|
|
286
291
|
}
|
|
@@ -314,6 +319,11 @@ function configureTestEnvironment (readConfigsResult) {
|
|
|
314
319
|
sessionAsyncResource.runInAsyncScope(() => {
|
|
315
320
|
testSessionConfigurationCh.publish(configs.map(config => config.testEnvironmentOptions))
|
|
316
321
|
})
|
|
322
|
+
// We can't directly use isCodeCoverageEnabled when reporting coverage in `jestAdapterWrapper`
|
|
323
|
+
// because `jestAdapterWrapper` runs in a different process. We have to go through `testEnvironmentOptions`
|
|
324
|
+
configs.forEach(config => {
|
|
325
|
+
config.testEnvironmentOptions._ddTestCodeCoverageEnabled = isCodeCoverageEnabled
|
|
326
|
+
})
|
|
317
327
|
if (isCodeCoverageEnabled) {
|
|
318
328
|
const globalConfig = {
|
|
319
329
|
...readConfigsResult.globalConfig,
|
|
@@ -31,9 +31,10 @@ class HttpClientPlugin extends Plugin {
|
|
|
31
31
|
const host = options.port ? `${hostname}:${options.port}` : hostname
|
|
32
32
|
const path = options.path ? options.path.split(/[?#]/)[0] : '/'
|
|
33
33
|
const uri = `${protocol}//${host}${path}`
|
|
34
|
+
const allowed = this.config.filter(uri)
|
|
34
35
|
|
|
35
36
|
const method = (options.method || 'GET').toUpperCase()
|
|
36
|
-
const childOf = store ? store.span :
|
|
37
|
+
const childOf = store && allowed ? store.span : null
|
|
37
38
|
const span = this.tracer.startSpan('http.request', {
|
|
38
39
|
childOf,
|
|
39
40
|
tags: {
|
|
@@ -46,6 +47,11 @@ class HttpClientPlugin extends Plugin {
|
|
|
46
47
|
}
|
|
47
48
|
})
|
|
48
49
|
|
|
50
|
+
// TODO: Figure out a better way to do this for any span.
|
|
51
|
+
if (!allowed) {
|
|
52
|
+
span._spanContext._trace.record = false
|
|
53
|
+
}
|
|
54
|
+
|
|
49
55
|
if (!(hasAmazonSignature(options) || !this.config.propagationFilter(uri))) {
|
|
50
56
|
this.tracer.inject(span, HTTP_HEADERS, options.headers)
|
|
51
57
|
}
|
|
@@ -116,12 +122,14 @@ function addRequestHeaders (req, span, config) {
|
|
|
116
122
|
|
|
117
123
|
function normalizeClientConfig (config) {
|
|
118
124
|
const validateStatus = getStatusValidator(config)
|
|
125
|
+
const filter = getFilter(config)
|
|
119
126
|
const propagationFilter = getFilter({ blocklist: config.propagationBlocklist })
|
|
120
127
|
const headers = getHeaders(config)
|
|
121
128
|
const hooks = getHooks(config)
|
|
122
129
|
|
|
123
130
|
return Object.assign({}, config, {
|
|
124
131
|
validateStatus,
|
|
132
|
+
filter,
|
|
125
133
|
propagationFilter,
|
|
126
134
|
headers,
|
|
127
135
|
hooks
|
|
@@ -9,6 +9,7 @@ const tags = require('../../../ext/tags')
|
|
|
9
9
|
const kinds = require('../../../ext/kinds')
|
|
10
10
|
const formats = require('../../../ext/formats')
|
|
11
11
|
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
12
|
+
const urlFilter = require('../../dd-trace/src/plugins/util/urlfilter')
|
|
12
13
|
|
|
13
14
|
const HTTP_HEADERS = formats.HTTP_HEADERS
|
|
14
15
|
const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
|
|
@@ -36,9 +37,10 @@ class Http2ClientPlugin extends Plugin {
|
|
|
36
37
|
const pathname = path.split(/[?#]/)[0]
|
|
37
38
|
const method = headers[HTTP2_HEADER_METHOD] || HTTP2_METHOD_GET
|
|
38
39
|
const uri = `${sessionDetails.protocol}//${sessionDetails.host}:${sessionDetails.port}${pathname}`
|
|
40
|
+
const allowed = this.config.filter(uri)
|
|
39
41
|
|
|
40
42
|
const store = storage.getStore()
|
|
41
|
-
const childOf = store ? store.span :
|
|
43
|
+
const childOf = store && allowed ? store.span : null
|
|
42
44
|
const span = this.tracer.startSpan('http.request', {
|
|
43
45
|
childOf,
|
|
44
46
|
tags: {
|
|
@@ -51,6 +53,11 @@ class Http2ClientPlugin extends Plugin {
|
|
|
51
53
|
}
|
|
52
54
|
})
|
|
53
55
|
|
|
56
|
+
// TODO: Figure out a better way to do this for any span.
|
|
57
|
+
if (!allowed) {
|
|
58
|
+
span._spanContext._trace.record = false
|
|
59
|
+
}
|
|
60
|
+
|
|
54
61
|
addHeaderTags(span, headers, HTTP_REQUEST_HEADERS, this.config)
|
|
55
62
|
|
|
56
63
|
if (!hasAmazonSignature(headers, path)) {
|
|
@@ -155,14 +162,24 @@ function getStatusValidator (config) {
|
|
|
155
162
|
|
|
156
163
|
function normalizeConfig (config) {
|
|
157
164
|
const validateStatus = getStatusValidator(config)
|
|
165
|
+
const filter = getFilter(config)
|
|
158
166
|
const headers = getHeaders(config)
|
|
159
167
|
|
|
160
168
|
return Object.assign({}, config, {
|
|
161
169
|
validateStatus,
|
|
170
|
+
filter,
|
|
162
171
|
headers
|
|
163
172
|
})
|
|
164
173
|
}
|
|
165
174
|
|
|
175
|
+
function getFilter (config) {
|
|
176
|
+
config = Object.assign({}, config, {
|
|
177
|
+
blocklist: config.blocklist || []
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
return urlFilter.getFilter(config)
|
|
181
|
+
}
|
|
182
|
+
|
|
166
183
|
function addHeaderTags (span, headers, prefix, config) {
|
|
167
184
|
if (!headers) return
|
|
168
185
|
|
|
@@ -99,6 +99,7 @@ class JestPlugin extends Plugin {
|
|
|
99
99
|
return
|
|
100
100
|
}
|
|
101
101
|
const testConfiguration = {
|
|
102
|
+
url: this.config.url,
|
|
102
103
|
site: this.config.site,
|
|
103
104
|
env: this.tracer._env,
|
|
104
105
|
service: this.config.service || this.tracer._service,
|
|
@@ -130,6 +131,7 @@ class JestPlugin extends Plugin {
|
|
|
130
131
|
return onError(gitUploadError)
|
|
131
132
|
}
|
|
132
133
|
const testConfiguration = {
|
|
134
|
+
url: this.config.url,
|
|
133
135
|
site: this.config.site,
|
|
134
136
|
env: this.tracer._env,
|
|
135
137
|
service: this.config.service || this.tracer._service,
|
package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js
CHANGED
|
@@ -2,6 +2,7 @@ const request = require('../../exporters/common/request')
|
|
|
2
2
|
const id = require('../../id')
|
|
3
3
|
|
|
4
4
|
function getItrConfiguration ({
|
|
5
|
+
url,
|
|
5
6
|
site,
|
|
6
7
|
env,
|
|
7
8
|
service,
|
|
@@ -14,7 +15,7 @@ function getItrConfiguration ({
|
|
|
14
15
|
runtimeVersion,
|
|
15
16
|
branch
|
|
16
17
|
}, done) {
|
|
17
|
-
const
|
|
18
|
+
const intakeUrl = url || new URL(`https://api.${site}`)
|
|
18
19
|
|
|
19
20
|
const apiKey = process.env.DATADOG_API_KEY || process.env.DD_API_KEY
|
|
20
21
|
const appKey = process.env.DATADOG_APP_KEY ||
|
|
@@ -35,9 +36,9 @@ function getItrConfiguration ({
|
|
|
35
36
|
'dd-application-key': appKey,
|
|
36
37
|
'Content-Type': 'application/json'
|
|
37
38
|
},
|
|
38
|
-
protocol:
|
|
39
|
-
hostname:
|
|
40
|
-
port:
|
|
39
|
+
protocol: intakeUrl.protocol,
|
|
40
|
+
hostname: intakeUrl.hostname,
|
|
41
|
+
port: intakeUrl.port
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
const data = JSON.stringify({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const request = require('../../exporters/common/request')
|
|
2
2
|
|
|
3
3
|
function getSkippableSuites ({
|
|
4
|
+
url,
|
|
4
5
|
site,
|
|
5
6
|
env,
|
|
6
7
|
service,
|
|
@@ -12,7 +13,7 @@ function getSkippableSuites ({
|
|
|
12
13
|
runtimeName,
|
|
13
14
|
runtimeVersion
|
|
14
15
|
}, done) {
|
|
15
|
-
const
|
|
16
|
+
const intakeUrl = url || new URL(`https://api.${site}`)
|
|
16
17
|
|
|
17
18
|
const apiKey = process.env.DATADOG_API_KEY || process.env.DD_API_KEY
|
|
18
19
|
const appKey = process.env.DATADOG_APP_KEY ||
|
|
@@ -33,9 +34,9 @@ function getSkippableSuites ({
|
|
|
33
34
|
'Content-Type': 'application/json'
|
|
34
35
|
},
|
|
35
36
|
timeout: 15000,
|
|
36
|
-
protocol:
|
|
37
|
-
hostname:
|
|
38
|
-
port:
|
|
37
|
+
protocol: intakeUrl.protocol,
|
|
38
|
+
hostname: intakeUrl.hostname,
|
|
39
|
+
port: intakeUrl.port
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
const data = JSON.stringify({
|
|
@@ -4,6 +4,7 @@ const fs = require('fs')
|
|
|
4
4
|
const os = require('os')
|
|
5
5
|
const URL = require('url').URL
|
|
6
6
|
const path = require('path')
|
|
7
|
+
const log = require('./log')
|
|
7
8
|
const pkg = require('./pkg')
|
|
8
9
|
const coalesce = require('koalas')
|
|
9
10
|
const tagger = require('./tagger')
|
|
@@ -44,6 +45,21 @@ class Config {
|
|
|
44
45
|
constructor (options) {
|
|
45
46
|
options = options || {}
|
|
46
47
|
|
|
48
|
+
// Configure the logger first so it can be used to warn about other configs
|
|
49
|
+
this.debug = isTrue(coalesce(
|
|
50
|
+
process.env.DD_TRACE_DEBUG,
|
|
51
|
+
false
|
|
52
|
+
))
|
|
53
|
+
this.logger = options.logger
|
|
54
|
+
this.logLevel = coalesce(
|
|
55
|
+
options.logLevel,
|
|
56
|
+
process.env.DD_TRACE_LOG_LEVEL,
|
|
57
|
+
'debug'
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
log.use(this.logger)
|
|
61
|
+
log.toggle(this.debug, this.logLevel, this)
|
|
62
|
+
|
|
47
63
|
this.tags = {}
|
|
48
64
|
|
|
49
65
|
tagger.add(this.tags, process.env.DD_TAGS)
|
|
@@ -128,10 +144,6 @@ class Config {
|
|
|
128
144
|
process.env.DD_TRACE_TELEMETRY_ENABLED,
|
|
129
145
|
!process.env.AWS_LAMBDA_FUNCTION_NAME
|
|
130
146
|
)
|
|
131
|
-
const DD_TRACE_DEBUG = coalesce(
|
|
132
|
-
process.env.DD_TRACE_DEBUG,
|
|
133
|
-
false
|
|
134
|
-
)
|
|
135
147
|
const DD_TRACE_AGENT_PROTOCOL_VERSION = coalesce(
|
|
136
148
|
options.protocolVersion,
|
|
137
149
|
process.env.DD_TRACE_AGENT_PROTOCOL_VERSION,
|
|
@@ -295,7 +307,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
295
307
|
const defaultFlushInterval = inAWSLambda ? 0 : 2000
|
|
296
308
|
|
|
297
309
|
this.tracing = !isFalse(DD_TRACING_ENABLED)
|
|
298
|
-
this.debug = isTrue(DD_TRACE_DEBUG)
|
|
299
310
|
this.logInjection = isTrue(DD_LOGS_INJECTION)
|
|
300
311
|
this.env = DD_ENV
|
|
301
312
|
this.url = DD_CIVISIBILITY_AGENTLESS_URL ? new URL(DD_CIVISIBILITY_AGENTLESS_URL)
|
|
@@ -309,7 +320,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
309
320
|
this.clientIpHeaderDisabled = !isTrue(DD_APPSEC_ENABLED)
|
|
310
321
|
this.clientIpHeader = DD_TRACE_CLIENT_IP_HEADER
|
|
311
322
|
this.queryStringObfuscation = DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP
|
|
312
|
-
this.logger = options.logger
|
|
313
323
|
this.plugins = !!coalesce(options.plugins, true)
|
|
314
324
|
this.service = DD_SERVICE
|
|
315
325
|
this.serviceMapping = DD_SERVICE_MAPPING.length ? fromEntries(
|
|
@@ -331,11 +341,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
331
341
|
this.sampler = sampler
|
|
332
342
|
this.reportHostname = isTrue(coalesce(options.reportHostname, process.env.DD_TRACE_REPORT_HOSTNAME, false))
|
|
333
343
|
this.scope = process.env.DD_TRACE_SCOPE
|
|
334
|
-
this.logLevel = coalesce(
|
|
335
|
-
options.logLevel,
|
|
336
|
-
process.env.DD_TRACE_LOG_LEVEL,
|
|
337
|
-
'debug'
|
|
338
|
-
)
|
|
339
344
|
this.profiling = {
|
|
340
345
|
enabled: isTrue(DD_PROFILING_ENABLED),
|
|
341
346
|
sourceMap: !isFalse(DD_PROFILING_SOURCE_MAP),
|
|
@@ -124,7 +124,8 @@ module.exports = class PluginManager {
|
|
|
124
124
|
isIntelligentTestRunnerEnabled,
|
|
125
125
|
site,
|
|
126
126
|
experimental,
|
|
127
|
-
queryStringObfuscation
|
|
127
|
+
queryStringObfuscation,
|
|
128
|
+
url
|
|
128
129
|
} = this._tracerConfig
|
|
129
130
|
|
|
130
131
|
const sharedConfig = {}
|
|
@@ -156,6 +157,7 @@ module.exports = class PluginManager {
|
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
sharedConfig.site = site
|
|
160
|
+
sharedConfig.url = url
|
|
159
161
|
|
|
160
162
|
return sharedConfig
|
|
161
163
|
}
|
|
@@ -29,9 +29,6 @@ class Tracer extends NoopProxy {
|
|
|
29
29
|
try {
|
|
30
30
|
const config = new Config(options) // TODO: support dynamic config
|
|
31
31
|
|
|
32
|
-
log.use(config.logger)
|
|
33
|
-
log.toggle(config.debug, config.logLevel, this)
|
|
34
|
-
|
|
35
32
|
if (config.profiling.enabled) {
|
|
36
33
|
// do not stop tracer initialization if the profiler fails to be imported
|
|
37
34
|
try {
|
|
@@ -27,6 +27,7 @@ class SpanProcessor {
|
|
|
27
27
|
const { flushMinSpans } = this._config
|
|
28
28
|
const { started, finished } = trace
|
|
29
29
|
|
|
30
|
+
if (trace.record === false) return
|
|
30
31
|
if (started.length === finished.length || finished.length >= flushMinSpans) {
|
|
31
32
|
this._prioritySampler.sample(spanContext)
|
|
32
33
|
this._spanSampler.sample(spanContext)
|