dd-trace 2.12.2 → 2.15.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 (76) hide show
  1. package/LICENSE-3rdparty.csv +2 -0
  2. package/ext/tags.d.ts +2 -1
  3. package/ext/tags.js +2 -1
  4. package/index.d.ts +43 -20
  5. package/package.json +5 -3
  6. package/packages/datadog-core/src/storage/async_resource.js +19 -1
  7. package/packages/datadog-instrumentations/index.js +1 -52
  8. package/packages/datadog-instrumentations/src/crypto.js +30 -0
  9. package/packages/datadog-instrumentations/src/cucumber.js +15 -0
  10. package/packages/datadog-instrumentations/src/fs.js +11 -0
  11. package/packages/datadog-instrumentations/src/helpers/hooks.js +70 -0
  12. package/packages/datadog-instrumentations/src/helpers/instrument.js +5 -34
  13. package/packages/datadog-instrumentations/src/helpers/instrumentations.js +7 -0
  14. package/packages/datadog-instrumentations/src/helpers/register.js +59 -0
  15. package/packages/datadog-instrumentations/src/http/server.js +1 -1
  16. package/packages/datadog-instrumentations/src/jest.js +33 -11
  17. package/packages/datadog-instrumentations/src/net.js +13 -0
  18. package/packages/datadog-plugin-cucumber/src/index.js +4 -0
  19. package/packages/datadog-plugin-fs/src/index.js +72 -38
  20. package/packages/datadog-plugin-jest/src/index.js +25 -4
  21. package/packages/datadog-plugin-mocha/src/index.js +2 -2
  22. package/packages/datadog-plugin-mongodb-core/src/index.js +32 -8
  23. package/packages/datadog-plugin-oracledb/src/index.js +12 -4
  24. package/packages/dd-trace/index.js +1 -1
  25. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +3 -0
  26. package/packages/dd-trace/src/appsec/iast/analyzers/index.js +20 -0
  27. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +48 -0
  28. package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +24 -0
  29. package/packages/dd-trace/src/appsec/iast/iast-context.js +50 -0
  30. package/packages/dd-trace/src/appsec/iast/index.js +59 -0
  31. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +94 -0
  32. package/packages/dd-trace/src/appsec/iast/path-line.js +70 -0
  33. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +113 -0
  34. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +50 -0
  35. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +53 -8
  36. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +23 -24
  37. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +220 -0
  38. package/packages/dd-trace/src/config.js +89 -10
  39. package/packages/dd-trace/src/constants.js +9 -1
  40. package/packages/dd-trace/src/encode/0.4.js +51 -58
  41. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +13 -34
  42. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +84 -0
  43. package/packages/dd-trace/src/encode/span-stats.js +155 -0
  44. package/packages/dd-trace/src/exporters/agent/index.js +25 -7
  45. package/packages/dd-trace/src/exporters/agent/writer.js +7 -4
  46. package/packages/dd-trace/src/{profiling/exporters → exporters/common}/form-data.js +0 -0
  47. package/packages/dd-trace/src/exporters/common/request.js +25 -10
  48. package/packages/dd-trace/src/exporters/common/writer.js +9 -6
  49. package/packages/dd-trace/src/exporters/span-stats/index.js +20 -0
  50. package/packages/dd-trace/src/exporters/span-stats/writer.js +54 -0
  51. package/packages/dd-trace/src/format.js +2 -0
  52. package/packages/dd-trace/src/id.js +16 -13
  53. package/packages/dd-trace/src/iitm.js +11 -0
  54. package/packages/dd-trace/src/index.js +10 -0
  55. package/packages/dd-trace/src/noop/proxy.js +87 -0
  56. package/packages/dd-trace/src/opentracing/propagation/text_map.js +77 -6
  57. package/packages/dd-trace/src/opentracing/tracer.js +1 -1
  58. package/packages/dd-trace/src/plugin_manager.js +107 -65
  59. package/packages/dd-trace/src/plugins/index.js +58 -45
  60. package/packages/dd-trace/src/plugins/log_plugin.js +16 -9
  61. package/packages/dd-trace/src/plugins/util/ci.js +34 -9
  62. package/packages/dd-trace/src/plugins/util/git.js +52 -2
  63. package/packages/dd-trace/src/plugins/util/ip_blocklist.js +25 -0
  64. package/packages/dd-trace/src/plugins/util/tags.js +4 -1
  65. package/packages/dd-trace/src/plugins/util/web.js +99 -2
  66. package/packages/dd-trace/src/priority_sampler.js +36 -1
  67. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  68. package/packages/dd-trace/src/proxy.js +23 -89
  69. package/packages/dd-trace/src/ritm.js +10 -1
  70. package/packages/dd-trace/src/span_processor.js +7 -1
  71. package/packages/dd-trace/src/span_stats.js +210 -0
  72. package/packages/dd-trace/src/startup-log.js +8 -19
  73. package/packages/dd-trace/src/telemetry/dependencies.js +83 -0
  74. package/packages/dd-trace/src/{telemetry.js → telemetry/index.js} +11 -79
  75. package/packages/dd-trace/src/telemetry/send-data.js +35 -0
  76. package/scripts/install_plugin_modules.js +17 -26
