dd-trace 3.3.0 → 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 +6 -4
- 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/config.js +1 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
- package/packages/dd-trace/src/opentracing/span.js +6 -0
- 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
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -46,6 +46,8 @@ dev,int64-buffer,MIT,Copyright 2015-2016 Yusuke Kawasaki
|
|
|
46
46
|
dev,jszip,MIT,Copyright 2015-2016 Stuart Knightley and contributors
|
|
47
47
|
dev,mkdirp,MIT,Copyright 2010 James Halliday
|
|
48
48
|
dev,mocha,MIT,Copyright 2011-2018 JS Foundation and contributors https://js.foundation
|
|
49
|
+
dev,mocha-junit-reporter,MIT,Copyright (c) 2015 Michael Allen
|
|
50
|
+
dev,mocha-multi-reporters,MIT,Copyright 2019 Yousaf Nabi and 2015 Stanley Ng
|
|
49
51
|
dev,multer,MIT,Copyright 2014 Hage Yaapa
|
|
50
52
|
dev,msgpack-lite,MIT,Copyright 2015 Yusuke Kawasaki
|
|
51
53
|
dev,nock,MIT,Copyright 2017 Pedro Teixeira and other contributors
|
package/index.d.ts
CHANGED
|
@@ -587,6 +587,7 @@ interface Plugins {
|
|
|
587
587
|
"kafkajs": plugins.kafkajs
|
|
588
588
|
"knex": plugins.knex;
|
|
589
589
|
"koa": plugins.koa;
|
|
590
|
+
"mariadb": plugins.mariadb;
|
|
590
591
|
"memcached": plugins.memcached;
|
|
591
592
|
"microgateway-core": plugins.microgateway_core;
|
|
592
593
|
"mocha": plugins.mocha;
|
|
@@ -1164,6 +1165,12 @@ declare namespace plugins {
|
|
|
1164
1165
|
*/
|
|
1165
1166
|
interface kafkajs extends Instrumentation {}
|
|
1166
1167
|
|
|
1168
|
+
/**
|
|
1169
|
+
* This plugin automatically instruments the
|
|
1170
|
+
* [mariadb](https://github.com/mariadb-corporation/mariadb-connector-nodejs) module.
|
|
1171
|
+
*/
|
|
1172
|
+
interface mariadb extends mysql {}
|
|
1173
|
+
|
|
1167
1174
|
/**
|
|
1168
1175
|
* This plugin automatically instruments the
|
|
1169
1176
|
* [memcached](https://github.com/3rd-Eden/memcached) module.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"tdd": "node scripts/tdd.js",
|
|
18
18
|
"test": "SERVICES=* yarn services && mocha --colors --exit --expose-gc 'packages/dd-trace/test/setup/node.js' 'packages/*/test/**/*.spec.js'",
|
|
19
19
|
"test:trace:core": "mocha --colors --exit --expose-gc --file packages/dd-trace/test/setup/core.js --exclude \"packages/dd-trace/test/profiling/**/*.spec.js\" \"packages/dd-trace/test/**/*.spec.js\"",
|
|
20
|
-
"test:trace:core:ci": "nyc --no-clean --include \"packages/dd-trace/src/**/*.js\" --exclude \"packages/dd-trace/src/profiling/**/*.js\" -- npm run test:trace:core",
|
|
20
|
+
"test:trace:core:ci": "nyc --no-clean --include \"packages/dd-trace/src/**/*.js\" --exclude \"packages/dd-trace/src/profiling/**/*.js\" -- npm run test:trace:core -- --reporter mocha-multi-reporters --reporter-options configFile=mocha-reporter.json",
|
|
21
21
|
"test:instrumentations": "mocha --colors --file 'packages/dd-trace/test/setup/core.js' 'packages/datadog-instrumentations/test/**/*.spec.js'",
|
|
22
22
|
"test:instrumentations:ci": "nyc --no-clean --include 'packages/datadog-instrumentations/src/**/*.js' -- npm run test:instrumentations",
|
|
23
23
|
"test:core": "mocha --colors --file packages/datadog-core/test/setup.js 'packages/datadog-core/test/**/*.spec.js'",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"crypto-randomuuid": "^1.0.0",
|
|
66
66
|
"diagnostics_channel": "^1.1.0",
|
|
67
67
|
"ignore": "^5.2.0",
|
|
68
|
-
"import-in-the-middle": "^1.3.
|
|
68
|
+
"import-in-the-middle": "^1.3.4",
|
|
69
69
|
"ipaddr.js": "^2.0.1",
|
|
70
70
|
"istanbul-lib-coverage": "3.2.0",
|
|
71
71
|
"koalas": "^1.0.2",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"checksum": "^0.1.1",
|
|
94
94
|
"cli-table3": "^0.5.1",
|
|
95
95
|
"dotenv": "8.2.0",
|
|
96
|
-
"eslint": "^
|
|
96
|
+
"eslint": "^8.23.0",
|
|
97
97
|
"eslint-config-standard": "^11.0.0-beta.0",
|
|
98
98
|
"eslint-plugin-import": "^2.8.0",
|
|
99
99
|
"eslint-plugin-node": "^5.2.1",
|
|
@@ -107,6 +107,8 @@
|
|
|
107
107
|
"jszip": "^3.5.0",
|
|
108
108
|
"mkdirp": "^0.5.1",
|
|
109
109
|
"mocha": "8",
|
|
110
|
+
"mocha-junit-reporter": "^2.1.0",
|
|
111
|
+
"mocha-multi-reporters": "^1.5.1",
|
|
110
112
|
"msgpack-lite": "^0.1.26",
|
|
111
113
|
"multer": "^1.4.5-lts.1",
|
|
112
114
|
"nock": "^11.3.3",
|
|
@@ -7,10 +7,10 @@ const {
|
|
|
7
7
|
} = require('./helpers/instrument')
|
|
8
8
|
const shimmer = require('../../datadog-shimmer')
|
|
9
9
|
|
|
10
|
-
const startCh = channel('apm:cassandra:query:start')
|
|
11
|
-
const finishCh = channel('apm:cassandra:query:finish')
|
|
12
|
-
const errorCh = channel('apm:cassandra:query:error')
|
|
13
|
-
const
|
|
10
|
+
const startCh = channel('apm:cassandra-driver:query:start')
|
|
11
|
+
const finishCh = channel('apm:cassandra-driver:query:finish')
|
|
12
|
+
const errorCh = channel('apm:cassandra-driver:query:error')
|
|
13
|
+
const connectCh = channel(`apm:cassandra-driver:query:connect`)
|
|
14
14
|
|
|
15
15
|
addHook({ name: 'cassandra-driver', versions: ['>=3.0.0'] }, cassandra => {
|
|
16
16
|
shimmer.wrap(cassandra.Client.prototype, 'batch', batch => function (queries, options, callback) {
|
|
@@ -115,7 +115,7 @@ addHook({ name: 'cassandra-driver', versions: ['>=3.3'], file: 'lib/request-exec
|
|
|
115
115
|
if (!startCh.hasSubscribers) {
|
|
116
116
|
return _sendOnConnection.apply(this, arguments)
|
|
117
117
|
}
|
|
118
|
-
|
|
118
|
+
connectCh.publish({ hostname: this._connection.address, port: this._connection.port })
|
|
119
119
|
return _sendOnConnection.apply(this, arguments)
|
|
120
120
|
})
|
|
121
121
|
return RequestExecution
|
|
@@ -136,7 +136,7 @@ addHook({ name: 'cassandra-driver', versions: ['3.3 - 4.3'], file: 'lib/request-
|
|
|
136
136
|
getHostCallback = asyncResource.bind(getHostCallback)
|
|
137
137
|
|
|
138
138
|
arguments[0] = AsyncResource.bind(function () {
|
|
139
|
-
|
|
139
|
+
connectCh.publish({ hostname: execution._connection.address, port: execution._connection.port })
|
|
140
140
|
return getHostCallback.apply(this, arguments)
|
|
141
141
|
})
|
|
142
142
|
|
|
@@ -160,7 +160,7 @@ addHook({ name: 'cassandra-driver', versions: ['3 - 3.2'], file: 'lib/request-ha
|
|
|
160
160
|
callback = asyncResource.bind(callback)
|
|
161
161
|
|
|
162
162
|
arguments[2] = AsyncResource.bind(function () {
|
|
163
|
-
|
|
163
|
+
connectCh.publish({ hostname: handler.connection.address, port: handler.connection.port })
|
|
164
164
|
return callback.apply(this, arguments)
|
|
165
165
|
})
|
|
166
166
|
|
|
@@ -10,6 +10,7 @@ module.exports = {
|
|
|
10
10
|
'@jest/core': () => require('../jest'),
|
|
11
11
|
'@koa/router': () => require('../koa'),
|
|
12
12
|
'@node-redis/client': () => require('../redis'),
|
|
13
|
+
'@redis/client': () => require('../redis'),
|
|
13
14
|
'amqp10': () => require('../amqp10'),
|
|
14
15
|
'amqplib': () => require('../amqplib'),
|
|
15
16
|
'aws-sdk': () => require('../aws-sdk'),
|
|
@@ -41,6 +42,7 @@ module.exports = {
|
|
|
41
42
|
'koa-router': () => require('../koa'),
|
|
42
43
|
'kafkajs': () => require('../kafkajs'),
|
|
43
44
|
'limitd-client': () => require('../limitd-client'),
|
|
45
|
+
'mariadb': () => require('../mariadb'),
|
|
44
46
|
'memcached': () => require('../memcached'),
|
|
45
47
|
'microgateway-core': () => require('../microgateway-core'),
|
|
46
48
|
'mocha': () => require('../mocha'),
|
|
@@ -1,3 +1,69 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// Old instrumentation temporarily replaced with compatibility mode only instrumentation.
|
|
4
|
+
// See https://github.com/DataDog/dd-trace-js/issues/312
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
channel,
|
|
8
|
+
addHook,
|
|
9
|
+
AsyncResource
|
|
10
|
+
} = require('../helpers/instrument')
|
|
11
|
+
const shimmer = require('../../../datadog-shimmer')
|
|
12
|
+
|
|
13
|
+
const startServerCh = channel('apm:http2:server:request:start')
|
|
14
|
+
const errorServerCh = channel('apm:http2:server:request:error')
|
|
15
|
+
const finishServerCh = channel('apm:http2:server:request:finish')
|
|
16
|
+
|
|
17
|
+
addHook({ name: 'http2' }, http2 => {
|
|
18
|
+
shimmer.wrap(http2, 'createSecureServer', wrapCreateServer)
|
|
19
|
+
shimmer.wrap(http2, 'createServer', wrapCreateServer)
|
|
20
|
+
return http2
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
function wrapCreateServer (createServer) {
|
|
24
|
+
return function (...args) {
|
|
25
|
+
const server = createServer.apply(this, args)
|
|
26
|
+
shimmer.wrap(server, 'emit', wrapEmit)
|
|
27
|
+
return server
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function wrapResponseEmit (emit) {
|
|
32
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
33
|
+
return function (eventName, event) {
|
|
34
|
+
return asyncResource.runInAsyncScope(() => {
|
|
35
|
+
if (eventName === 'close' && finishServerCh.hasSubscribers) {
|
|
36
|
+
finishServerCh.publish({ req: this.req })
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return emit.apply(this, arguments)
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function wrapEmit (emit) {
|
|
44
|
+
return function (eventName, req, res) {
|
|
45
|
+
if (!startServerCh.hasSubscribers) {
|
|
46
|
+
return emit.apply(this, arguments)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (eventName === 'request') {
|
|
50
|
+
res.req = req
|
|
51
|
+
|
|
52
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
53
|
+
return asyncResource.runInAsyncScope(() => {
|
|
54
|
+
startServerCh.publish({ req, res })
|
|
55
|
+
|
|
56
|
+
shimmer.wrap(res, 'emit', wrapResponseEmit)
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
return emit.apply(this, arguments)
|
|
60
|
+
} catch (err) {
|
|
61
|
+
errorServerCh.publish(err)
|
|
62
|
+
|
|
63
|
+
throw err
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
return emit.apply(this, arguments)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const istanbul = require('istanbul-lib-coverage')
|
|
3
3
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
4
4
|
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
const log = require('../../dd-trace/src/log')
|
|
5
6
|
|
|
6
7
|
const testSessionStartCh = channel('ci:jest:session:start')
|
|
7
8
|
const testSessionFinishCh = channel('ci:jest:session:finish')
|
|
@@ -17,6 +18,12 @@ const testSkippedCh = channel('ci:jest:test:skip')
|
|
|
17
18
|
const testRunFinishCh = channel('ci:jest:test:finish')
|
|
18
19
|
const testErrCh = channel('ci:jest:test:err')
|
|
19
20
|
|
|
21
|
+
const skippableSuitesCh = channel('ci:jest:test-suite:skippable')
|
|
22
|
+
const jestConfigurationCh = channel('ci:jest:configuration')
|
|
23
|
+
|
|
24
|
+
let skippableSuites = []
|
|
25
|
+
let isCodeCoverageEnabled = false
|
|
26
|
+
|
|
20
27
|
const {
|
|
21
28
|
getTestSuitePath,
|
|
22
29
|
getTestParametersString
|
|
@@ -179,17 +186,66 @@ addHook({
|
|
|
179
186
|
|
|
180
187
|
function cliWrapper (cli) {
|
|
181
188
|
const wrapped = shimmer.wrap(cli, 'runCLI', runCLI => async function () {
|
|
182
|
-
|
|
189
|
+
let onResponse, onError
|
|
190
|
+
const configurationPromise = new Promise((resolve, reject) => {
|
|
191
|
+
onResponse = resolve
|
|
192
|
+
onError = reject
|
|
193
|
+
})
|
|
194
|
+
|
|
183
195
|
sessionAsyncResource.runInAsyncScope(() => {
|
|
184
|
-
|
|
196
|
+
jestConfigurationCh.publish({ onResponse, onError })
|
|
185
197
|
})
|
|
186
|
-
|
|
187
|
-
|
|
198
|
+
|
|
199
|
+
let isSuitesSkippingEnabled = false
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
const config = await configurationPromise
|
|
203
|
+
isCodeCoverageEnabled = config.isCodeCoverageEnabled
|
|
204
|
+
isSuitesSkippingEnabled = config.isSuitesSkippingEnabled
|
|
205
|
+
} catch (e) {
|
|
206
|
+
// ignore error
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (isSuitesSkippingEnabled) {
|
|
210
|
+
const skippableSuitesPromise = new Promise((resolve, reject) => {
|
|
211
|
+
onResponse = resolve
|
|
212
|
+
onError = reject
|
|
213
|
+
})
|
|
214
|
+
|
|
188
215
|
sessionAsyncResource.runInAsyncScope(() => {
|
|
189
|
-
|
|
216
|
+
skippableSuitesCh.publish({ onResponse, onError })
|
|
190
217
|
})
|
|
191
|
-
|
|
218
|
+
|
|
219
|
+
try {
|
|
220
|
+
skippableSuites = await skippableSuitesPromise
|
|
221
|
+
} catch (e) {
|
|
222
|
+
log.error(e)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const isTestsSkipped = !!skippableSuites.length
|
|
227
|
+
|
|
228
|
+
const processArgv = process.argv.slice(2).join(' ')
|
|
229
|
+
sessionAsyncResource.runInAsyncScope(() => {
|
|
230
|
+
testSessionStartCh.publish(`jest ${processArgv}`)
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
const result = await runCLI.apply(this, arguments)
|
|
234
|
+
|
|
235
|
+
const { results: { success, coverageMap } } = result
|
|
236
|
+
|
|
237
|
+
let testCodeCoverageLinesTotal
|
|
238
|
+
try {
|
|
239
|
+
testCodeCoverageLinesTotal = coverageMap.getCoverageSummary().lines.pct
|
|
240
|
+
} catch (e) {
|
|
241
|
+
// ignore errors
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
sessionAsyncResource.runInAsyncScope(() => {
|
|
245
|
+
testSessionFinishCh.publish({ status: success ? 'pass' : 'fail', isTestsSkipped, testCodeCoverageLinesTotal })
|
|
192
246
|
})
|
|
247
|
+
|
|
248
|
+
return result
|
|
193
249
|
})
|
|
194
250
|
|
|
195
251
|
cli.runCLI = wrapped.runCLI
|
|
@@ -249,9 +305,23 @@ addHook({
|
|
|
249
305
|
|
|
250
306
|
function configureTestEnvironment (readConfigsResult) {
|
|
251
307
|
const { configs } = readConfigsResult
|
|
308
|
+
configs.forEach(config => {
|
|
309
|
+
skippableSuites.forEach((suite) => {
|
|
310
|
+
config.testMatch.push(`!**/${suite}`)
|
|
311
|
+
})
|
|
312
|
+
skippableSuites = []
|
|
313
|
+
})
|
|
252
314
|
sessionAsyncResource.runInAsyncScope(() => {
|
|
253
315
|
testSessionConfigurationCh.publish(configs.map(config => config.testEnvironmentOptions))
|
|
254
316
|
})
|
|
317
|
+
if (isCodeCoverageEnabled) {
|
|
318
|
+
const globalConfig = {
|
|
319
|
+
...readConfigsResult.globalConfig,
|
|
320
|
+
collectCoverage: true
|
|
321
|
+
}
|
|
322
|
+
readConfigsResult.globalConfig = globalConfig
|
|
323
|
+
}
|
|
324
|
+
return readConfigsResult
|
|
255
325
|
}
|
|
256
326
|
|
|
257
327
|
function jestConfigAsyncWrapper (jestConfig) {
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { channel, addHook, AsyncResource } = require('./helpers/instrument')
|
|
4
|
+
|
|
5
|
+
const shimmer = require('../../datadog-shimmer')
|
|
6
|
+
|
|
7
|
+
const startCh = channel('apm:mariadb:query:start')
|
|
8
|
+
const finishCh = channel('apm:mariadb:query:finish')
|
|
9
|
+
const errorCh = channel('apm:mariadb:query:error')
|
|
10
|
+
|
|
11
|
+
function wrapConnectionAddCommand (addCommand) {
|
|
12
|
+
return function (cmd) {
|
|
13
|
+
if (!startCh.hasSubscribers) return addCommand.apply(this, arguments)
|
|
14
|
+
|
|
15
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
16
|
+
const name = cmd && cmd.constructor && cmd.constructor.name
|
|
17
|
+
const isCommand = typeof cmd.start === 'function'
|
|
18
|
+
const isQuery = isCommand && (name === 'Execute' || name === 'Query')
|
|
19
|
+
|
|
20
|
+
// TODO: consider supporting all commands and not just queries
|
|
21
|
+
cmd.start = isQuery
|
|
22
|
+
? wrapStart(cmd, cmd.start, asyncResource, this.opts)
|
|
23
|
+
: bindStart(cmd, cmd.start, asyncResource)
|
|
24
|
+
|
|
25
|
+
return asyncResource.bind(addCommand, this).apply(this, arguments)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function bindStart (cmd, start, asyncResource) {
|
|
30
|
+
return asyncResource.bind(function (packet, connection) {
|
|
31
|
+
if (this.resolve) {
|
|
32
|
+
this.resolve = asyncResource.bind(this.resolve)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (this.reject) {
|
|
36
|
+
this.reject = asyncResource.bind(this.reject)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return start.apply(this, arguments)
|
|
40
|
+
}, cmd)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function wrapStart (cmd, start, asyncResource, config) {
|
|
44
|
+
const callbackResource = new AsyncResource('bound-anonymous-fn')
|
|
45
|
+
|
|
46
|
+
return asyncResource.bind(function (packet, connection) {
|
|
47
|
+
if (!this.resolve || !this.reject) return start.apply(this, arguments)
|
|
48
|
+
|
|
49
|
+
const sql = cmd.statement ? cmd.statement.query : cmd.sql
|
|
50
|
+
|
|
51
|
+
startCh.publish({ sql, conf: config })
|
|
52
|
+
|
|
53
|
+
const resolve = callbackResource.bind(this.resolve)
|
|
54
|
+
const reject = callbackResource.bind(this.reject)
|
|
55
|
+
|
|
56
|
+
this.resolve = asyncResource.bind(function () {
|
|
57
|
+
finishCh.publish(undefined)
|
|
58
|
+
resolve.apply(this, arguments)
|
|
59
|
+
}, 'bound-anonymous-fn', this)
|
|
60
|
+
|
|
61
|
+
this.reject = asyncResource.bind(function (error) {
|
|
62
|
+
errorCh.publish(error)
|
|
63
|
+
finishCh.publish(undefined)
|
|
64
|
+
reject.apply(this, arguments)
|
|
65
|
+
}, 'bound-anonymous-fn', this)
|
|
66
|
+
|
|
67
|
+
this.start = start
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
return start.apply(this, arguments)
|
|
71
|
+
} catch (err) {
|
|
72
|
+
errorCh.publish(err)
|
|
73
|
+
}
|
|
74
|
+
}, cmd)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
addHook(
|
|
78
|
+
{
|
|
79
|
+
name: 'mariadb',
|
|
80
|
+
file: 'lib/connection.js',
|
|
81
|
+
versions: ['>=3']
|
|
82
|
+
},
|
|
83
|
+
(Connection) => {
|
|
84
|
+
shimmer.wrap(Connection.prototype, 'addCommandEnable', wrapConnectionAddCommand)
|
|
85
|
+
shimmer.wrap(Connection.prototype, 'addCommandEnablePipeline', wrapConnectionAddCommand)
|
|
86
|
+
|
|
87
|
+
return Connection
|
|
88
|
+
}
|
|
89
|
+
)
|
|
@@ -9,7 +9,6 @@ const shimmer = require('../../datadog-shimmer')
|
|
|
9
9
|
|
|
10
10
|
addHook({ name: 'memcached', versions: ['>=2.2'] }, Memcached => {
|
|
11
11
|
const startCh = channel('apm:memcached:command:start')
|
|
12
|
-
const startWithArgsCh = channel('apm:memcached:command:start:with-args')
|
|
13
12
|
const finishCh = channel('apm:memcached:command:finish')
|
|
14
13
|
const errorCh = channel('apm:memcached:command:error')
|
|
15
14
|
|
|
@@ -35,14 +34,12 @@ addHook({ name: 'memcached', versions: ['>=2.2'] }, Memcached => {
|
|
|
35
34
|
|
|
36
35
|
return callback.apply(this, arguments)
|
|
37
36
|
})
|
|
38
|
-
|
|
37
|
+
startCh.publish({ client, server, query })
|
|
39
38
|
|
|
40
39
|
return query
|
|
41
40
|
})
|
|
42
41
|
|
|
43
42
|
return asyncResource.runInAsyncScope(() => {
|
|
44
|
-
startCh.publish()
|
|
45
|
-
|
|
46
43
|
arguments[0] = wrappedQueryCompiler
|
|
47
44
|
|
|
48
45
|
const result = command.apply(this, arguments)
|
|
@@ -99,12 +99,16 @@ function instrument (req, res, handler) {
|
|
|
99
99
|
try {
|
|
100
100
|
const promise = handler()
|
|
101
101
|
|
|
102
|
+
// promise should only reject when propagateError is true:
|
|
103
|
+
// https://github.com/vercel/next.js/blob/cee656238a/packages/next/server/api-utils/node.ts#L547
|
|
102
104
|
return promise.then(
|
|
103
105
|
result => finish(req, res, result),
|
|
104
106
|
err => finish(req, res, null, err)
|
|
105
107
|
)
|
|
106
108
|
} catch (e) {
|
|
107
|
-
|
|
109
|
+
// this will probably never happen as the handler caller is an async function:
|
|
110
|
+
// https://github.com/vercel/next.js/blob/cee656238a/packages/next/server/api-utils/node.ts#L420
|
|
111
|
+
return finish(req, res, null, e)
|
|
108
112
|
}
|
|
109
113
|
})
|
|
110
114
|
}
|
|
@@ -116,7 +120,11 @@ function finish (req, res, result, err) {
|
|
|
116
120
|
|
|
117
121
|
finishChannel.publish({ req, res })
|
|
118
122
|
|
|
119
|
-
|
|
123
|
+
if (err) {
|
|
124
|
+
throw err
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return result
|
|
120
128
|
}
|
|
121
129
|
|
|
122
130
|
addHook({ name: 'next', versions: ['>=11.1'], file: 'dist/server/next-server.js' }, nextServer => {
|
|
@@ -10,21 +10,21 @@ const shimmer = require('../../datadog-shimmer')
|
|
|
10
10
|
const connectionAttributes = new WeakMap()
|
|
11
11
|
const poolAttributes = new WeakMap()
|
|
12
12
|
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
13
|
+
const startChannel = channel('apm:oracledb:query:start')
|
|
14
|
+
const errorChannel = channel('apm:oracledb:query:error')
|
|
15
|
+
const finishChannel = channel('apm:oracledb:query:finish')
|
|
16
16
|
|
|
17
17
|
function finish (err) {
|
|
18
18
|
if (err) {
|
|
19
|
-
|
|
19
|
+
errorChannel.publish(err)
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
finishChannel.publish(undefined)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
addHook({ name: 'oracledb', versions: ['5'] }, oracledb => {
|
|
25
25
|
shimmer.wrap(oracledb.Connection.prototype, 'execute', execute => {
|
|
26
26
|
return function wrappedExecute (dbQuery, ...args) {
|
|
27
|
-
if (!
|
|
27
|
+
if (!startChannel.hasSubscribers) {
|
|
28
28
|
return execute.apply(this, arguments)
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -39,7 +39,7 @@ addHook({ name: 'oracledb', versions: ['5'] }, oracledb => {
|
|
|
39
39
|
|
|
40
40
|
return new AsyncResource('apm:oracledb:inner-scope').runInAsyncScope(() => {
|
|
41
41
|
const connAttrs = connectionAttributes.get(this)
|
|
42
|
-
|
|
42
|
+
startChannel.publish({ query: dbQuery, connAttrs })
|
|
43
43
|
try {
|
|
44
44
|
let result = execute.apply(this, arguments)
|
|
45
45
|
|
|
@@ -58,7 +58,7 @@ addHook({ name: 'oracledb', versions: ['5'] }, oracledb => {
|
|
|
58
58
|
|
|
59
59
|
return result
|
|
60
60
|
} catch (err) {
|
|
61
|
-
|
|
61
|
+
errorChannel.publish(err)
|
|
62
62
|
throw err
|
|
63
63
|
}
|
|
64
64
|
})
|
|
@@ -11,8 +11,8 @@ const startCh = channel('apm:redis:command:start')
|
|
|
11
11
|
const finishCh = channel('apm:redis:command:finish')
|
|
12
12
|
const errorCh = channel('apm:redis:command:error')
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
function wrapAddCommand (addCommand) {
|
|
15
|
+
return function (command) {
|
|
16
16
|
if (!startCh.hasSubscribers) {
|
|
17
17
|
return addCommand.apply(this, arguments)
|
|
18
18
|
}
|
|
@@ -32,7 +32,16 @@ addHook({ name: '@node-redis/client', file: 'dist/lib/client/commands-queue.js',
|
|
|
32
32
|
|
|
33
33
|
return res
|
|
34
34
|
})
|
|
35
|
-
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
addHook({ name: '@redis/client', file: 'dist/lib/client/commands-queue.js', versions: ['>=1.1'] }, redis => {
|
|
39
|
+
shimmer.wrap(redis.default.prototype, 'addCommand', wrapAddCommand)
|
|
40
|
+
return redis
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
addHook({ name: '@node-redis/client', file: 'dist/lib/client/commands-queue.js', versions: ['>=1'] }, redis => {
|
|
44
|
+
shimmer.wrap(redis.default.prototype, 'addCommand', wrapAddCommand)
|
|
36
45
|
return redis
|
|
37
46
|
})
|
|
38
47
|
|
|
@@ -15,8 +15,19 @@ const dispatchCh = channel('apm:rhea:dispatch')
|
|
|
15
15
|
const errorCh = channel('apm:rhea:error')
|
|
16
16
|
const finishCh = channel('apm:rhea:finish')
|
|
17
17
|
|
|
18
|
+
const encodeCh = channel('apm:rhea:encode')
|
|
19
|
+
|
|
18
20
|
const contexts = new WeakMap()
|
|
19
21
|
|
|
22
|
+
addHook({ name: 'rhea', versions: ['>=1'] }, rhea => {
|
|
23
|
+
shimmer.wrap(rhea.message, 'encode', encode => function (msg) {
|
|
24
|
+
encodeCh.publish(msg)
|
|
25
|
+
return encode.apply(this, arguments)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
return rhea
|
|
29
|
+
})
|
|
30
|
+
|
|
20
31
|
addHook({ name: 'rhea', versions: ['>=1'], file: 'lib/link.js' }, obj => {
|
|
21
32
|
const startSendCh = channel('apm:rhea:send:start')
|
|
22
33
|
const startReceiveCh = channel('apm:rhea:receive:start')
|
|
@@ -1,66 +1,28 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
this.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
tags: {
|
|
25
|
-
'service.name': this.config.service || `${this.tracer._service}-cassandra`,
|
|
26
|
-
'resource.name': trim(query, 5000),
|
|
27
|
-
'span.type': 'cassandra',
|
|
28
|
-
'span.kind': 'client',
|
|
29
|
-
'db.type': 'cassandra',
|
|
30
|
-
'cassandra.query': query,
|
|
31
|
-
'cassandra.keyspace': keyspace
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
if (connectionOptions) {
|
|
36
|
-
span.addTags({
|
|
37
|
-
'out.host': connectionOptions.host,
|
|
38
|
-
'out.port': connectionOptions.port
|
|
39
|
-
})
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
analyticsSampler.sample(span, this.config.measured)
|
|
43
|
-
this.enter(span, store)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
this.addSub(`apm:cassandra:query:error`, err => {
|
|
47
|
-
storage.getStore().span.setTag('error', err)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
this.addSub(`apm:cassandra:query:finish`, () => {
|
|
51
|
-
storage.getStore().span.finish()
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
this.addSub(`apm:cassandra:query:addConnection`, connectionOptions => {
|
|
55
|
-
const store = storage.getStore()
|
|
56
|
-
if (!store) {
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
|
-
const span = store.span
|
|
60
|
-
span.addTags({
|
|
61
|
-
'out.host': connectionOptions.address,
|
|
3
|
+
const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
4
|
+
|
|
5
|
+
class CassandraDriverPlugin extends DatabasePlugin {
|
|
6
|
+
static get name () { return 'cassandra-driver' }
|
|
7
|
+
static get system () { return 'cassandra' }
|
|
8
|
+
|
|
9
|
+
start ({ keyspace, query, connectionOptions = {} }) {
|
|
10
|
+
if (Array.isArray(query)) {
|
|
11
|
+
query = combine(query)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
this.startSpan('cassandra.query', {
|
|
15
|
+
service: this.config.service,
|
|
16
|
+
resource: trim(query, 5000),
|
|
17
|
+
type: 'cassandra',
|
|
18
|
+
kind: 'client',
|
|
19
|
+
meta: {
|
|
20
|
+
'db.type': 'cassandra',
|
|
21
|
+
'cassandra.query': query,
|
|
22
|
+
'cassandra.keyspace': keyspace,
|
|
23
|
+
'out.host': connectionOptions.host,
|
|
62
24
|
'out.port': connectionOptions.port
|
|
63
|
-
}
|
|
25
|
+
}
|
|
64
26
|
})
|
|
65
27
|
}
|
|
66
28
|
}
|