dd-trace 2.0.0-appsec-beta.3 → 2.0.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 (91) hide show
  1. package/MIGRATING.md +65 -0
  2. package/NOTICE +4 -0
  3. package/ci/cypress/plugin.js +3 -0
  4. package/ci/cypress/support.js +1 -0
  5. package/ci/init.js +13 -0
  6. package/ci/jest/env.js +14 -0
  7. package/index.d.ts +35 -48
  8. package/package.json +7 -4
  9. package/packages/datadog-instrumentations/index.js +10 -0
  10. package/packages/datadog-instrumentations/src/bluebird.js +26 -0
  11. package/packages/datadog-instrumentations/src/dns.js +94 -0
  12. package/packages/datadog-instrumentations/src/helpers/instrument.js +120 -0
  13. package/packages/datadog-instrumentations/src/helpers/promise.js +29 -0
  14. package/packages/datadog-instrumentations/src/memcached.js +53 -0
  15. package/packages/datadog-instrumentations/src/mysql.js +67 -0
  16. package/packages/datadog-instrumentations/src/promise-js.js +15 -0
  17. package/packages/datadog-instrumentations/src/promise.js +14 -0
  18. package/packages/datadog-instrumentations/src/q.js +13 -0
  19. package/packages/datadog-instrumentations/src/when.js +14 -0
  20. package/packages/datadog-plugin-cucumber/src/index.js +4 -4
  21. package/packages/datadog-plugin-cypress/src/plugin.js +12 -2
  22. package/packages/datadog-plugin-cypress/src/support.js +21 -6
  23. package/packages/datadog-plugin-dns/src/index.js +65 -178
  24. package/packages/datadog-plugin-fs/src/index.js +7 -3
  25. package/packages/datadog-plugin-http/src/client.js +9 -24
  26. package/packages/datadog-plugin-http/src/server.js +5 -0
  27. package/packages/datadog-plugin-http2/src/client.js +1 -24
  28. package/packages/datadog-plugin-http2/src/server.js +2 -2
  29. package/packages/datadog-plugin-jest/src/jest-environment.js +4 -4
  30. package/packages/datadog-plugin-jest/src/jest-jasmine2.js +2 -2
  31. package/packages/datadog-plugin-knex/src/index.js +3 -3
  32. package/packages/datadog-plugin-memcached/src/index.js +41 -63
  33. package/packages/datadog-plugin-mocha/src/index.js +3 -2
  34. package/packages/datadog-plugin-moleculer/src/client.js +60 -0
  35. package/packages/datadog-plugin-moleculer/src/index.js +8 -0
  36. package/packages/datadog-plugin-moleculer/src/server.js +61 -0
  37. package/packages/datadog-plugin-moleculer/src/util.js +21 -0
  38. package/packages/datadog-plugin-mongoose/src/index.js +2 -2
  39. package/packages/datadog-plugin-mysql/src/index.js +37 -89
  40. package/packages/datadog-plugin-net/src/index.js +5 -0
  41. package/packages/datadog-plugin-pino/src/index.js +25 -1
  42. package/packages/datadog-plugin-redis/src/index.js +31 -1
  43. package/packages/datadog-plugin-router/src/index.js +28 -3
  44. package/packages/dd-trace/lib/version.js +1 -1
  45. package/packages/dd-trace/src/appsec/addresses.js +11 -4
  46. package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +5 -8
  47. package/packages/dd-trace/src/{gateway → appsec/gateway}/als.js +1 -0
  48. package/packages/dd-trace/src/appsec/gateway/channels.js +11 -0
  49. package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/engine.js +20 -30
  50. package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/index.js +0 -0
  51. package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/runner.js +2 -0
  52. package/packages/dd-trace/src/appsec/index.js +54 -38
  53. package/packages/dd-trace/src/appsec/recommended.json +1 -1
  54. package/packages/dd-trace/src/appsec/reporter.js +27 -10
  55. package/packages/dd-trace/src/config.js +31 -27
  56. package/packages/dd-trace/src/constants.js +6 -3
  57. package/packages/dd-trace/src/exporters/agent/request.js +8 -0
  58. package/packages/dd-trace/src/format.js +26 -39
  59. package/packages/dd-trace/src/instrumenter.js +6 -1
  60. package/packages/dd-trace/src/log.js +6 -15
  61. package/packages/dd-trace/src/noop/span_context.js +0 -1
  62. package/packages/dd-trace/src/noop/tracer.js +0 -6
  63. package/packages/dd-trace/src/opentracing/propagation/text_map.js +79 -46
  64. package/packages/dd-trace/src/opentracing/span.js +2 -7
  65. package/packages/dd-trace/src/opentracing/span_context.js +2 -4
  66. package/packages/dd-trace/src/opentracing/tracer.js +5 -23
  67. package/packages/dd-trace/src/plugin_manager.js +65 -0
  68. package/packages/dd-trace/src/plugins/index.js +1 -5
  69. package/packages/dd-trace/src/plugins/plugin.js +63 -0
  70. package/packages/dd-trace/src/plugins/util/ci.js +13 -4
  71. package/packages/dd-trace/src/plugins/util/redis.js +0 -2
  72. package/packages/dd-trace/src/plugins/util/test.js +9 -4
  73. package/packages/dd-trace/src/plugins/util/user-provided-git.js +17 -2
  74. package/packages/dd-trace/src/plugins/util/web.js +6 -16
  75. package/packages/dd-trace/src/priority_sampler.js +71 -19
  76. package/packages/dd-trace/src/profiling/exporters/agent.js +35 -34
  77. package/packages/dd-trace/src/proxy.js +39 -35
  78. package/packages/dd-trace/src/ritm.js +40 -16
  79. package/packages/dd-trace/src/span_processor.js +0 -7
  80. package/packages/dd-trace/src/tracer.js +5 -6
  81. package/scripts/install_plugin_modules.js +30 -1
  82. package/packages/datadog-plugin-bluebird/src/index.js +0 -69
  83. package/packages/datadog-plugin-promise/src/index.js +0 -17
  84. package/packages/datadog-plugin-promise-js/src/index.js +0 -20
  85. package/packages/datadog-plugin-q/src/index.js +0 -16
  86. package/packages/datadog-plugin-when/src/index.js +0 -17
  87. package/packages/dd-trace/src/gateway/channels.js +0 -8
  88. package/packages/dd-trace/src/gateway/dc_block.js +0 -68
  89. package/packages/dd-trace/src/plugins/util/ci-app-spec.json +0 -36
  90. package/packages/dd-trace/src/plugins/util/promise.js +0 -31
  91. package/packages/dd-trace/src/scope/noop/scope_manager.js +0 -28