@@ -11,6 +11,7 @@ const traceKey = 'x-datadog-trace-id'
11
11
  const spanKey = 'x-datadog-parent-id'
12
12
  const originKey = 'x-datadog-origin'
13
13
  const samplingKey = 'x-datadog-sampling-priority'
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
@@ -23,6 +24,8 @@ const b3HeaderKey = 'b3'
23
24
  const sqsdHeaderHey = 'x-aws-sqsd-attr-_datadog'
24
25
  const b3HeaderExpr = /^(([0-9a-f]{16}){1,2}-[0-9a-f]{16}(-[01d](-[0-9a-f]{16})?)?|[01d])$/i
25
26
  const baggageExpr = new RegExp(`^${baggagePrefix}(.+)$`)
27
+ const tagKeyExpr = /^_dd\.p\.[\x21-\x2b\x2d-\x7e]+$/ // ASCII minus spaces and commas
28
+ const tagValueExpr = /^[\x20-\x2b\x2d-\x7e]*$/ // ASCII minus commas
26
29
  const ddKeys = [traceKey, spanKey, samplingKey, originKey]
27
30
  const b3Keys = [b3TraceKey, b3SpanKey, b3ParentKey, b3SampledKey, b3FlagsKey, b3HeaderKey]
28
31
  const logKeys = ddKeys.concat(b3Keys)
@@ -43,6 +46,7 @@ class TextMapPropagator {
43
46
  this._injectBaggageItems(spanContext, carrier)
44
47
  this._injectB3(spanContext, carrier)
45
48
  this._injectTraceparent(spanContext, carrier)
49
+ this._injectTags(spanContext, carrier)
46
50
 
47
51
  log.debug(() => `Inject into carrier: ${JSON.stringify(pick(carrier, logKeys))}.`)
48
52
  }
@@ -79,11 +83,40 @@ class TextMapPropagator {
79
83
  })
80
84
  }
81
85
 
