dd-trace 4.2.0 → 4.3.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/index.d.ts +7 -0
- package/package.json +5 -5
- package/packages/datadog-instrumentations/src/cookie.js +21 -0
- package/packages/datadog-instrumentations/src/fetch.js +48 -0
- package/packages/datadog-instrumentations/src/grpc/server.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +10 -0
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +18 -0
- package/packages/datadog-plugin-fetch/src/index.js +36 -0
- package/packages/datadog-plugin-http/src/client.js +24 -8
- package/packages/datadog-plugin-mysql/src/index.js +2 -11
- package/packages/datadog-plugin-tedious/src/index.js +2 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +3 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +52 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/insecure-cookie-analyzer.js +3 -22
- package/packages/dd-trace/src/appsec/iast/analyzers/no-httponly-cookie-analyzer.js +12 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/no-samesite-cookie-analyzer.js +12 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +7 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +3 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +48 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +3 -3
- package/packages/dd-trace/src/appsec/iast/index.js +9 -2
- package/packages/dd-trace/src/appsec/iast/path-line.js +13 -0
- package/packages/dd-trace/src/appsec/iast/tags.js +6 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +2 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +13 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/origin-types.js +5 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +24 -4
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +3 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +3 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +7 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -3
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +5 -2
- package/packages/dd-trace/src/config.js +13 -0
- package/packages/dd-trace/src/external-logger/src/index.js +126 -0
- package/packages/dd-trace/src/external-logger/test/index.spec.js +147 -0
- package/packages/dd-trace/src/lambda/handler.js +3 -15
- package/packages/dd-trace/src/noop/proxy.js +4 -0
- package/packages/dd-trace/src/opentelemetry/context_manager.js +1 -1
- package/packages/dd-trace/src/plugin_manager.js +10 -7
- package/packages/dd-trace/src/plugins/database.js +7 -3
- package/packages/dd-trace/src/plugins/plugin.js +3 -1
- package/packages/dd-trace/src/plugins/util/exec.js +2 -2
- package/packages/dd-trace/src/plugins/util/git.js +51 -24
- package/packages/dd-trace/src/profiling/config.js +2 -0
- package/packages/dd-trace/src/profiling/profiler.js +13 -4
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +24 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +18 -1
- package/packages/dd-trace/src/util.js +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { execFileSync } = require('child_process')
|
|
2
2
|
const os = require('os')
|
|
3
3
|
const path = require('path')
|
|
4
|
+
const fs = require('fs')
|
|
4
5
|
|
|
5
6
|
const log = require('../../log')
|
|
6
7
|
const { sanitizedExec } = require('./exec')
|
|
@@ -21,26 +22,35 @@ const {
|
|
|
21
22
|
|
|
22
23
|
const GIT_REV_LIST_MAX_BUFFER = 8 * 1024 * 1024 // 8MB
|
|
23
24
|
|
|
25
|
+
function isDirectory (path) {
|
|
26
|
+
try {
|
|
27
|
+
const stats = fs.statSync(path)
|
|
28
|
+
return stats.isDirectory()
|
|
29
|
+
} catch (e) {
|
|
30
|
+
return false
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
24
34
|
function isShallowRepository () {
|
|
25
|
-
return sanitizedExec('git rev-parse --is-shallow-repository'
|
|
35
|
+
return sanitizedExec('git', ['rev-parse', '--is-shallow-repository']) === 'true'
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
function unshallowRepository () {
|
|
29
39
|
try {
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
sanitizedExec('git', ['config', 'remote.origin.partialclonefilter', '"blob:none"'])
|
|
41
|
+
sanitizedExec('git', ['fetch', '--shallow-since="1 month ago"', '--update-shallow', '--refetch'])
|
|
32
42
|
} catch (err) {
|
|
33
43
|
log.error(err)
|
|
34
44
|
}
|
|
35
45
|
}
|
|
36
46
|
|
|
37
47
|
function getRepositoryUrl () {
|
|
38
|
-
return sanitizedExec('git config --get remote.origin.url'
|
|
48
|
+
return sanitizedExec('git', ['config', '--get', 'remote.origin.url'])
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
function getLatestCommits () {
|
|
42
52
|
try {
|
|
43
|
-
return
|
|
53
|
+
return execFileSync('git', ['log', '--format=%H', '-n 1000', '--since="1 month ago"'], { stdio: 'pipe' })
|
|
44
54
|
.toString()
|
|
45
55
|
.split('\n')
|
|
46
56
|
.filter(commit => commit)
|
|
@@ -51,15 +61,21 @@ function getLatestCommits () {
|
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
function getCommitsToUpload (commitsToExclude) {
|
|
54
|
-
|
|
55
|
-
'git rev-list --objects --no-object-names --filter=blob:none --since="1 month ago" HEAD'
|
|
56
|
-
|
|
57
|
-
commitsToExclude.forEach(commit => {
|
|
58
|
-
gitCommandToGetCommitsToUpload = `${gitCommandToGetCommitsToUpload} ^${commit}`
|
|
59
|
-
})
|
|
64
|
+
const commitsToExcludeString = commitsToExclude.map(commit => `^${commit}`)
|
|
60
65
|
|
|
61
66
|
try {
|
|
62
|
-
return
|
|
67
|
+
return execFileSync(
|
|
68
|
+
'git',
|
|
69
|
+
[
|
|
70
|
+
'rev-list',
|
|
71
|
+
'--objects',
|
|
72
|
+
'--no-object-names',
|
|
73
|
+
'--filter=blob:none',
|
|
74
|
+
'--since="1 month ago"',
|
|
75
|
+
'HEAD',
|
|
76
|
+
...commitsToExcludeString
|
|
77
|
+
],
|
|
78
|
+
{ stdio: 'pipe', maxBuffer: GIT_REV_LIST_MAX_BUFFER })
|
|
63
79
|
.toString()
|
|
64
80
|
.split('\n')
|
|
65
81
|
.filter(commit => commit)
|
|
@@ -72,6 +88,11 @@ function getCommitsToUpload (commitsToExclude) {
|
|
|
72
88
|
function generatePackFilesForCommits (commitsToUpload) {
|
|
73
89
|
const tmpFolder = os.tmpdir()
|
|
74
90
|
|
|
91
|
+
if (!isDirectory(tmpFolder)) {
|
|
92
|
+
log.error(new Error('Provided path to generate packfiles is not a directory'))
|
|
93
|
+
return []
|
|
94
|
+
}
|
|
95
|
+
|
|
75
96
|
const randomPrefix = String(Math.floor(Math.random() * 10000))
|
|
76
97
|
const temporaryPath = path.join(tmpFolder, randomPrefix)
|
|
77
98
|
const cwdPath = path.join(process.cwd(), randomPrefix)
|
|
@@ -79,14 +100,20 @@ function generatePackFilesForCommits (commitsToUpload) {
|
|
|
79
100
|
// Generates pack files to upload and
|
|
80
101
|
// returns the ordered list of packfiles' paths
|
|
81
102
|
function execGitPackObjects (targetPath) {
|
|
82
|
-
return
|
|
83
|
-
|
|
84
|
-
|
|
103
|
+
return execFileSync(
|
|
104
|
+
'git',
|
|
105
|
+
[
|
|
106
|
+
'pack-objects',
|
|
107
|
+
'--compression=9',
|
|
108
|
+
'--max-pack-size=3m',
|
|
109
|
+
targetPath
|
|
110
|
+
],
|
|
111
|
+
{ stdio: 'pipe', input: commitsToUpload.join('\n') }
|
|
85
112
|
).toString().split('\n').filter(commit => commit).map(commit => `${targetPath}-${commit}.pack`)
|
|
86
113
|
}
|
|
87
114
|
|
|
88
115
|
try {
|
|
89
|
-
return execGitPackObjects(temporaryPath
|
|
116
|
+
return execGitPackObjects(temporaryPath)
|
|
90
117
|
} catch (err) {
|
|
91
118
|
log.error(err)
|
|
92
119
|
/**
|
|
@@ -102,7 +129,7 @@ function generatePackFilesForCommits (commitsToUpload) {
|
|
|
102
129
|
* TODO: fix issue and remove workaround.
|
|
103
130
|
*/
|
|
104
131
|
try {
|
|
105
|
-
return execGitPackObjects(cwdPath
|
|
132
|
+
return execGitPackObjects(cwdPath)
|
|
106
133
|
} catch (err) {
|
|
107
134
|
log.error(err)
|
|
108
135
|
}
|
|
@@ -133,23 +160,23 @@ function getGitMetadata (ciMetadata) {
|
|
|
133
160
|
committerName,
|
|
134
161
|
committerEmail,
|
|
135
162
|
committerDate
|
|
136
|
-
] = sanitizedExec('git show -s --format=%an,%ae,%aI,%cn,%ce,%cI'
|
|
163
|
+
] = sanitizedExec('git', ['show', '-s', '--format=%an,%ae,%aI,%cn,%ce,%cI']).split(',')
|
|
137
164
|
|
|
138
165
|
return {
|
|
139
166
|
[GIT_REPOSITORY_URL]:
|
|
140
|
-
repositoryUrl || sanitizedExec('git ls-remote --get-url'
|
|
167
|
+
repositoryUrl || sanitizedExec('git', ['ls-remote', '--get-url']),
|
|
141
168
|
[GIT_COMMIT_MESSAGE]:
|
|
142
|
-
commitMessage || sanitizedExec('git show -s --format=%s'
|
|
169
|
+
commitMessage || sanitizedExec('git', ['show', '-s', '--format=%s']),
|
|
143
170
|
[GIT_COMMIT_AUTHOR_DATE]: authorDate,
|
|
144
171
|
[GIT_COMMIT_AUTHOR_NAME]: ciAuthorName || authorName,
|
|
145
172
|
[GIT_COMMIT_AUTHOR_EMAIL]: ciAuthorEmail || authorEmail,
|
|
146
173
|
[GIT_COMMIT_COMMITTER_DATE]: committerDate,
|
|
147
174
|
[GIT_COMMIT_COMMITTER_NAME]: committerName,
|
|
148
175
|
[GIT_COMMIT_COMMITTER_EMAIL]: committerEmail,
|
|
149
|
-
[GIT_BRANCH]: branch || sanitizedExec('git rev-parse --abbrev-ref
|
|
150
|
-
[GIT_COMMIT_SHA]: commitSHA || sanitizedExec('git rev-parse
|
|
176
|
+
[GIT_BRANCH]: branch || sanitizedExec('git', ['rev-parse', '--abbrev-ref', 'HEAD']),
|
|
177
|
+
[GIT_COMMIT_SHA]: commitSHA || sanitizedExec('git', ['rev-parse', 'HEAD']),
|
|
151
178
|
[GIT_TAG]: tag,
|
|
152
|
-
[CI_WORKSPACE_PATH]: ciWorkspacePath || sanitizedExec('git rev-parse --show-toplevel'
|
|
179
|
+
[CI_WORKSPACE_PATH]: ciWorkspacePath || sanitizedExec('git', ['rev-parse', '--show-toplevel'])
|
|
153
180
|
}
|
|
154
181
|
}
|
|
155
182
|
|
|
@@ -27,6 +27,7 @@ class Config {
|
|
|
27
27
|
DD_TRACE_AGENT_URL,
|
|
28
28
|
DD_AGENT_HOST,
|
|
29
29
|
DD_TRACE_AGENT_PORT,
|
|
30
|
+
DD_PROFILING_DEBUG_SOURCE_MAPS,
|
|
30
31
|
DD_PROFILING_UPLOAD_TIMEOUT,
|
|
31
32
|
DD_PROFILING_SOURCE_MAP,
|
|
32
33
|
DD_PROFILING_UPLOAD_PERIOD,
|
|
@@ -70,6 +71,7 @@ class Config {
|
|
|
70
71
|
this.flushInterval = flushInterval
|
|
71
72
|
this.uploadTimeout = uploadTimeout
|
|
72
73
|
this.sourceMap = sourceMap
|
|
74
|
+
this.debugSourceMaps = isTrue(coalesce(options.debugSourceMaps, DD_PROFILING_DEBUG_SOURCE_MAPS, false))
|
|
73
75
|
this.endpointCollection = endpointCollection
|
|
74
76
|
this.pprofPrefix = pprofPrefix
|
|
75
77
|
|
|
@@ -4,12 +4,11 @@ const { EventEmitter } = require('events')
|
|
|
4
4
|
const { Config } = require('./config')
|
|
5
5
|
const { snapshotKinds } = require('./constants')
|
|
6
6
|
|
|
7
|
-
function maybeSourceMap (sourceMap) {
|
|
7
|
+
function maybeSourceMap (sourceMap, SourceMapper, debug) {
|
|
8
8
|
if (!sourceMap) return
|
|
9
|
-
const { SourceMapper } = require('@datadog/pprof')
|
|
10
9
|
return SourceMapper.create([
|
|
11
10
|
process.cwd()
|
|
12
|
-
])
|
|
11
|
+
], debug)
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
class Profiler extends EventEmitter {
|
|
@@ -42,7 +41,17 @@ class Profiler extends EventEmitter {
|
|
|
42
41
|
// of the profiler from running without source maps.
|
|
43
42
|
let mapper
|
|
44
43
|
try {
|
|
45
|
-
|
|
44
|
+
const { setLogger, SourceMapper } = require('@datadog/pprof')
|
|
45
|
+
setLogger(config.logger)
|
|
46
|
+
|
|
47
|
+
mapper = await maybeSourceMap(config.sourceMap, SourceMapper, config.debugSourceMaps)
|
|
48
|
+
if (config.SourceMap && config.debugSourceMaps) {
|
|
49
|
+
this._logger.debug(() => {
|
|
50
|
+
return mapper.infoMap.size === 0
|
|
51
|
+
? 'Found no source maps'
|
|
52
|
+
: `Found source maps for following files: [${Array.from(mapper.infoMap.keys()).join(', ')}]`
|
|
53
|
+
})
|
|
54
|
+
}
|
|
46
55
|
} catch (err) {
|
|
47
56
|
this._logger.error(err)
|
|
48
57
|
}
|
|
@@ -12,6 +12,13 @@ function fromSystem (service, system) {
|
|
|
12
12
|
return system ? `${service}-${system}` : undefined
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
function mysqlServiceName (service, config, dbConfig, system) {
|
|
16
|
+
if (typeof config.service === 'function') {
|
|
17
|
+
return config.service(dbConfig)
|
|
18
|
+
}
|
|
19
|
+
return config.service ? config.service : fromSystem(service, system)
|
|
20
|
+
}
|
|
21
|
+
|
|
15
22
|
const redisConfig = {
|
|
16
23
|
opName: () => 'redis.command',
|
|
17
24
|
serviceName: (service, config, system, connectionName) => {
|
|
@@ -22,11 +29,27 @@ const redisConfig = {
|
|
|
22
29
|
const storage = {
|
|
23
30
|
client: {
|
|
24
31
|
ioredis: redisConfig,
|
|
32
|
+
mariadb: {
|
|
33
|
+
opName: () => 'mariadb.query',
|
|
34
|
+
serviceName: mysqlServiceName
|
|
35
|
+
},
|
|
25
36
|
memcached: {
|
|
26
37
|
opName: () => 'memcached.command',
|
|
27
38
|
serviceName: (service, config, system) => config.service || fromSystem(service, system)
|
|
28
39
|
},
|
|
29
|
-
|
|
40
|
+
mysql: {
|
|
41
|
+
opName: () => 'mysql.query',
|
|
42
|
+
serviceName: mysqlServiceName
|
|
43
|
+
},
|
|
44
|
+
mysql2: {
|
|
45
|
+
opName: () => 'mysql.query',
|
|
46
|
+
serviceName: mysqlServiceName
|
|
47
|
+
},
|
|
48
|
+
redis: redisConfig,
|
|
49
|
+
tedious: {
|
|
50
|
+
opName: () => 'tedious.request',
|
|
51
|
+
serviceName: (service, config, system) => config.service || fromSystem(service, system)
|
|
52
|
+
}
|
|
30
53
|
}
|
|
31
54
|
}
|
|
32
55
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const { identityService } = require('../util')
|
|
2
|
+
|
|
1
3
|
function configWithFallback (service, config) {
|
|
2
4
|
return config.service || service
|
|
3
5
|
}
|
|
@@ -7,14 +9,29 @@ const redisNaming = {
|
|
|
7
9
|
serviceName: configWithFallback
|
|
8
10
|
}
|
|
9
11
|
|
|
12
|
+
const mySQLNaming = {
|
|
13
|
+
opName: () => 'mysql.query',
|
|
14
|
+
serviceName: identityService
|
|
15
|
+
}
|
|
16
|
+
|
|
10
17
|
const storage = {
|
|
11
18
|
client: {
|
|
12
19
|
ioredis: redisNaming,
|
|
20
|
+
mariadb: {
|
|
21
|
+
opName: () => 'mariadb.query',
|
|
22
|
+
serviceName: identityService
|
|
23
|
+
},
|
|
13
24
|
memcached: {
|
|
14
25
|
opName: () => 'memcached.command',
|
|
15
26
|
serviceName: configWithFallback
|
|
16
27
|
},
|
|
17
|
-
|
|
28
|
+
mysql: mySQLNaming,
|
|
29
|
+
mysql2: mySQLNaming,
|
|
30
|
+
redis: redisNaming,
|
|
31
|
+
tedious: {
|
|
32
|
+
opName: () => 'mssql.query',
|
|
33
|
+
serviceName: configWithFallback
|
|
34
|
+
}
|
|
18
35
|
}
|
|
19
36
|
}
|
|
20
37
|
|