dd-trace 2.0.0-appsec-beta.4 → 2.0.1

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 (82) hide show
  1. package/MIGRATING.md +65 -0
  2. package/ci/init.js +5 -1
  3. package/ci/jest/env.js +5 -1
  4. package/index.d.ts +31 -44
  5. package/package.json +5 -2
  6. package/packages/datadog-instrumentations/index.js +6 -0
  7. package/packages/datadog-instrumentations/src/bluebird.js +26 -0
  8. package/packages/datadog-instrumentations/src/dns.js +2 -2
  9. package/packages/datadog-instrumentations/src/helpers/instrument.js +24 -25
  10. package/packages/datadog-instrumentations/src/helpers/promise.js +29 -0
  11. package/packages/datadog-instrumentations/src/memcached.js +3 -5
  12. package/packages/datadog-instrumentations/src/mysql.js +67 -0
  13. package/packages/datadog-instrumentations/src/promise-js.js +15 -0
  14. package/packages/datadog-instrumentations/src/promise.js +14 -0
  15. package/packages/datadog-instrumentations/src/q.js +21 -0
  16. package/packages/datadog-instrumentations/src/when.js +14 -0
  17. package/packages/datadog-plugin-cucumber/src/index.js +4 -4
  18. package/packages/datadog-plugin-cypress/src/plugin.js +12 -2
  19. package/packages/datadog-plugin-cypress/src/support.js +21 -6
  20. package/packages/datadog-plugin-dns/src/index.js +1 -1
  21. package/packages/datadog-plugin-fs/src/index.js +7 -3
  22. package/packages/datadog-plugin-http/src/client.js +9 -24
  23. package/packages/datadog-plugin-http2/src/client.js +1 -24
  24. package/packages/datadog-plugin-http2/src/server.js +2 -2
  25. package/packages/datadog-plugin-jest/src/jest-environment.js +4 -4
  26. package/packages/datadog-plugin-jest/src/jest-jasmine2.js +2 -2
  27. package/packages/datadog-plugin-knex/src/index.js +3 -3
  28. package/packages/datadog-plugin-mocha/src/index.js +3 -2
  29. package/packages/datadog-plugin-moleculer/src/client.js +60 -0
  30. package/packages/datadog-plugin-moleculer/src/index.js +8 -0
  31. package/packages/datadog-plugin-moleculer/src/server.js +61 -0
  32. package/packages/datadog-plugin-moleculer/src/util.js +21 -0
  33. package/packages/datadog-plugin-mongoose/src/index.js +2 -2
  34. package/packages/datadog-plugin-mysql/src/index.js +37 -89
  35. package/packages/datadog-plugin-net/src/index.js +5 -0
  36. package/packages/datadog-plugin-pino/src/index.js +25 -1
  37. package/packages/datadog-plugin-router/src/index.js +28 -3
  38. package/packages/datadog-plugin-winston/src/index.js +30 -12
  39. package/packages/dd-trace/lib/version.js +1 -1
  40. package/packages/dd-trace/src/appsec/addresses.js +11 -4
  41. package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +4 -7
  42. package/packages/dd-trace/src/appsec/gateway/als.js +1 -0
  43. package/packages/dd-trace/src/appsec/gateway/channels.js +3 -0
  44. package/packages/dd-trace/src/appsec/gateway/engine/engine.js +20 -30
  45. package/packages/dd-trace/src/appsec/gateway/engine/runner.js +2 -0
  46. package/packages/dd-trace/src/appsec/index.js +41 -25
  47. package/packages/dd-trace/src/appsec/recommended.json +5708 -1
  48. package/packages/dd-trace/src/appsec/reporter.js +27 -10
  49. package/packages/dd-trace/src/config.js +31 -27
  50. package/packages/dd-trace/src/constants.js +0 -2
  51. package/packages/dd-trace/src/exporters/agent/request.js +8 -0
  52. package/packages/dd-trace/src/format.js +14 -39
  53. package/packages/dd-trace/src/log.js +6 -15
  54. package/packages/dd-trace/src/noop/span_context.js +0 -1
  55. package/packages/dd-trace/src/noop/tracer.js +0 -6
  56. package/packages/dd-trace/src/opentracing/propagation/text_map.js +46 -47
  57. package/packages/dd-trace/src/opentracing/span.js +2 -7
  58. package/packages/dd-trace/src/opentracing/span_context.js +0 -3
  59. package/packages/dd-trace/src/opentracing/tracer.js +5 -23
  60. package/packages/dd-trace/src/plugins/index.js +1 -5
  61. package/packages/dd-trace/src/plugins/plugin.js +7 -1
  62. package/packages/dd-trace/src/plugins/util/test.js +9 -4
  63. package/packages/dd-trace/src/plugins/util/web.js +3 -3
  64. package/packages/dd-trace/src/profiling/config.js +5 -1
  65. package/packages/dd-trace/src/profiling/exporters/agent.js +33 -32
  66. package/packages/dd-trace/src/profiling/profiler.js +15 -6
  67. package/packages/dd-trace/src/profiling/profilers/cpu.js +1 -1
  68. package/packages/dd-trace/src/profiling/profilers/heap.js +3 -2
  69. package/packages/dd-trace/src/proxy.js +35 -35
  70. package/packages/dd-trace/src/span_processor.js +0 -7
  71. package/packages/dd-trace/src/tracer.js +5 -6
  72. package/scripts/install_plugin_modules.js +7 -0
  73. package/scripts/publish_docs.js +1 -1
  74. package/packages/datadog-plugin-bluebird/src/index.js +0 -69
  75. package/packages/datadog-plugin-promise/src/index.js +0 -17
  76. package/packages/datadog-plugin-promise-js/src/index.js +0 -20
  77. package/packages/datadog-plugin-q/src/index.js +0 -16
  78. package/packages/datadog-plugin-when/src/index.js +0 -17
  79. package/packages/dd-trace/src/appsec/gateway/dc_block.js +0 -68
  80. package/packages/dd-trace/src/plugins/util/promise.js +0 -31
  81. package/packages/dd-trace/src/profiling/mapper.js +0 -91
  82. package/packages/dd-trace/src/scope/noop/scope_manager.js +0 -28
