dd-trace 3.5.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 (85) 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/rhea.js +20 -17
  12. package/packages/datadog-plugin-amqp10/src/consumer.js +32 -0
  13. package/packages/datadog-plugin-amqp10/src/index.js +11 -101
  14. package/packages/datadog-plugin-amqp10/src/producer.js +34 -0
  15. package/packages/datadog-plugin-amqp10/src/util.js +15 -0
  16. package/packages/datadog-plugin-amqplib/src/client.js +38 -0
  17. package/packages/datadog-plugin-amqplib/src/consumer.js +40 -0
  18. package/packages/datadog-plugin-amqplib/src/index.js +14 -102
  19. package/packages/datadog-plugin-amqplib/src/producer.js +37 -0
  20. package/packages/datadog-plugin-amqplib/src/util.js +14 -0
  21. package/packages/datadog-plugin-dns/src/index.js +16 -91
  22. package/packages/datadog-plugin-dns/src/lookup.js +40 -0
  23. package/packages/datadog-plugin-dns/src/lookup_service.js +24 -0
  24. package/packages/datadog-plugin-dns/src/resolve.js +24 -0
  25. package/packages/datadog-plugin-dns/src/reverse.js +21 -0
  26. package/packages/datadog-plugin-elasticsearch/src/index.js +7 -7
  27. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +25 -0
  28. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +42 -0
  29. package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +14 -99
  30. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +34 -0
  31. package/packages/datadog-plugin-graphql/src/execute.js +73 -0
  32. package/packages/datadog-plugin-graphql/src/index.js +14 -176
  33. package/packages/datadog-plugin-graphql/src/parse.js +32 -0
  34. package/packages/datadog-plugin-graphql/src/resolve.js +70 -76
  35. package/packages/datadog-plugin-graphql/src/validate.js +28 -0
  36. package/packages/datadog-plugin-grpc/src/client.js +46 -55
  37. package/packages/datadog-plugin-grpc/src/index.js +7 -24
  38. package/packages/datadog-plugin-grpc/src/server.js +50 -52
  39. package/packages/datadog-plugin-grpc/src/util.js +15 -14
  40. package/packages/datadog-plugin-http/src/index.js +7 -22
  41. package/packages/datadog-plugin-http2/src/index.js +8 -26
  42. package/packages/datadog-plugin-jest/src/index.js +3 -0
  43. package/packages/datadog-plugin-kafkajs/src/consumer.js +42 -0
  44. package/packages/datadog-plugin-kafkajs/src/index.js +11 -87
  45. package/packages/datadog-plugin-kafkajs/src/producer.js +31 -0
  46. package/packages/datadog-plugin-mocha/src/index.js +2 -2
  47. package/packages/datadog-plugin-moleculer/src/client.js +22 -36
  48. package/packages/datadog-plugin-moleculer/src/index.js +8 -26
  49. package/packages/datadog-plugin-moleculer/src/server.js +18 -30
  50. package/packages/datadog-plugin-net/src/ipc.js +21 -0
  51. package/packages/datadog-plugin-net/src/tcp.js +46 -0
  52. package/packages/datadog-plugin-opensearch/src/index.js +11 -0
  53. package/packages/datadog-plugin-pg/src/index.js +2 -1
  54. package/packages/datadog-plugin-rhea/src/consumer.js +55 -0
  55. package/packages/datadog-plugin-rhea/src/index.js +11 -99
  56. package/packages/datadog-plugin-rhea/src/producer.js +45 -0
  57. package/packages/datadog-plugin-sharedb/src/index.js +22 -39
  58. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +1 -1
  59. package/packages/dd-trace/src/appsec/iast/index.js +4 -6
  60. package/packages/dd-trace/src/appsec/iast/path-line.js +3 -0
  61. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -5
  62. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -5
  63. package/packages/dd-trace/src/config.js +26 -6
  64. package/packages/dd-trace/src/constants.js +3 -0
  65. package/packages/dd-trace/src/dogstatsd.js +42 -10
  66. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +10 -2
  67. package/packages/dd-trace/src/exporters/agent/writer.js +2 -9
  68. package/packages/dd-trace/src/exporters/common/request.js +12 -0
  69. package/packages/dd-trace/src/format.js +13 -0
  70. package/packages/dd-trace/src/metrics.js +10 -2
  71. package/packages/dd-trace/src/plugins/client.js +3 -1
  72. package/packages/dd-trace/src/plugins/composite.js +26 -0
  73. package/packages/dd-trace/src/plugins/consumer.js +9 -0
  74. package/packages/dd-trace/src/plugins/incoming.js +7 -0
  75. package/packages/dd-trace/src/plugins/index.js +1 -0
  76. package/packages/dd-trace/src/plugins/outgoing.js +1 -1
  77. package/packages/dd-trace/src/plugins/producer.js +9 -0
  78. package/packages/dd-trace/src/plugins/server.js +9 -0
  79. package/packages/dd-trace/src/plugins/storage.js +0 -4
  80. package/packages/dd-trace/src/plugins/tracing.js +9 -9
  81. package/packages/dd-trace/src/profiling/profiler.js +8 -1
  82. package/packages/dd-trace/src/span_processor.js +3 -0
  83. package/packages/dd-trace/src/span_sampler.js +80 -0
  84. package/packages/dd-trace/src/tracer.js +6 -2
  85. package/packages/dd-trace/src/util.js +43 -1
