dd-trace 3.4.0 → 3.6.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 (87) hide show
  1. package/index.d.ts +40 -2
  2. package/package.json +1 -1
  3. package/packages/datadog-instrumentations/src/cucumber.js +0 -2
  4. package/packages/datadog-instrumentations/src/elasticsearch.js +51 -47
  5. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +1 -1
  6. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  7. package/packages/datadog-instrumentations/src/mariadb.js +43 -69
  8. package/packages/datadog-instrumentations/src/mocha.js +14 -18
  9. package/packages/datadog-instrumentations/src/opensearch.js +10 -0
  10. package/packages/datadog-instrumentations/src/pg.js +2 -1
  11. package/packages/datadog-instrumentations/src/restify.js +1 -0
  12. package/packages/datadog-instrumentations/src/rhea.js +20 -17
  13. package/packages/datadog-plugin-amqp10/src/consumer.js +32 -0
  14. package/packages/datadog-plugin-amqp10/src/index.js +11 -101
  15. package/packages/datadog-plugin-amqp10/src/producer.js +34 -0
  16. package/packages/datadog-plugin-amqp10/src/util.js +15 -0
  17. package/packages/datadog-plugin-amqplib/src/client.js +38 -0
  18. package/packages/datadog-plugin-amqplib/src/consumer.js +40 -0
  19. package/packages/datadog-plugin-amqplib/src/index.js +14 -102
  20. package/packages/datadog-plugin-amqplib/src/producer.js +37 -0
  21. package/packages/datadog-plugin-amqplib/src/util.js +14 -0
  22. package/packages/datadog-plugin-dns/src/index.js +16 -91
  23. package/packages/datadog-plugin-dns/src/lookup.js +40 -0
  24. package/packages/datadog-plugin-dns/src/lookup_service.js +24 -0
  25. package/packages/datadog-plugin-dns/src/resolve.js +24 -0
  26. package/packages/datadog-plugin-dns/src/reverse.js +21 -0
  27. package/packages/datadog-plugin-elasticsearch/src/index.js +7 -7
  28. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +25 -0
  29. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +42 -0
  30. package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +14 -99
  31. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +34 -0
  32. package/packages/datadog-plugin-graphql/src/execute.js +73 -0
  33. package/packages/datadog-plugin-graphql/src/index.js +14 -176
  34. package/packages/datadog-plugin-graphql/src/parse.js +32 -0
  35. package/packages/datadog-plugin-graphql/src/resolve.js +70 -76
  36. package/packages/datadog-plugin-graphql/src/validate.js +28 -0
  37. package/packages/datadog-plugin-grpc/src/client.js +46 -55
  38. package/packages/datadog-plugin-grpc/src/index.js +7 -24
  39. package/packages/datadog-plugin-grpc/src/server.js +50 -52
  40. package/packages/datadog-plugin-grpc/src/util.js +15 -14
  41. package/packages/datadog-plugin-http/src/index.js +7 -22
  42. package/packages/datadog-plugin-http2/src/index.js +8 -26
  43. package/packages/datadog-plugin-jest/src/index.js +3 -0
  44. package/packages/datadog-plugin-kafkajs/src/consumer.js +42 -0
  45. package/packages/datadog-plugin-kafkajs/src/index.js +11 -87
  46. package/packages/datadog-plugin-kafkajs/src/producer.js +31 -0
  47. package/packages/datadog-plugin-mocha/src/index.js +2 -2
  48. package/packages/datadog-plugin-moleculer/src/client.js +22 -36
  49. package/packages/datadog-plugin-moleculer/src/index.js +8 -26
  50. package/packages/datadog-plugin-moleculer/src/server.js +18 -30
  51. package/packages/datadog-plugin-net/src/ipc.js +21 -0
  52. package/packages/datadog-plugin-net/src/tcp.js +46 -0
  53. package/packages/datadog-plugin-opensearch/src/index.js +11 -0
  54. package/packages/datadog-plugin-pg/src/index.js +2 -1
  55. package/packages/datadog-plugin-rhea/src/consumer.js +55 -0
  56. package/packages/datadog-plugin-rhea/src/index.js +11 -99
  57. package/packages/datadog-plugin-rhea/src/producer.js +45 -0
  58. package/packages/datadog-plugin-sharedb/src/index.js +22 -39
  59. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +1 -1
  60. package/packages/dd-trace/src/appsec/iast/index.js +4 -6
  61. package/packages/dd-trace/src/appsec/iast/path-line.js +3 -0
  62. package/packages/dd-trace/src/appsec/recommended.json +60 -46
  63. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -5
  64. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -5
  65. package/packages/dd-trace/src/config.js +26 -6
  66. package/packages/dd-trace/src/constants.js +3 -0
  67. package/packages/dd-trace/src/dogstatsd.js +42 -10
  68. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +10 -2
  69. package/packages/dd-trace/src/exporters/agent/writer.js +2 -9
  70. package/packages/dd-trace/src/exporters/common/request.js +12 -0
  71. package/packages/dd-trace/src/format.js +13 -0
  72. package/packages/dd-trace/src/metrics.js +10 -2
  73. package/packages/dd-trace/src/plugins/client.js +3 -1
  74. package/packages/dd-trace/src/plugins/composite.js +26 -0
  75. package/packages/dd-trace/src/plugins/consumer.js +9 -0
  76. package/packages/dd-trace/src/plugins/incoming.js +7 -0
  77. package/packages/dd-trace/src/plugins/index.js +1 -0
  78. package/packages/dd-trace/src/plugins/outgoing.js +1 -1
  79. package/packages/dd-trace/src/plugins/producer.js +9 -0
  80. package/packages/dd-trace/src/plugins/server.js +9 -0
  81. package/packages/dd-trace/src/plugins/storage.js +0 -4
  82. package/packages/dd-trace/src/plugins/tracing.js +10 -9
  83. package/packages/dd-trace/src/profiling/profiler.js +8 -1
  84. package/packages/dd-trace/src/span_processor.js +3 -0
  85. package/packages/dd-trace/src/span_sampler.js +80 -0
  86. package/packages/dd-trace/src/tracer.js +6 -2
  87. package/packages/dd-trace/src/util.js +43 -1
