dd-trace 3.3.1 → 3.4.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 +7 -0
- package/package.json +5 -3
- package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/http2/server.js +67 -1
- package/packages/datadog-instrumentations/src/jest.js +76 -6
- package/packages/datadog-instrumentations/src/mariadb.js +89 -0
- package/packages/datadog-instrumentations/src/memcached.js +1 -4
- package/packages/datadog-instrumentations/src/next.js +10 -2
- package/packages/datadog-instrumentations/src/oracledb.js +8 -8
- package/packages/datadog-instrumentations/src/redis.js +12 -3
- package/packages/datadog-instrumentations/src/rhea.js +11 -0
- package/packages/datadog-plugin-cassandra-driver/src/index.js +22 -60
- package/packages/datadog-plugin-elasticsearch/src/index.js +24 -60
- package/packages/datadog-plugin-http2/src/server.js +41 -0
- package/packages/datadog-plugin-jest/src/index.js +97 -2
- package/packages/datadog-plugin-mariadb/src/index.js +10 -0
- package/packages/datadog-plugin-memcached/src/index.js +17 -52
- package/packages/datadog-plugin-mongodb-core/src/index.js +20 -48
- package/packages/datadog-plugin-mysql/src/index.js +23 -52
- package/packages/datadog-plugin-mysql2/src/index.js +1 -3
- package/packages/datadog-plugin-oracledb/src/index.js +29 -54
- package/packages/datadog-plugin-pg/src/index.js +24 -52
- package/packages/datadog-plugin-redis/src/index.js +29 -60
- package/packages/datadog-plugin-rhea/src/index.js +4 -1
- package/packages/datadog-plugin-tedious/src/index.js +20 -41
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +32 -54
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +87 -0
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +79 -0
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
- package/packages/dd-trace/src/plugin_manager.js +3 -0
- package/packages/dd-trace/src/plugins/cache.js +9 -0
- package/packages/dd-trace/src/plugins/client.js +7 -0
- package/packages/dd-trace/src/plugins/database.js +9 -0
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/outgoing.js +31 -0
- package/packages/dd-trace/src/plugins/plugin.js +3 -0
- package/packages/dd-trace/src/plugins/storage.js +25 -0
- package/packages/dd-trace/src/plugins/tracing.js +91 -0
- package/packages/dd-trace/src/plugins/util/git.js +58 -18
- package/packages/dd-trace/src/plugins/util/test.js +7 -1
- package/packages/dd-trace/src/proxy.js +4 -0
- package/packages/dd-trace/src/telemetry/index.js +7 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const TracingPlugin = require('./tracing')
|
|
4
|
+
|
|
5
|
+
// TODO: Exit span on finish when AsyncResource instances are removed.
|
|
6
|
+
class OutgoingPlugin extends TracingPlugin {
|
|
7
|
+
constructor (...args) {
|
|
8
|
+
super(...args)
|
|
9
|
+
|
|
10
|
+
this.addTraceSub('connect', message => {
|
|
11
|
+
this.connect(message)
|
|
12
|
+
})
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
connect (url) {
|
|
16
|
+
this.addHost(url.hostname, url.port)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
addHost (hostname, port) {
|
|
20
|
+
const span = this.activeSpan()
|
|
21
|
+
|
|
22
|
+
if (!span) return
|
|
23
|
+
|
|
24
|
+
span.addTags({
|
|
25
|
+
'out.host': hostname,
|
|
26
|
+
'out.port': port
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = OutgoingPlugin
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// TODO: move anything related to tracing to TracingPlugin instead
|
|
4
|
+
|
|
3
5
|
const dc = require('diagnostics_channel')
|
|
4
6
|
const { storage } = require('../../../datadog-core')
|
|
5
7
|
|
|
@@ -39,6 +41,7 @@ module.exports = class Plugin {
|
|
|
39
41
|
storage.enterWith({ ...store, span })
|
|
40
42
|
}
|
|
41
43
|
|
|
44
|
+
// TODO: Implement filters on resource name for all plugins.
|
|
42
45
|
/** Prevents creation of spans here and for all async descendants. */
|
|
43
46
|
skip () {
|
|
44
47
|
storage.enterWith({ noop: true })
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ClientPlugin = require('./client')
|
|
4
|
+
|
|
5
|
+
class StoragePlugin extends ClientPlugin {
|
|
6
|
+
constructor (...args) {
|
|
7
|
+
super(...args)
|
|
8
|
+
|
|
9
|
+
this.system = this.constructor.system || this.component
|
|
10
|
+
|
|
11
|
+
this.addTraceSub('connect', message => {
|
|
12
|
+
this.connect(message)
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
startSpan (name, options) {
|
|
17
|
+
if (!options.service && this.system) {
|
|
18
|
+
options.service = `${this.tracer._service}-${this.system}`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return super.startSpan(name, options)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = StoragePlugin
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Plugin = require('./plugin')
|
|
4
|
+
const { storage } = require('../../../datadog-core')
|
|
5
|
+
const analyticsSampler = require('../analytics_sampler')
|
|
6
|
+
|
|
7
|
+
class TracingPlugin extends Plugin {
|
|
8
|
+
constructor (...args) {
|
|
9
|
+
super(...args)
|
|
10
|
+
|
|
11
|
+
this.component = this.constructor.component || this.constructor.name
|
|
12
|
+
this.operation = this.constructor.operation
|
|
13
|
+
|
|
14
|
+
this.addTraceSub('start', message => {
|
|
15
|
+
this.start(message)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
this.addTraceSub('error', err => {
|
|
19
|
+
this.error(err)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
this.addTraceSub('finish', message => {
|
|
23
|
+
this.finish(message)
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
configure (config) {
|
|
28
|
+
return super.configure({
|
|
29
|
+
...config,
|
|
30
|
+
hooks: {
|
|
31
|
+
[this.operation]: () => {},
|
|
32
|
+
...config.hooks
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
start () {} // implemented by individual plugins
|
|
38
|
+
|
|
39
|
+
finish () {
|
|
40
|
+
this.activeSpan().finish()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
error (error) {
|
|
44
|
+
this.addError(error)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
addTraceSub (eventName, handler) {
|
|
48
|
+
this.addSub(`apm:${this.component}:${this.operation}:${eventName}`, handler)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
addError (error) {
|
|
52
|
+
const span = this.activeSpan()
|
|
53
|
+
|
|
54
|
+
if (!span._spanContext._tags['error']) {
|
|
55
|
+
span.setTag('error', error || 1)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
startSpan (name, { childOf, kind, meta, metrics, service, resource, type } = {}) {
|
|
60
|
+
const store = storage.getStore()
|
|
61
|
+
|
|
62
|
+
if (store && childOf === undefined) {
|
|
63
|
+
childOf = store.span
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const span = this.tracer.startSpan(name, {
|
|
67
|
+
tags: {
|
|
68
|
+
'service.name': service,
|
|
69
|
+
'resource.name': resource,
|
|
70
|
+
'span.kind': kind,
|
|
71
|
+
'span.type': type,
|
|
72
|
+
...meta,
|
|
73
|
+
...metrics
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
analyticsSampler.sample(span, this.config.measured)
|
|
78
|
+
|
|
79
|
+
storage.enterWith({ ...store, span })
|
|
80
|
+
|
|
81
|
+
return span
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
activeSpan () {
|
|
85
|
+
const store = storage.getStore()
|
|
86
|
+
|
|
87
|
+
return store && store.span
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = TracingPlugin
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const { execSync } = require('child_process')
|
|
2
2
|
const os = require('os')
|
|
3
|
+
const path = require('path')
|
|
3
4
|
|
|
5
|
+
const log = require('../../log')
|
|
4
6
|
const { sanitizedExec } = require('./exec')
|
|
5
7
|
const {
|
|
6
8
|
GIT_COMMIT_SHA,
|
|
@@ -17,15 +19,22 @@ const {
|
|
|
17
19
|
CI_WORKSPACE_PATH
|
|
18
20
|
} = require('./tags')
|
|
19
21
|
|
|
22
|
+
const GIT_REV_LIST_MAX_BUFFER = 8 * 1024 * 1024 // 8MB
|
|
23
|
+
|
|
20
24
|
function getRepositoryUrl () {
|
|
21
25
|
return sanitizedExec('git config --get remote.origin.url', { stdio: 'pipe' })
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
function getLatestCommits () {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
try {
|
|
30
|
+
return execSync('git log --format=%H -n 1000 --since="1 month ago"', { stdio: 'pipe' })
|
|
31
|
+
.toString()
|
|
32
|
+
.split('\n')
|
|
33
|
+
.filter(commit => commit)
|
|
34
|
+
} catch (err) {
|
|
35
|
+
log.error(err)
|
|
36
|
+
return []
|
|
37
|
+
}
|
|
29
38
|
}
|
|
30
39
|
|
|
31
40
|
function getCommitsToUpload (commitsToExclude) {
|
|
@@ -36,27 +45,57 @@ function getCommitsToUpload (commitsToExclude) {
|
|
|
36
45
|
gitCommandToGetCommitsToUpload = `${gitCommandToGetCommitsToUpload} ^${commit}`
|
|
37
46
|
})
|
|
38
47
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
48
|
+
try {
|
|
49
|
+
return execSync(gitCommandToGetCommitsToUpload, { stdio: 'pipe', maxBuffer: GIT_REV_LIST_MAX_BUFFER })
|
|
50
|
+
.toString()
|
|
51
|
+
.split('\n')
|
|
52
|
+
.filter(commit => commit)
|
|
53
|
+
} catch (err) {
|
|
54
|
+
log.error(err)
|
|
55
|
+
return []
|
|
56
|
+
}
|
|
43
57
|
}
|
|
44
58
|
|
|
45
|
-
// Generates pack files to upload and
|
|
46
|
-
// returns the ordered list of packfiles' paths
|
|
47
59
|
function generatePackFilesForCommits (commitsToUpload) {
|
|
48
60
|
const tmpFolder = os.tmpdir()
|
|
49
61
|
|
|
50
|
-
const
|
|
51
|
-
const
|
|
62
|
+
const randomPrefix = String(Math.floor(Math.random() * 10000))
|
|
63
|
+
const temporaryPath = path.join(tmpFolder, randomPrefix)
|
|
64
|
+
const cwdPath = path.join(process.cwd(), randomPrefix)
|
|
52
65
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
66
|
+
// Generates pack files to upload and
|
|
67
|
+
// returns the ordered list of packfiles' paths
|
|
68
|
+
function execGitPackObjects (targetPath) {
|
|
69
|
+
return execSync(
|
|
70
|
+
`git pack-objects --compression=9 --max-pack-size=3m ${targetPath}`,
|
|
56
71
|
{ input: commitsToUpload.join('\n') }
|
|
57
|
-
).toString().split('\n').filter(commit =>
|
|
72
|
+
).toString().split('\n').filter(commit => commit).map(commit => `${targetPath}-${commit}.pack`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
return execGitPackObjects(temporaryPath, commitsToUpload)
|
|
77
|
+
} catch (err) {
|
|
78
|
+
log.error(err)
|
|
79
|
+
/**
|
|
80
|
+
* The generation of pack files in the temporary folder (from `os.tmpdir()`)
|
|
81
|
+
* sometimes fails in certain CI setups with the error message
|
|
82
|
+
* `unable to rename temporary pack file: Invalid cross-device link`.
|
|
83
|
+
* The reason why is unclear.
|
|
84
|
+
*
|
|
85
|
+
* A workaround is to attempt to generate the pack files in `process.cwd()`.
|
|
86
|
+
* While this works most of the times, it's not ideal since it affects the git status.
|
|
87
|
+
* This workaround is intended to be temporary.
|
|
88
|
+
*
|
|
89
|
+
* TODO: fix issue and remove workaround.
|
|
90
|
+
*/
|
|
91
|
+
try {
|
|
92
|
+
return execGitPackObjects(cwdPath, commitsToUpload)
|
|
93
|
+
} catch (err) {
|
|
94
|
+
log.error(err)
|
|
95
|
+
}
|
|
58
96
|
|
|
59
|
-
|
|
97
|
+
return []
|
|
98
|
+
}
|
|
60
99
|
}
|
|
61
100
|
|
|
62
101
|
// If there is ciMetadata, it takes precedence.
|
|
@@ -106,5 +145,6 @@ module.exports = {
|
|
|
106
145
|
getLatestCommits,
|
|
107
146
|
getRepositoryUrl,
|
|
108
147
|
generatePackFilesForCommits,
|
|
109
|
-
getCommitsToUpload
|
|
148
|
+
getCommitsToUpload,
|
|
149
|
+
GIT_REV_LIST_MAX_BUFFER
|
|
110
150
|
}
|
|
@@ -48,6 +48,10 @@ const CI_APP_ORIGIN = 'ciapp-test'
|
|
|
48
48
|
|
|
49
49
|
const JEST_TEST_RUNNER = 'test.jest.test_runner'
|
|
50
50
|
|
|
51
|
+
const TEST_ITR_TESTS_SKIPPED = '_dd.ci.itr.tests_skipped'
|
|
52
|
+
|
|
53
|
+
const TEST_CODE_COVERAGE_LINES_TOTAL = 'test.codecov_lines_total'
|
|
54
|
+
|
|
51
55
|
module.exports = {
|
|
52
56
|
TEST_CODE_OWNERS,
|
|
53
57
|
TEST_FRAMEWORK,
|
|
@@ -78,7 +82,9 @@ module.exports = {
|
|
|
78
82
|
getTestSuiteCommonTags,
|
|
79
83
|
TEST_COMMAND,
|
|
80
84
|
TEST_SESSION_ID,
|
|
81
|
-
TEST_SUITE_ID
|
|
85
|
+
TEST_SUITE_ID,
|
|
86
|
+
TEST_ITR_TESTS_SKIPPED,
|
|
87
|
+
TEST_CODE_COVERAGE_LINES_TOTAL
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
function getTestEnvironmentMetadata (testFramework, config) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
const { channel } = require('diagnostics_channel')
|
|
2
3
|
|
|
3
4
|
const NoopProxy = require('./noop/proxy')
|
|
4
5
|
const DatadogTracer = require('./tracer')
|
|
@@ -10,6 +11,8 @@ const telemetry = require('./telemetry')
|
|
|
10
11
|
const PluginManager = require('./plugin_manager')
|
|
11
12
|
const { sendGitMetadata } = require('./ci-visibility/exporters/git/git_metadata')
|
|
12
13
|
|
|
14
|
+
const gitMetadataUploadFinishCh = channel('ci:git-metadata-upload:finish')
|
|
15
|
+
|
|
13
16
|
class Tracer extends NoopProxy {
|
|
14
17
|
constructor () {
|
|
15
18
|
super()
|
|
@@ -65,6 +68,7 @@ class Tracer extends NoopProxy {
|
|
|
65
68
|
} else {
|
|
66
69
|
log.debug('Successfully uploaded git metadata')
|
|
67
70
|
}
|
|
71
|
+
gitMetadataUploadFinishCh.publish(err)
|
|
68
72
|
})
|
|
69
73
|
}
|
|
70
74
|
} catch (e) {
|
|
@@ -6,6 +6,10 @@ const os = require('os')
|
|
|
6
6
|
const dependencies = require('./dependencies')
|
|
7
7
|
const { sendData } = require('./send-data')
|
|
8
8
|
|
|
9
|
+
const HEARTBEAT_INTERVAL = process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL
|
|
10
|
+
? Number(process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL) * 1000
|
|
11
|
+
: 60000
|
|
12
|
+
|
|
9
13
|
let config
|
|
10
14
|
let pluginManager
|
|
11
15
|
|
|
@@ -88,7 +92,9 @@ function start (aConfig, thePluginManager) {
|
|
|
88
92
|
host = createHostObject()
|
|
89
93
|
dependencies.start(config, application, host)
|
|
90
94
|
sendData(config, application, host, 'app-started', appStarted())
|
|
91
|
-
interval = setInterval(() =>
|
|
95
|
+
interval = setInterval(() => {
|
|
96
|
+
sendData(config, application, host, 'app-heartbeat')
|
|
97
|
+
}, HEARTBEAT_INTERVAL)
|
|
92
98
|
interval.unref()
|
|
93
99
|
process.on('beforeExit', onBeforeExit)
|
|
94
100
|
}
|