@@ -3,15 +3,30 @@ beforeEach(() => {
3
3
  cy.task('dd:beforeEach', {
4
4
  testName: Cypress.mocha.getRunner().suite.ctx.currentTest.fullTitle(),
5
5
  testSuite: Cypress.mocha.getRootSuite().file
6
+ }).then(traceId => {
7
+ Cypress.env('traceId', traceId)
6
8
  })
7
9
  })
8
10
 
11
+ after(() => {
12
+ cy.window().then(win => {
13
+ win.dispatchEvent(new Event('beforeunload'))
14
+ })
15
+ })
16
+
17
+
9
18
  afterEach(() => {
10
- const currentTest = Cypress.mocha.getRunner().suite.ctx.currentTest
11
- cy.task('dd:afterEach', {
12
- testName: currentTest.fullTitle(),
13
- testSuite: Cypress.mocha.getRootSuite().file,
14
- state: currentTest.state,
15
- error: currentTest.err
19
+ cy.window().then(win => {
20
+ const currentTest = Cypress.mocha.getRunner().suite.ctx.currentTest
21
+ const testInfo = {
22
+ testName: currentTest.fullTitle(),
23
+ testSuite: Cypress.mocha.getRootSuite().file,
24
+ state: currentTest.state,
25
+ error: currentTest.err,
26
+ }
27
+ if (win.DD_RUM) {
28
+ testInfo.isRUMActive = true
29
+ }
30
+ cy.task('dd:afterEach', testInfo)
16
31
  })
17
32
  })
@@ -82,7 +82,7 @@ function defaultAsyncEnd () {
82
82
  }
83
83
 
84
84
  function errorHandler (error) {
85
- storage.getStore().addError(error)
85
+ storage.getStore().span.setTag('error', error)
86
86
  }
87
87
 
88
88
  module.exports = DNSPlugin
@@ -1,5 +1,7 @@
1
1
  'use strict'
2
2
 
3
+ const { storage } = require('../../datadog-core')
4
+
3
5
  let kDirReadPromisified
4
6
  let kDirClosePromisified
5
7
  let kHandle
@@ -52,7 +54,7 @@ const orphanable = false
52
54
  function createWrapCreateReadStream (config, tracer) {
53
55
  return function wrapCreateReadStream (createReadStream) {
54
56
  return function createReadStreamWithTrace (path, options) {
55
- if (!hasParent(tracer)) {
57
+ if (!hasParent()) {
56
58
  return createReadStream.apply(this, arguments)
57
59
  }
58
60
  const tags = makeFSFlagTags('ReadStream', path, options, 'r', config, tracer)
@@ -282,8 +284,10 @@ function getSymbolName (sym) {
282
284
  return sym.description || sym.toString()
283
285
  }
284
286
 
285
- function hasParent (tracer) {
286
- return !!tracer.scope().active()
287
+ function hasParent () {
288
+ const store = storage.getStore()
289
+
290
+ return store && store.span && !store.noop
287
291
  }
288
292
 
289
293
  function createWrapCb (tracer, config, name, tagMaker) {
@@ -1,16 +1,13 @@
1
1
  'use strict'
2
2
 
3
3
  const url = require('url')
4
- const opentracing = require('opentracing')
5
4
  const log = require('../../dd-trace/src/log')
6
- const constants = require('../../dd-trace/src/constants')
7
5
  const tags = require('../../../ext/tags')
8
6
  const kinds = require('../../../ext/kinds')
9
7
  const formats = require('../../../ext/formats')
10
8
  const urlFilter = require('../../dd-trace/src/plugins/util/urlfilter')
11
9
  const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
12
-
13
- const Reference = opentracing.Reference
10
+ const { storage } = require('../../datadog-core')
14
11
 
15
12
  const HTTP_HEADERS = formats.HTTP_HEADERS
16
13
  const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
@@ -18,8 +15,6 @@ const HTTP_REQUEST_HEADERS = tags.HTTP_REQUEST_HEADERS
18
15
  const HTTP_RESPONSE_HEADERS = tags.HTTP_RESPONSE_HEADERS
19
16
  const SPAN_KIND = tags.SPAN_KIND
20
17
  const CLIENT = kinds.CLIENT
21
- const REFERENCE_CHILD_OF = opentracing.REFERENCE_CHILD_OF
22
- const REFERENCE_NOOP = constants.REFERENCE_NOOP
23
18
 
24
19
  function patch (http, methodName, tracer, config) {
25
20
  config = normalizeConfig(tracer, config)
@@ -27,6 +22,10 @@ function patch (http, methodName, tracer, config) {
27
22
 
28
23
  function makeRequestTrace (request) {
29
24
  return function requestTrace () {
25
+ const store = storage.getStore()
26
+
27
+ if (store && store.noop) return request.apply(this, arguments)
28
+
30
29
  let args
31
30
 
32
31
  try {
@@ -50,11 +49,8 @@ function patch (http, methodName, tracer, config) {
50
49
 
51
50
  const scope = tracer.scope()
52
51
  const childOf = scope.active()
53
- const type = config.filter(uri) ? REFERENCE_CHILD_OF : REFERENCE_NOOP
54
52
  const span = tracer.startSpan('http.request', {
55
- references: [
56
- new Reference(type, childOf)
57
- ],
53
+ childOf,
58
54
  tags: {
59
55
  [SPAN_KIND]: CLIENT,
60
56
  'service.name': getServiceName(tracer, config, options),
@@ -286,35 +282,24 @@ function getStatusValidator (config) {
286
282
  return code => code < 400 || code >= 500
287
283
  }
288
284
 
289
- function getFilter (tracer, config) {
290
- const blocklist = tracer._url ? [getAgentFilter(tracer._url)] : []
291
-
285
+ function getFilter (config) {
292
286
  config = Object.assign({}, config, {
293
- blocklist: blocklist.concat(config.blocklist || [])
287
+ blocklist: config.blocklist || []
294
288
  })
295
289
 
296
290
  return urlFilter.getFilter(config)
297
291
  }
298
292
 
299
- function getAgentFilter (url) {
300
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
301
- const agentFilter = url.href.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
302
-
303
- return RegExp(`^${agentFilter}.*$`, 'i')
304
- }
305
-
306
293
  function normalizeConfig (tracer, config) {
307
294
  config = config.client || config
308
295
 
309
296
  const validateStatus = getStatusValidator(config)
310
- const filter = getFilter(tracer, config)
311
- const propagationFilter = getFilter(tracer, { blocklist: config.propagationBlocklist })
297
+ const propagationFilter = getFilter({ blocklist: config.propagationBlocklist })
312
298
  const headers = getHeaders(config)
313
299
  const hooks = getHooks(config)
314
300
 
315
301
  return Object.assign({}, config, {
316
302
  validateStatus,
317
- filter,
318
303
  propagationFilter,
319
304
  headers,
320
305
  hooks
@@ -1,26 +1,19 @@
1
1
  'use strict'
2
2
 
3
3
  const URL = require('url').URL
4
- const opentracing = require('opentracing')
5
4
  const log = require('../../dd-trace/src/log')
6
- const constants = require('../../dd-trace/src/constants')
7
5
  const tags = require('../../../ext/tags')
8
6
  const kinds = require('../../../ext/kinds')
9
7
  const formats = require('../../../ext/formats')
10
- const urlFilter = require('../../dd-trace/src/plugins/util/urlfilter')
11
8
  const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
12
9
  const shimmer = require('../../datadog-shimmer')
13
10
 
14
- const Reference = opentracing.Reference
15
-
16
11
  const HTTP_HEADERS = formats.HTTP_HEADERS
17
12
  const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
18
13
  const HTTP_REQUEST_HEADERS = tags.HTTP_REQUEST_HEADERS
19
14
  const HTTP_RESPONSE_HEADERS = tags.HTTP_RESPONSE_HEADERS
20
15
  const SPAN_KIND = tags.SPAN_KIND
21
16
  const CLIENT = kinds.CLIENT
22
- const REFERENCE_CHILD_OF = opentracing.REFERENCE_CHILD_OF
23
- const REFERENCE_NOOP = constants.REFERENCE_NOOP
24
17
 
25
18
  const HTTP2_HEADER_METHOD = ':method'
26
19
  const HTTP2_HEADER_PATH = ':path'
@@ -91,26 +84,14 @@ function getStatusValidator (config) {
91
84
  return code => code < 400 || code >= 500
92
85
  }
93
86
 
94
- function getFilter (tracer, config) {
95
- const blocklist = tracer._url ? [`${tracer._url.href}/v0.4/traces`] : []
96
-
97
- config = Object.assign({}, config, {
98
- blocklist: blocklist.concat(config.blocklist || [])
99
- })
100
-
101
- return urlFilter.getFilter(config)
102
- }
103
-
104
87
  function normalizeConfig (tracer, config) {
105
88
  config = config.client || config
106
89
 
107
90
  const validateStatus = getStatusValidator(config)
108
- const filter = getFilter(tracer, config)
109
91
  const headers = getHeaders(config)
110
92
 
111
93
  return Object.assign({}, config, {
112
94
  validateStatus,
113
- filter,
114
95
  headers
115
96
  })
116
97
  }
@@ -165,12 +146,8 @@ function startSpan (tracer, config, headers, sessionDetails) {
165
146
  const method = headers[HTTP2_HEADER_METHOD] || HTTP2_METHOD_GET
166
147
  const url = `${sessionDetails.protocol}//${sessionDetails.host}:${sessionDetails.port}${path}`
167
148
 
168
- const type = config.filter(url) ? REFERENCE_CHILD_OF : REFERENCE_NOOP
169
-
170
149
  const span = tracer.startSpan('http.request', {
171
- references: [
172
- new Reference(type, childOf)
173
- ],
150
+ childOf,
174
151
  tags: {
175
152
  [SPAN_KIND]: CLIENT,
176
153
  'service.name': getServiceName(tracer, config, sessionDetails),
@@ -20,6 +20,7 @@ const HTTP_STATUS_CODE = tags.HTTP_STATUS_CODE
20
20
  const HTTP_ROUTE = tags.HTTP_ROUTE
21
21
  const HTTP_REQUEST_HEADERS = tags.HTTP_REQUEST_HEADERS
22
22
  const HTTP_RESPONSE_HEADERS = tags.HTTP_RESPONSE_HEADERS
23
+ const MANUAL_DROP = tags.MANUAL_DROP
23
24
 
24
25
  const HTTP_STATUS_OK = 200
25
26
  const HTTP2_HEADER_AUTHORITY = ':authority'
@@ -73,9 +74,8 @@ function instrumentStream (tracer, config, stream, headers, name, callback) {
73
74
 
74
75
  const span = startStreamSpan(tracer, config, stream, headers, name)
75
76
 
76
- // TODO: replace this with a REFERENCE_NOOP after we split http/express/etc
77
77
  if (!config.filter(headers[HTTP2_HEADER_PATH])) {
78
- span.context()._traceFlags.sampled = false
78
+ span.setTag(MANUAL_DROP, true)
79
79
  }
80
80
 
81
81
  if (config.service) {
@@ -238,8 +238,8 @@ module.exports = [
238
238
  {
239
239
  name: 'jest-environment-node',
240
240
  versions: ['>=24.8.0'],
241
- patch: function (NodeEnvironment, tracer) {
242
- const testEnvironmentMetadata = getTestEnvironmentMetadata('jest')
241
+ patch: function (NodeEnvironment, tracer, config) {
242
+ const testEnvironmentMetadata = getTestEnvironmentMetadata('jest', config)
243
243
 
244
244
  this.wrap(NodeEnvironment.prototype, 'teardown', createWrapTeardown(tracer, this))
245
245
 
@@ -257,8 +257,8 @@ module.exports = [
257
257
  {
258
258
  name: 'jest-environment-jsdom',
259
259
  versions: ['>=24.8.0'],
260
- patch: function (JsdomEnvironment, tracer) {
261
- const testEnvironmentMetadata = getTestEnvironmentMetadata('jest')
260
+ patch: function (JsdomEnvironment, tracer, config) {
261
+ const testEnvironmentMetadata = getTestEnvironmentMetadata('jest', config)
262
262
 
263
263
  this.wrap(JsdomEnvironment.prototype, 'teardown', createWrapTeardown(tracer, this))
264
264
 
@@ -169,8 +169,8 @@ module.exports = [
169
169
  name: 'jest-jasmine2',
170
170
  versions: ['>=24.8.0'],
171
171
  file: 'build/jasmineAsyncInstall.js',
172
- patch: function (jasmineAsyncInstallExport, tracer) {
173
- const testEnvironmentMetadata = getTestEnvironmentMetadata('jest')
172
+ patch: function (jasmineAsyncInstallExport, tracer, config) {
173
+ const testEnvironmentMetadata = getTestEnvironmentMetadata('jest', config)
174
174
  return this.wrapExport(
175
175
  jasmineAsyncInstallExport.default,
176
176
  createWrapJasmineAsyncInstall(tracer, this, testEnvironmentMetadata)(jasmineAsyncInstallExport.default)
@@ -1,14 +1,14 @@
1
1
  'use strict'
2
2
 
3
- const tx = require('../../dd-trace/src/plugins/util/promise')
3
+ const { wrapThen } = require('../../datadog-instrumentations/src/helpers/promise')
4
4
 
5
5
  function createPatch (file) {
6
6
  return {
7
7
  name: 'knex',
8
8
  versions: ['>=0.8.0'],
9
9
  file,
10
- patch (Builder, tracer, config) {
11
- this.wrap(Builder.prototype, 'then', tx.createWrapThen(tracer, config))
10
+ patch (Builder) {
11
+ this.wrap(Builder.prototype, 'then', wrapThen)
12
12
  },
13
13
  unpatch (Builder) {
14
14
  this.unwrap(Builder.prototype, 'then')
@@ -122,6 +122,7 @@ function getAllTestsInSuite (root) {
122
122
  function createWrapRunTests (tracer, testEnvironmentMetadata, sourceRoot) {
123
123
  return function wrapRunTests (runTests) {
124
124
  return function runTestsWithTrace () {
125
+ this.once('end', () => tracer._exporter._writer.flush())
125
126
  runTests.apply(this, arguments)
126
127
  const suite = arguments[0]
127
128
  const tests = getAllTestsInSuite(suite)
@@ -239,8 +240,8 @@ module.exports = [
239
240
  name: 'mocha',
240
241
  versions: ['>=5.2.0'],
241
242
  file: 'lib/runner.js',
242
- patch (Runner, tracer) {
243
- const testEnvironmentMetadata = getTestEnvironmentMetadata('mocha')
243
+ patch (Runner, tracer, config) {
244
+ const testEnvironmentMetadata = getTestEnvironmentMetadata('mocha', config)
244
245
  const sourceRoot = process.cwd()
245
246
  this.wrap(Runner.prototype, 'runTests', createWrapRunTests(tracer, testEnvironmentMetadata, sourceRoot))
246
247
  this.wrap(Runner.prototype, 'runTest', createWrapRunTest(tracer, testEnvironmentMetadata, sourceRoot))
@@ -0,0 +1,60 @@
1
+ 'use strict'
2
+
3
+ const { moleculerTags } = require('./util')
4
+
5
+ function createWrapCall (tracer, config) {
6
+ return function wrapCall (call) {
7
+ return function callWithTrace (actionName, params, opts) {
8
+ const options = {
9
+ service: config.service,
10
+ resource: actionName,
11
+ tags: {
12
+ 'span.kind': 'client'
13
+ }
14
+ }
15
+
16
+ opts = arguments[2] = opts || {}
17
+ opts.meta = opts.meta || {}
18
+
19
+ arguments.length = Math.max(3, arguments.length)
20
+
21
+ return tracer.trace('moleculer.call', options, () => {
22
+ const span = tracer.scope().active()
23
+
24
+ tracer.inject(span, 'text_map', opts.meta)
25
+
26
+ const promise = call.apply(this, arguments)
27
+
28
+ if (promise.ctx) {
29
+ const endpoint = promise.ctx.endpoint || {}
30
+ const node = endpoint.node || {}
31
+
32
+ span.addTags({
33
+ 'out.host': node.hostname,
34
+ 'out.port': node.port,
35
+ ...moleculerTags(this, promise.ctx, config)
36
+ })
37
+ }
38
+
39
+ return promise
40
+ })
41
+ }
42
+ }
43
+ }
44
+
45
+ module.exports = [
46
+ {
47
+ name: 'moleculer',
48
+ versions: ['>=0.14'],
49
+ patch ({ ServiceBroker }, tracer, config) {
50
+ if (config.client === false) return
51
+
52
+ config = Object.assign({}, config, config.client)
53
+
54
+ this.wrap(ServiceBroker.prototype, 'call', createWrapCall(tracer, config))
55
+ },
56
+ unpatch ({ ServiceBroker }) {
57
+ this.unwrap(ServiceBroker.prototype, 'call')
58
+ }
59
+ }
60
+ ]
@@ -0,0 +1,8 @@
1
+ 'use strict'
2
+
3
+ // TODO: support https://moleculer.services/docs/0.13/actions.html#Streaming
4
+
5
+ const client = require('./client')
6
+ const server = require('./server')
7
+
8
+ module.exports = [].concat(client, server)
@@ -0,0 +1,61 @@
1
+ 'use strict'
2
+
3
+ const { moleculerTags } = require('./util')
4
+
5
+ function createWrapRegisterMiddlewares (tracer, config) {
6
+ return function wrapRegisterMiddlewares (registerMiddlewares) {
7
+ return function registerMiddlewaresWithTrace (userMiddlewares) {
8
+ if (this.middlewares && this.middlewares.add) {
9
+ this.middlewares.add(createMiddleware(tracer, config))
10
+ }
11
+
12
+ return registerMiddlewares.apply(this, arguments)
13
+ }
14
+ }
15
+ }
16
+
17
+ function createMiddleware (tracer, config) {
18
+ return {
19
+ name: 'Datadog',
20
+
21
+ localAction (next, action) {
22
+ const broker = this
23
+
24
+ return function datadogMiddleware (ctx) {
25
+ const childOf = tracer.extract('text_map', ctx.meta)
26
+ const options = {
27
+ service: config.service,
28
+ resource: action.name,
29
+ type: 'web',
30
+ tags: {
31
+ 'span.kind': 'server',
32
+ ...moleculerTags(broker, ctx, config)
33
+ }
34
+ }
35
+
36
+ if (childOf) {
37
+ options.childOf = childOf
38
+ }
39
+
40
+ return tracer.trace('moleculer.action', options, () => next(ctx))
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ module.exports = [
47
+ {
48
+ name: 'moleculer',
49
+ versions: ['>=0.14'],
50
+ patch ({ ServiceBroker }, tracer, config) {
51
+ if (config.server === false) return
52
+
53
+ config = Object.assign({}, config, config.server)
54
+
55
+ this.wrap(ServiceBroker.prototype, 'registerMiddlewares', createWrapRegisterMiddlewares(tracer, config))
56
+ },
57
+ unpatch ({ ServiceBroker }) {
58
+ this.unwrap(ServiceBroker.prototype, 'registerMiddlewares')
59
+ }
60
+ }
61
+ ]
@@ -0,0 +1,21 @@
1
+ 'use strict'
2
+
3
+ // TODO: add ctx.params when nested object properties are deprecated
4
+
5
+ function moleculerTags (broker, ctx, config) {
6
+ const service = ctx.service || {}
7
+ const action = ctx.action || {}
8
+ const meta = config.meta && ctx.meta
9
+
10
+ return {
11
+ 'moleculer.context.action': action.name,
12
+ 'moleculer.context.meta': meta,
13
+ 'moleculer.context.node_id': ctx.nodeID,
14
+ 'moleculer.context.request_id': ctx.requestID,
15
+ 'moleculer.context.service': service.name,
16
+ 'moleculer.namespace': broker.namespace,
17
+ 'moleculer.node_id': broker.nodeID
18
+ }
19
+ }
20
+
21
+ module.exports = { moleculerTags }
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const tx = require('../../dd-trace/src/plugins/util/promise')
3
+ const { wrapThen } = require('../../datadog-instrumentations/src/helpers/promise')
4
4
 
5
5
  function createWrapCollectionAddQueue (tracer, config) {
6
6
  return function wrapAddQueue (addQueue) {
@@ -33,7 +33,7 @@ module.exports = [
33
33
  versions: ['>=4.6.4'],
34
34
  patch (mongoose, tracer, config) {
35
35
  if (mongoose.Promise !== global.Promise) {
36
- this.wrap(mongoose.Promise.prototype, 'then', tx.createWrapThen(tracer, config))
36
+ this.wrap(mongoose.Promise.prototype, 'then', wrapThen)
37
37
  }
38
38
 
39
39
  this.wrap(mongoose.Collection.prototype, 'addQueue', createWrapCollectionAddQueue(tracer, config))
@@ -1,110 +1,58 @@
1
1
  'use strict'
2
2
 
3
- const Tags = require('opentracing').Tags
3
+ const Plugin = require('../../dd-trace/src/plugins/plugin')
4
+ const { storage } = require('../../datadog-core')
4
5
  const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
5
6
 
6
- function createWrapQuery (tracer, config) {
7
- return function wrapQuery (query) {
8
- return function queryWithTrace (sql, values, cb) {
9
- const scope = tracer.scope()
10
- const childOf = scope.active()
11
- const span = tracer.startSpan('mysql.query', {
7
+ class MySQLPlugin extends Plugin {
8
+ static get name () {
9
+ return 'mysql'
10
+ }
11
+
12
+ constructor (...args) {
13
+ super(...args)
14
+
15
+ this.addSub('apm:mysql:query:start', ([sql, conf]) => {
16
+ const store = storage.getStore()
17
+ const childOf = store ? store.span : store
18
+ const span = this.tracer.startSpan('mysql.query', {
12
19
  childOf,
13
20
  tags: {
14
- [Tags.SPAN_KIND]: Tags.SPAN_KIND_RPC_CLIENT,
15
- 'service.name': config.service || `${tracer._service}-mysql`,
21
+ 'service.name': this.config.service || `${this.tracer._service}-mysql`,
16
22
  'span.type': 'sql',
17
23
  'span.kind': 'client',
18
24
  'db.type': 'mysql',
19
- 'db.user': this.config.user,
20
- 'out.host': this.config.host,
21
- 'out.port': this.config.port
25
+ 'db.user': conf.user,
26
+ 'out.host': conf.host,
27
+ 'out.port': conf.port,
28
+ 'resource.name': sql
22
29
  }
23
30
  })
24
31
 
25
- if (this.config.database) {
26
- span.setTag('db.name', this.config.database)
32
+ if (conf.database) {
33
+ span.setTag('db.name', conf.database)
27
34
  }
28
35
 
29
- analyticsSampler.sample(span, config.measured)
36
+ analyticsSampler.sample(span, this.config.measured)
37
+ this.enter(span, store)
38
+ })
30
39
 
31
- const sequence = scope.bind(query, span).apply(this, arguments)
40
+ this.addSub('apm:mysql:query:end', () => {
41
+ this.exit()
42
+ })
32
43
 
33
- scope.bind(sequence)
34
-
35
- span.setTag('resource.name', sequence.sql)
36
-
37
- if (sequence._callback) {
38
- sequence._callback = wrapCallback(tracer, span, childOf, sequence._callback)
39
- } else {
40
- sequence.on('end', () => {
41
- span.finish()
42
- })
44
+ this.addSub('apm:mysql:query:error', err => {
45
+ if (err) {
46
+ const span = storage.getStore().span
47
+ span.setTag('error', err)
43
48
  }
49
+ })
44
50
 
45
- return sequence
46
- }
47
- }
48
- }
49
-
50
- function createWrapGetConnection (tracer, config) {
51
- return function wrapGetConnection (getConnection) {
52
- return function getConnectionWithTrace (cb) {
53
- const scope = tracer.scope()
54
-
55
- arguments[0] = scope.bind(cb)
56
-
57
- return scope.bind(getConnection).apply(this, arguments)
58
- }
51
+ this.addSub('apm:mysql:query:async-end', () => {
52
+ const span = storage.getStore().span
53
+ span.finish()
54
+ })
59
55
  }
60
56
  }
61
57
 
62
- function wrapCallback (tracer, span, parent, done) {
63
- return tracer.scope().bind((...args) => {
64
- const err = args[0]
65
- if (err) {
66
- span.addTags({
67
- 'error.type': err.name,
68
- 'error.msg': err.message,
69
- 'error.stack': err.stack
70
- })
71
- }
72
-
73
- span.finish()
74
-
75
- done(...args)
76
- }, parent)
77
- }
78
-
79
- function patchConnection (Connection, tracer, config) {
80
- this.wrap(Connection.prototype, 'query', createWrapQuery(tracer, config))
81
- }
82
-
83
- function unpatchConnection (Connection) {
84
- this.unwrap(Connection.prototype, 'query')
85
- }
86
-
87
- function patchPool (Pool, tracer, config) {
88
- this.wrap(Pool.prototype, 'getConnection', createWrapGetConnection(tracer, config))
89
- }
90
-
91
- function unpatchPool (Pool) {
92
- this.unwrap(Pool.prototype, 'getConnection')
93
- }
94
-
95
- module.exports = [
96
- {
97
- name: 'mysql',
98
- file: 'lib/Connection.js',
99
- versions: ['>=2'],
100
- patch: patchConnection,
101
- unpatch: unpatchConnection
102
- },
103
- {
104
- name: 'mysql',
105
- file: 'lib/Pool.js',
106
- versions: ['>=2'],
107
- patch: patchPool,
108
- unpatch: unpatchPool
109
- }
110
- ]
58
+ module.exports = MySQLPlugin
@@ -2,10 +2,15 @@
2
2
 
3
3
  const tx = require('../../dd-trace/src/plugins/util/tx')
4
4
  const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
5
+ const { storage } = require('../../datadog-core')
5
6
 
6
7
  function createWrapConnect (tracer, config) {
7
8
  return function wrapConnect (connect) {
8
9
  return function connectWithTrace () {
10
+ const store = storage.getStore()
11
+
12
+ if (store && store.noop) return connect.apply(this, arguments)
13
+
9
14
  const scope = tracer.scope()
10
15
  const options = getOptions(arguments)
11
16
  const lastIndex = arguments.length - 1