dd-trace 2.12.1 → 3.2.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 +3 -2
- package/MIGRATING.md +119 -0
- package/ci/init.js +2 -27
- package/ext/formats.js +3 -5
- package/ext/tags.d.ts +2 -1
- package/ext/tags.js +2 -1
- package/index.d.ts +44 -38
- package/package.json +9 -8
- package/packages/datadog-core/src/storage/async_resource.js +19 -1
- package/packages/datadog-core/src/storage/index.js +1 -1
- package/packages/datadog-instrumentations/index.js +1 -52
- package/packages/datadog-instrumentations/src/connect.js +1 -1
- package/packages/datadog-instrumentations/src/crypto.js +30 -0
- package/packages/datadog-instrumentations/src/cucumber.js +15 -0
- package/packages/datadog-instrumentations/src/grpc/client.js +2 -2
- package/packages/datadog-instrumentations/src/grpc/server.js +1 -1
- package/packages/datadog-instrumentations/src/hapi.js +3 -31
- package/packages/datadog-instrumentations/src/helpers/hooks.js +69 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +5 -34
- package/packages/datadog-instrumentations/src/helpers/instrumentations.js +7 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +59 -0
- package/packages/datadog-instrumentations/src/http/server.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +33 -11
- package/packages/datadog-instrumentations/src/koa.js +1 -1
- package/packages/datadog-instrumentations/src/mocha.js +4 -1
- package/packages/datadog-instrumentations/src/net.js +13 -0
- package/packages/datadog-instrumentations/src/pg.js +2 -2
- package/packages/datadog-instrumentations/src/restify.js +27 -5
- package/packages/datadog-instrumentations/src/router.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/base.js +1 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -2
- package/packages/datadog-plugin-cucumber/src/index.js +4 -0
- package/packages/datadog-plugin-grpc/src/client.js +2 -2
- package/packages/datadog-plugin-grpc/src/server.js +2 -2
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-http/src/server.js +1 -1
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +25 -4
- package/packages/datadog-plugin-mocha/src/index.js +2 -2
- package/packages/datadog-plugin-mongodb-core/src/index.js +32 -8
- package/packages/datadog-plugin-oracledb/src/index.js +12 -4
- package/packages/datadog-plugin-restify/src/index.js +7 -0
- package/packages/dd-trace/index.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +3 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/index.js +20 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +48 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +24 -0
- package/packages/dd-trace/src/appsec/iast/iast-context.js +50 -0
- package/packages/dd-trace/src/appsec/iast/index.js +59 -0
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +94 -0
- package/packages/dd-trace/src/appsec/iast/path-line.js +70 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +113 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +50 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +53 -8
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +23 -24
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +220 -0
- package/packages/dd-trace/src/config.js +97 -10
- package/packages/dd-trace/src/constants.js +9 -1
- package/packages/dd-trace/src/encode/0.4.js +55 -58
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +13 -34
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +84 -0
- package/packages/dd-trace/src/encode/span-stats.js +155 -0
- package/packages/dd-trace/src/exporters/agent/index.js +25 -7
- package/packages/dd-trace/src/exporters/agent/writer.js +7 -4
- package/packages/dd-trace/src/{profiling/exporters → exporters/common}/form-data.js +0 -0
- package/packages/dd-trace/src/exporters/common/request.js +69 -39
- package/packages/dd-trace/src/exporters/common/writer.js +16 -6
- package/packages/dd-trace/src/exporters/span-stats/index.js +20 -0
- package/packages/dd-trace/src/exporters/span-stats/writer.js +54 -0
- package/packages/dd-trace/src/format.js +2 -0
- package/packages/dd-trace/src/id.js +16 -13
- package/packages/dd-trace/src/iitm.js +12 -1
- package/packages/dd-trace/src/index.js +10 -0
- package/packages/dd-trace/src/noop/proxy.js +77 -0
- package/packages/dd-trace/src/noop/scope.js +2 -6
- package/packages/dd-trace/src/noop/span.js +12 -12
- package/packages/dd-trace/src/noop/tracer.js +8 -9
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +77 -6
- package/packages/dd-trace/src/opentracing/span.js +63 -49
- package/packages/dd-trace/src/opentracing/span_context.js +1 -5
- package/packages/dd-trace/src/opentracing/tracer.js +32 -37
- package/packages/dd-trace/src/plugin_manager.js +111 -64
- package/packages/dd-trace/src/plugins/index.js +57 -45
- package/packages/dd-trace/src/plugins/log_plugin.js +16 -9
- package/packages/dd-trace/src/plugins/util/ci.js +34 -9
- package/packages/dd-trace/src/plugins/util/git.js +52 -2
- package/packages/dd-trace/src/plugins/util/ip_blocklist.js +25 -0
- package/packages/dd-trace/src/plugins/util/tags.js +4 -1
- package/packages/dd-trace/src/plugins/util/web.js +149 -6
- package/packages/dd-trace/src/priority_sampler.js +36 -1
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/cpu.js +3 -3
- package/packages/dd-trace/src/proxy.js +21 -90
- package/packages/dd-trace/src/ritm.js +10 -1
- package/packages/dd-trace/src/scope.js +2 -184
- package/packages/dd-trace/src/span_processor.js +7 -1
- package/packages/dd-trace/src/span_stats.js +210 -0
- package/packages/dd-trace/src/startup-log.js +8 -19
- package/packages/dd-trace/src/telemetry/dependencies.js +83 -0
- package/packages/dd-trace/src/{telemetry.js → telemetry/index.js} +11 -79
- package/packages/dd-trace/src/telemetry/send-data.js +35 -0
- package/packages/dd-trace/src/tracer.js +0 -4
- package/scripts/install_plugin_modules.js +17 -26
- package/ci/jest/env.js +0 -39
- package/cypress/plugin.js +0 -5
- package/cypress/support.js +0 -1
- package/packages/datadog-plugin-fs/src/index.js +0 -548
|
@@ -2,30 +2,75 @@
|
|
|
2
2
|
|
|
3
3
|
const URL = require('url').URL
|
|
4
4
|
const Writer = require('./writer')
|
|
5
|
-
const
|
|
5
|
+
const CoverageWriter = require('./coverage-writer')
|
|
6
|
+
|
|
7
|
+
const log = require('../../../log')
|
|
6
8
|
|
|
7
9
|
class AgentlessCiVisibilityExporter {
|
|
8
10
|
constructor (config) {
|
|
9
|
-
|
|
11
|
+
this._config = config
|
|
12
|
+
const { tags, site, url, isIntelligentTestRunnerEnabled } = config
|
|
13
|
+
this._isIntelligentTestRunnerEnabled = isIntelligentTestRunnerEnabled
|
|
10
14
|
this._url = url || new URL(`https://citestcycle-intake.${site}`)
|
|
11
15
|
this._writer = new Writer({ url: this._url, tags })
|
|
16
|
+
this._timer = undefined
|
|
17
|
+
this._coverageTimer = undefined
|
|
18
|
+
|
|
19
|
+
this._coverageUrl = url || new URL(`https://event-platform-intake.${site}`)
|
|
20
|
+
this._coverageWriter = new CoverageWriter({ url: this._coverageUrl })
|
|
21
|
+
|
|
22
|
+
process.once('beforeExit', () => {
|
|
23
|
+
this._writer.flush()
|
|
24
|
+
this._coverageWriter.flush()
|
|
25
|
+
})
|
|
26
|
+
}
|
|
12
27
|
|
|
13
|
-
|
|
14
|
-
|
|
28
|
+
exportCoverage ({ testSpan, coverageFiles }) {
|
|
29
|
+
const formattedCoverage = {
|
|
30
|
+
traceId: testSpan.context()._traceId,
|
|
31
|
+
spanId: testSpan.context()._spanId,
|
|
32
|
+
files: coverageFiles
|
|
33
|
+
}
|
|
34
|
+
this._coverageWriter.append(formattedCoverage)
|
|
35
|
+
|
|
36
|
+
const { flushInterval } = this._config
|
|
37
|
+
|
|
38
|
+
if (flushInterval === 0) {
|
|
39
|
+
this._coverageWriter.flush()
|
|
40
|
+
} else if (flushInterval > 0 && !this._coverageTimer) {
|
|
41
|
+
this._coverageTimer = setTimeout(() => {
|
|
42
|
+
this._coverageWriter.flush()
|
|
43
|
+
this._coverageTimer = clearTimeout(this._coverageTimer)
|
|
44
|
+
}, flushInterval).unref()
|
|
15
45
|
}
|
|
16
|
-
this._scheduler && this._scheduler.start()
|
|
17
46
|
}
|
|
18
47
|
|
|
19
48
|
export (trace) {
|
|
20
49
|
this._writer.append(trace)
|
|
21
50
|
|
|
22
|
-
|
|
51
|
+
const { flushInterval } = this._config
|
|
52
|
+
|
|
53
|
+
if (flushInterval === 0) {
|
|
23
54
|
this._writer.flush()
|
|
55
|
+
} else if (flushInterval > 0 && !this._timer) {
|
|
56
|
+
this._timer = setTimeout(() => {
|
|
57
|
+
this._writer.flush()
|
|
58
|
+
this._timer = clearTimeout(this._timer)
|
|
59
|
+
}, flushInterval).unref()
|
|
24
60
|
}
|
|
25
61
|
}
|
|
26
62
|
|
|
27
|
-
|
|
28
|
-
|
|
63
|
+
setUrl (url, coverageUrl = url) {
|
|
64
|
+
try {
|
|
65
|
+
url = new URL(url)
|
|
66
|
+
coverageUrl = new URL(coverageUrl)
|
|
67
|
+
this._url = url
|
|
68
|
+
this._coverageUrl = coverageUrl
|
|
69
|
+
this._writer.setUrl(url)
|
|
70
|
+
this._coverageWriter.setUrl(coverageUrl)
|
|
71
|
+
} catch (e) {
|
|
72
|
+
log.error(e)
|
|
73
|
+
}
|
|
29
74
|
}
|
|
30
75
|
}
|
|
31
76
|
|
|
@@ -5,16 +5,37 @@ const log = require('../../../log')
|
|
|
5
5
|
const { AgentlessCiVisibilityEncoder } = require('../../../encode/agentless-ci-visibility')
|
|
6
6
|
const BaseWriter = require('../../../exporters/common/writer')
|
|
7
7
|
|
|
8
|
+
function safeJSONStringify (value) {
|
|
9
|
+
return JSON.stringify(value, (key, value) =>
|
|
10
|
+
key !== 'dd-api-key' ? value : undefined
|
|
11
|
+
)
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
class Writer extends BaseWriter {
|
|
9
15
|
constructor ({ url, tags }) {
|
|
10
16
|
super(...arguments)
|
|
11
17
|
const { 'runtime-id': runtimeId, env, service } = tags
|
|
12
18
|
this._url = url
|
|
13
|
-
this._encoder = new AgentlessCiVisibilityEncoder({ runtimeId, env, service })
|
|
19
|
+
this._encoder = new AgentlessCiVisibilityEncoder(this, { runtimeId, env, service })
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
_sendPayload (data, _, done) {
|
|
17
|
-
|
|
23
|
+
const options = {
|
|
24
|
+
path: '/api/v2/citestcycle',
|
|
25
|
+
method: 'POST',
|
|
26
|
+
headers: {
|
|
27
|
+
'dd-api-key': process.env.DATADOG_API_KEY || process.env.DD_API_KEY,
|
|
28
|
+
'Content-Type': 'application/msgpack'
|
|
29
|
+
},
|
|
30
|
+
timeout: 15000
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
options.protocol = this._url.protocol
|
|
34
|
+
options.hostname = this._url.hostname
|
|
35
|
+
options.port = this._url.port
|
|
36
|
+
|
|
37
|
+
log.debug(() => `Request to the intake: ${safeJSONStringify(options)}`)
|
|
38
|
+
request(data, options, (err, res) => {
|
|
18
39
|
if (err) {
|
|
19
40
|
log.error(err)
|
|
20
41
|
done()
|
|
@@ -26,26 +47,4 @@ class Writer extends BaseWriter {
|
|
|
26
47
|
}
|
|
27
48
|
}
|
|
28
49
|
|
|
29
|
-
function makeRequest (data, url, cb) {
|
|
30
|
-
const options = {
|
|
31
|
-
path: '/api/v2/citestcycle',
|
|
32
|
-
method: 'POST',
|
|
33
|
-
headers: {
|
|
34
|
-
'Content-Type': 'application/msgpack',
|
|
35
|
-
'dd-api-key': process.env.DATADOG_API_KEY || process.env.DD_API_KEY
|
|
36
|
-
},
|
|
37
|
-
timeout: 15000
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
options.protocol = url.protocol
|
|
41
|
-
options.hostname = url.hostname
|
|
42
|
-
options.port = url.port
|
|
43
|
-
|
|
44
|
-
log.debug(() => `Request to the intake: ${JSON.stringify(options)}`)
|
|
45
|
-
|
|
46
|
-
request(data, options, false, (err, res) => {
|
|
47
|
-
cb(err, res)
|
|
48
|
-
})
|
|
49
|
-
}
|
|
50
|
-
|
|
51
50
|
module.exports = Writer
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
const https = require('https')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
|
|
6
|
+
const FormData = require('../../../exporters/common/form-data')
|
|
7
|
+
|
|
8
|
+
const log = require('../../../log')
|
|
9
|
+
const {
|
|
10
|
+
getLatestCommits,
|
|
11
|
+
getRepositoryUrl,
|
|
12
|
+
generatePackFilesForCommits,
|
|
13
|
+
getCommitsToUpload
|
|
14
|
+
} = require('../../../plugins/util/git')
|
|
15
|
+
|
|
16
|
+
const isValidSha = (sha) => /[0-9a-f]{40}/.test(sha)
|
|
17
|
+
|
|
18
|
+
function sanitizeCommits (commits) {
|
|
19
|
+
return commits.map(({ id: commitSha, type }) => {
|
|
20
|
+
if (type !== 'commit') {
|
|
21
|
+
throw new Error('Invalid commit response')
|
|
22
|
+
}
|
|
23
|
+
const sanitizedCommit = commitSha.replace(/[^0-9a-f]+/g, '')
|
|
24
|
+
if (sanitizedCommit !== commitSha || !isValidSha(sanitizedCommit)) {
|
|
25
|
+
throw new Error('Invalid commit format')
|
|
26
|
+
}
|
|
27
|
+
return sanitizedCommit
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getCommonRequestOptions (url) {
|
|
32
|
+
return {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: {
|
|
35
|
+
'dd-api-key': process.env.DATADOG_API_KEY || process.env.DD_API_KEY
|
|
36
|
+
},
|
|
37
|
+
timeout: 15000,
|
|
38
|
+
protocol: url.protocol,
|
|
39
|
+
hostname: url.hostname,
|
|
40
|
+
port: url.port
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* This function posts the SHAs of the commits of the last month
|
|
46
|
+
* The response are the commits for which the backend already has information
|
|
47
|
+
* This response is used to know which commits can be ignored from there on
|
|
48
|
+
*/
|
|
49
|
+
function getCommitsToExclude ({ url, repositoryUrl }, callback) {
|
|
50
|
+
const latestCommits = getLatestCommits()
|
|
51
|
+
const [headCommit] = latestCommits
|
|
52
|
+
|
|
53
|
+
const commonOptions = getCommonRequestOptions(url)
|
|
54
|
+
|
|
55
|
+
const options = {
|
|
56
|
+
...commonOptions,
|
|
57
|
+
headers: {
|
|
58
|
+
...commonOptions.headers,
|
|
59
|
+
'Content-Type': 'application/json'
|
|
60
|
+
},
|
|
61
|
+
path: '/api/v2/git/repository/search_commits'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const localCommitData = JSON.stringify({
|
|
65
|
+
meta: {
|
|
66
|
+
repository_url: repositoryUrl
|
|
67
|
+
},
|
|
68
|
+
data: latestCommits.map(commit => ({
|
|
69
|
+
id: commit,
|
|
70
|
+
type: 'commit'
|
|
71
|
+
}))
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const request = https.request(options, (res) => {
|
|
75
|
+
let responseData = ''
|
|
76
|
+
|
|
77
|
+
res.on('data', chunk => { responseData += chunk })
|
|
78
|
+
res.on('end', () => {
|
|
79
|
+
if (res.statusCode === 200) {
|
|
80
|
+
let commitsToExclude
|
|
81
|
+
try {
|
|
82
|
+
commitsToExclude = sanitizeCommits(JSON.parse(responseData).data)
|
|
83
|
+
} catch (e) {
|
|
84
|
+
callback(new Error(`Can't parse response: ${e.message}`))
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
callback(null, commitsToExclude, headCommit)
|
|
88
|
+
} else {
|
|
89
|
+
const error = new Error(`Error getting commits: ${res.statusCode} ${res.statusMessage}`)
|
|
90
|
+
callback(error)
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
request.write(localCommitData)
|
|
96
|
+
request.on('error', callback)
|
|
97
|
+
|
|
98
|
+
request.end()
|
|
99
|
+
|
|
100
|
+
return request
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* This function uploads a git packfile
|
|
105
|
+
*/
|
|
106
|
+
function uploadPackFile ({ url, packFileToUpload, repositoryUrl, headCommit }, callback) {
|
|
107
|
+
const form = new FormData()
|
|
108
|
+
|
|
109
|
+
const pushedSha = JSON.stringify({
|
|
110
|
+
data: {
|
|
111
|
+
id: headCommit,
|
|
112
|
+
type: 'commit'
|
|
113
|
+
},
|
|
114
|
+
meta: {
|
|
115
|
+
repository_url: repositoryUrl
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
form.append('pushedSha', pushedSha, { contentType: 'application/json' })
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
const packFileContent = fs.readFileSync(packFileToUpload)
|
|
123
|
+
// The original filename includes a random prefix, so we remove it here
|
|
124
|
+
const [, filename] = path.basename(packFileToUpload).split('-')
|
|
125
|
+
form.append('packfile', packFileContent, {
|
|
126
|
+
filename,
|
|
127
|
+
contentType: 'application/octet-stream'
|
|
128
|
+
})
|
|
129
|
+
} catch (e) {
|
|
130
|
+
callback(new Error(`Error reading packfile: ${packFileToUpload}`))
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const commonOptions = getCommonRequestOptions(url)
|
|
135
|
+
|
|
136
|
+
const options = {
|
|
137
|
+
...commonOptions,
|
|
138
|
+
path: '/api/v2/git/repository/packfile',
|
|
139
|
+
headers: {
|
|
140
|
+
...commonOptions.headers,
|
|
141
|
+
...form.getHeaders()
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const req = https.request(options, res => {
|
|
146
|
+
res.on('data', () => {})
|
|
147
|
+
res.on('end', () => {
|
|
148
|
+
if (res.statusCode === 204) {
|
|
149
|
+
callback(null)
|
|
150
|
+
} else {
|
|
151
|
+
const error = new Error(`Error uploading packfiles: ${res.statusCode} ${res.statusMessage}`)
|
|
152
|
+
error.status = res.statusCode
|
|
153
|
+
|
|
154
|
+
callback(error)
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
req.on('error', err => {
|
|
160
|
+
callback(err)
|
|
161
|
+
})
|
|
162
|
+
form.pipe(req)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* This function uploads git metadata to CI Visibility's backend.
|
|
167
|
+
*/
|
|
168
|
+
function sendGitMetadata (site, callback) {
|
|
169
|
+
const url = new URL(`https://api.${site}`)
|
|
170
|
+
|
|
171
|
+
const repositoryUrl = getRepositoryUrl()
|
|
172
|
+
|
|
173
|
+
getCommitsToExclude({ url, repositoryUrl }, (err, commitsToExclude, headCommit) => {
|
|
174
|
+
if (err) {
|
|
175
|
+
callback(err)
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
const commitsToUpload = getCommitsToUpload(commitsToExclude)
|
|
179
|
+
|
|
180
|
+
if (!commitsToUpload.length) {
|
|
181
|
+
log.debug('No commits to upload')
|
|
182
|
+
callback(null)
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const packFilesToUpload = generatePackFilesForCommits(commitsToUpload)
|
|
187
|
+
|
|
188
|
+
let packFileIndex = 0
|
|
189
|
+
// This uploads packfiles sequentially
|
|
190
|
+
const uploadPackFileCallback = (err) => {
|
|
191
|
+
if (err || packFileIndex === packFilesToUpload.length) {
|
|
192
|
+
callback(err)
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
return uploadPackFile(
|
|
196
|
+
{
|
|
197
|
+
packFileToUpload: packFilesToUpload[packFileIndex++],
|
|
198
|
+
url,
|
|
199
|
+
repositoryUrl,
|
|
200
|
+
headCommit
|
|
201
|
+
},
|
|
202
|
+
uploadPackFileCallback
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
uploadPackFile(
|
|
207
|
+
{
|
|
208
|
+
url,
|
|
209
|
+
packFileToUpload: packFilesToUpload[packFileIndex++],
|
|
210
|
+
repositoryUrl,
|
|
211
|
+
headCommit
|
|
212
|
+
},
|
|
213
|
+
uploadPackFileCallback
|
|
214
|
+
)
|
|
215
|
+
})
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
module.exports = {
|
|
219
|
+
sendGitMetadata
|
|
220
|
+
}
|
|
@@ -13,6 +13,17 @@ const uuid = require('crypto-randomuuid')
|
|
|
13
13
|
const fromEntries = Object.fromEntries || (entries =>
|
|
14
14
|
entries.reduce((obj, [k, v]) => Object.assign(obj, { [k]: v }), {}))
|
|
15
15
|
|
|
16
|
+
// eslint-disable-next-line max-len
|
|
17
|
+
const qsRegex = '(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:(?:\\s|%20)*(?:=|%3D)[^&]+|(?:"|%22)(?:\\s|%20)*(?::|%3A)(?:\\s|%20)*(?:"|%22)(?:%2[^2]|%[^2]|[^"%])+(?:"|%22))|bearer(?:\\s|%20)+[a-z0-9\\._\\-]|token(?::|%3A)[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L](?:[\\w=-]|%3D)+\\.ey[I-L](?:[\\w=-]|%3D)+(?:\\.(?:[\\w.+\\/=-]|%3D|%2F|%2B)+)?|[\\-]{5}BEGIN(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY[\\-]{5}[^\\-]+[\\-]{5}END(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY|ssh-rsa(?:\\s|%20)*(?:[a-z0-9\\/\\.+]|%2F|%5C|%2B){100,}'
|
|
18
|
+
|
|
19
|
+
function safeJsonParse (input) {
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(input)
|
|
22
|
+
} catch (err) {
|
|
23
|
+
return undefined
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
16
27
|
class Config {
|
|
17
28
|
constructor (options) {
|
|
18
29
|
options = options || {}
|
|
@@ -67,6 +78,12 @@ class Config {
|
|
|
67
78
|
null
|
|
68
79
|
)
|
|
69
80
|
const DD_CIVISIBILITY_AGENTLESS_URL = process.env.DD_CIVISIBILITY_AGENTLESS_URL
|
|
81
|
+
|
|
82
|
+
const DD_CIVISIBILITY_ITR_ENABLED = coalesce(
|
|
83
|
+
process.env.DD_CIVISIBILITY_ITR_ENABLED,
|
|
84
|
+
false
|
|
85
|
+
)
|
|
86
|
+
|
|
70
87
|
const DD_SERVICE = options.service ||
|
|
71
88
|
process.env.DD_SERVICE ||
|
|
72
89
|
process.env.DD_SERVICE_NAME ||
|
|
@@ -109,6 +126,18 @@ class Config {
|
|
|
109
126
|
parseInt(process.env.DD_TRACE_PARTIAL_FLUSH_MIN_SPANS),
|
|
110
127
|
1000
|
|
111
128
|
)
|
|
129
|
+
const DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP = coalesce(
|
|
130
|
+
process.env.DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
|
|
131
|
+
qsRegex
|
|
132
|
+
)
|
|
133
|
+
const DD_TRACE_CLIENT_IP_HEADER_DISABLED = coalesce(
|
|
134
|
+
process.env.DD_TRACE_CLIENT_IP_HEADER_DISABLED,
|
|
135
|
+
false
|
|
136
|
+
)
|
|
137
|
+
const DD_TRACE_CLIENT_IP_HEADER = coalesce(
|
|
138
|
+
process.env.DD_TRACE_CLIENT_IP_HEADER,
|
|
139
|
+
null
|
|
140
|
+
)
|
|
112
141
|
const DD_TRACE_B3_ENABLED = coalesce(
|
|
113
142
|
options.experimental && options.experimental.b3,
|
|
114
143
|
process.env.DD_TRACE_EXPERIMENTAL_B3_ENABLED,
|
|
@@ -134,6 +163,17 @@ class Config {
|
|
|
134
163
|
false
|
|
135
164
|
)
|
|
136
165
|
|
|
166
|
+
const DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH = coalesce(
|
|
167
|
+
process.env.DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
|
|
168
|
+
'512'
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
const DD_TRACE_STATS_COMPUTATION_ENABLED = coalesce(
|
|
172
|
+
options.stats,
|
|
173
|
+
process.env.DD_TRACE_STATS_COMPUTATION_ENABLED,
|
|
174
|
+
false
|
|
175
|
+
)
|
|
176
|
+
|
|
137
177
|
let appsec = options.appsec || (options.experimental && options.experimental.appsec)
|
|
138
178
|
|
|
139
179
|
const DD_APPSEC_ENABLED = coalesce(
|
|
@@ -174,19 +214,51 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
174
214
|
|[\\-]{5}BEGIN[a-z\\s]+PRIVATE\\sKEY[\\-]{5}[^\\-]+[\\-]{5}END[a-z\\s]+PRIVATE\\sKEY|ssh-rsa\\s*[a-z0-9\\/\\.+]{100,}`
|
|
175
215
|
)
|
|
176
216
|
|
|
177
|
-
const
|
|
217
|
+
const iastOptions = options.experimental && options.experimental.iast
|
|
218
|
+
const DD_IAST_ENABLED = coalesce(
|
|
219
|
+
iastOptions &&
|
|
220
|
+
(iastOptions === true || iastOptions.enabled === true),
|
|
221
|
+
process.env.DD_IAST_ENABLED,
|
|
222
|
+
false
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
const defaultIastRequestSampling = 30
|
|
226
|
+
const iastRequestSampling = coalesce(
|
|
227
|
+
parseInt(iastOptions && iastOptions.requestSampling),
|
|
228
|
+
parseInt(process.env.DD_IAST_REQUEST_SAMPLING),
|
|
229
|
+
defaultIastRequestSampling
|
|
230
|
+
)
|
|
231
|
+
const DD_IAST_REQUEST_SAMPLING = iastRequestSampling < 0 ||
|
|
232
|
+
iastRequestSampling > 100 ? defaultIastRequestSampling : iastRequestSampling
|
|
233
|
+
|
|
234
|
+
const DD_IAST_MAX_CONCURRENT_REQUESTS = coalesce(
|
|
235
|
+
parseInt(iastOptions && iastOptions.maxConcurrentRequests),
|
|
236
|
+
parseInt(process.env.DD_IAST_MAX_CONCURRENT_REQUESTS),
|
|
237
|
+
2
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
const DD_IAST_MAX_CONTEXT_OPERATIONS = coalesce(
|
|
241
|
+
parseInt(iastOptions && iastOptions.maxContextOperations),
|
|
242
|
+
parseInt(process.env.DD_IAST_MAX_CONTEXT_OPERATIONS),
|
|
243
|
+
2
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
const DD_CIVISIBILITY_GIT_UPLOAD_ENABLED = coalesce(
|
|
247
|
+
process.env.DD_CIVISIBILITY_GIT_UPLOAD_ENABLED,
|
|
248
|
+
false
|
|
249
|
+
)
|
|
250
|
+
|
|
178
251
|
const ingestion = options.ingestion || {}
|
|
179
252
|
const dogstatsd = coalesce(options.dogstatsd, {})
|
|
180
|
-
|
|
181
|
-
Object.assign(sampler, {
|
|
253
|
+
const sampler = {
|
|
182
254
|
sampleRate: coalesce(
|
|
183
255
|
options.sampleRate,
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
process.env.DD_TRACE_SAMPLE_RATE
|
|
256
|
+
process.env.DD_TRACE_SAMPLE_RATE,
|
|
257
|
+
ingestion.sampleRate
|
|
187
258
|
),
|
|
188
|
-
rateLimit: coalesce(
|
|
189
|
-
|
|
259
|
+
rateLimit: coalesce(options.rateLimit, process.env.DD_TRACE_RATE_LIMIT, ingestion.rateLimit),
|
|
260
|
+
rules: coalesce(options.samplingRules, safeJsonParse(process.env.DD_TRACE_SAMPLING_RULES), [])
|
|
261
|
+
}
|
|
190
262
|
|
|
191
263
|
const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
|
|
192
264
|
const defaultFlushInterval = inAWSLambda ? 0 : 2000
|
|
@@ -203,6 +275,9 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
203
275
|
this.flushInterval = coalesce(parseInt(options.flushInterval, 10), defaultFlushInterval)
|
|
204
276
|
this.flushMinSpans = DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
|
|
205
277
|
this.sampleRate = coalesce(Math.min(Math.max(sampler.sampleRate, 0), 1), 1)
|
|
278
|
+
this.queryStringObfuscation = DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP
|
|
279
|
+
this.clientIpHeaderDisabled = isTrue(DD_TRACE_CLIENT_IP_HEADER_DISABLED)
|
|
280
|
+
this.clientIpHeader = DD_TRACE_CLIENT_IP_HEADER
|
|
206
281
|
this.logger = options.logger
|
|
207
282
|
this.plugins = !!coalesce(options.plugins, true)
|
|
208
283
|
this.service = DD_SERVICE
|
|
@@ -220,9 +295,9 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
220
295
|
traceparent: isTrue(DD_TRACE_TRACEPARENT_ENABLED),
|
|
221
296
|
runtimeId: isTrue(DD_TRACE_RUNTIME_ID_ENABLED),
|
|
222
297
|
exporter: DD_TRACE_EXPORTER,
|
|
223
|
-
enableGetRumData: isTrue(DD_TRACE_GET_RUM_DATA_ENABLED)
|
|
224
|
-
sampler
|
|
298
|
+
enableGetRumData: isTrue(DD_TRACE_GET_RUM_DATA_ENABLED)
|
|
225
299
|
}
|
|
300
|
+
this.sampler = sampler
|
|
226
301
|
this.reportHostname = isTrue(coalesce(options.reportHostname, process.env.DD_TRACE_REPORT_HOSTNAME, false))
|
|
227
302
|
this.scope = process.env.DD_TRACE_SCOPE
|
|
228
303
|
this.logLevel = coalesce(
|
|
@@ -240,6 +315,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
240
315
|
// Disabled for CI Visibility's agentless
|
|
241
316
|
this.telemetryEnabled = DD_TRACE_EXPORTER !== 'datadog' && isTrue(DD_TRACE_TELEMETRY_ENABLED)
|
|
242
317
|
this.protocolVersion = DD_TRACE_AGENT_PROTOCOL_VERSION
|
|
318
|
+
this.tagsHeaderMaxLength = parseInt(DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH)
|
|
243
319
|
this.appsec = {
|
|
244
320
|
enabled: isTrue(DD_APPSEC_ENABLED),
|
|
245
321
|
rules: DD_APPSEC_RULES,
|
|
@@ -248,6 +324,17 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
248
324
|
obfuscatorKeyRegex: DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP,
|
|
249
325
|
obfuscatorValueRegex: DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP
|
|
250
326
|
}
|
|
327
|
+
this.iast = {
|
|
328
|
+
enabled: isTrue(DD_IAST_ENABLED),
|
|
329
|
+
requestSampling: DD_IAST_REQUEST_SAMPLING,
|
|
330
|
+
maxConcurrentRequests: DD_IAST_MAX_CONCURRENT_REQUESTS,
|
|
331
|
+
maxContextOperations: DD_IAST_MAX_CONTEXT_OPERATIONS
|
|
332
|
+
}
|
|
333
|
+
this.isGitUploadEnabled = isTrue(DD_CIVISIBILITY_GIT_UPLOAD_ENABLED)
|
|
334
|
+
this.isIntelligentTestRunnerEnabled = isTrue(DD_CIVISIBILITY_ITR_ENABLED)
|
|
335
|
+
this.stats = {
|
|
336
|
+
enabled: isTrue(DD_TRACE_STATS_COMPUTATION_ENABLED)
|
|
337
|
+
}
|
|
251
338
|
|
|
252
339
|
tagger.add(this.tags, {
|
|
253
340
|
service: this.service,
|
|
@@ -5,8 +5,16 @@ module.exports = {
|
|
|
5
5
|
ANALYTICS_KEY: '_dd1.sr.eausr',
|
|
6
6
|
ORIGIN_KEY: '_dd.origin',
|
|
7
7
|
HOSTNAME_KEY: '_dd.hostname',
|
|
8
|
+
TOP_LEVEL_KEY: '_dd.top_level',
|
|
8
9
|
SAMPLING_RULE_DECISION: '_dd.rule_psr',
|
|
9
10
|
SAMPLING_LIMIT_DECISION: '_dd.limit_psr',
|
|
10
11
|
SAMPLING_AGENT_DECISION: '_dd.agent_psr',
|
|
11
|
-
|
|
12
|
+
SAMPLING_MECHANISM_DEFAULT: 0,
|
|
13
|
+
SAMPLING_MECHANISM_AGENT: 1,
|
|
14
|
+
SAMPLING_MECHANISM_RULE: 3,
|
|
15
|
+
SAMPLING_MECHANISM_MANUAL: 4,
|
|
16
|
+
SAMPLING_MECHANISM_APPSEC: 5,
|
|
17
|
+
SAMPLING_MECHANISM_SPAN: 8,
|
|
18
|
+
DATADOG_LAMBDA_EXTENSION_PATH: '/opt/extensions/datadog-agent',
|
|
19
|
+
DECISION_MAKER_KEY: '_dd.p.dm'
|
|
12
20
|
}
|