@@ -3,14 +3,15 @@
3
3
  const pick = require('lodash.pick')
4
4
  const id = require('../../id')
5
5
  const DatadogSpanContext = require('../span_context')
6
- const NoopSpanContext = require('../../noop/span_context')
7
6
  const log = require('../../log')
8
7
 
8
+ const { AUTO_KEEP, AUTO_REJECT, USER_KEEP } = require('../../../../../ext/priority')
9
+
9
10
  const traceKey = 'x-datadog-trace-id'
10
11
  const spanKey = 'x-datadog-parent-id'
11
12
  const originKey = 'x-datadog-origin'
12
13
  const samplingKey = 'x-datadog-sampling-priority'
13
- const sampleKey = 'x-datadog-sampled'
14
+ const tagsKey = 'x-datadog-tags'
14
15
  const baggagePrefix = 'ot-baggage-'
15
16
  const b3TraceKey = 'x-b3-traceid'
16
17
  const b3TraceExpr = /^([0-9a-f]{16}){1,2}$/i
@@ -35,12 +36,12 @@ class TextMapPropagator {
35
36
  inject (spanContext, carrier) {
36
37
  carrier[traceKey] = spanContext.toTraceId()
37
38
  carrier[spanKey] = spanContext.toSpanId()
38
- carrier[sampleKey] = spanContext._traceFlags.sampled ? '1' : '0'
39
39
 
40
40
  this._injectOrigin(spanContext, carrier)
41
41
  this._injectSamplingPriority(spanContext, carrier)
42
42
  this._injectBaggageItems(spanContext, carrier)
43
43
  this._injectB3(spanContext, carrier)
44
+ this._injectTags(spanContext, carrier)
44
45
 
45
46
  log.debug(() => `Inject into carrier: ${JSON.stringify(pick(carrier, logKeys))}.`)
46
47
  }
@@ -50,10 +51,6 @@ class TextMapPropagator {
50
51
 
51
52
  if (!spanContext) return spanContext
52
53
 
53
- this._extractOrigin(carrier, spanContext)
54
- this._extractBaggageItems(carrier, spanContext)
55
- this._extractSamplingPriority(carrier, spanContext)
56
-
57
54
  log.debug(() => `Extract from carrier: ${JSON.stringify(pick(carrier, logKeys))}.`)
58
55
 
59
56
  return spanContext
@@ -81,14 +78,33 @@ class TextMapPropagator {
81
78
  })
82
79
  }
