dd-trace 3.7.1 → 3.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 +2 -0
- package/index.d.ts +11 -0
- package/package.json +4 -2
- package/packages/datadog-instrumentations/src/body-parser.js +26 -0
- package/packages/datadog-instrumentations/src/child-process.js +30 -0
- package/packages/datadog-instrumentations/src/cucumber.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +5 -0
- package/packages/datadog-instrumentations/src/jest.js +110 -40
- package/packages/datadog-instrumentations/src/mocha.js +87 -6
- package/packages/datadog-instrumentations/src/pg.js +1 -2
- package/packages/datadog-instrumentations/src/qs.js +24 -0
- package/packages/datadog-plugin-cucumber/src/index.js +13 -32
- package/packages/datadog-plugin-cypress/src/plugin.js +2 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +0 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +0 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +0 -1
- package/packages/datadog-plugin-http/src/client.js +14 -4
- package/packages/datadog-plugin-http/src/server.js +3 -0
- package/packages/datadog-plugin-http2/src/client.js +20 -1
- package/packages/datadog-plugin-http2/src/server.js +3 -0
- package/packages/datadog-plugin-jest/src/index.js +11 -129
- package/packages/datadog-plugin-mocha/src/index.js +33 -46
- package/packages/datadog-plugin-net/src/index.js +4 -0
- package/packages/datadog-plugin-next/src/index.js +3 -0
- package/packages/datadog-plugin-oracledb/src/index.js +0 -1
- package/packages/datadog-plugin-pg/src/index.js +5 -2
- package/packages/datadog-plugin-router/src/index.js +2 -0
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +3 -5
- package/packages/dd-trace/src/appsec/gateway/engine/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +3 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +11 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/injection-analyzer.js +19 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +13 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/index.js +6 -0
- package/packages/dd-trace/src/appsec/iast/path-line.js +8 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +16 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +18 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +125 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/origin-types.js +4 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +38 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +66 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +52 -6
- package/packages/dd-trace/src/appsec/index.js +8 -0
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +7 -0
- package/packages/dd-trace/src/appsec/remote_config/index.js +34 -0
- package/packages/dd-trace/src/appsec/remote_config/manager.js +264 -0
- package/packages/dd-trace/src/{exporters → appsec/remote_config}/scheduler.js +9 -9
- package/packages/dd-trace/src/appsec/rule_manager.js +3 -0
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +5 -7
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +3 -4
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +3 -4
- package/packages/dd-trace/src/config.js +41 -20
- package/packages/dd-trace/src/constants.js +6 -1
- package/packages/dd-trace/src/exporters/common/request.js +7 -1
- package/packages/dd-trace/src/format.js +12 -10
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -5
- package/packages/dd-trace/src/opentracing/span_context.js +9 -0
- package/packages/dd-trace/src/plugin_manager.js +6 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +132 -0
- package/packages/dd-trace/src/plugins/database.js +46 -0
- package/packages/dd-trace/src/plugins/tracing.js +2 -0
- package/packages/dd-trace/src/plugins/util/test.js +61 -8
- package/packages/dd-trace/src/plugins/util/web.js +9 -8
- package/packages/dd-trace/src/proxy.js +4 -3
- package/packages/dd-trace/src/span_processor.js +1 -0
- package/packages/dd-trace/src/tracer.js +4 -3
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
const { channel } = require('diagnostics_channel')
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
getTestEnvironmentMetadata,
|
|
5
|
+
getCodeOwnersFileEntries,
|
|
6
|
+
getTestParentSpan,
|
|
7
|
+
getTestCommonTags,
|
|
8
|
+
getCodeOwnersForFilename,
|
|
9
|
+
TEST_CODE_OWNERS,
|
|
10
|
+
CI_APP_ORIGIN
|
|
11
|
+
} = require('./util/test')
|
|
12
|
+
const { getItrConfiguration } = require('../ci-visibility/intelligent-test-runner/get-itr-configuration')
|
|
13
|
+
const { getSkippableSuites } = require('../ci-visibility/intelligent-test-runner/get-skippable-suites')
|
|
14
|
+
const { COMPONENT } = require('../constants')
|
|
15
|
+
|
|
16
|
+
const Plugin = require('./plugin')
|
|
17
|
+
|
|
18
|
+
module.exports = class CiPlugin extends Plugin {
|
|
19
|
+
constructor (...args) {
|
|
20
|
+
super(...args)
|
|
21
|
+
|
|
22
|
+
const gitMetadataUploadFinishCh = channel('ci:git-metadata-upload:finish')
|
|
23
|
+
// `gitMetadataPromise` is used to wait until git metadata is uploaded to
|
|
24
|
+
// proceed with calculating the suites to skip
|
|
25
|
+
// TODO: add timeout after which the promise is resolved
|
|
26
|
+
const gitMetadataPromise = new Promise(resolve => {
|
|
27
|
+
gitMetadataUploadFinishCh.subscribe(err => {
|
|
28
|
+
resolve(err)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
this.codeOwnersEntries = getCodeOwnersFileEntries()
|
|
33
|
+
|
|
34
|
+
this.addSub(`ci:${this.constructor.name}:configuration`, ({ onDone }) => {
|
|
35
|
+
if (!this.config.isAgentlessEnabled || !this.config.isIntelligentTestRunnerEnabled) {
|
|
36
|
+
onDone({ config: {} })
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
getItrConfiguration(this.testConfiguration, (err, config) => {
|
|
40
|
+
if (err) {
|
|
41
|
+
onDone({ err })
|
|
42
|
+
} else {
|
|
43
|
+
this.itrConfig = config
|
|
44
|
+
onDone({ config })
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
this.addSub(`ci:${this.constructor.name}:test-suite:skippable`, ({ onDone }) => {
|
|
50
|
+
if (!this.config.isAgentlessEnabled || !this.config.isIntelligentTestRunnerEnabled) {
|
|
51
|
+
return onDone({ skippableSuites: [] })
|
|
52
|
+
}
|
|
53
|
+
// we only request after git upload has happened, if it didn't fail
|
|
54
|
+
gitMetadataPromise.then((gitUploadError) => {
|
|
55
|
+
if (gitUploadError) {
|
|
56
|
+
return onDone({ err: gitUploadError })
|
|
57
|
+
}
|
|
58
|
+
if (!this.itrConfig || !this.itrConfig.isSuitesSkippingEnabled) {
|
|
59
|
+
return onDone({ skippableSuites: [] })
|
|
60
|
+
}
|
|
61
|
+
getSkippableSuites(this.testConfiguration, (err, skippableSuites) => {
|
|
62
|
+
if (err) {
|
|
63
|
+
onDone({ err })
|
|
64
|
+
} else {
|
|
65
|
+
onDone({ skippableSuites })
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
configure (config) {
|
|
73
|
+
super.configure(config)
|
|
74
|
+
this.testEnvironmentMetadata = getTestEnvironmentMetadata(this.constructor.name, this.config)
|
|
75
|
+
|
|
76
|
+
const {
|
|
77
|
+
'git.repository_url': repositoryUrl,
|
|
78
|
+
'git.commit.sha': sha,
|
|
79
|
+
'os.version': osVersion,
|
|
80
|
+
'os.platform': osPlatform,
|
|
81
|
+
'os.architecture': osArchitecture,
|
|
82
|
+
'runtime.name': runtimeName,
|
|
83
|
+
'runtime.version': runtimeVersion,
|
|
84
|
+
'git.branch': branch
|
|
85
|
+
} = this.testEnvironmentMetadata
|
|
86
|
+
|
|
87
|
+
this.testConfiguration = {
|
|
88
|
+
repositoryUrl,
|
|
89
|
+
sha,
|
|
90
|
+
osVersion,
|
|
91
|
+
osPlatform,
|
|
92
|
+
osArchitecture,
|
|
93
|
+
runtimeName,
|
|
94
|
+
runtimeVersion,
|
|
95
|
+
branch,
|
|
96
|
+
url: this.config.url,
|
|
97
|
+
site: this.config.site,
|
|
98
|
+
env: this.tracer._env,
|
|
99
|
+
service: this.config.service || this.tracer._service
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
startTestSpan (name, suite, extraTags, childOf) {
|
|
104
|
+
const parent = childOf || getTestParentSpan(this.tracer)
|
|
105
|
+
const testCommonTags = getTestCommonTags(name, suite, this.tracer._version)
|
|
106
|
+
|
|
107
|
+
const testTags = {
|
|
108
|
+
...testCommonTags,
|
|
109
|
+
[COMPONENT]: this.constructor.name,
|
|
110
|
+
...extraTags
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const codeOwners = getCodeOwnersForFilename(suite, this.codeOwnersEntries)
|
|
114
|
+
|
|
115
|
+
if (codeOwners) {
|
|
116
|
+
testTags[TEST_CODE_OWNERS] = codeOwners
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const testSpan = this.tracer
|
|
120
|
+
.startSpan(`${this.constructor.name}.test`, {
|
|
121
|
+
childOf: parent,
|
|
122
|
+
tags: {
|
|
123
|
+
...this.testEnvironmentMetadata,
|
|
124
|
+
...testTags
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
testSpan.context()._trace.origin = CI_APP_ORIGIN
|
|
129
|
+
|
|
130
|
+
return testSpan
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -4,6 +4,52 @@ const StoragePlugin = require('./storage')
|
|
|
4
4
|
|
|
5
5
|
class DatabasePlugin extends StoragePlugin {
|
|
6
6
|
static get operation () { return 'query' }
|
|
7
|
+
|
|
8
|
+
constructor (...args) {
|
|
9
|
+
super(...args)
|
|
10
|
+
this.serviceTags = {
|
|
11
|
+
dddbs: '',
|
|
12
|
+
encodedDddbs: '',
|
|
13
|
+
dde: '',
|
|
14
|
+
encodedDde: '',
|
|
15
|
+
ddps: '',
|
|
16
|
+
encodedDdps: '',
|
|
17
|
+
ddpv: '',
|
|
18
|
+
encodedDdpv: ''
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
encodingServiceTags (serviceTag, encodeATag, spanConfig) {
|
|
22
|
+
if (serviceTag !== spanConfig) {
|
|
23
|
+
this.serviceTags[serviceTag] = spanConfig
|
|
24
|
+
this.serviceTags[encodeATag] = encodeURIComponent(spanConfig)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
createDBMPropagationCommentService () {
|
|
29
|
+
this.encodingServiceTags('dddbs', 'encodedDddbs', this.config.service)
|
|
30
|
+
this.encodingServiceTags('dde', 'encodedDde', this.tracer._env)
|
|
31
|
+
this.encodingServiceTags('ddps', 'encodedDdps', this.tracer._service)
|
|
32
|
+
this.encodingServiceTags('ddpv', 'encodedDdpv', this.tracer._version)
|
|
33
|
+
|
|
34
|
+
const { encodedDddbs, encodedDde, encodedDdps, encodedDdpv } = this.serviceTags
|
|
35
|
+
|
|
36
|
+
return `dddbs='${encodedDddbs}',dde='${encodedDde}',` +
|
|
37
|
+
`ddps='${encodedDdps}',ddpv='${encodedDdpv}'`
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
injectDbmQuery (query) {
|
|
41
|
+
if (this.config.dbmPropagationMode === 'disabled') {
|
|
42
|
+
return query
|
|
43
|
+
}
|
|
44
|
+
const servicePropagation = this.createDBMPropagationCommentService()
|
|
45
|
+
if (this.config.dbmPropagationMode === 'service') {
|
|
46
|
+
return `/*${servicePropagation}*/ ${query}`
|
|
47
|
+
} else if (this.config.dbmPropagationMode === 'full') {
|
|
48
|
+
this.activeSpan.setTag('_dd.dbm_trace_injected', 'true')
|
|
49
|
+
const traceparent = this.activeSpan._spanContext.toTraceparent()
|
|
50
|
+
return `/*${servicePropagation},traceparent='${traceparent}'*/ ${query}`
|
|
51
|
+
}
|
|
52
|
+
}
|
|
7
53
|
}
|
|
8
54
|
|
|
9
55
|
module.exports = DatabasePlugin
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const Plugin = require('./plugin')
|
|
4
4
|
const { storage } = require('../../../datadog-core')
|
|
5
5
|
const analyticsSampler = require('../analytics_sampler')
|
|
6
|
+
const { COMPONENT } = require('../constants')
|
|
6
7
|
|
|
7
8
|
class TracingPlugin extends Plugin {
|
|
8
9
|
constructor (...args) {
|
|
@@ -72,6 +73,7 @@ class TracingPlugin extends Plugin {
|
|
|
72
73
|
const span = this.tracer.startSpan(name, {
|
|
73
74
|
childOf,
|
|
74
75
|
tags: {
|
|
76
|
+
[COMPONENT]: this.component,
|
|
75
77
|
'service.name': service || this.tracer._service,
|
|
76
78
|
'resource.name': resource,
|
|
77
79
|
'span.kind': kind,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const fs = require('fs')
|
|
3
3
|
|
|
4
|
+
const istanbul = require('istanbul-lib-coverage')
|
|
4
5
|
const ignore = require('ignore')
|
|
5
6
|
|
|
6
7
|
const { getGitMetadata } = require('./git')
|
|
@@ -40,10 +41,6 @@ const TEST_COMMAND = 'test.command'
|
|
|
40
41
|
const TEST_SESSION_ID = 'test_session_id'
|
|
41
42
|
const TEST_SUITE_ID = 'test_suite_id'
|
|
42
43
|
|
|
43
|
-
const ERROR_TYPE = 'error.type'
|
|
44
|
-
const ERROR_MESSAGE = 'error.msg'
|
|
45
|
-
const ERROR_STACK = 'error.stack'
|
|
46
|
-
|
|
47
44
|
const CI_APP_ORIGIN = 'ciapp-test'
|
|
48
45
|
|
|
49
46
|
const JEST_TEST_RUNNER = 'test.jest.test_runner'
|
|
@@ -65,9 +62,6 @@ module.exports = {
|
|
|
65
62
|
TEST_SKIP_REASON,
|
|
66
63
|
TEST_IS_RUM_ACTIVE,
|
|
67
64
|
TEST_SOURCE_FILE,
|
|
68
|
-
ERROR_TYPE,
|
|
69
|
-
ERROR_MESSAGE,
|
|
70
|
-
ERROR_STACK,
|
|
71
65
|
CI_APP_ORIGIN,
|
|
72
66
|
LIBRARY_VERSION,
|
|
73
67
|
getTestEnvironmentMetadata,
|
|
@@ -84,7 +78,11 @@ module.exports = {
|
|
|
84
78
|
TEST_SESSION_ID,
|
|
85
79
|
TEST_SUITE_ID,
|
|
86
80
|
TEST_ITR_TESTS_SKIPPED,
|
|
87
|
-
TEST_CODE_COVERAGE_LINES_TOTAL
|
|
81
|
+
TEST_CODE_COVERAGE_LINES_TOTAL,
|
|
82
|
+
getCoveredFilenamesFromCoverage,
|
|
83
|
+
resetCoverage,
|
|
84
|
+
mergeCoverage,
|
|
85
|
+
fromCoverageMapToCoverage
|
|
88
86
|
}
|
|
89
87
|
|
|
90
88
|
function getTestEnvironmentMetadata (testFramework, config) {
|
|
@@ -262,3 +260,58 @@ function getTestSuiteCommonTags (command, version, testSuite) {
|
|
|
262
260
|
[TEST_COMMAND]: command
|
|
263
261
|
}
|
|
264
262
|
}
|
|
263
|
+
|
|
264
|
+
function getCoveredFilenamesFromCoverage (coverage) {
|
|
265
|
+
const coverageMap = istanbul.createCoverageMap(coverage)
|
|
266
|
+
|
|
267
|
+
return coverageMap
|
|
268
|
+
.files()
|
|
269
|
+
.filter(filename => {
|
|
270
|
+
const fileCoverage = coverageMap.fileCoverageFor(filename)
|
|
271
|
+
const lineCoverage = fileCoverage.getLineCoverage()
|
|
272
|
+
const isAnyLineExecuted = Object.entries(lineCoverage).some(([, numExecutions]) => !!numExecutions)
|
|
273
|
+
|
|
274
|
+
return isAnyLineExecuted
|
|
275
|
+
})
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function resetCoverage (coverage) {
|
|
279
|
+
const coverageMap = istanbul.createCoverageMap(coverage)
|
|
280
|
+
|
|
281
|
+
return coverageMap
|
|
282
|
+
.files()
|
|
283
|
+
.forEach(filename => {
|
|
284
|
+
const fileCoverage = coverageMap.fileCoverageFor(filename)
|
|
285
|
+
fileCoverage.resetHits()
|
|
286
|
+
})
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function mergeCoverage (coverage, targetCoverage) {
|
|
290
|
+
const coverageMap = istanbul.createCoverageMap(coverage)
|
|
291
|
+
return coverageMap
|
|
292
|
+
.files()
|
|
293
|
+
.forEach(filename => {
|
|
294
|
+
const fileCoverage = coverageMap.fileCoverageFor(filename)
|
|
295
|
+
|
|
296
|
+
// If the fileCoverage is not there for this filename,
|
|
297
|
+
// we create it to force a merge between the fileCoverages
|
|
298
|
+
// instead of a reference assignment (which would not work if the coverage is reset later on)
|
|
299
|
+
if (!targetCoverage.data[filename]) {
|
|
300
|
+
targetCoverage.addFileCoverage(istanbul.createFileCoverage(filename))
|
|
301
|
+
}
|
|
302
|
+
targetCoverage.addFileCoverage(fileCoverage)
|
|
303
|
+
const targetFileCoverage = targetCoverage.fileCoverageFor(filename)
|
|
304
|
+
|
|
305
|
+
// branches (.b) are copied by reference, so `resetHits` affects the copy, so we need to copy it manually
|
|
306
|
+
Object.entries(targetFileCoverage.data.b).forEach(([key, value]) => {
|
|
307
|
+
targetFileCoverage.data.b[key] = [...value]
|
|
308
|
+
})
|
|
309
|
+
})
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function fromCoverageMapToCoverage (coverageMap) {
|
|
313
|
+
return Object.entries(coverageMap.data).reduce((acc, [filename, fileCoverage]) => {
|
|
314
|
+
acc[filename] = fileCoverage.data
|
|
315
|
+
return acc
|
|
316
|
+
}, {})
|
|
317
|
+
}
|
|
@@ -11,6 +11,7 @@ const kinds = require('../../../../../ext/kinds')
|
|
|
11
11
|
const urlFilter = require('./urlfilter')
|
|
12
12
|
const BlockList = require('./ip_blocklist')
|
|
13
13
|
const { incomingHttpRequestEnd } = require('../../appsec/gateway/channels')
|
|
14
|
+
const { ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../constants')
|
|
14
15
|
|
|
15
16
|
const WEB = types.WEB
|
|
16
17
|
const SERVER = kinds.SERVER
|
|
@@ -51,8 +52,6 @@ const ends = new WeakMap()
|
|
|
51
52
|
const web = {
|
|
52
53
|
// Ensure the configuration has the correct structure and defaults.
|
|
53
54
|
normalizeConfig (config) {
|
|
54
|
-
config = config.server || config
|
|
55
|
-
|
|
56
55
|
const headers = getHeadersToRecord(config)
|
|
57
56
|
const validateStatus = getStatusValidator(config)
|
|
58
57
|
const hooks = getHooks(config)
|
|
@@ -60,14 +59,15 @@ const web = {
|
|
|
60
59
|
const middleware = getMiddlewareSetting(config)
|
|
61
60
|
const queryStringObfuscation = getQsObfuscator(config)
|
|
62
61
|
|
|
63
|
-
return
|
|
62
|
+
return {
|
|
63
|
+
...config,
|
|
64
64
|
headers,
|
|
65
65
|
validateStatus,
|
|
66
66
|
hooks,
|
|
67
67
|
filter,
|
|
68
68
|
middleware,
|
|
69
69
|
queryStringObfuscation
|
|
70
|
-
}
|
|
70
|
+
}
|
|
71
71
|
},
|
|
72
72
|
|
|
73
73
|
setFramework (req, name, config) {
|
|
@@ -77,6 +77,7 @@ const web = {
|
|
|
77
77
|
if (!span) return
|
|
78
78
|
|
|
79
79
|
span.context()._name = `${name}.request`
|
|
80
|
+
span.context()._tags['component'] = name
|
|
80
81
|
|
|
81
82
|
web.setConfig(req, config)
|
|
82
83
|
},
|
|
@@ -204,9 +205,9 @@ const web = {
|
|
|
204
205
|
if (span) {
|
|
205
206
|
if (error) {
|
|
206
207
|
span.addTags({
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
208
|
+
[ERROR_TYPE]: error.name,
|
|
209
|
+
[ERROR_MESSAGE]: error.message,
|
|
210
|
+
[ERROR_STACK]: error.stack
|
|
210
211
|
})
|
|
211
212
|
}
|
|
212
213
|
|
|
@@ -276,7 +277,7 @@ const web = {
|
|
|
276
277
|
const context = contexts.get(req)
|
|
277
278
|
const span = context.span
|
|
278
279
|
const error = context.error
|
|
279
|
-
const hasExistingError = span.context()._tags['error'] || span.context()._tags[
|
|
280
|
+
const hasExistingError = span.context()._tags['error'] || span.context()._tags[ERROR_MESSAGE]
|
|
280
281
|
|
|
281
282
|
if (!hasExistingError && !context.config.validateStatus(statusCode)) {
|
|
282
283
|
span.setTag(ERROR, error || true)
|
|
@@ -10,6 +10,7 @@ const { setStartupLogPluginManager } = require('./startup-log')
|
|
|
10
10
|
const telemetry = require('./telemetry')
|
|
11
11
|
const PluginManager = require('./plugin_manager')
|
|
12
12
|
const { sendGitMetadata } = require('./ci-visibility/exporters/git/git_metadata')
|
|
13
|
+
const remoteConfig = require('./appsec/remote_config')
|
|
13
14
|
|
|
14
15
|
const gitMetadataUploadFinishCh = channel('ci:git-metadata-upload:finish')
|
|
15
16
|
|
|
@@ -29,8 +30,7 @@ class Tracer extends NoopProxy {
|
|
|
29
30
|
try {
|
|
30
31
|
const config = new Config(options) // TODO: support dynamic config
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
log.toggle(config.debug, config.logLevel, this)
|
|
33
|
+
remoteConfig.enable(config)
|
|
34
34
|
|
|
35
35
|
if (config.profiling.enabled) {
|
|
36
36
|
// do not stop tracer initialization if the profiler fails to be imported
|
|
@@ -51,6 +51,7 @@ class Tracer extends NoopProxy {
|
|
|
51
51
|
if (config.appsec.enabled) {
|
|
52
52
|
require('./appsec').enable(config)
|
|
53
53
|
}
|
|
54
|
+
|
|
54
55
|
if (config.iast.enabled) {
|
|
55
56
|
require('./appsec/iast').enable(config)
|
|
56
57
|
}
|
|
@@ -64,7 +65,7 @@ class Tracer extends NoopProxy {
|
|
|
64
65
|
if (config.isGitUploadEnabled) {
|
|
65
66
|
sendGitMetadata(config.site, (err) => {
|
|
66
67
|
if (err) {
|
|
67
|
-
log.error(`Error uploading git metadata: ${err}`)
|
|
68
|
+
log.error(`Error uploading git metadata: ${err.message}`)
|
|
68
69
|
} else {
|
|
69
70
|
log.debug('Successfully uploaded git metadata')
|
|
70
71
|
}
|
|
@@ -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)
|
|
@@ -6,6 +6,7 @@ const Scope = require('./scope')
|
|
|
6
6
|
const { storage } = require('../../datadog-core')
|
|
7
7
|
const { isError } = require('./util')
|
|
8
8
|
const { setStartupLogConfig } = require('./startup-log')
|
|
9
|
+
const { ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../dd-trace/src/constants')
|
|
9
10
|
|
|
10
11
|
const SPAN_TYPE = tags.SPAN_TYPE
|
|
11
12
|
const RESOURCE_NAME = tags.RESOURCE_NAME
|
|
@@ -143,9 +144,9 @@ class DatadogTracer extends Tracer {
|
|
|
143
144
|
function addError (span, error) {
|
|
144
145
|
if (isError(error)) {
|
|
145
146
|
span.addTags({
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
[ERROR_TYPE]: error.name,
|
|
148
|
+
[ERROR_MESSAGE]: error.message,
|
|
149
|
+
[ERROR_STACK]: error.stack
|
|
149
150
|
})
|
|
150
151
|
}
|
|
151
152
|
}
|