dd-trace 3.3.1 → 3.5.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/restify.js +1 -0
- 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/appsec/recommended.json +60 -46
- 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 +92 -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
|
@@ -1,71 +1,35 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
'span.kind': 'client',
|
|
24
|
-
'service.name': this.config.service || `${this.tracer._service}-elasticsearch`,
|
|
25
|
-
'resource.name': `${params.method} ${quantizePath(params.path)}`,
|
|
26
|
-
'span.type': 'elasticsearch',
|
|
27
|
-
'elasticsearch.url': params.path,
|
|
28
|
-
'elasticsearch.method': params.method,
|
|
29
|
-
'elasticsearch.body': body,
|
|
30
|
-
'elasticsearch.params': JSON.stringify(params.querystring || params.query)
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
analyticsSampler.sample(span, this.config.measured)
|
|
34
|
-
this.enter(span, store)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
this.addSub('apm:elasticsearch:query:error', err => {
|
|
38
|
-
const span = storage.getStore().span
|
|
39
|
-
span.setTag('error', err)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
this.addSub('apm:elasticsearch:query:finish', ({ params }) => {
|
|
43
|
-
const span = storage.getStore().span
|
|
44
|
-
this.config.hooks.query(span, params)
|
|
45
|
-
span.finish()
|
|
3
|
+
const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
4
|
+
|
|
5
|
+
class ElasticsearchPlugin extends DatabasePlugin {
|
|
6
|
+
static get name () { return 'elasticsearch' }
|
|
7
|
+
|
|
8
|
+
start ({ params }) {
|
|
9
|
+
const body = getBody(params.body || params.bulkBody)
|
|
10
|
+
|
|
11
|
+
this.startSpan('elasticsearch.query', {
|
|
12
|
+
service: this.config.service,
|
|
13
|
+
resource: `${params.method} ${quantizePath(params.path)}`,
|
|
14
|
+
type: 'elasticsearch',
|
|
15
|
+
kind: 'client',
|
|
16
|
+
meta: {
|
|
17
|
+
'db.type': 'elasticsearch',
|
|
18
|
+
'elasticsearch.url': params.path,
|
|
19
|
+
'elasticsearch.method': params.method,
|
|
20
|
+
'elasticsearch.body': body,
|
|
21
|
+
'elasticsearch.params': JSON.stringify(params.querystring || params.query)
|
|
22
|
+
}
|
|
46
23
|
})
|
|
47
24
|
}
|
|
48
25
|
|
|
49
|
-
|
|
50
|
-
|
|
26
|
+
finish ({ params }) {
|
|
27
|
+
const span = this.activeSpan()
|
|
28
|
+
this.config.hooks.query(span, params)
|
|
29
|
+
super.finish({ params })
|
|
51
30
|
}
|
|
52
31
|
}
|
|
53
32
|
|
|
54
|
-
function normalizeConfig (config) {
|
|
55
|
-
const hooks = getHooks(config)
|
|
56
|
-
|
|
57
|
-
return Object.assign({}, config, {
|
|
58
|
-
hooks
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function getHooks (config) {
|
|
63
|
-
const noop = () => {}
|
|
64
|
-
const query = (config.hooks && config.hooks.query) || noop
|
|
65
|
-
|
|
66
|
-
return { query }
|
|
67
|
-
}
|
|
68
|
-
|
|
69
33
|
function getBody (body) {
|
|
70
34
|
return body && JSON.stringify(body)
|
|
71
35
|
}
|
|
@@ -3,11 +3,52 @@
|
|
|
3
3
|
// Plugin temporarily disabled. See https://github.com/DataDog/dd-trace-js/issues/312
|
|
4
4
|
|
|
5
5
|
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
6
|
+
const { storage } = require('../../datadog-core')
|
|
7
|
+
const web = require('../../dd-trace/src/plugins/util/web')
|
|
8
|
+
const { incomingHttpRequestStart } = require('../../dd-trace/src/appsec/gateway/channels')
|
|
6
9
|
|
|
7
10
|
class Http2ServerPlugin extends Plugin {
|
|
8
11
|
static get name () {
|
|
9
12
|
return 'http2'
|
|
10
13
|
}
|
|
14
|
+
|
|
15
|
+
constructor (...args) {
|
|
16
|
+
super(...args)
|
|
17
|
+
|
|
18
|
+
this.addSub('apm:http2:server:request:start', ({ req, res }) => {
|
|
19
|
+
const store = storage.getStore()
|
|
20
|
+
const span = web.startSpan(this.tracer, this.config, req, res, 'web.request')
|
|
21
|
+
|
|
22
|
+
this.enter(span, { ...store, req })
|
|
23
|
+
|
|
24
|
+
const context = web.getContext(req)
|
|
25
|
+
|
|
26
|
+
if (!context.instrumented) {
|
|
27
|
+
context.res.writeHead = web.wrapWriteHead(context)
|
|
28
|
+
context.instrumented = true
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (incomingHttpRequestStart.hasSubscribers) {
|
|
32
|
+
incomingHttpRequestStart.publish({ req, res })
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
this.addSub('apm:http2:server:request:error', (error) => {
|
|
37
|
+
web.addError(error)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
this.addSub('apm:http2:server:request:finish', ({ req }) => {
|
|
41
|
+
const context = web.getContext(req)
|
|
42
|
+
|
|
43
|
+
if (!context || !context.res) return // Not created by a http.Server instance.
|
|
44
|
+
|
|
45
|
+
web.finishAll(context)
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
configure (config) {
|
|
50
|
+
return super.configure(web.normalizeConfig(config))
|
|
51
|
+
}
|
|
11
52
|
}
|
|
12
53
|
|
|
13
54
|
module.exports = Http2ServerPlugin
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const { channel } = require('diagnostics_channel')
|
|
2
|
+
|
|
1
3
|
const Plugin = require('../../dd-trace/src/plugins/plugin')
|
|
2
4
|
const { storage } = require('../../datadog-core')
|
|
3
5
|
|
|
@@ -17,9 +19,16 @@ const {
|
|
|
17
19
|
TEST_CODE_OWNERS,
|
|
18
20
|
TEST_SESSION_ID,
|
|
19
21
|
TEST_SUITE_ID,
|
|
20
|
-
TEST_COMMAND
|
|
22
|
+
TEST_COMMAND,
|
|
23
|
+
TEST_ITR_TESTS_SKIPPED,
|
|
24
|
+
TEST_CODE_COVERAGE_LINES_TOTAL
|
|
21
25
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
22
26
|
|
|
27
|
+
const { getSkippableSuites } = require('../../dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites')
|
|
28
|
+
const {
|
|
29
|
+
getItrConfiguration
|
|
30
|
+
} = require('../../dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration')
|
|
31
|
+
|
|
23
32
|
// https://github.com/facebook/jest/blob/d6ad15b0f88a05816c2fe034dd6900d28315d570/packages/jest-worker/src/types.ts#L38
|
|
24
33
|
const CHILD_MESSAGE_END = 2
|
|
25
34
|
|
|
@@ -46,6 +55,16 @@ class JestPlugin extends Plugin {
|
|
|
46
55
|
constructor (...args) {
|
|
47
56
|
super(...args)
|
|
48
57
|
|
|
58
|
+
const gitMetadataUploadFinishCh = channel('ci:git-metadata-upload:finish')
|
|
59
|
+
// `gitMetadataPromise` is used to wait until git metadata is uploaded to
|
|
60
|
+
// proceed with calculating the suites to skip
|
|
61
|
+
// TODO: add timeout after which the promise is resolved
|
|
62
|
+
const gitMetadataPromise = new Promise(resolve => {
|
|
63
|
+
gitMetadataUploadFinishCh.subscribe(err => {
|
|
64
|
+
resolve(err)
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
|
|
49
68
|
// Used to handle the end of a jest worker to be able to flush
|
|
50
69
|
const handler = ([message]) => {
|
|
51
70
|
if (message === CHILD_MESSAGE_END) {
|
|
@@ -63,6 +82,76 @@ class JestPlugin extends Plugin {
|
|
|
63
82
|
this.testEnvironmentMetadata = getTestEnvironmentMetadata('jest', this.config)
|
|
64
83
|
this.codeOwnersEntries = getCodeOwnersFileEntries()
|
|
65
84
|
|
|
85
|
+
const {
|
|
86
|
+
'git.repository_url': repositoryUrl,
|
|
87
|
+
'git.commit.sha': sha,
|
|
88
|
+
'os.version': osVersion,
|
|
89
|
+
'os.platform': osPlatform,
|
|
90
|
+
'os.architecture': osArchitecture,
|
|
91
|
+
'runtime.name': runtimeName,
|
|
92
|
+
'runtime.version': runtimeVersion,
|
|
93
|
+
'git.branch': gitBranch
|
|
94
|
+
} = this.testEnvironmentMetadata
|
|
95
|
+
|
|
96
|
+
this.addSub('ci:jest:configuration', ({ onResponse, onError }) => {
|
|
97
|
+
if (!this.config.isAgentlessEnabled || !this.config.isIntelligentTestRunnerEnabled) {
|
|
98
|
+
onResponse({})
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
const testConfiguration = {
|
|
102
|
+
site: this.config.site,
|
|
103
|
+
env: this.tracer._env,
|
|
104
|
+
service: this.config.service || this.tracer._service,
|
|
105
|
+
repositoryUrl,
|
|
106
|
+
sha,
|
|
107
|
+
osVersion,
|
|
108
|
+
osPlatform,
|
|
109
|
+
osArchitecture,
|
|
110
|
+
runtimeName,
|
|
111
|
+
runtimeVersion,
|
|
112
|
+
branch: gitBranch
|
|
113
|
+
}
|
|
114
|
+
getItrConfiguration(testConfiguration, (err, config) => {
|
|
115
|
+
if (err) {
|
|
116
|
+
onError(err)
|
|
117
|
+
} else {
|
|
118
|
+
onResponse(config)
|
|
119
|
+
}
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
this.addSub('ci:jest:test-suite:skippable', ({ onResponse, onError }) => {
|
|
124
|
+
if (!this.config.isAgentlessEnabled || !this.config.isIntelligentTestRunnerEnabled) {
|
|
125
|
+
return onResponse([])
|
|
126
|
+
}
|
|
127
|
+
// we only request after git upload has happened, if it didn't fail
|
|
128
|
+
gitMetadataPromise.then((gitUploadError) => {
|
|
129
|
+
if (gitUploadError) {
|
|
130
|
+
return onError(gitUploadError)
|
|
131
|
+
}
|
|
132
|
+
const testConfiguration = {
|
|
133
|
+
site: this.config.site,
|
|
134
|
+
env: this.tracer._env,
|
|
135
|
+
service: this.config.service || this.tracer._service,
|
|
136
|
+
repositoryUrl,
|
|
137
|
+
sha,
|
|
138
|
+
osVersion,
|
|
139
|
+
osPlatform,
|
|
140
|
+
osArchitecture,
|
|
141
|
+
runtimeName,
|
|
142
|
+
runtimeVersion,
|
|
143
|
+
branch: gitBranch
|
|
144
|
+
}
|
|
145
|
+
getSkippableSuites(testConfiguration, (err, skippableTests) => {
|
|
146
|
+
if (err) {
|
|
147
|
+
onError(err)
|
|
148
|
+
} else {
|
|
149
|
+
onResponse(skippableTests)
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
|
|
66
155
|
this.addSub('ci:jest:session:start', (command) => {
|
|
67
156
|
if (!this.config.isAgentlessEnabled) {
|
|
68
157
|
return
|
|
@@ -81,12 +170,18 @@ class JestPlugin extends Plugin {
|
|
|
81
170
|
this.enter(testSessionSpan, store)
|
|
82
171
|
})
|
|
83
172
|
|
|
84
|
-
this.addSub('ci:jest:session:finish', (status) => {
|
|
173
|
+
this.addSub('ci:jest:session:finish', ({ status, isTestsSkipped, testCodeCoverageLinesTotal }) => {
|
|
85
174
|
if (!this.config.isAgentlessEnabled) {
|
|
86
175
|
return
|
|
87
176
|
}
|
|
88
177
|
const testSessionSpan = storage.getStore().span
|
|
89
178
|
testSessionSpan.setTag(TEST_STATUS, status)
|
|
179
|
+
if (isTestsSkipped) {
|
|
180
|
+
testSessionSpan.setTag(TEST_ITR_TESTS_SKIPPED, 'true')
|
|
181
|
+
}
|
|
182
|
+
if (testCodeCoverageLinesTotal !== undefined) {
|
|
183
|
+
testSessionSpan.setTag(TEST_CODE_COVERAGE_LINES_TOTAL, testCodeCoverageLinesTotal)
|
|
184
|
+
}
|
|
90
185
|
testSessionSpan.finish()
|
|
91
186
|
finishAllTraceSpans(testSessionSpan)
|
|
92
187
|
this.tracer._exporter._writer.flush()
|
|
@@ -1,59 +1,24 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
tags: {
|
|
21
|
-
'span.kind': 'client',
|
|
22
|
-
'span.type': 'memcached',
|
|
23
|
-
'service.name': this.config.service || `${this.tracer._service}-memcached`
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
analyticsSampler.sample(span, this.config.measured)
|
|
28
|
-
this.enter(span, store)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
this.addSub('apm:memcached:command:start:with-args', ({ client, server, query }) => {
|
|
32
|
-
const span = storage.getStore().span
|
|
33
|
-
span.addTags({
|
|
34
|
-
'resource.name': query.type,
|
|
35
|
-
'memcached.command': query.command
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
const address = getAddress(client, server, query)
|
|
39
|
-
|
|
40
|
-
if (address) {
|
|
41
|
-
span.addTags({
|
|
42
|
-
'out.host': address[0],
|
|
43
|
-
'out.port': address[1]
|
|
44
|
-
})
|
|
3
|
+
const CachePlugin = require('../../dd-trace/src/plugins/cache')
|
|
4
|
+
|
|
5
|
+
class MemcachedPlugin extends CachePlugin {
|
|
6
|
+
static get name () { return 'memcached' }
|
|
7
|
+
|
|
8
|
+
start ({ client, server, query }) {
|
|
9
|
+
const address = getAddress(client, server, query)
|
|
10
|
+
|
|
11
|
+
this.startSpan('memcached.command', {
|
|
12
|
+
service: this.config.service,
|
|
13
|
+
resource: query.type,
|
|
14
|
+
type: 'memcached',
|
|
15
|
+
kind: 'client',
|
|
16
|
+
meta: {
|
|
17
|
+
'memcached.command': query.command,
|
|
18
|
+
'out.host': address[0],
|
|
19
|
+
'out.port': address[1]
|
|
45
20
|
}
|
|
46
21
|
})
|
|
47
|
-
|
|
48
|
-
this.addSub('apm:memcached:command:error', err => {
|
|
49
|
-
const span = storage.getStore().span
|
|
50
|
-
span.setTag('error', err)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
this.addSub('apm:memcached:command:finish', () => {
|
|
54
|
-
const span = storage.getStore().span
|
|
55
|
-
span.finish()
|
|
56
|
-
})
|
|
57
22
|
}
|
|
58
23
|
}
|
|
59
24
|
|
|
@@ -1,54 +1,26 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
'service.name': this.config.service || `${this.tracer._service}-mongodb`,
|
|
24
|
-
'resource.name': resource,
|
|
25
|
-
'span.type': 'mongodb',
|
|
26
|
-
'span.kind': 'client',
|
|
27
|
-
'db.name': ns
|
|
28
|
-
}
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
if (query) {
|
|
32
|
-
span.setTag('mongodb.query', query)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (options && options.host && options.port) {
|
|
36
|
-
span.addTags({
|
|
37
|
-
'out.host': options.host,
|
|
38
|
-
'out.port': options.port
|
|
39
|
-
})
|
|
3
|
+
const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
4
|
+
|
|
5
|
+
class MongodbCorePlugin extends DatabasePlugin {
|
|
6
|
+
static get name () { return 'mongodb-core' }
|
|
7
|
+
static get component () { return 'mongodb' }
|
|
8
|
+
|
|
9
|
+
start ({ ns, ops, options = {}, name }) {
|
|
10
|
+
const query = getQuery(ops)
|
|
11
|
+
const resource = truncate(getResource(ns, query, name))
|
|
12
|
+
|
|
13
|
+
this.startSpan('mongodb.query', {
|
|
14
|
+
service: this.config.service,
|
|
15
|
+
resource,
|
|
16
|
+
type: 'mongodb',
|
|
17
|
+
kind: 'client',
|
|
18
|
+
meta: {
|
|
19
|
+
'db.name': ns,
|
|
20
|
+
'mongodb.query': query,
|
|
21
|
+
'out.host': options.host,
|
|
22
|
+
'out.port': options.port
|
|
40
23
|
}
|
|
41
|
-
|
|
42
|
-
analyticsSampler.sample(span, this.config.measured)
|
|
43
|
-
this.enter(span, store)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
this.addSub(`apm:mongodb:query:error`, err => {
|
|
47
|
-
storage.getStore().span.setTag('error', err)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
this.addSub(`apm:mongodb:query:finish`, () => {
|
|
51
|
-
storage.getStore().span.finish()
|
|
52
24
|
})
|
|
53
25
|
}
|
|
54
26
|
}
|
|
@@ -1,65 +1,36 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
'span.type': 'sql',
|
|
24
|
-
'span.kind': 'client',
|
|
25
|
-
'db.type': 'mysql',
|
|
26
|
-
'db.user': dbConfig.user,
|
|
27
|
-
'out.host': dbConfig.host,
|
|
28
|
-
'out.port': dbConfig.port,
|
|
29
|
-
'resource.name': sql
|
|
30
|
-
}
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
if (dbConfig.database) {
|
|
34
|
-
span.setTag('db.name', dbConfig.database)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
analyticsSampler.sample(span, this.config.measured)
|
|
38
|
-
this.enter(span, store)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
this.addSub(`apm:${this.constructor.name}:query:error`, err => {
|
|
42
|
-
if (err) {
|
|
43
|
-
const span = storage.getStore().span
|
|
44
|
-
span.setTag('error', err)
|
|
3
|
+
const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
4
|
+
|
|
5
|
+
class MySQLPlugin extends DatabasePlugin {
|
|
6
|
+
static get name () { return 'mysql' }
|
|
7
|
+
static get system () { return 'mysql' }
|
|
8
|
+
|
|
9
|
+
start ({ sql, conf: dbConfig }) {
|
|
10
|
+
const service = getServiceName(this.config, dbConfig)
|
|
11
|
+
|
|
12
|
+
this.startSpan(`${this.system}.query`, {
|
|
13
|
+
service,
|
|
14
|
+
resource: sql,
|
|
15
|
+
type: 'sql',
|
|
16
|
+
kind: 'client',
|
|
17
|
+
meta: {
|
|
18
|
+
'db.type': this.system,
|
|
19
|
+
'db.user': dbConfig.user,
|
|
20
|
+
'db.name': dbConfig.database,
|
|
21
|
+
'out.host': dbConfig.host,
|
|
22
|
+
'out.port': dbConfig.port
|
|
45
23
|
}
|
|
46
24
|
})
|
|
47
|
-
|
|
48
|
-
this.addSub(`apm:${this.constructor.name}:query:finish`, () => {
|
|
49
|
-
const span = storage.getStore().span
|
|
50
|
-
span.finish()
|
|
51
|
-
})
|
|
52
25
|
}
|
|
53
26
|
}
|
|
54
27
|
|
|
55
|
-
function getServiceName (
|
|
28
|
+
function getServiceName (config, dbConfig) {
|
|
56
29
|
if (typeof config.service === 'function') {
|
|
57
30
|
return config.service(dbConfig)
|
|
58
|
-
} else if (config.service) {
|
|
59
|
-
return config.service
|
|
60
|
-
} else {
|
|
61
|
-
return `${tracer._service}-mysql`
|
|
62
31
|
}
|
|
32
|
+
|
|
33
|
+
return config.service
|
|
63
34
|
}
|
|
64
35
|
|
|
65
36
|
module.exports = MySQLPlugin
|
|
@@ -1,72 +1,47 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const { storage } = require('../../datadog-core')
|
|
5
|
-
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
3
|
+
const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
6
4
|
const log = require('../../dd-trace/src/log')
|
|
7
5
|
|
|
8
|
-
class OracledbPlugin extends
|
|
9
|
-
static get name () {
|
|
10
|
-
|
|
11
|
-
}
|
|
6
|
+
class OracledbPlugin extends DatabasePlugin {
|
|
7
|
+
static get name () { return 'oracledb' }
|
|
8
|
+
static get system () { return 'oracle' }
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
start ({ query, connAttrs }) {
|
|
11
|
+
const service = getServiceName(this.config, connAttrs)
|
|
12
|
+
const url = getUrl(connAttrs.connectString)
|
|
15
13
|
|
|
16
|
-
this.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
log.error(e)
|
|
23
|
-
}
|
|
24
|
-
const tags = {
|
|
25
|
-
'span.kind': 'client',
|
|
26
|
-
'span.type': 'sql',
|
|
14
|
+
this.startSpan('oracle.query', {
|
|
15
|
+
service,
|
|
16
|
+
resource: query,
|
|
17
|
+
type: 'sql',
|
|
18
|
+
kind: 'client',
|
|
19
|
+
meta: {
|
|
27
20
|
'sql.query': query,
|
|
28
21
|
'db.user': this.config.user,
|
|
29
|
-
'
|
|
30
|
-
'
|
|
31
|
-
|
|
32
|
-
if (typeof connectStringObj !== 'undefined') {
|
|
33
|
-
tags['db.instance'] = connectStringObj.pathname.substring(1)
|
|
34
|
-
tags['db.hostname'] = connectStringObj.hostname
|
|
35
|
-
tags['db.port'] = connectStringObj.port
|
|
36
|
-
}
|
|
37
|
-
const store = storage.getStore()
|
|
38
|
-
const childOf = store ? store.span : store
|
|
39
|
-
const span = this.tracer.startSpan('oracle.query', {
|
|
40
|
-
childOf,
|
|
41
|
-
tags
|
|
42
|
-
})
|
|
43
|
-
analyticsSampler.sample(span, this.config.measured)
|
|
44
|
-
this.enter(span, store)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
this.addSub('apm:oracledb:execute:error', err => {
|
|
48
|
-
const store = storage.getStore()
|
|
49
|
-
if (store && store.span) {
|
|
50
|
-
store.span.setTag('error', err)
|
|
51
|
-
}
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
this.addSub('apm:oracledb:execute:finish', () => {
|
|
55
|
-
const store = storage.getStore()
|
|
56
|
-
if (store && store.span) {
|
|
57
|
-
store.span.finish()
|
|
22
|
+
'db.instance': url.pathname && url.pathname.substring(1),
|
|
23
|
+
'db.hostname': url.hostname,
|
|
24
|
+
'db.port': url.port
|
|
58
25
|
}
|
|
59
26
|
})
|
|
60
27
|
}
|
|
61
28
|
}
|
|
62
29
|
|
|
63
|
-
function getServiceName (
|
|
30
|
+
function getServiceName (config, connAttrs) {
|
|
64
31
|
if (typeof config.service === 'function') {
|
|
65
32
|
return config.service(connAttrs)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return config.service
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// TODO: Avoid creating an error since it's a heavy operation.
|
|
39
|
+
function getUrl (connectString) {
|
|
40
|
+
try {
|
|
41
|
+
return new URL(`http://${connectString}`)
|
|
42
|
+
} catch (e) {
|
|
43
|
+
log.error(e)
|
|
44
|
+
return {}
|
|
70
45
|
}
|
|
71
46
|
}
|
|
72
47
|
|