@@ -1,98 +1,92 @@
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')
3
+ const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
6
4
 
7
5
  const collapsedPathSym = Symbol('collapsedPaths')
8
6
 
9
- class GraphQLResolvePlugin extends Plugin {
10
- static get name () {
11
- return 'graphql'
7
+ class GraphQLResolvePlugin extends TracingPlugin {
8
+ static get name () { return 'graphql' }
9
+ static get operation () { return 'resolve' }
10
+
11
+ start ({ info, context }) {
12
+ const path = getPath(info, this.config)
13
+
14
+ if (!shouldInstrument(this.config, path)) return
15
+
16
+ const computedPathString = path.join('.')
17
+
18
+ if (this.config.collapse) {
19
+ if (!context[collapsedPathSym]) {
20
+ context[collapsedPathSym] = {}
21
+ }
22
+
23
+ if (context.fields[computedPathString]) return
24
+ if (context[collapsedPathSym][computedPathString]) return
25
+
26
+ context[collapsedPathSym][computedPathString] = true
27
+ }
28
+
29
+ const document = context.source
30
+ const fieldNode = info.fieldNodes.find(fieldNode => fieldNode.kind === 'Field')
31
+ const loc = this.config.source && document && fieldNode && fieldNode.loc
32
+ const source = loc && document.substring(loc.start, loc.end)
33
+
34
+ const span = this.startSpan('graphql.resolve', {
35
+ service: this.config.service,
36
+ resource: `${info.fieldName}:${info.returnType}`,
37
+ type: 'graphql',
38
+ meta: {
39
+ 'graphql.field.name': info.fieldName,
40
+ 'graphql.field.path': computedPathString,
41
+ 'graphql.field.type': info.returnType.name,
42
+ 'graphql.source': source
43
+ }
44
+ })
45
+
46
+ if (fieldNode && this.config.variables && fieldNode.arguments) {
47
+ const variables = this.config.variables(info.variableValues)
48
+
49
+ fieldNode.arguments
50
+ .filter(arg => arg.value && arg.value.kind === 'Variable')
51
+ .filter(arg => arg.value.name && variables[arg.value.name.value])
52
+ .map(arg => arg.value.name.value)
53
+ .forEach(name => {
54
+ span.setTag(`graphql.variables.${name}`, variables[name])
55
+ })
56
+ }
57
+ }
58
+
59
+ finish (finishTime) {
60
+ const span = this.activeSpan
61
+ span.finish(finishTime)
12
62
  }
13
63
 
14
64
  constructor (...args) {
15
65
  super(...args)
16
66
 
17
- this.addSub('apm:graphql:resolve:start', ({ info, context }) => {
18
- const store = storage.getStore()
19
- depthPredicate(info, this.config, (computedPath) => {
20
- const computedPathString = computedPath.join('.')
21
- if ((!this.config.collapse && !context.fields[computedPathString]) ||
22
- (!context[collapsedPathSym] || !context[collapsedPathSym][computedPathString])) {
23
- // cache the collapsed string here
24
- if (this.config.collapse) {
25
- if (!context[collapsedPathSym]) context[collapsedPathSym] = {}
26
- context[collapsedPathSym][computedPathString] = true
27
- }
28
-
29
- const service = this.config.service || this.tracer._service
30
- const childOf = store ? store.span : store
31
- const span = this.tracer.startSpan(`graphql.resolve`, {
32
- childOf: childOf,
33
- tags: {
34
- 'service.name': service,
35
- 'span.type': 'graphql'
36
- }
37
- })
38
- const document = context.source
39
- const fieldNode = info.fieldNodes.find(fieldNode => fieldNode.kind === 'Field')
40
-
41
- analyticsSampler.sample(span, this.config.measured)
42
-
43
- span.addTags({
44
- 'resource.name': `${info.fieldName}:${info.returnType}`,
45
- 'graphql.field.name': info.fieldName,
46
- 'graphql.field.path': computedPathString,
47
- 'graphql.field.type': info.returnType.name
48
- })
49
-
50
- if (fieldNode) {
51
- if (this.config.source && document && fieldNode.loc) {
52
- span.setTag('graphql.source', document.substring(fieldNode.loc.start, fieldNode.loc.end))
53
- }
54
-
55
- if (this.config.variables && fieldNode.arguments) {
56
- const variables = this.config.variables(info.variableValues)
57
-
58
- fieldNode.arguments
59
- .filter(arg => arg.value && arg.value.kind === 'Variable')
60
- .filter(arg => arg.value.name && variables[arg.value.name.value])
61
- .map(arg => arg.value.name.value)
62
- .forEach(name => {
63
- span.setTag(`graphql.variables.${name}`, variables[name])
64
- })
65
- }
66
- }
67
- this.enter(span, store)
68
- }
69
- })
70
- })
67
+ this.addTraceSub('updateField', ({ field, info, err }) => {
68
+ const path = getPath(info, this.config)
71
69
 
72
- this.addSub('apm:graphql:resolve:updateField', ({ field, info, err }) => {
73
- depthPredicate(info, this.config, () => {
74
- const span = storage.getStore().span
75
- field.finishTime = span._getTime ? span._getTime() : 0
76
- field.error = field.error || err
77
- })
78
- })
70
+ if (!shouldInstrument(this.config, path)) return
79
71
 
80
- this.addSub('apm:graphql:resolve:error', this.addError)
81
-
82
- this.addSub('apm:graphql:resolve:finish', finishTime => {
83
- const span = storage.getStore().span
84
- span.finish(finishTime)
72
+ const span = this.activeSpan
73
+ field.finishTime = span._getTime ? span._getTime() : 0
74
+ field.error = field.error || err
85
75
  })
86
76
  }
77
+
78
+ configure (config) {
79
+ // this will disable resolve subscribers if `config.depth` is set to 0
80
+ super.configure(config.depth === 0 ? false : config)
81
+ }
87
82
  }
88
83
 
89
84
  // helpers
90
85
 
91
- function depthPredicate (info, config, func) {
92
- func = func || (() => {})
93
- const path = getPath(info, config)
86
+ function shouldInstrument (config, path) {
94
87
  const depth = path.filter(item => typeof item === 'string').length
95
- if (config.depth < 0 || config.depth >= depth) func(path)
88
+
89
+ return config.depth < 0 || config.depth >= depth
96
90
  }
97
91
 
98
92
  function getPath (info, config) {
@@ -0,0 +1,28 @@
1
+ 'use strict'
2
+
3
+ const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
4
+
5
+ class GraphQLValidatePlugin extends TracingPlugin {
6
+ static get name () { return 'graphql' }
7
+ static get operation () { return 'validate' }
8
+
9
+ start ({ docSource, document }) {
10
+ const source = this.config.source && document && docSource
11
+
12
+ this.startSpan('graphql.validate', {
13
+ service: this.config.service,
14
+ type: 'graphql',
15
+ meta: {
16
+ 'graphql.source': source
17
+ }
18
+ })
19
+ }
20
+
21
+ finish ({ document, errors }) {
22
+ const span = this.activeSpan
23
+ this.config.hooks.validate(span, document, errors)
24
+ span.finish()
25
+ }
26
+ }
27
+
28
+ module.exports = GraphQLValidatePlugin
@@ -1,72 +1,63 @@
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
- const Tags = require('../../../ext/tags')
3
+ const ClientPlugin = require('../../dd-trace/src/plugins/client')
7
4
  const { TEXT_MAP } = require('../../../ext/formats')
8
- const { addMethodTags, addMetadataTags, getFilter } = require('./util')
9
-
10
- class GrpcClientPlugin extends Plugin {
11
- static get name () {
12
- return 'grpc'
13
- }
14
-
15
- constructor (...args) {
16
- super(...args)
17
-
18
- this.addSub('apm:grpc:client:request:start', ({ metadata, path, type }) => {
19
- const metadataFilter = this.config.metadataFilter
20
- const store = storage.getStore()
21
- const childOf = store && store.span
22
- const span = this.tracer.startSpan('grpc.client', {
23
- childOf,
24
- tags: {
25
- [Tags.SPAN_KIND]: 'client',
26
- 'span.type': 'http',
27
- 'resource.name': path,
28
- 'service.name': this.config.service || this.tracer._service,
29
- 'component': 'grpc'
30
- }
31
- })
32
-
33
- addMethodTags(span, path, type)
34
-
35
- if (metadata) {
36
- addMetadataTags(span, metadata, metadataFilter, 'request')
37
- inject(this.tracer, span, metadata)
5
+ const { addMetadataTags, getFilter, getMethodMetadata } = require('./util')
6
+
7
+ class GrpcClientPlugin extends ClientPlugin {
8
+ static get name () { return 'grpc' }
9
+ static get operation () { return 'client:request' }
10
+
11
+ start ({ metadata, path, type }) {
12
+ const metadataFilter = this.config.metadataFilter
13
+ const method = getMethodMetadata(path, type)
14
+ const span = this.startSpan('grpc.client', {
15
+ service: this.config.service,
16
+ resource: path,
17
+ kind: 'client',
18
+ type: 'http',
19
+ meta: {
20
+ 'component': 'grpc',
21
+ 'grpc.method.kind': method.kind,
22
+ 'grpc.method.path': method.path,
23
+ 'grpc.method.name': method.name,
24
+ 'grpc.method.service': method.service,
25
+ 'grpc.method.package': method.package
26
+ },
27
+ metrics: {
28
+ 'grpc.status.code': 0
38
29
  }
39
-
40
- analyticsSampler.sample(span, this.config.measured)
41
-
42
- this.enter(span, store)
43
30
  })
44
31
 
45
- this.addSub('apm:grpc:client:request:error', error => {
46
- const store = storage.getStore()
32
+ if (metadata) {
33
+ addMetadataTags(span, metadata, metadataFilter, 'request')
34
+ inject(this.tracer, span, metadata)
35
+ }
36
+ }
47
37
 
48
- if (!store || !store.span) return
38
+ error (error) {
39
+ const span = this.activeSpan
49
40
 
50
- this.addCode(store.span, error.code)
51
- this.addError(error)
52
- })
41
+ if (!span) return
53
42
 
54
- this.addSub('apm:grpc:client:request:finish', ({ code, metadata }) => {
55
- const store = storage.getStore()
43
+ this.addCode(span, error.code)
44
+ this.addError(error)
45
+ }
56
46
 
57
- if (!store || !store.span) return
47
+ finish ({ code, metadata }) {
48
+ const span = this.activeSpan
58
49
 
59
- const span = store.span
60
- const metadataFilter = this.config.metadataFilter
50
+ if (!span) return
61
51
 
62
- this.addCode(span, code)
52
+ const metadataFilter = this.config.metadataFilter
63
53
 
64
- if (metadata && metadataFilter) {
65
- addMetadataTags(span, metadata, metadataFilter, 'response')
66
- }
54
+ this.addCode(span, code)
67
55
 
68
- store.span.finish()
69
- })
56
+ if (metadata && metadataFilter) {
57
+ addMetadataTags(span, metadata, metadataFilter, 'response')
58
+ }
59
+
60
+ span.finish()
70
61
  }
71
62
 
72
63
  configure (config) {
@@ -1,33 +1,16 @@
1
1
  'use strict'
2
2
 
3
- const Plugin = require('../../dd-trace/src/plugins/plugin')
4
3
  const GrpcServerPlugin = require('./server')
5
4
  const GrpcClientPlugin = require('./client')
5
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
6
6
 
7
- class GrpcPlugin extends Plugin {
8
- static get name () {
9
- return 'grpc'
10
- }
11
-
12
- constructor (...args) {
13
- super(...args)
14
- this.server = new GrpcServerPlugin(...args)
15
- this.client = new GrpcClientPlugin(...args)
16
- }
17
-
18
- configure (config) {
19
- const clientConfig = config.client === false ? false : {
20
- ...config,
21
- ...config.client
7
+ class GrpcPlugin extends CompositePlugin {
8
+ static get name () { return 'grpc' }
9
+ static get plugins () {
10
+ return {
11
+ server: GrpcServerPlugin,
12
+ client: GrpcClientPlugin
22
13
  }
23
-
24
- const serverConfig = config.server === false ? false : {
25
- ...config,
26
- ...config.server
27
- }
28
-
29
- this.server.configure(serverConfig)
30
- this.client.configure(clientConfig)
31
14
  }
32
15
  }
33
16
 
@@ -1,76 +1,74 @@
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
- const Tags = require('../../../ext/tags')
3
+ const ServerPlugin = require('../../dd-trace/src/plugins/server')
7
4
  const { TEXT_MAP } = require('../../../ext/formats')
8
- const { addMethodTags, addMetadataTags, getFilter } = require('./util')
5
+ const { addMetadataTags, getFilter, getMethodMetadata } = require('./util')
9
6
 
10
- class GrpcServerPlugin extends Plugin {
11
- static get name () {
12
- return 'http'
13
- }
7
+ class GrpcServerPlugin extends ServerPlugin {
8
+ static get name () { return 'grpc' }
9
+ static get operation () { return 'server:request' }
14
10
 
15
11
  constructor (...args) {
16
12
  super(...args)
17
13
 
18
- this.addSub('apm:grpc:server:request:start', ({ name, metadata, type }) => {
19
- const metadataFilter = this.config.metadataFilter
20
- const store = storage.getStore()
21
- const childOf = extract(this.tracer, metadata)
22
- const span = this.tracer.startSpan('grpc.server', {
23
- childOf,
24
- tags: {
25
- [Tags.SPAN_KIND]: 'server',
26
- 'span.type': 'web',
27
- 'resource.name': name,
28
- 'service.name': this.config.service || this.tracer._service,
29
- 'component': 'grpc'
30
- }
31
- })
32
-
33
- addMethodTags(span, name, type)
34
- addMetadataTags(span, metadata, metadataFilter, 'request')
35
-
36
- analyticsSampler.sample(span, this.config.measured, true)
37
-
38
- this.enter(span, store)
39
- })
14
+ this.addTraceSub('update', ({ code }) => {
15
+ const span = this.activeSpan
40
16
 
41
- this.addSub('apm:grpc:server:request:error', error => {
42
- const store = storage.getStore()
17
+ if (!span) return
43
18
 
44
- if (!store || !store.span) return
19
+ this.addCode(span, code)
20
+ })
21
+ }
45
22
 
46
- this.addCode(store.span, error.code)
47
- this.addError(error)
23
+ start ({ name, metadata, type }) {
24
+ const metadataFilter = this.config.metadataFilter
25
+ const childOf = extract(this.tracer, metadata)
26
+ const method = getMethodMetadata(name, type)
27
+ const span = this.startSpan('grpc.server', {
28
+ childOf,
29
+ service: this.config.service,
30
+ resource: name,
31
+ kind: 'server',
32
+ type: 'web',
33
+ meta: {
34
+ 'component': 'grpc',
35
+ 'grpc.method.kind': method.kind,
36
+ 'grpc.method.path': method.path,
37
+ 'grpc.method.name': method.name,
38
+ 'grpc.method.service': method.service,
39
+ 'grpc.method.package': method.package
40
+ },
41
+ metrics: {
42
+ 'grpc.status.code': 0
43
+ }
48
44
  })
49
45
 
50
- this.addSub('apm:grpc:server:request:update', ({ code }) => {
51
- const store = storage.getStore()
46
+ addMetadataTags(span, metadata, metadataFilter, 'request')
47
+ }
48
+
49
+ error (error) {
50
+ const span = this.activeSpan
52
51
 
53
- if (!store || !store.span) return
52
+ if (!span) return
54
53
 
55
- this.addCode(store.span, code)
56
- })
54
+ this.addCode(span, error.code)
55
+ this.addError(error)
56
+ }
57
57
 
58
- this.addSub('apm:grpc:server:request:finish', ({ code, trailer } = {}) => {
59
- const store = storage.getStore()
58
+ finish ({ code, trailer } = {}) {
59
+ const span = this.activeSpan
60
60
 
61
- if (!store || !store.span) return
61
+ if (!span) return
62
62
 
63
- const span = store.span
64
- const metadataFilter = this.config.metadataFilter
63
+ const metadataFilter = this.config.metadataFilter
65
64
 
66
- this.addCode(span, code)
65
+ this.addCode(span, code)
67
66
 
68
- if (trailer && metadataFilter) {
69
- addMetadataTags(span, trailer, metadataFilter, 'response')
70
- }
67
+ if (trailer && metadataFilter) {
68
+ addMetadataTags(span, trailer, metadataFilter, 'response')
69
+ }
71
70
 
72
- store.span.finish()
73
- })
71
+ span.finish()
74
72
  }
75
73
 
76
74
  configure (config) {
@@ -4,13 +4,16 @@ const pick = require('lodash.pick')
4
4
  const log = require('../../dd-trace/src/log')
5
5
 
6
6
  module.exports = {
7
- addMethodTags (span, path, kind) {
8
- if (typeof path !== 'string') return
7
+ getMethodMetadata (path, kind) {
8
+ const tags = {
9
+ path,
10
+ kind,
11
+ name: '',
12
+ service: '',
13
+ package: ''
14
+ }
9
15
 
10
- span.addTags({
11
- 'grpc.method.path': path,
12
- 'grpc.method.kind': kind
13
- })
16
+ if (typeof path !== 'string') return tags
14
17
 
15
18
  const methodParts = path.split('/')
16
19
 
@@ -20,16 +23,14 @@ module.exports = {
20
23
  const service = serviceParts.pop()
21
24
  const pkg = serviceParts.join('.')
22
25
 
23
- span.addTags({
24
- 'grpc.method.name': name,
25
- 'grpc.method.service': service,
26
- 'grpc.method.package': pkg
27
- })
26
+ tags.name = name
27
+ tags.service = service
28
+ tags.package = pkg
28
29
  } else {
29
- span.addTags({
30
- 'grpc.method.name': methodParts[methodParts.length - 1]
31
- })
30
+ tags.name = methodParts[methodParts.length - 1]
32
31
  }
32
+
33
+ return tags
33
34
  },
34
35
 
35
36
  addMetadataTags (span, metadata, filter, type) {
@@ -1,31 +1,16 @@
1
1
  'use strict'
2
2
 
3
- const Plugin = require('../../dd-trace/src/plugins/plugin')
4
3
  const HttpServerPlugin = require('./server')
5
4
  const HttpClientPlugin = require('./client')
5
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
6
6
 
7
- class HttpPlugin extends Plugin {
8
- static get name () {
9
- return 'http'
10
- }
11
- constructor (...args) {
12
- super(...args)
13
- this.server = new HttpServerPlugin(...args)
14
- this.client = new HttpClientPlugin(...args)
15
- }
16
- configure (config) {
17
- const clientConfig = config.client === false ? false : {
18
- ...config,
19
- ...config.client
7
+ class HttpPlugin extends CompositePlugin {
8
+ static get name () { return 'http' }
9
+ static get plugins () {
10
+ return {
11
+ server: HttpServerPlugin,
12
+ client: HttpClientPlugin
20
13
  }
21
-
22
- const serverConfig = config.server === false ? false : {
23
- ...config,
24
- ...config.server
25
- }
26
-
27
- this.server.configure(serverConfig)
28
- this.client.configure(clientConfig)
29
14
  }
30
15
  }
31
16
 
@@ -1,34 +1,16 @@
1
1
  'use strict'
2
2
 
3
- const Plugin = require('../../dd-trace/src/plugins/plugin')
4
3
  const Http2ServerPlugin = require('./server')
5
4
  const Http2ClientPlugin = require('./client')
6
-
7
- class Http2Plugin extends Plugin {
8
- static get name () {
9
- return 'http2'
10
- }
11
-
12
- constructor (...args) {
13
- super(...args)
14
-
15
- this.server = new Http2ServerPlugin(...args)
16
- this.client = new Http2ClientPlugin(...args)
17
- }
18
-
19
- configure (config) {
20
- const clientConfig = config.client === false ? false : {
21
- ...config,
22
- ...config.client
23
- }
24
-
25
- const serverConfig = config.server === false ? false : {
26
- ...config,
27
- ...config.server
5
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
6
+
7
+ class Http2Plugin extends CompositePlugin {
8
+ static get name () { return 'http2' }
9
+ static get plugins () {
10
+ return {
11
+ server: Http2ServerPlugin,
12
+ client: Http2ClientPlugin
28
13
  }
29
-
30
- this.server.configure(serverConfig)
31
- this.client.configure(clientConfig)
32
14
  }
33
15
  }
34
16
 
@@ -237,6 +237,9 @@ class JestPlugin extends Plugin {
237
237
  testSuiteSpan.setTag('error', new Error(errorMessage))
238
238
  }
239
239
  testSuiteSpan.finish()
240
+ // Suites potentially run in a different process than the session,
241
+ // so calling finishAllTraceSpans on the session span is not enough
242
+ finishAllTraceSpans(testSuiteSpan)
240
243
  })
241
244
 
242
245
  this.addSub('ci:jest:test-suite:code-coverage', (coverageFiles) => {
@@ -0,0 +1,42 @@
1
+ 'use strict'
2
+
3
+ const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
4
+
5
+ class KafkajsConsumerPlugin extends ConsumerPlugin {
6
+ static get name () { return 'kafkajs' }
7
+ static get operation () { return 'consume' }
8
+
9
+ start ({ topic, partition, message }) {
10
+ const childOf = extract(this.tracer, message.headers)
11
+
12
+ this.startSpan('kafka.consume', {
13
+ childOf,
14
+ service: this.config.service || `${this.tracer._service}-kafka`,
15
+ resource: topic,
16
+ kind: 'consumer',
17
+ type: 'worker',
18
+ meta: {
19
+ 'component': 'kafkajs',
20
+ 'kafka.topic': topic,
21
+ 'kafka.message.offset': message.offset
22
+ },
23
+ metrics: {
24
+ 'kafka.partition': partition
25
+ }
26
+ })
27
+ }
28
+ }
29
+
30
+ function extract (tracer, bufferMap) {
31
+ if (!bufferMap) return null
32
+
33
+ const textMap = {}
34
+
35
+ for (const key of Object.keys(bufferMap)) {
36
+ textMap[key] = bufferMap[key].toString()
37
+ }
38
+
39
+ return tracer.extract('text_map', textMap)
40
+ }
41
+
42
+ module.exports = KafkajsConsumerPlugin