@@ -1,93 +1,17 @@
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 KafkajsPlugin extends Plugin {
8
- static get name () {
9
- return 'kafkajs'
10
- }
11
-
12
- constructor (...args) {
13
- super(...args)
14
-
15
- this.addSub(`apm:kafkajs:produce:start`, ({ topic, messages }) => {
16
- const store = storage.getStore()
17
- const childOf = store ? store.span : store
18
- const span = this.tracer.startSpan('kafka.produce', {
19
- childOf,
20
- tags: {
21
- 'service.name': this.config.service || `${this.tracer._service}-kafka`,
22
- 'span.kind': 'producer',
23
- 'component': 'kafkajs'
24
- }
25
- })
26
-
27
- analyticsSampler.sample(span, this.config.measured)
28
- this.enter(span, store)
29
-
30
- span.addTags({
31
- 'resource.name': topic,
32
- 'kafka.topic': topic,
33
- 'kafka.batch_size': messages.length
34
- })
35
- for (const message of messages) {
36
- if (typeof message === 'object') {
37
- this.tracer.inject(span, 'text_map', message.headers)
38
- }
39
- }
40
- })
41
-
42
- this.addSub(`apm:kafkajs:consume:start`, ({ topic, partition, message }) => {
43
- const store = storage.getStore()
44
- const childOf = extract(this.tracer, message.headers)
45
- const span = this.tracer.startSpan('kafka.consume', {
46
- childOf,
47
- tags: {
48
- 'service.name': this.config.service || `${this.tracer._service}-kafka`,
49
- 'span.kind': 'consumer',
50
- 'span.type': 'worker',
51
- 'component': 'kafkajs',
52
- 'resource.name': topic,
53
- 'kafka.topic': topic,
54
- 'kafka.partition': partition,
55
- 'kafka.message.offset': message.offset
56
- }
57
- })
58
-
59
- analyticsSampler.sample(span, this.config.measured, true)
60
- this.enter(span, store)
61
- })
62
-
63
- this.addSub(`apm:kafkajs:consume:error`, errorHandler)
64
-
65
- this.addSub(`apm:kafkajs:consume:finish`, finishHandler)
66
-
67
- this.addSub(`apm:kafkajs:produce:error`, errorHandler)
68
-
69
- this.addSub(`apm:kafkajs:produce:finish`, finishHandler)
3
+ const ProducerPlugin = require('./producer')
4
+ const ConsumerPlugin = require('./consumer')
5
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
6
+
7
+ class KafkajsPlugin extends CompositePlugin {
8
+ static get name () { return 'kafkajs' }
9
+ static get plugins () {
10
+ return {
11
+ producer: ProducerPlugin,
12
+ consumer: ConsumerPlugin
13
+ }
70
14
  }
71
15
  }
72
16
 
73
- function finishHandler () {
74
- storage.getStore().span.finish()
75
- }
76
-
77
- function errorHandler (error) {
78
- storage.getStore().span.setTag('error', error)
79
- }
80
-
81
- function extract (tracer, bufferMap) {
82
- if (!bufferMap) return null
83
-
84
- const textMap = {}
85
-
86
- for (const key of Object.keys(bufferMap)) {
87
- textMap[key] = bufferMap[key].toString()
88
- }
89
-
90
- return tracer.extract('text_map', textMap)
91
- }
92
-
93
17
  module.exports = KafkajsPlugin
@@ -0,0 +1,31 @@
1
+ 'use strict'
2
+
3
+ const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
4
+
5
+ class KafkajsProducerPlugin extends ProducerPlugin {
6
+ static get name () { return 'kafkajs' }
7
+ static get operation () { return 'produce' }
8
+
9
+ start ({ topic, messages }) {
10
+ const span = this.startSpan('kafka.produce', {
11
+ service: this.config.service || `${this.tracer._service}-kafka`,
12
+ resource: topic,
13
+ kind: 'producer',
14
+ meta: {
15
+ 'component': 'kafkajs',
16
+ 'kafka.topic': topic
17
+ },
18
+ metrics: {
19
+ 'kafka.batch_size': messages.length
20
+ }
21
+ })
22
+
23
+ for (const message of messages) {
24
+ if (typeof message === 'object') {
25
+ this.tracer.inject(span, 'text_map', message.headers)
26
+ }
27
+ }
28
+ }
29
+ }
30
+
31
+ module.exports = KafkajsProducerPlugin
@@ -53,7 +53,7 @@ class MochaPlugin extends Plugin {
53
53
  this.sourceRoot = process.cwd()
54
54
  this.codeOwnersEntries = getCodeOwnersFileEntries(this.sourceRoot)
55
55
 
56
- this.addSub('ci:mocha:run:start', (command) => {
56
+ this.addSub('ci:mocha:session:start', (command) => {
57
57
  if (!this.config.isAgentlessEnabled) {
58
58
  return
59
59
  }
@@ -154,7 +154,7 @@ class MochaPlugin extends Plugin {
154
154
  this._testNameToParams[name] = params
155
155
  })
156
156
 
157
- this.addSub('ci:mocha:run:finish', (status) => {
157
+ this.addSub('ci:mocha:session:finish', (status) => {
158
158
  if (this.testSessionSpan) {
159
159
  this.testSessionSpan.setTag(TEST_STATUS, status)
160
160
  this.testSessionSpan.finish()
@@ -1,49 +1,35 @@
1
1
  'use strict'
2
2
 
3
- const { storage } = require('../../datadog-core')
4
- const Plugin = require('../../dd-trace/src/plugins/plugin')
3
+ const ClientPlugin = require('../../dd-trace/src/plugins/client')
5
4
  const { moleculerTags } = require('./util')
6
5
 
7
- class MoleculerClientPlugin extends Plugin {
8
- constructor (...args) {
9
- super(...args)
10
-
11
- this.addSub('apm:moleculer:call:start', ({ actionName, params, opts }) => {
12
- const store = storage.getStore()
13
- const childOf = store && store.span
14
- const span = this.tracer.startSpan('moleculer.call', {
15
- childOf,
16
- tags: {
17
- 'service.name': this.config.service || this.tracer._service,
18
- 'span.kind': 'client',
19
- 'resource.name': actionName
20
- }
21
- })
22
-
23
- this.tracer.inject(span, 'text_map', opts.meta)
24
-
25
- this.enter(span, store)
6
+ class MoleculerClientPlugin extends ClientPlugin {
7
+ static get name () { return 'moleculer' }
8
+ static get operation () { return 'call' }
9
+
10
+ start ({ actionName, opts }) {
11
+ const span = this.startSpan('moleculer.call', {
12
+ service: this.config.service,
13
+ resource: actionName,
14
+ kind: 'client'
26
15
  })
27
16
 
28
- this.addSub('apm:moleculer:call:finish', ({ broker, ctx }) => {
29
- const store = storage.getStore()
30
- const span = store.span
17
+ this.tracer.inject(span, 'text_map', opts.meta)
18
+ }
19
+
20
+ finish ({ broker, ctx }) {
21
+ const span = this.activeSpan
31
22
 
32
- if (ctx) {
33
- const endpoint = ctx.endpoint || {}
34
- const node = endpoint.node || {}
23
+ if (ctx) {
24
+ const endpoint = ctx.endpoint || {}
25
+ const node = endpoint.node || {}
35
26
 
36
- span.addTags({
37
- 'out.host': node.hostname,
38
- 'out.port': node.port,
39
- ...moleculerTags(broker, ctx, this.config)
40
- })
41
- }
27
+ this.addHost(node.hostname, node.port)
42
28
 
43
- span.finish()
44
- })
29
+ span.addTags(moleculerTags(broker, ctx, this.config))
30
+ }
45
31
 
46
- this.addSub('apm:moleculer:call:error', this.addError)
32
+ span.finish()
47
33
  }
48
34
  }
49
35
 
@@ -2,35 +2,17 @@
2
2
 
3
3
  // TODO: support https://moleculer.services/docs/0.13/actions.html#Streaming
4
4
 
5
- const Plugin = require('../../dd-trace/src/plugins/plugin')
6
5
  const MoleculerServerPlugin = require('./server')
7
6
  const MoleculerClientPlugin = require('./client')
8
-
9
- class MoleculerPlugin extends Plugin {
10
- static get name () {
11
- return 'moleculer'
12
- }
13
-
14
- constructor (...args) {
15
- super(...args)
16
-
17
- this.server = new MoleculerServerPlugin(...args)
18
- this.client = new MoleculerClientPlugin(...args)
19
- }
20
-
21
- configure (config) {
22
- const clientConfig = config.client === false ? false : {
23
- ...config,
24
- ...config.client
25
- }
26
-
27
- const serverConfig = config.server === false ? false : {
28
- ...config,
29
- ...config.server
7
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
8
+
9
+ class MoleculerPlugin extends CompositePlugin {
10
+ static get name () { return 'moleculer' }
11
+ static get plugins () {
12
+ return {
13
+ server: MoleculerServerPlugin,
14
+ client: MoleculerClientPlugin
30
15
  }
31
-
32
- this.server.configure(serverConfig)
33
- this.client.configure(clientConfig)
34
16
  }
35
17
  }
36
18
 
@@ -1,38 +1,26 @@
1
1
  'use strict'
2
2
 
3
- const { storage } = require('../../datadog-core')
4
- const Plugin = require('../../dd-trace/src/plugins/plugin')
3
+ const ServerPlugin = require('../../dd-trace/src/plugins/server')
5
4
  const { moleculerTags } = require('./util')
6
5
 
7
- class MoleculerServerPlugin extends Plugin {
8
- constructor (...args) {
9
- super(...args)
10
-
11
- this.addSub('apm:moleculer:action:start', ({ action, ctx, broker }) => {
12
- const store = storage.getStore()
13
- const followsFrom = this.tracer.extract('text_map', ctx.meta)
14
- const span = this.tracer.startSpan('moleculer.action', {
15
- childOf: followsFrom || (store && store.span),
16
- tags: {
17
- 'service.name': this.config.service || this.tracer._service,
18
- 'span.type': 'web',
19
- 'span.kind': 'server',
20
- 'resource.name': action.name,
21
- ...moleculerTags(broker, ctx, this.config)
22
- }
23
- })
24
-
25
- this.enter(span, store)
26
- })
27
-
28
- this.addSub('apm:moleculer:action:finish', () => {
29
- const store = storage.getStore()
30
- const span = store.span
31
-
32
- span.finish()
6
+ class MoleculerServerPlugin extends ServerPlugin {
7
+ static get name () { return 'moleculer' }
8
+ static get operation () { return 'action' }
9
+
10
+ start ({ action, ctx, broker }) {
11
+ const followsFrom = this.tracer.extract('text_map', ctx.meta)
12
+
13
+ this.startSpan('moleculer.action', {
14
+ childOf: followsFrom || this.activeSpan,
15
+ service: this.config.service,
16
+ resource: action.name,
17
+ kind: 'server',
18
+ type: 'web',
19
+ meta: {
20
+ 'resource.name': action.name,
21
+ ...moleculerTags(broker, ctx, this.config)
22
+ }
33
23
  })
34
-
35
- this.addSub('apm:moleculer:action:error', this.addError)
36
24
  }
37
25
  }
38
26
 
@@ -0,0 +1,21 @@
1
+ 'use strict'
2
+
3
+ const ClientPlugin = require('../../dd-trace/src/plugins/client')
4
+
5
+ class NetIPCPlugin extends ClientPlugin {
6
+ static get name () { return 'net' }
7
+ static get operation () { return 'ipc' }
8
+
9
+ start ({ options }) {
10
+ this.startSpan('ipc.connect', {
11
+ service: this.config.service,
12
+ resource: options.path,
13
+ kind: 'client',
14
+ meta: {
15
+ 'ipc.path': options.path
16
+ }
17
+ })
18
+ }
19
+ }
20
+
21
+ module.exports = NetIPCPlugin
@@ -0,0 +1,46 @@
1
+ 'use strict'
2
+
3
+ const ClientPlugin = require('../../dd-trace/src/plugins/client')
4
+
5
+ class NetTCPPlugin extends ClientPlugin {
6
+ static get name () { return 'net' }
7
+ static get operation () { return 'tcp' }
8
+
9
+ constructor (...args) {
10
+ super(...args)
11
+
12
+ this.addTraceSub('connection', ({ socket }) => {
13
+ const span = this.activeSpan
14
+
15
+ span.addTags({
16
+ 'tcp.local.address': socket.localAddress,
17
+ 'tcp.local.port': socket.localPort
18
+ })
19
+ })
20
+ }
21
+
22
+ start ({ options }) {
23
+ const host = options.host || 'localhost'
24
+ const port = options.port || 0
25
+ const family = options.family || 4
26
+
27
+ this.startSpan('tcp.connect', {
28
+ service: this.config.service,
29
+ resource: [host, port].filter(val => val).join(':'),
30
+ kind: 'client',
31
+ meta: {
32
+ 'tcp.remote.host': host,
33
+ 'tcp.family': `IPv${family}`,
34
+ 'tcp.local.address': '',
35
+ 'out.host': host
36
+ },
37
+ metrics: {
38
+ 'tcp.remote.port': port,
39
+ 'tcp.local.port': 0,
40
+ 'out.port': port
41
+ }
42
+ })
43
+ }
44
+ }
45
+
46
+ module.exports = NetTCPPlugin
@@ -0,0 +1,11 @@
1
+ 'use strict'
2
+
3
+ const ElasticsearchPlugin = require('../../datadog-plugin-elasticsearch/src')
4
+
5
+ class OpenSearchPlugin extends ElasticsearchPlugin {
6
+ static get name () {
7
+ return 'opensearch'
8
+ }
9
+ }
10
+
11
+ module.exports = OpenSearchPlugin
@@ -7,7 +7,7 @@ class PGPlugin extends DatabasePlugin {
7
7
  static get operation () { return 'query' }
8
8
  static get system () { return 'postgres' }
9
9
 
10
- start ({ params = {}, statement }) {
10
+ start ({ params = {}, statement, processId }) {
11
11
  const service = getServiceName(this.config, params)
12
12
 
13
13
  this.startSpan('pg.query', {
@@ -17,6 +17,7 @@ class PGPlugin extends DatabasePlugin {
17
17
  kind: 'client',
18
18
  meta: {
19
19
  'db.type': 'postgres',
20
+ 'db.pid': processId,
20
21
  'db.name': params.database,
21
22
  'db.user': params.user,
22
23
  'out.host': params.host,
@@ -0,0 +1,55 @@
1
+ 'use strict'
2
+
3
+ const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
4
+ const { storage } = require('../../datadog-core')
5
+
6
+ class RheaConsumerPlugin extends ConsumerPlugin {
7
+ static get name () { return 'rhea' }
8
+
9
+ constructor (...args) {
10
+ super(...args)
11
+
12
+ this.addTraceSub('dispatch', ({ state }) => {
13
+ const span = storage.getStore().span
14
+ span.setTag('amqp.delivery.state', state)
15
+ })
16
+ }
17
+
18
+ start ({ msgObj }) {
19
+ const name = getResourceNameFromMessage(msgObj)
20
+ const childOf = extractTextMap(msgObj, this.tracer)
21
+
22
+ this.startSpan('amqp.receive', {
23
+ childOf,
24
+ service: this.config.service,
25
+ resource: name,
26
+ type: 'worker',
27
+ kind: 'consumer',
28
+ meta: {
29
+ 'component': 'rhea',
30
+ 'amqp.link.source.address': name,
31
+ 'amqp.link.role': 'receiver'
32
+ }
33
+ })
34
+ }
35
+ }
36
+
37
+ function getResourceNameFromMessage (msgObj) {
38
+ let resourceName = 'amq.topic'
39
+ let options = {}
40
+ if (msgObj.receiver && msgObj.receiver.options) {
41
+ options = msgObj.receiver.options
42
+ }
43
+ if (options.source && options.source.address) {
44
+ resourceName = options.source.address
45
+ }
46
+ return resourceName
47
+ }
48
+
49
+ function extractTextMap (msgObj, tracer) {
50
+ if (msgObj.message) {
51
+ return tracer.extract('text_map', msgObj.message.delivery_annotations)
52
+ }
53
+ }
54
+
55
+ module.exports = RheaConsumerPlugin
@@ -1,104 +1,16 @@
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 RheaPlugin extends Plugin {
8
- static get name () {
9
- return 'rhea'
10
- }
11
-
12
- constructor (...args) {
13
- super(...args)
14
-
15
- this.addSub(`apm:rhea:send:start`, ({ targetAddress, host, port, msg }) => {
16
- const store = storage.getStore()
17
- const childOf = store ? store.span : store
18
- const name = targetAddress || 'amq.topic'
19
- const span = this.tracer.startSpan('amqp.send', {
20
- childOf,
21
- tags: {
22
- 'component': 'rhea',
23
- 'resource.name': name,
24
- 'service.name': this.config.service || `${this.tracer._service}-amqp-producer`,
25
- 'span.kind': 'producer',
26
- 'amqp.link.target.address': name,
27
- 'amqp.link.role': 'sender',
28
- 'out.host': host,
29
- 'out.port': port
30
- }
31
- })
32
- analyticsSampler.sample(span, this.config.measured)
33
-
34
- this.enter(span, store)
35
- })
36
-
37
- this.addSub('apm:rhea:encode', msg => {
38
- addDeliveryAnnotations(msg, this.tracer, this.tracer.scope().active())
39
- })
40
-
41
- this.addSub(`apm:rhea:receive:start`, ({ msgObj, connection }) => {
42
- const name = getResourceNameFromMessage(msgObj)
43
-
44
- const store = storage.getStore()
45
- const childOf = extractTextMap(msgObj, this.tracer)
46
- const span = this.tracer.startSpan('amqp.receive', {
47
- childOf,
48
- tags: {
49
- 'span.type': 'worker',
50
- 'component': 'rhea',
51
- 'resource.name': name,
52
- 'service.name': this.config.service || this.tracer._service,
53
- 'span.kind': 'consumer',
54
- 'amqp.link.source.address': name,
55
- 'amqp.link.role': 'receiver'
56
- }
57
- })
58
- analyticsSampler.sample(span, this.config.measured, true)
59
-
60
- this.enter(span, store)
61
- })
62
-
63
- this.addSub(`apm:rhea:error`, error => {
64
- storage.getStore().span.setTag('error', error)
65
- })
66
-
67
- this.addSub(`apm:rhea:finish`, () => {
68
- const span = storage.getStore().span
69
- span.finish()
70
- })
71
-
72
- this.addSub(`apm:rhea:dispatch`, ({ state }) => {
73
- const span = storage.getStore().span
74
- span.setTag('amqp.delivery.state', state)
75
- })
76
- }
77
- }
78
-
79
- function getResourceNameFromMessage (msgObj) {
80
- let resourceName = 'amq.topic'
81
- let options = {}
82
- if (msgObj.receiver && msgObj.receiver.options) {
83
- options = msgObj.receiver.options
84
- }
85
- if (options.source && options.source.address) {
86
- resourceName = options.source.address
87
- }
88
- return resourceName
89
- }
90
-
91
- function extractTextMap (msgObj, tracer) {
92
- if (msgObj.message) {
93
- return tracer.extract('text_map', msgObj.message.delivery_annotations)
94
- }
95
- }
96
-
97
- function addDeliveryAnnotations (msg, tracer, span) {
98
- if (msg) {
99
- msg.delivery_annotations = msg.delivery_annotations || {}
100
-
101
- tracer.inject(span, 'text_map', msg.delivery_annotations)
3
+ const ProducerPlugin = require('./producer')
4
+ const ConsumerPlugin = require('./consumer')
5
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
6
+
7
+ class RheaPlugin extends CompositePlugin {
8
+ static get name () { return 'rhea' }
9
+ static get plugins () {
10
+ return {
11
+ producer: ProducerPlugin,
12
+ consumer: ConsumerPlugin
13
+ }
102
14
  }
103
15
  }
104
16
 
@@ -0,0 +1,45 @@
1
+ 'use strict'
2
+
3
+ const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
4
+
5
+ class RheaProducerPlugin extends ProducerPlugin {
6
+ static get name () { return 'rhea' }
7
+ static get operation () { return 'send' }
8
+
9
+ constructor (...args) {
10
+ super(...args)
11
+
12
+ this.addTraceSub('encode', this.encode.bind(this))
13
+ }
14
+
15
+ start ({ targetAddress, host, port }) {
16
+ const name = targetAddress || 'amq.topic'
17
+
18
+ this.startSpan('amqp.send', {
19
+ service: this.config.service || `${this.tracer._service}-amqp-producer`,
20
+ resource: name,
21
+ kind: 'producer',
22
+ meta: {
23
+ 'component': 'rhea',
24
+ 'amqp.link.target.address': name,
25
+ 'amqp.link.role': 'sender',
26
+ 'out.host': host,
27
+ 'out.port': port
28
+ }
29
+ })
30
+ }
31
+
32
+ encode (msg) {
33
+ addDeliveryAnnotations(msg, this.tracer, this.activeSpan)
34
+ }
35
+ }
36
+
37
+ function addDeliveryAnnotations (msg, tracer, span) {
38
+ if (msg) {
39
+ msg.delivery_annotations = msg.delivery_annotations || {}
40
+
41
+ tracer.inject(span, 'text_map', msg.delivery_annotations)
42
+ }
43
+ }
44
+
45
+ module.exports = RheaProducerPlugin