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.
Files changed (44) hide show
  1. package/LICENSE-3rdparty.csv +2 -0
  2. package/index.d.ts +7 -0
  3. package/package.json +5 -3
  4. package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
  5. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
  6. package/packages/datadog-instrumentations/src/http2/server.js +67 -1
  7. package/packages/datadog-instrumentations/src/jest.js +76 -6
  8. package/packages/datadog-instrumentations/src/mariadb.js +89 -0
  9. package/packages/datadog-instrumentations/src/memcached.js +1 -4
  10. package/packages/datadog-instrumentations/src/next.js +10 -2
  11. package/packages/datadog-instrumentations/src/oracledb.js +8 -8
  12. package/packages/datadog-instrumentations/src/redis.js +12 -3
  13. package/packages/datadog-instrumentations/src/rhea.js +11 -0
  14. package/packages/datadog-plugin-cassandra-driver/src/index.js +22 -60
  15. package/packages/datadog-plugin-elasticsearch/src/index.js +24 -60
  16. package/packages/datadog-plugin-http2/src/server.js +41 -0
  17. package/packages/datadog-plugin-jest/src/index.js +97 -2
  18. package/packages/datadog-plugin-mariadb/src/index.js +10 -0
  19. package/packages/datadog-plugin-memcached/src/index.js +17 -52
  20. package/packages/datadog-plugin-mongodb-core/src/index.js +20 -48
  21. package/packages/datadog-plugin-mysql/src/index.js +23 -52
  22. package/packages/datadog-plugin-mysql2/src/index.js +1 -3
  23. package/packages/datadog-plugin-oracledb/src/index.js +29 -54
  24. package/packages/datadog-plugin-pg/src/index.js +24 -52
  25. package/packages/datadog-plugin-redis/src/index.js +29 -60
  26. package/packages/datadog-plugin-rhea/src/index.js +4 -1
  27. package/packages/datadog-plugin-tedious/src/index.js +20 -41
  28. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +32 -54
  29. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +87 -0
  30. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +79 -0
  31. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
  32. package/packages/dd-trace/src/plugin_manager.js +3 -0
  33. package/packages/dd-trace/src/plugins/cache.js +9 -0
  34. package/packages/dd-trace/src/plugins/client.js +7 -0
  35. package/packages/dd-trace/src/plugins/database.js +9 -0
  36. package/packages/dd-trace/src/plugins/index.js +2 -0
  37. package/packages/dd-trace/src/plugins/outgoing.js +31 -0
  38. package/packages/dd-trace/src/plugins/plugin.js +3 -0
  39. package/packages/dd-trace/src/plugins/storage.js +25 -0
  40. package/packages/dd-trace/src/plugins/tracing.js +91 -0
  41. package/packages/dd-trace/src/plugins/util/git.js +58 -18
  42. package/packages/dd-trace/src/plugins/util/test.js +7 -1
  43. package/packages/dd-trace/src/proxy.js +4 -0
  44. package/packages/dd-trace/src/telemetry/index.js +7 -1
@@ -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.1",
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'",
@@ -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": "^7.32.0",
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 addConnectionCh = channel(`apm:cassandra:query:addConnection`)
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
- addConnectionCh.publish({ address: this._connection.address, port: this._connection.port })
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
- addConnectionCh.publish({ address: execution._connection.address, port: execution._connection.port })
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
- addConnectionCh.publish({ address: handler.connection.address, port: handler.connection.port })
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
- // Instrumentation temporarily disabled. See https://github.com/DataDog/dd-trace-js/issues/312
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
- const processArgv = process.argv.slice(2).join(' ')
189
+ let onResponse, onError
190
+ const configurationPromise = new Promise((resolve, reject) => {
191
+ onResponse = resolve
192
+ onError = reject
193
+ })
194
+
183
195
  sessionAsyncResource.runInAsyncScope(() => {
184
- testSessionStartCh.publish(`jest ${processArgv}`)
196
+ jestConfigurationCh.publish({ onResponse, onError })
185
197
  })
186
- return runCLI.apply(this, arguments).then(result => {
187
- const { results: { success } } = result
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
- testSessionFinishCh.publish(success ? 'pass' : 'fail')
216
+ skippableSuitesCh.publish({ onResponse, onError })
190
217
  })
191
- return result
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
- startWithArgsCh.publish({ client, server, query })
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
- finish(req, res, null, e)
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
- return result || err
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 executeStartChannel = channel('apm:oracledb:execute:start')
14
- const executeErrorChannel = channel('apm:oracledb:execute:error')
15
- const executeFinishChannel = channel('apm:oracledb:execute:finish')
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
- executeErrorChannel.publish(err)
19
+ errorChannel.publish(err)
20
20
  }
21
- executeFinishChannel.publish(undefined)
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 (!executeStartChannel.hasSubscribers) {
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
- executeStartChannel.publish({ query: dbQuery, connAttrs })
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
- executeErrorChannel.publish(err)
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
- addHook({ name: '@node-redis/client', file: 'dist/lib/client/commands-queue.js', versions: ['>=1'] }, redis => {
15
- shimmer.wrap(redis.default.prototype, 'addCommand', addCommand => function (command) {
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 Plugin = require('../../dd-trace/src/plugins/plugin')
4
- const { storage } = require('../../datadog-core')
5
- const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
6
-
7
- class CassandraDriverPlugin extends Plugin {
8
- static get name () {
9
- return 'cassandra-driver'
10
- }
11
- constructor (...args) {
12
- super(...args)
13
-
14
- this.addSub(`apm:cassandra:query:start`, ({ keyspace, query, connectionOptions }) => {
15
- const store = storage.getStore()
16
- const childOf = store ? store.span : store
17
-
18
- if (Array.isArray(query)) {
19
- query = combine(query)
20
- }
21
-
22
- const span = this.tracer.startSpan('cassandra.query', {
23
- childOf,
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
  }