83
80
 
81
+ _injectTags (spanContext, carrier) {
82
+ const trace = spanContext._trace
83
+ const tags = []
84
+
85
+ for (const key in trace.tags) {
86
+ if (!key.startsWith('_dd.p.')) continue
87
+
88
+ tags.push(`${key}=${trace.tags[key]}`)
89
+ }
90
+
91
+ const header = tags.join(',')
92
+
93
+ if (header.length <= 512) {
94
+ carrier[tagsKey] = header
95
+ } else {
96
+ trace.tags['_dd.propagation_error:max_size'] = 1
97
+ }
98
+ }
99
+
84
100
  _injectB3 (spanContext, carrier) {
85
101
  if (!this._config.experimental.b3) return
86
102
 
87
103
  carrier[b3TraceKey] = spanContext._traceId.toString('hex')
88
104
  carrier[b3SpanKey] = spanContext._spanId.toString('hex')
89
- carrier[b3SampledKey] = spanContext._traceFlags.sampled ? '1' : '0'
105
+ carrier[b3SampledKey] = spanContext._sampling.priority >= AUTO_KEEP ? '1' : '0'
90
106
 
91
- if (spanContext._traceFlags.debug) {
107
+ if (spanContext._sampling.priority > AUTO_KEEP) {
92
108
  carrier[b3FlagsKey] = '1'
93
109
  }
94
110
 
@@ -98,25 +114,20 @@ class TextMapPropagator {
98
114
  }
99
115
 
100
116
  _extractSpanContext (carrier) {
101
- const context = this._extractContext(carrier)
102
-
103
- if (!context) return null
104
-
105
- if (context.traceFlags.sampled !== false) {
106
- return new DatadogSpanContext(context)
107
- } else {
108
- return new NoopSpanContext(context)
109
- }
110
- }
111
-
112
- _extractContext (carrier) {
113
117
  return this._extractDatadogContext(carrier) || this._extractB3Context(carrier) || this._extractSqsdContext(carrier)
114
118
  }
115
119
 
116
120
  _extractDatadogContext (carrier) {
117
- const sampled = this._isSampled(carrier[sampleKey])
121
+ const spanContext = this._extractGenericContext(carrier, traceKey, spanKey, 10)
122
+
123
+ if (spanContext) {
124
+ this._extractOrigin(carrier, spanContext)
125
+ this._extractBaggageItems(carrier, spanContext)
126
+ this._extractSamplingPriority(carrier, spanContext)
127
+ this._extractTags(carrier, spanContext)
128
+ }
118
129
 
119
- return this._extractGenericContext(carrier, traceKey, spanKey, { sampled }, 10)
130
+ return spanContext
120
131
  }
121
132
 
122
133
  _extractB3Context (carrier) {
@@ -124,9 +135,23 @@ class TextMapPropagator {
124
135
 
125
136
  const b3 = this._extractB3Headers(carrier)
126
137
  const debug = b3[b3FlagsKey] === '1'
127
- const sampled = this._isSampled(b3[b3SampledKey], debug)
138
+ const priority = this._getPriority(b3[b3SampledKey], debug)
139
+ const spanContext = this._extractGenericContext(b3, b3TraceKey, b3SpanKey)
140
+
141
+ if (priority !== undefined) {
142
+ if (!spanContext) {
143
+ // B3 can force a sampling decision without providing IDs
144
+ return new DatadogSpanContext({
145
+ traceId: id(),
146
+ spanId: null,
147
+ sampling: { priority }
148
+ })
149
+ }
128
150
 
129
- return this._extractGenericContext(b3, b3TraceKey, b3SpanKey, { sampled, debug })
151
+ spanContext._sampling.priority = priority
152
+ }
153
+
154
+ return spanContext
130
155
  }
131
156
 
132
157
  _extractSqsdContext (carrier) {
@@ -143,19 +168,12 @@ class TextMapPropagator {
143
168
  return this._extractDatadogContext(parsed)
144
169
  }
145
170
 
146
- _extractGenericContext (carrier, traceKey, spanKey, traceFlags, radix) {
171
+ _extractGenericContext (carrier, traceKey, spanKey, radix) {
147
172
  if (carrier[traceKey] && carrier[spanKey]) {
148
- return {
173
+ return new DatadogSpanContext({
149
174
  traceId: id(carrier[traceKey], radix),
150
- spanId: id(carrier[spanKey], radix),
151
- traceFlags
152
- }
153
- } else if (typeof traceFlags.sampled === 'boolean') {
154
- return {
155
- traceId: id(),
156
- spanId: null,
157
- traceFlags
158
- }
175
+ spanId: id(carrier[spanKey], radix)
176
+ })
159
177
  }
160
178
 
161
179
  return null
@@ -203,12 +221,15 @@ class TextMapPropagator {
203
221
  } else {
204
222
  const b3 = {
205
223
  [b3TraceKey]: parts[0],
206
- [b3SpanKey]: parts[1],
207
- [b3SampledKey]: parts[2] !== '0' ? '1' : '0'
224
+ [b3SpanKey]: parts[1]
208
225
  }
209
226
 
210
- if (parts[2] === 'd') {
211
- b3[b3FlagsKey] = '1'
227
+ if (parts[2]) {
228
+ b3[b3SampledKey] = parts[2] !== '0' ? '1' : '0'
229
+
230
+ if (parts[2] === 'd') {
231
+ b3[b3FlagsKey] = '1'
232
+ }
212
233
  }
213
234
 
214
235
  return b3
@@ -241,14 +262,26 @@ class TextMapPropagator {
241
262
  }
242
263
  }
243
264
 
244
- _isSampled (sampled, debug) {
245
- if (debug || sampled === '1') {
246
- return true
247
- } else if (sampled === '0') {
248
- return false
265
+ _extractTags (carrier, spanContext) {
266
+ if (!carrier[tagsKey]) return
267
+
268
+ const pairs = carrier[tagsKey].split(',')
269
+
270
+ for (const pair of pairs) {
271
+ const [key, value] = pair.split('=')
272
+
273
+ spanContext._trace.tags[key] = value
249
274
  }
275
+ }
250
276
 
251
- return null
277
+ _getPriority (sampled, debug) {
278
+ if (debug) {
279
+ return USER_KEEP
280
+ } else if (sampled === '1') {
281
+ return AUTO_KEEP
282
+ } else if (sampled === '0') {
283
+ return AUTO_REJECT
284
+ }
252
285
  }
253
286
  }
254
287
 
@@ -4,29 +4,24 @@ const opentracing = require('opentracing')
4
4
  const now = require('performance-now')
5
5
  const Span = opentracing.Span
6
6
  const SpanContext = require('./span_context')
7
- const constants = require('../constants')
8
7
  const id = require('../id')
9
8
  const tagger = require('../tagger')
10
9
  const log = require('../log')
11
10
  const { storage } = require('../../../datadog-core')
12
11
 
13
- const SAMPLE_RATE_METRIC_KEY = constants.SAMPLE_RATE_METRIC_KEY
14
12
  const { DD_TRACE_EXPERIMENTAL_STATE_TRACKING } = process.env
15
13
 
16
14
  class DatadogSpan extends Span {
17
- constructor (tracer, processor, sampler, prioritySampler, fields, debug) {
15
+ constructor (tracer, processor, prioritySampler, fields, debug) {
18
16
  super()
19
17
 
20
18
  const operationName = fields.operationName
21
19
  const parent = fields.parent || null
22
- const tags = Object.assign({
23
- [SAMPLE_RATE_METRIC_KEY]: sampler.rate()
24
- }, fields.tags)
20
+ const tags = Object.assign({}, fields.tags)
25
21
  const hostname = fields.hostname
26
22
 
27
23
  this._parentTracer = tracer
28
24
  this._debug = debug
29
- this._sampler = sampler
30
25
  this._processor = processor
31
26
  this._prioritySampler = prioritySampler
32
27
  this._store = storage.getStore()
@@ -16,13 +16,11 @@ class DatadogSpanContext extends SpanContext {
16
16
  this._tags = props.tags || {}
17
17
  this._sampling = props.sampling || {}
18
18
  this._baggageItems = props.baggageItems || {}
19
- this._traceFlags = props.traceFlags || {}
20
- this._traceFlags.sampled = this._traceFlags.sampled !== false
21
- this._traceFlags.debug = this._traceFlags.debug === true
22
19
  this._noop = props.noop || null
23
20
  this._trace = props.trace || {
24
21
  started: [],
25
- finished: []
22
+ finished: [],
23
+ tags: {}
26
24
  }
27
25
  }
28
26
 
@@ -7,21 +7,17 @@ const Reference = opentracing.Reference
7
7
  const Span = require('./span')
8
8
  const SpanContext = require('./span_context')
9
9
  const SpanProcessor = require('../span_processor')
10
- const Sampler = require('../sampler')
11
10
  const PrioritySampler = require('../priority_sampler')
12
11
  const TextMapPropagator = require('./propagation/text_map')
13
12
  const HttpPropagator = require('./propagation/http')
14
13
  const BinaryPropagator = require('./propagation/binary')
15
14
  const LogPropagator = require('./propagation/log')
16
- const NoopSpan = require('../noop/span')
17
15
  const formats = require('../../../../ext/formats')
18
16
 
19
17
  const log = require('../log')
20
- const constants = require('../constants')
21
18
  const metrics = require('../metrics')
22
19
  const getExporter = require('../exporter')
23
20
 
24
- const REFERENCE_NOOP = constants.REFERENCE_NOOP
25
21
  const REFERENCE_CHILD_OF = opentracing.REFERENCE_CHILD_OF
26
22
  const REFERENCE_FOLLOWS_FROM = opentracing.REFERENCE_FOLLOWS_FROM
27
23
 
@@ -37,12 +33,10 @@ class DatadogTracer extends Tracer {
37
33
  this._tags = config.tags
38
34
  this._logInjection = config.logInjection
39
35
  this._debug = config.debug
40
- this._internalErrors = config.experimental.internalErrors
41
36
  this._prioritySampler = new PrioritySampler(config.env, config.experimental.sampler)
42
37
  this._exporter = new Exporter(config, this._prioritySampler)
43
38
  this._processor = new SpanProcessor(this._exporter, this._prioritySampler)
44
39
  this._url = this._exporter._url
45
- this._sampler = new Sampler(config.sampleRate)
46
40
  this._enableGetRumData = config.experimental.enableGetRumData
47
41
  this._propagators = {
48
42
  [formats.TEXT_MAP]: new TextMapPropagator(config),
@@ -57,20 +51,16 @@ class DatadogTracer extends Tracer {
57
51
 
58
52
  _startSpan (name, fields) {
59
53
  const reference = getParent(fields.references)
60
- const type = reference && reference.type()
61
54
  const parent = reference && reference.referencedContext()
62
- return this._startSpanInternal(name, fields, parent, type)
55
+ return this._startSpanInternal(name, fields, parent)
63
56
  }
64
57
 
65
- _startSpanInternal (name, fields = {}, parent, type) {
66
- if (parent && parent._noop) return parent._noop
67
- if (!isSampled(this._sampler, parent, type)) return new NoopSpan(this, parent)
68
-
58
+ _startSpanInternal (name, fields = {}, parent) {
69
59
  const tags = {
70
60
  'service.name': this._service
71
61
  }
72
62
 
73
- const span = new Span(this, this._processor, this._sampler, this._prioritySampler, {
63
+ const span = new Span(this, this._processor, this._prioritySampler, {
74
64
  operationName: fields.operationName || name,
75
65
  parent,
76
66
  tags,
@@ -121,12 +111,12 @@ function getParent (references = []) {
121
111
  const spanContext = ref.referencedContext()
122
112
  const type = ref.type()
123
113
 
124
- if (type !== REFERENCE_NOOP && spanContext && !(spanContext instanceof SpanContext)) {
114
+ if (spanContext && !(spanContext instanceof SpanContext)) {
125
115
  log.error(() => `Expected ${spanContext} to be an instance of SpanContext`)
126
116
  continue
127
117
  }
128
118
 
129
- if (type === REFERENCE_CHILD_OF || type === REFERENCE_NOOP) {
119
+ if (type === REFERENCE_CHILD_OF) {
130
120
  parent = ref
131
121
  break
132
122
  } else if (type === REFERENCE_FOLLOWS_FROM) {
@@ -139,12 +129,4 @@ function getParent (references = []) {
139
129
  return parent
140
130
  }
141
131
 
142
- function isSampled (sampler, parent, type) {
143
- if (type === REFERENCE_NOOP) return false
144
- if (parent && !parent._traceFlags.sampled) return false
145
- if (!parent && !sampler.isSampled()) return false
146
-
147
- return true
148
- }
149
-
150
132
  module.exports = DatadogTracer
@@ -0,0 +1,65 @@
1
+ 'use strict'
2
+
3
+ const { isTrue } = require('./util')
4
+ const plugins = require('./plugins')
5
+
6
+ // instrument everything that needs Plugin System V2 instrumentation
7
+ require('../../datadog-instrumentations')
8
+
9
+ // TODO this is shared w/ instrumenter. DRY up.
10
+ function getConfig (name, config = {}) {
11
+ const enabled = process.env[`DD_TRACE_${name.toUpperCase()}_ENABLED`.replace(/[^a-z0-9_]/ig, '_')]
12
+ if (enabled !== undefined) {
13
+ config.enabled = isTrue(enabled)
14
+ }
15
+
16
+ // TODO is this the best/correct place for this default?
17
+ if (!('enabled' in config)) {
18
+ config.enabled = true
19
+ }
20
+
21
+ return config
22
+ }
23
+
24
+ // TODO actually ... should we be looking at envrionment variables this deep down in the code?
25
+
26
+ // TODO this must always be a singleton.
27
+ module.exports = class PluginManager {
28
+ constructor (tracer) {
29
+ this._pluginsByName = {}
30
+ for (const PluginClass of Object.values(plugins)) {
31
+ if (typeof PluginClass !== 'function') continue
32
+ this._pluginsByName[PluginClass.name] = new PluginClass(tracer)
33
+ }
34
+ }
35
+
36
+ // like instrumenter.use()
37
+ configurePlugin (name, pluginConfig) {
38
+ if (!(name in this._pluginsByName)) return
39
+ if (typeof pluginConfig === 'boolean') {
40
+ pluginConfig = { enabled: pluginConfig }
41
+ }
42
+
43
+ this._pluginsByName[name].configure(getConfig(name, pluginConfig))
44
+ }
45
+
46
+ // like instrumenter.enable()
47
+ configure (config) {
48
+ const serviceMapping = config.serviceMapping
49
+
50
+ if (config.plugins !== false) {
51
+ for (const name in this._pluginsByName) {
52
+ const pluginConfig = {}
53
+ if (serviceMapping && serviceMapping[name]) {
54
+ pluginConfig.service = serviceMapping[name]
55
+ }
56
+ this.configurePlugin(name, pluginConfig)
57
+ }
58
+ }
59
+ }
60
+
61
+ // This is basically just for testing. like intrumenter.disable()
62
+ destroy () {
63
+ for (const name in this._pluginsByName) this._pluginsByName[name].configure({ enabled: false })
64
+ }
65
+ }
@@ -4,7 +4,6 @@ module.exports = {
4
4
  'amqp10': require('../../../datadog-plugin-amqp10/src'),
5
5
  'amqplib': require('../../../datadog-plugin-amqplib/src'),
6
6
  'aws-sdk': require('../../../datadog-plugin-aws-sdk/src'),
7
- 'bluebird': require('../../../datadog-plugin-bluebird/src'),
8
7
  'bunyan': require('../../../datadog-plugin-bunyan/src'),
9
8
  'cassandra-driver': require('../../../datadog-plugin-cassandra-driver/src'),
10
9
  'connect': require('../../../datadog-plugin-connect/src'),
@@ -32,6 +31,7 @@ module.exports = {
32
31
  'memcached': require('../../../datadog-plugin-memcached/src'),
33
32
  'microgateway-core': require('../../../datadog-plugin-microgateway-core/src'),
34
33
  'mocha': require('../../../datadog-plugin-mocha/src'),
34
+ 'moleculer': require('../../../datadog-plugin-moleculer/src'),
35
35
  'mongodb-core': require('../../../datadog-plugin-mongodb-core/src'),
36
36
  'mongoose': require('../../../datadog-plugin-mongoose/src'),
37
37
  'mysql': require('../../../datadog-plugin-mysql/src'),
@@ -42,15 +42,11 @@ module.exports = {
42
42
  'paperplane': require('../../../datadog-plugin-paperplane/src'),
43
43
  'pg': require('../../../datadog-plugin-pg/src'),
44
44
  'pino': require('../../../datadog-plugin-pino/src'),
45
- 'promise': require('../../../datadog-plugin-promise/src'),
46
- 'promise-js': require('../../../datadog-plugin-promise-js/src'),
47
- 'q': require('../../../datadog-plugin-q/src'),
48
45
  'redis': require('../../../datadog-plugin-redis/src'),
49
46
  'restify': require('../../../datadog-plugin-restify/src'),
50
47
  'rhea': require('../../../datadog-plugin-rhea/src'),
51
48
  'router': require('../../../datadog-plugin-router/src'),
52
49
  'sharedb': require('../../../datadog-plugin-sharedb/src'),
53
50
  'tedious': require('../../../datadog-plugin-tedious/src'),
54
- 'when': require('../../../datadog-plugin-when/src'),
55
51
  'winston': require('../../../datadog-plugin-winston/src')
56
52
  }
@@ -0,0 +1,63 @@
1
+ 'use strict'
2
+
3
+ const dc = require('diagnostics_channel')
4
+ const { storage } = require('../../../datadog-core')
5
+
6
+ class Subscription {
7
+ constructor (event, handler) {
8
+ this._channel = dc.channel(event)
9
+ this._handler = (message, name) => {
10
+ const store = storage.getStore()
11
+
12
+ if (!store || !store.noop) {
13
+ handler(message, name)
14
+ }
15
+ }
16
+ }
17
+
18
+ enable () {
19
+ this._channel.subscribe(this._handler)
20
+ }
21
+
22
+ disable () {
23
+ this._channel.unsubscribe(this._handler)
24
+ }
25
+ }
26
+
27
+ module.exports = class Plugin {
28
+ constructor (tracer) {
29
+ this._subscriptions = []
30
+ this._enabled = false
31
+ this._storeStack = []
32
+ this._tracer = tracer
33
+ }
34
+
35
+ get tracer () {
36
+ return this._tracer._tracer
37
+ }
38
+
39
+ enter (span, store) {
40
+ store = store || storage.getStore()
41
+ this._storeStack.push(store)
42
+ storage.enterWith({ ...store, span })
43
+ }
44
+
45
+ exit () {
46
+ storage.enterWith(this._storeStack.pop())
47
+ }
48
+
49
+ addSub (channelName, handler) {
50
+ this._subscriptions.push(new Subscription(channelName, handler))
51
+ }
52
+
53
+ configure (config) {
54
+ this.config = config
55
+ if (config.enabled && !this._enabled) {
56
+ this._enabled = true
57
+ this._subscriptions.forEach(sub => sub.enable())
58
+ } else if (!config.enabled && this._enabled) {
59
+ this._enabled = false
60
+ this._subscriptions.forEach(sub => sub.disable())
61
+ }
62
+ }
63
+ }
@@ -88,6 +88,7 @@ function resolveTilde (filePath) {
88
88
  }
89
89
 
90
90
  module.exports = {
91
+ normalizeRef,
91
92
  getCIMetadata () {
92
93
  const { env } = process
93
94
 
@@ -215,11 +216,19 @@ module.exports = {
215
216
  GITHUB_HEAD_REF,
216
217
  GITHUB_REF,
217
218
  GITHUB_SHA,
218
- GITHUB_REPOSITORY
219
+ GITHUB_REPOSITORY,
220
+ GITHUB_SERVER_URL,
221
+ GITHUB_RUN_ATTEMPT
219
222
  } = env
220
223
 
221
- const repositoryURL = `https://github.com/${GITHUB_REPOSITORY}.git`
222
- const pipelineURL = `https://github.com/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}/checks`
224
+ const repositoryURL = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git`
225
+ let pipelineURL = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}`
226
+
227
+ if (GITHUB_RUN_ATTEMPT) {
228
+ pipelineURL = `${pipelineURL}/attempts/${GITHUB_RUN_ATTEMPT}`
229
+ }
230
+
231
+ const jobUrl = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}/checks`
223
232
 
224
233
  const ref = GITHUB_HEAD_REF || GITHUB_REF || ''
225
234
  const refKey = ref.includes('tags') ? GIT_TAG : GIT_BRANCH
@@ -232,7 +241,7 @@ module.exports = {
232
241
  [CI_PROVIDER_NAME]: 'github',
233
242
  [GIT_COMMIT_SHA]: GITHUB_SHA,
234
243
  [GIT_REPOSITORY_URL]: repositoryURL,
235
- [CI_JOB_URL]: pipelineURL,
244
+ [CI_JOB_URL]: jobUrl,
236
245
  [CI_WORKSPACE_PATH]: GITHUB_WORKSPACE,
237
246
  [refKey]: ref
238
247
  }
@@ -25,8 +25,6 @@ const redis = {
25
25
  'span.type': 'redis',
26
26
  'db.type': 'redis',
27
27
  'db.name': db || '0',
28
- 'out.host': '127.0.0.1',
29
- 'out.port': String(6379),
30
28
  'redis.raw_command': formatCommand(command, args)
31
29
  }
32
30
  })
@@ -24,6 +24,7 @@ const TEST_SUITE = 'test.suite'
24
24
  const TEST_STATUS = 'test.status'
25
25
  const TEST_PARAMETERS = 'test.parameters'
26
26
  const TEST_SKIP_REASON = 'test.skip_reason'
27
+ const TEST_IS_RUM_ACTIVE = 'test.is_rum_active'
27
28
 
28
29
  const ERROR_TYPE = 'error.type'
29
30
  const ERROR_MESSAGE = 'error.msg'
@@ -43,6 +44,7 @@ module.exports = {
43
44
  TEST_STATUS,
44
45
  TEST_PARAMETERS,
45
46
  TEST_SKIP_REASON,
47
+ TEST_IS_RUM_ACTIVE,
46
48
  ERROR_TYPE,
47
49
  ERROR_MESSAGE,
48
50
  ERROR_STACK,
@@ -54,7 +56,7 @@ module.exports = {
54
56
  getTestSuitePath
55
57
  }
56
58
 
57
- function getTestEnvironmentMetadata (testFramework) {
59
+ function getTestEnvironmentMetadata (testFramework, config) {
58
60
  // TODO: eventually these will come from the tracer (generally available)
59
61
  const ciMetadata = getCIMetadata()
60
62
  const {
@@ -83,13 +85,17 @@ function getTestEnvironmentMetadata (testFramework) {
83
85
 
84
86
  const runtimeAndOSMetadata = getRuntimeAndOSMetadata()
85
87
 
86
- return {
88
+ const metadata = {
87
89
  [TEST_FRAMEWORK]: testFramework,
88
90
  ...gitMetadata,
89
91
  ...ciMetadata,
90
92
  ...userProvidedGitMetadata,
91
93
  ...runtimeAndOSMetadata
92
94
  }
95
+ if (config && config.service) {
96
+ metadata['service.name'] = config.service
97
+ }
98
+ return metadata
93
99
  }
94
100
 
95
101
  function getTestParametersString (parametersByTestName, testName) {
@@ -118,8 +124,7 @@ function finishAllTraceSpans (span) {
118
124
  function getTestParentSpan (tracer) {
119
125
  return tracer.extract('text_map', {
120
126
  'x-datadog-trace-id': id().toString(10),
121
- 'x-datadog-parent-id': '0000000000000000',
122
- 'x-datadog-sampled': 1
127
+ 'x-datadog-parent-id': '0000000000000000'
123
128
  })
124
129
  }
125
130
  /**
@@ -12,6 +12,8 @@ const {
12
12
  GIT_COMMIT_AUTHOR_NAME
13
13
  } = require('./tags')
14
14
 
15
+ const { normalizeRef } = require('./ci')
16
+
15
17
  function removeEmptyValues (tags) {
16
18
  return Object.keys(tags).reduce((filteredTags, tag) => {
17
19
  if (!tags[tag]) {
@@ -39,11 +41,24 @@ function getUserProviderGitMetadata () {
39
41
  DD_GIT_COMMIT_AUTHOR_DATE
40
42
  } = process.env
41
43
 
44
+ let branch = normalizeRef(DD_GIT_BRANCH)
45
+ let tag = normalizeRef(DD_GIT_TAG)
46
+
47
+ if (DD_GIT_TAG) {
48
+ branch = undefined
49
+ }
50
+
51
+ // if DD_GIT_BRANCH is a tag, we associate its value to TAG instead of BRANCH
52
+ if ((DD_GIT_BRANCH || '').includes('origin/tags') || (DD_GIT_BRANCH || '').includes('refs/heads/tags')) {
53
+ branch = undefined
54
+ tag = normalizeRef(DD_GIT_BRANCH)
55
+ }
56
+
42
57
  return removeEmptyValues({
43
58
  [GIT_COMMIT_SHA]: DD_GIT_COMMIT_SHA,
44
- [GIT_BRANCH]: DD_GIT_BRANCH,
59
+ [GIT_BRANCH]: branch,
45
60
  [GIT_REPOSITORY_URL]: DD_GIT_REPOSITORY_URL,
46
- [GIT_TAG]: DD_GIT_TAG,
61
+ [GIT_TAG]: tag,
47
62
  [GIT_COMMIT_MESSAGE]: DD_GIT_COMMIT_MESSAGE,
48
63
  [GIT_COMMIT_COMMITTER_NAME]: DD_GIT_COMMIT_COMMITTER_NAME,
49
64
  [GIT_COMMIT_COMMITTER_DATE]: DD_GIT_COMMIT_COMMITTER_DATE,