86
+ _injectTags (spanContext, carrier) {
87
+ const trace = spanContext._trace
88
+
89
+ if (this._config.tagsHeaderMaxLength === 0) {
90
+ log.debug('Trace tag propagation is disabled, skipping injection.')
91
+ return
92
+ }
93
+
94
+ const tags = []
95
+
96
+ for (const key in trace.tags) {
97
+ if (!trace.tags[key] || !key.startsWith('_dd.p.')) continue
98
+ if (!this._validateTagKey(key) || !this._validateTagValue(trace.tags[key])) {
99
+ log.error('Trace tags from span are invalid, skipping injection.')
100
+ return
101
+ }
102
+
103
+ tags.push(`${key}=${trace.tags[key]}`)
104
+ }
105
+
106
+ const header = tags.join(',')
107
+
108
+ if (header.length > this._config.tagsHeaderMaxLength) {
109
+ log.error('Trace tags from span are too large, skipping injection.')
110
+ } else if (header) {
111
+ carrier[tagsKey] = header
112
+ }
113
+ }
114
+
82
115
  _injectB3 (spanContext, carrier) {
83
116
  if (!this._config.experimental.b3) return
84
117
 
85
- carrier[b3TraceKey] = spanContext._traceId.toString('hex')
86
- carrier[b3SpanKey] = spanContext._spanId.toString('hex')
118
+ carrier[b3TraceKey] = spanContext._traceId.toString(16)
119
+ carrier[b3SpanKey] = spanContext._spanId.toString(16)
87
120
  carrier[b3SampledKey] = spanContext._sampling.priority >= AUTO_KEEP ? '1' : '0'
88
121
 
89
122
  if (spanContext._sampling.priority > AUTO_KEEP) {
@@ -91,7 +124,7 @@ class TextMapPropagator {
91
124
  }
92
125
 
93
126
  if (spanContext._parentId) {
94
- carrier[b3ParentKey] = spanContext._parentId.toString('hex')
127
+ carrier[b3ParentKey] = spanContext._parentId.toString(16)
95
128
  }
96
129
  }
97
130
 
@@ -99,8 +132,8 @@ class TextMapPropagator {
99
132
  if (!this._config.experimental.traceparent) return
100
133
 
101
134
  const sampling = spanContext._sampling.priority >= AUTO_KEEP ? '01' : '00'
102
- const traceId = spanContext._traceId.toString('hex').padStart(32, '0')
103
- const spanId = spanContext._spanId.toString('hex').padStart(16, '0')
135
+ const traceId = spanContext._traceId.toString(16).padStart(32, '0')
136
+ const spanId = spanContext._spanId.toString(16).padStart(16, '0')
104
137
  carrier[traceparentKey] = `01-${traceId}-${spanId}-${sampling}`
105
138
  }
106
139
 
@@ -118,6 +151,7 @@ class TextMapPropagator {
118
151
  this._extractOrigin(carrier, spanContext)
119
152
  this._extractBaggageItems(carrier, spanContext)
120
153
  this._extractSamplingPriority(carrier, spanContext)
154
+ this._extractTags(carrier, spanContext)
121
155
  }
122
156
 
123
157
  return spanContext
@@ -129,7 +163,7 @@ class TextMapPropagator {
129
163
  const b3 = this._extractB3Headers(carrier)
130
164
  const debug = b3[b3FlagsKey] === '1'
131
165
  const priority = this._getPriority(b3[b3SampledKey], debug)
132
- const spanContext = this._extractGenericContext(b3, b3TraceKey, b3SpanKey)
166
+ const spanContext = this._extractGenericContext(b3, b3TraceKey, b3SpanKey, 16)
133
167
 
134
168
  if (priority !== undefined) {
135
169
  if (!spanContext) {
@@ -273,6 +307,43 @@ class TextMapPropagator {
273
307
  }
274
308
  }
275
309
 
310
+ _extractTags (carrier, spanContext) {
311
+ if (!carrier[tagsKey]) return
312
+
313
+ const trace = spanContext._trace
314
+
315
+ if (this._config.tagsHeaderMaxLength === 0) {
316
+ log.debug('Trace tag propagation is disabled, skipping extraction.')
317
+ } else if (carrier[tagsKey].length > this._config.tagsHeaderMaxLength) {
318
+ log.error('Trace tags from carrier are too large, skipping extraction.')
319
+ } else {
320
+ const pairs = carrier[tagsKey].split(',')
321
+ const tags = {}
322
+
323
+ for (const pair of pairs) {
324
+ const [key, ...rest] = pair.split('=')
325
+ const value = rest.join('=')
326
+
327
+ if (!this._validateTagKey(key) || !this._validateTagValue(value)) {
328
+ log.error('Trace tags from carrier are invalid, skipping extraction.')
329
+ return
330
+ }
331
+
332
+ tags[key] = value
333
+ }
334
+
335
+ Object.assign(trace.tags, tags)
336
+ }
337
+ }
338
+
339
+ _validateTagKey (key) {
340
+ return tagKeyExpr.test(key)
341
+ }
342
+
343
+ _validateTagValue (value) {
344
+ return tagValueExpr.test(value)
345
+ }
346
+
276
347
  _getPriority (sampled, debug) {
277
348
  if (debug) {
278
349
  return USER_KEEP
@@ -28,7 +28,7 @@ class DatadogTracer {
28
28
  this._tags = config.tags
29
29
  this._logInjection = config.logInjection
30
30
  this._debug = config.debug
31
- this._prioritySampler = new PrioritySampler(config.env, config.experimental.sampler)
31
+ this._prioritySampler = new PrioritySampler(config.env, config.sampler)
32
32
  this._exporter = new Exporter(config, this._prioritySampler)
33
33
  this._processor = new SpanProcessor(this._exporter, this._prioritySampler, config)
34
34
  this._url = this._exporter._url
@@ -1,112 +1,154 @@
1
1
  'use strict'
2
2
 
3
- const { isTrue } = require('./util')
3
+ const { channel } = require('diagnostics_channel')
4
+ const { isFalse } = require('./util')
4
5
  const plugins = require('./plugins')
5
6
  const log = require('./log')
6
7
 
8
+ const loadChannel = channel('dd-trace:instrumentation:load')
9
+
7
10
  // instrument everything that needs Plugin System V2 instrumentation
8
11
  require('../../datadog-instrumentations')
9
12
 
10
- // TODO this is shared w/ instrumenter. DRY up.
11
- function getConfig (name, config = {}) {
12
- const enabled = process.env[`DD_TRACE_${name.toUpperCase()}_ENABLED`.replace(/[^a-z0-9_]/ig, '_')]
13
- if (enabled !== undefined) {
14
- config.enabled = isTrue(enabled)
15
- }
13
+ const { DD_TRACE_DISABLED_PLUGINS } = process.env
16
14
 
17
- // TODO is this the best/correct place for this default?
18
- if (!('enabled' in config)) {
19
- config.enabled = true
20
- }
15
+ const disabledPlugins = new Set(
16
+ DD_TRACE_DISABLED_PLUGINS && DD_TRACE_DISABLED_PLUGINS.split(',').map(plugin => plugin.trim())
17
+ )
21
18
 
22
- return config
23
- }
19
+ // TODO actually ... should we be looking at envrionment variables this deep down in the code?
24
20
 
25
- // TODO: maybe needs to DRY up as well, but depending on how the remaining old plugins
26
- // are migrated to the new system, can stay here for now, since this is the level
27
- // this check maybe should be happening on, even if it deals with env variabls
28
- const disabledPlugins = process.env.DD_TRACE_DISABLED_PLUGINS
21
+ const pluginClasses = {}
29
22
 
30
- const collectDisabledPlugins = () => {
31
- return new Set(disabledPlugins && disabledPlugins.split(',').map(plugin => plugin.trim()))
32
- }
23
+ loadChannel.subscribe(({ name }) => {
24
+ const Plugin = plugins[name]
33
25
 
34
- // TODO actually ... should we be looking at envrionment variables this deep down in the code?
26
+ if (!Plugin || typeof Plugin !== 'function') return
27
+ if (!pluginClasses[Plugin.name]) {
28
+ const envName = `DD_TRACE_${Plugin.name.toUpperCase()}_ENABLED`
29
+ const enabled = process.env[envName.replace(/[^a-z0-9_]/ig, '_')]
30
+
31
+ // TODO: remove the need to load the plugin class in order to disable the plugin
32
+ if (isFalse(enabled) || disabledPlugins.has(Plugin.name)) {
33
+ log.debug(`Plugin "${Plugin.name}" was disabled via configuration option.`)
34
+
35
+ pluginClasses[Plugin.name] = null
36
+ } else {
37
+ pluginClasses[Plugin.name] = Plugin
38
+ }
39
+ }
40
+ })
35
41
 
36
42
  // TODO this must always be a singleton.
37
43
  module.exports = class PluginManager {
38
44
  constructor (tracer) {
39
45
  this._tracer = tracer
46
+ this._tracerConfig = null
40
47
  this._pluginsByName = {}
41
48
  this._configsByName = {}
42
- this._disabledPlugins = collectDisabledPlugins()
49
+
50
+ this._loadedSubscriber = ({ name }) => {
51
+ const Plugin = plugins[name]
52
+
53
+ if (!Plugin || typeof Plugin !== 'function') return
54
+
55
+ this.loadPlugin(Plugin.name)
56
+ }
57
+
58
+ loadChannel.subscribe(this._loadedSubscriber)
43
59
  }
44
60
 
45
- // like instrumenter.use()
46
- configurePlugin (name, pluginConfig) {
47
- if (typeof pluginConfig === 'boolean') {
48
- pluginConfig = { enabled: pluginConfig }
61
+ loadPlugin (name) {
62
+ const Plugin = pluginClasses[name]
63
+
64
+ if (!Plugin) return
65
+ if (!this._pluginsByName[name]) {
66
+ this._pluginsByName[name] = new Plugin(this._tracer)
49
67
  }
50
- if (!pluginConfig) {
51
- pluginConfig = { enabled: true }
68
+ if (!this._tracerConfig) return // TODO: don't wait for tracer to be initialized
69
+
70
+ const pluginConfig = this._configsByName[name] || {
71
+ enabled: this._tracerConfig.plugins !== false
52
72
  }
53
73
 
54
- this._configsByName[name] = {
55
- ...this._configsByName[name],
74
+ this._pluginsByName[name].configure({
75
+ ...this._getSharedConfig(name),
56
76
  ...pluginConfig
57
- }
77
+ })
78
+ }
79
+
80
+ // TODO: merge config instead of replacing
81
+ configurePlugin (name, pluginConfig) {
82
+ const enabled = this._isEnabled(pluginConfig)
58
83
 
59
- if (this._pluginsByName[name]) {
60
- this._pluginsByName[name].configure(getConfig(name, this._configsByName[name]))
84
+ this._configsByName[name] = {
85
+ ...pluginConfig,
86
+ enabled
61
87
  }
88
+
89
+ this.loadPlugin(name)
62
90
  }
63
91
 
64
92
  // like instrumenter.enable()
65
93
  configure (config = {}) {
66
- const { logInjection, serviceMapping, experimental } = config
67
-
68
- for (const PluginClass of Object.values(plugins)) {
69
- const name = PluginClass.name
94
+ this._tracerConfig = config
70
95
 
71
- if (this._disabledPlugins.has(name)) {
72
- log.debug(`Plugin "${name}" was disabled via configuration option.`)
73
- continue
74
- }
96
+ for (const name in pluginClasses) {
97
+ this.loadPlugin(name)
98
+ }
99
+ }
75
100
 
76
- if (typeof PluginClass !== 'function') continue
101
+ // This is basically just for testing. like intrumenter.disable()
102
+ destroy () {
103
+ for (const name in this._pluginsByName) {
104
+ this._pluginsByName[name].configure({ enabled: false })
105
+ }
77
106
 
78
- this._pluginsByName[name] = new PluginClass(this._tracer)
107
+ loadChannel.unsubscribe(this._loadedSubscriber)
108
+ }
79
109
 
80
- if (config.plugins === false) continue
110
+ _isEnabled (pluginConfig) {
111
+ if (typeof pluginConfig === 'boolean') return pluginConfig
112
+ if (!pluginConfig) return true
81
113
 
82
- const pluginConfig = {
83
- ...this._configsByName[name]
84
- }
114
+ return pluginConfig.enabled !== false
115
+ }
85
116
 
86
- if (logInjection !== undefined) {
87
- pluginConfig.logInjection = logInjection
88
- }
117
+ // TODO: figure out a better way to handle this
118
+ _getSharedConfig (name) {
119
+ const {
120
+ logInjection,
121
+ serviceMapping,
122
+ clientIpHeaderDisabled,
123
+ clientIpHeader,
124
+ isIntelligentTestRunnerEnabled,
125
+ experimental
126
+ } = this._tracerConfig
127
+
128
+ const sharedConfig = {}
129
+
130
+ if (logInjection !== undefined) {
131
+ sharedConfig.logInjection = logInjection
132
+ }
89
133
 
90
- // TODO: update so that it's available for every CI Visibility's plugin
91
- if (name === 'mocha') {
92
- pluginConfig.isAgentlessEnabled = experimental && experimental.exporter === 'datadog'
93
- }
134
+ if (clientIpHeaderDisabled !== undefined) {
135
+ sharedConfig.clientIpHeaderDisabled = clientIpHeaderDisabled
136
+ }
94
137
 
95
- if (serviceMapping && serviceMapping[name]) {
96
- pluginConfig.service = serviceMapping[name]
97
- }
138
+ if (clientIpHeader !== undefined) {
139
+ sharedConfig.clientIpHeader = clientIpHeader
140
+ }
98
141
 
99
- this.configurePlugin(name, pluginConfig)
142
+ if (experimental) {
143
+ sharedConfig.isAgentlessEnabled = experimental.exporter === 'datadog'
100
144
  }
101
- }
102
145
 
103
- // This is basically just for testing. like intrumenter.disable()
104
- destroy () {
105
- for (const name in this._pluginsByName) {
106
- this._pluginsByName[name].configure({ enabled: false })
146
+ sharedConfig.isIntelligentTestRunnerEnabled = isIntelligentTestRunnerEnabled
147
+
148
+ if (serviceMapping && serviceMapping[name]) {
149
+ sharedConfig.service = serviceMapping[name]
107
150
  }
108
151
 
109
- this._pluginsByName = {}
110
- this._configsByName = {}
152
+ return sharedConfig
111
153
  }
112
154
  }
@@ -1,49 +1,62 @@
1
1
  'use strict'
2
2
 
3
3
  module.exports = {
4
- 'amqp10': require('../../../datadog-plugin-amqp10/src'),
5
- 'amqplib': require('../../../datadog-plugin-amqplib/src'),
6
- 'aws-sdk': require('../../../datadog-plugin-aws-sdk/src'),
7
- 'bunyan': require('../../../datadog-plugin-bunyan/src'),
8
- 'cassandra-driver': require('../../../datadog-plugin-cassandra-driver/src'),
9
- 'connect': require('../../../datadog-plugin-connect/src'),
10
- 'couchbase': require('../../../datadog-plugin-couchbase/src'),
11
- 'cucumber': require('../../../datadog-plugin-cucumber/src'),
12
- 'cypress': require('../../../datadog-plugin-cypress/src'),
13
- 'dns': require('../../../datadog-plugin-dns/src'),
14
- 'elasticsearch': require('../../../datadog-plugin-elasticsearch/src'),
15
- 'express': require('../../../datadog-plugin-express/src'),
16
- 'fastify': require('../../../datadog-plugin-fastify/src'),
17
- 'find-my-way': require('../../../datadog-plugin-find-my-way/src'),
18
- 'fs': require('../../../datadog-plugin-fs/src'),
19
- 'google-cloud-pubsub': require('../../../datadog-plugin-google-cloud-pubsub/src'),
20
- 'graphql': require('../../../datadog-plugin-graphql/src'),
21
- 'grpc': require('../../../datadog-plugin-grpc/src'),
22
- 'hapi': require('../../../datadog-plugin-hapi/src'),
23
- 'http': require('../../../datadog-plugin-http/src'),
24
- 'http2': require('../../../datadog-plugin-http2/src'),
25
- 'ioredis': require('../../../datadog-plugin-ioredis/src'),
26
- 'jest': require('../../../datadog-plugin-jest/src'),
27
- 'koa': require('../../../datadog-plugin-koa/src'),
28
- 'kafkajs': require('../../../datadog-plugin-kafkajs/src'),
29
- 'memcached': require('../../../datadog-plugin-memcached/src'),
30
- 'microgateway-core': require('../../../datadog-plugin-microgateway-core/src'),
31
- 'mocha': require('../../../datadog-plugin-mocha/src'),
32
- 'moleculer': require('../../../datadog-plugin-moleculer/src'),
33
- 'mongodb-core': require('../../../datadog-plugin-mongodb-core/src'),
34
- 'mysql': require('../../../datadog-plugin-mysql/src'),
35
- 'mysql2': require('../../../datadog-plugin-mysql2/src'),
36
- 'net': require('../../../datadog-plugin-net/src'),
37
- 'next': require('../../../datadog-plugin-next/src'),
38
- 'oracledb': require('../../../datadog-plugin-oracledb/src'),
39
- 'paperplane': require('../../../datadog-plugin-paperplane/src'),
40
- 'pg': require('../../../datadog-plugin-pg/src'),
41
- 'pino': require('../../../datadog-plugin-pino/src'),
42
- 'redis': require('../../../datadog-plugin-redis/src'),
43
- 'restify': require('../../../datadog-plugin-restify/src'),
44
- 'rhea': require('../../../datadog-plugin-rhea/src'),
45
- 'router': require('../../../datadog-plugin-router/src'),
46
- 'sharedb': require('../../../datadog-plugin-sharedb/src'),
47
- 'tedious': require('../../../datadog-plugin-tedious/src'),
48
- 'winston': require('../../../datadog-plugin-winston/src')
4
+ get '@cucumber/cucumber' () { return require('../../../datadog-plugin-cucumber/src') },
5
+ get '@elastic/elasticsearch' () { return require('../../../datadog-plugin-elasticsearch/src') },
6
+ get '@elastic/transport' () { return require('../../../datadog-plugin-elasticsearch/src') },
7
+ get '@google-cloud/pubsub' () { return require('../../../datadog-plugin-google-cloud-pubsub/src') },
8
+ get '@grpc/grpc-js' () { return require('../../../datadog-plugin-grpc/src') },
9
+ get '@hapi/hapi' () { return require('../../../datadog-plugin-hapi/src') },
10
+ get '@koa/router' () { return require('../../../datadog-plugin-koa/src') },
11
+ get '@node-redis/client' () { return require('../../../datadog-plugin-redis/src') },
12
+ get 'amqp10' () { return require('../../../datadog-plugin-amqp10/src') },
13
+ get 'amqplib' () { return require('../../../datadog-plugin-amqplib/src') },
14
+ get 'aws-sdk' () { return require('../../../datadog-plugin-aws-sdk/src') },
15
+ get 'bunyan' () { return require('../../../datadog-plugin-bunyan/src') },
16
+ get 'cassandra-driver' () { return require('../../../datadog-plugin-cassandra-driver/src') },
17
+ get 'connect' () { return require('../../../datadog-plugin-connect/src') },
18
+ get 'couchbase' () { return require('../../../datadog-plugin-couchbase/src') },
19
+ get 'cypress' () { return require('../../../datadog-plugin-cypress/src') },
20
+ get 'dns' () { return require('../../../datadog-plugin-dns/src') },
21
+ get 'elasticsearch' () { return require('../../../datadog-plugin-elasticsearch/src') },
22
+ get 'express' () { return require('../../../datadog-plugin-express/src') },
23
+ get 'fastify' () { return require('../../../datadog-plugin-fastify/src') },
24
+ get 'find-my-way' () { return require('../../../datadog-plugin-find-my-way/src') },
25
+ get 'fs' () { return require('../../../datadog-plugin-fs/src') },
26
+ get 'graphql' () { return require('../../../datadog-plugin-graphql/src') },
27
+ get 'grpc' () { return require('../../../datadog-plugin-grpc/src') },
28
+ get 'hapi' () { return require('../../../datadog-plugin-hapi/src') },
29
+ get 'http' () { return require('../../../datadog-plugin-http/src') },
30
+ get 'http2' () { return require('../../../datadog-plugin-http2/src') },
31
+ get 'https' () { return require('../../../datadog-plugin-http/src') },
32
+ get 'ioredis' () { return require('../../../datadog-plugin-ioredis/src') },
33
+ get 'jest-environment-node' () { return require('../../../datadog-plugin-jest/src') },
34
+ get 'jest-environment-jsdom' () { return require('../../../datadog-plugin-jest/src') },
35
+ get 'jest-jasmine2' () { return require('../../../datadog-plugin-jest/src') },
36
+ get 'koa' () { return require('../../../datadog-plugin-koa/src') },
37
+ get 'koa-router' () { return require('../../../datadog-plugin-koa/src') },
38
+ get 'kafkajs' () { return require('../../../datadog-plugin-kafkajs/src') },
39
+ get 'memcached' () { return require('../../../datadog-plugin-memcached/src') },
40
+ get 'microgateway-core' () { return require('../../../datadog-plugin-microgateway-core/src') },
41
+ get 'mocha' () { return require('../../../datadog-plugin-mocha/src') },
42
+ get 'mocha-each' () { return require('../../../datadog-plugin-mocha/src') },
43
+ get 'moleculer' () { return require('../../../datadog-plugin-moleculer/src') },
44
+ get 'mongodb' () { return require('../../../datadog-plugin-mongodb-core/src') },
45
+ get 'mongodb-core' () { return require('../../../datadog-plugin-mongodb-core/src') },
46
+ get 'mysql' () { return require('../../../datadog-plugin-mysql/src') },
47
+ get 'mysql2' () { return require('../../../datadog-plugin-mysql2/src') },
48
+ get 'net' () { return require('../../../datadog-plugin-net/src') },
49
+ get 'next' () { return require('../../../datadog-plugin-next/src') },
50
+ get 'oracledb' () { return require('../../../datadog-plugin-oracledb/src') },
51
+ get 'paperplane' () { return require('../../../datadog-plugin-paperplane/src') },
52
+ get 'pg' () { return require('../../../datadog-plugin-pg/src') },
53
+ get 'pino' () { return require('../../../datadog-plugin-pino/src') },
54
+ get 'pino-pretty' () { return require('../../../datadog-plugin-pino/src') },
55
+ get 'redis' () { return require('../../../datadog-plugin-redis/src') },
56
+ get 'restify' () { return require('../../../datadog-plugin-restify/src') },
57
+ get 'rhea' () { return require('../../../datadog-plugin-rhea/src') },
58
+ get 'router' () { return require('../../../datadog-plugin-router/src') },
59
+ get 'sharedb' () { return require('../../../datadog-plugin-sharedb/src') },
60
+ get 'tedious' () { return require('../../../datadog-plugin-tedious/src') },
61
+ get 'winston' () { return require('../../../datadog-plugin-winston/src') }
49
62
  }
@@ -9,25 +9,32 @@ const hasOwn = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
9
9
  function messageProxy (message, holder) {
10
10
  return new Proxy(message, {
11
11
  get (target, p, receiver) {
12
- switch (p) {
13
- case Symbol.toStringTag:
14
- return Object.prototype.toString.call(target).slice(8, -1)
15
- case 'dd':
16
- return holder.dd
17
- default:
18
- return Reflect.get(target, p, receiver)
12
+ if (p === Symbol.toStringTag) {
13
+ return Object.prototype.toString.call(target).slice(8, -1)
19
14
  }
15
+
16
+ if (shouldOverride(target, p)) {
17
+ return holder.dd
18
+ }
19
+
20
+ return Reflect.get(target, p, receiver)
20
21
  },
21
22
  ownKeys (target) {
22
23
  const ownKeys = Reflect.ownKeys(target)
23
- return hasOwn(target, 'dd') ? ownKeys : ['dd', ...ownKeys]
24
+ return hasOwn(target, 'dd') || !Reflect.isExtensible(target)
25
+ ? ownKeys
26
+ : ['dd', ...ownKeys]
24
27
  },
25
28
  getOwnPropertyDescriptor (target, p) {
26
- return Reflect.getOwnPropertyDescriptor(p === 'dd' ? holder : target, p)
29
+ return Reflect.getOwnPropertyDescriptor(shouldOverride(target, p) ? holder : target, p)
27
30
  }
28
31
  })
29
32
  }
30
33
 
34
+ function shouldOverride (target, p) {
35
+ return p === 'dd' && !Reflect.has(target, p) && Reflect.isExtensible(target)
36
+ }
37
+
31
38
  module.exports = class LogPlugin extends Plugin {
32
39
  constructor (...args) {
33
40
  super(...args)
@@ -17,7 +17,8 @@ const {
17
17
  CI_WORKSPACE_PATH,
18
18
  CI_JOB_URL,
19
19
  CI_JOB_NAME,
20
- CI_STAGE_NAME
20
+ CI_STAGE_NAME,
21
+ CI_ENV_VARS
21
22
  } = require('./tags')
22
23
 
23
24
  // Receives a string with the form 'John Doe <john.doe@gmail.com>'
@@ -104,7 +105,8 @@ module.exports = {
104
105
  GIT_BRANCH: JENKINS_GIT_BRANCH,
105
106
  GIT_COMMIT: JENKINS_GIT_COMMIT,
106
107
  GIT_URL: JENKINS_GIT_REPOSITORY_URL,
107
- GIT_URL_1: JENKINS_GIT_REPOSITORY_URL_1
108
+ GIT_URL_1: JENKINS_GIT_REPOSITORY_URL_1,
109
+ DD_CUSTOM_TRACE_ID
108
110
  } = env
109
111
 
110
112
  tags = {
@@ -114,7 +116,8 @@ module.exports = {
114
116
  [CI_PROVIDER_NAME]: 'jenkins',
115
117
  [GIT_COMMIT_SHA]: JENKINS_GIT_COMMIT,
116
118
  [GIT_REPOSITORY_URL]: JENKINS_GIT_REPOSITORY_URL || JENKINS_GIT_REPOSITORY_URL_1,
117
- [CI_WORKSPACE_PATH]: WORKSPACE
119
+ [CI_WORKSPACE_PATH]: WORKSPACE,
120
+ [CI_ENV_VARS]: JSON.stringify({ DD_CUSTOM_TRACE_ID })
118
121
  }
119
122
 
120
123
  const isTag = JENKINS_GIT_BRANCH && JENKINS_GIT_BRANCH.includes('tags')
@@ -152,7 +155,9 @@ module.exports = {
152
155
  CI_JOB_NAME: GITLAB_CI_JOB_NAME,
153
156
  CI_COMMIT_MESSAGE,
154
157
  CI_COMMIT_TIMESTAMP,
155
- CI_COMMIT_AUTHOR
158
+ CI_COMMIT_AUTHOR,
159
+ CI_PROJECT_URL: GITLAB_PROJECT_URL,
160
+ CI_JOB_ID: GITLAB_CI_JOB_ID
156
161
  } = env
157
162
 
158
163
  const { name, email } = parseEmailAndName(CI_COMMIT_AUTHOR)
@@ -174,7 +179,12 @@ module.exports = {
174
179
  [GIT_COMMIT_MESSAGE]: CI_COMMIT_MESSAGE,
175
180
  [GIT_COMMIT_AUTHOR_NAME]: name,
176
181
  [GIT_COMMIT_AUTHOR_EMAIL]: email,
177
- [GIT_COMMIT_AUTHOR_DATE]: CI_COMMIT_TIMESTAMP
182
+ [GIT_COMMIT_AUTHOR_DATE]: CI_COMMIT_TIMESTAMP,
183
+ [CI_ENV_VARS]: JSON.stringify({
184
+ CI_PROJECT_URL: GITLAB_PROJECT_URL,
185
+ CI_PIPELINE_ID: GITLAB_PIPELINE_ID,
186
+ CI_JOB_ID: GITLAB_CI_JOB_ID
187
+ })
178
188
  }
179
189
  }
180
190
 
@@ -188,7 +198,8 @@ module.exports = {
188
198
  CIRCLE_TAG,
189
199
  CIRCLE_SHA1,
190
200
  CIRCLE_REPOSITORY_URL,
191
- CIRCLE_JOB
201
+ CIRCLE_JOB,
202
+ CIRCLE_BUILD_NUM
192
203
  } = env
193
204
 
194
205
  const pipelineUrl = `https://app.circleci.com/pipelines/workflows/${CIRCLE_WORKFLOW_ID}`
@@ -203,7 +214,11 @@ module.exports = {
203
214
  [GIT_REPOSITORY_URL]: CIRCLE_REPOSITORY_URL,
204
215
  [CI_JOB_URL]: CIRCLE_BUILD_URL,
205
216
  [CI_WORKSPACE_PATH]: CIRCLE_WORKING_DIRECTORY,
206
- [CIRCLE_TAG ? GIT_TAG : GIT_BRANCH]: CIRCLE_TAG || CIRCLE_BRANCH
217
+ [CIRCLE_TAG ? GIT_TAG : GIT_BRANCH]: CIRCLE_TAG || CIRCLE_BRANCH,
218
+ [CI_ENV_VARS]: JSON.stringify({
219
+ CIRCLE_WORKFLOW_ID,
220
+ CIRCLE_BUILD_NUM
221
+ })
207
222
  }
208
223
  }
209
224
 
@@ -243,7 +258,13 @@ module.exports = {
243
258
  [GIT_REPOSITORY_URL]: repositoryURL,
244
259
  [CI_JOB_URL]: jobUrl,
245
260
  [CI_WORKSPACE_PATH]: GITHUB_WORKSPACE,
246
- [refKey]: ref
261
+ [refKey]: ref,
262
+ [CI_ENV_VARS]: JSON.stringify({
263
+ GITHUB_SERVER_URL,
264
+ GITHUB_REPOSITORY,
265
+ GITHUB_RUN_ID,
266
+ GITHUB_RUN_ATTEMPT
267
+ })
247
268
  }
248
269
  }
249
270
 
@@ -443,7 +464,11 @@ module.exports = {
443
464
  [refKey]: ref,
444
465
  [GIT_COMMIT_AUTHOR_NAME]: BUILDKITE_BUILD_AUTHOR,
445
466
  [GIT_COMMIT_AUTHOR_EMAIL]: BUILDKITE_BUILD_AUTHOR_EMAIL,
446
- [GIT_COMMIT_MESSAGE]: BUILDKITE_MESSAGE
467
+ [GIT_COMMIT_MESSAGE]: BUILDKITE_MESSAGE,
468
+ [CI_ENV_VARS]: JSON.stringify({
469
+ BUILDKITE_BUILD_ID,
470
+ BUILDKITE_JOB_ID
471
+ })
447
472
  }
448
473
  }
449
474