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
@@ -1,6 +1,10 @@
1
1
  'use strict'
2
2
 
3
3
  const addresses = require('./addresses')
4
+ const Limiter = require('../rate_limiter')
5
+
6
+ // default limiter, configurable with setRateLimit()
7
+ let limiter = new Limiter(100)
4
8
 
5
9
  const REQUEST_HEADERS_PASSLIST = [
6
10
  'accept',
@@ -36,7 +40,6 @@ function resolveHTTPRequest (context) {
36
40
  const headers = context.resolve(addresses.HTTP_INCOMING_HEADERS)
37
41
 
38
42
  return {
39
- // route: context.resolve(addresses.HTTP_INCOMING_ROUTE),
40
43
  remote_ip: context.resolve(addresses.HTTP_INCOMING_REMOTE_IP),
41
44
  headers: filterHeaders(headers, REQUEST_HEADERS_PASSLIST, 'http.request.headers.')
42
45
  }
@@ -48,6 +51,7 @@ function resolveHTTPResponse (context) {
48
51
  const headers = context.resolve(addresses.HTTP_INCOMING_RESPONSE_HEADERS)
49
52
 
50
53
  return {
54
+ endpoint: context.resolve(addresses.HTTP_INCOMING_ENDPOINT),
51
55
  headers: filterHeaders(headers, RESPONSE_HEADERS_PASSLIST, 'http.response.headers.')
52
56
  }
53
57
  }
@@ -61,16 +65,16 @@ function filterHeaders (headers, passlist, prefix) {
61
65
  const headerName = passlist[i]
62
66
 
63
67
  if (headers[headerName]) {
64
- result[`${prefix}${formatHeaderName(headerName)}`] = headers[headerName].toString()
68
+ result[`${prefix}${formatHeaderName(headerName)}`] = headers[headerName] + ''
65
69
  }
66
70
  }
67
71
 
68
72
  return result
69
73
  }
70
74
 
75
+ // TODO: this can be precomputed at start time
71
76
  function formatHeaderName (name) {
72
77
  return name
73
- .toString()
74
78
  .trim()
75
79
  .slice(0, 200)
76
80
  .replace(/[^a-zA-Z0-9_\-:/]/g, '_')
@@ -85,10 +89,14 @@ function reportAttack (attackData, store) {
85
89
  const currentTags = topSpan.context()._tags
86
90
 
87
91
  const newTags = {
88
- 'appsec.event': true,
89
- 'manual.keep': undefined
92
+ 'appsec.event': 'true'
93
+ }
94
+
95
+ if (limiter.isAllowed()) {
96
+ newTags['manual.keep'] = 'true' // TODO: figure out how to keep appsec traces with sampling revamp
90
97
  }
91
98
 
99
+ // TODO: maybe add this to format.js later (to take decision as late as possible)
92
100
  if (!currentTags['_dd.origin']) {
93
101
  newTags['_dd.origin'] = 'appsec'
94
102
  }
@@ -115,8 +123,6 @@ function reportAttack (attackData, store) {
115
123
  }
116
124
 
117
125
  newTags['network.client.ip'] = resolvedRequest.remote_ip
118
-
119
- // newTags['http.endpoint'] = resolvedRequest.route
120
126
  }
121
127
 
122
128
  topSpan.addTags(newTags)
@@ -126,9 +132,19 @@ function finishAttacks (req, context) {
126
132
  const topSpan = req && req._datadog && req._datadog.span
127
133
  if (!topSpan || !context) return false
128
134
 
129
- const resolvedReponse = resolveHTTPResponse(context)
135
+ const resolvedResponse = resolveHTTPResponse(context)
136
+
137
+ const newTags = resolvedResponse.headers
138
+
139
+ if (resolvedResponse.endpoint) {
140
+ newTags['http.endpoint'] = resolvedResponse.endpoint
141
+ }
142
+
143
+ topSpan.addTags(newTags)
144
+ }
130
145
 
131
- topSpan.addTags(resolvedReponse.headers)
146
+ function setRateLimit (rateLimit) {
147
+ limiter = new Limiter(rateLimit)
132
148
  }
133
149
 
134
150
  module.exports = {
@@ -137,5 +153,6 @@ module.exports = {
137
153
  filterHeaders,
138
154
  formatHeaderName,
139
155
  reportAttack,
140
- finishAttacks
156
+ finishAttacks,
157
+ setRateLimit
141
158
  }
@@ -24,9 +24,12 @@ class Config {
24
24
  tagger.add(this.tags, process.env.DD_TRACE_GLOBAL_TAGS)
25
25
  tagger.add(this.tags, options.tags)
26
26
 
27
- // Temporary disabled
27
+ const DD_TRACING_ENABLED = coalesce(
28
+ process.env.DD_TRACING_ENABLED,
29
+ true
30
+ )
28
31
  const DD_PROFILING_ENABLED = coalesce(
29
- options.profiling,
32
+ options.profiling, // TODO: remove when enabled by default
30
33
  process.env.DD_EXPERIMENTAL_PROFILING_ENABLED,
31
34
  process.env.DD_PROFILING_ENABLED,
32
35
  false
@@ -42,7 +45,7 @@ class Config {
42
45
  false
43
46
  )
44
47
  const DD_RUNTIME_METRICS_ENABLED = coalesce(
45
- options.runtimeMetrics,
48
+ options.runtimeMetrics, // TODO: remove when enabled by default
46
49
  process.env.DD_RUNTIME_METRICS_ENABLED,
47
50
  false
48
51
  )
@@ -85,15 +88,9 @@ class Config {
85
88
  const DD_TRACE_STARTUP_LOGS = coalesce(
86
89
  options.startupLogs,
87
90
  process.env.DD_TRACE_STARTUP_LOGS,
88
- true
89
- )
90
- const DD_TRACE_ENABLED = coalesce(
91
- options.enabled,
92
- process.env.DD_TRACE_ENABLED,
93
- true
91
+ false
94
92
  )
95
93
  const DD_TRACE_DEBUG = coalesce(
96
- options.debug,
97
94
  process.env.DD_TRACE_DEBUG,
98
95
  false
99
96
  )
@@ -121,39 +118,46 @@ class Config {
121
118
  process.env.DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
122
119
  false
123
120
  )
124
- const DD_TRACE_INTERNAL_ERRORS_ENABLED = coalesce(
125
- options.experimental && options.experimental.internalErrors,
126
- process.env.DD_TRACE_EXPERIMENTAL_INTERNAL_ERRORS_ENABLED,
127
- false
128
- )
129
- // TODO(simon-id): add documentation for appsec config when we release it in public beta
121
+
122
+ let appsec = options.appsec || (options.experimental && options.experimental.appsec)
123
+
130
124
  const DD_APPSEC_ENABLED = coalesce(
131
- options.experimental &&
132
- options.experimental.appsec &&
133
- (options.experimental.appsec === true || options.experimental.appsec.enabled === true),
134
- process.env.DD_EXPERIMENTAL_APPSEC_ENABLED,
125
+ appsec && (appsec === true || appsec.enabled === true), // TODO: remove when enabled by default
135
126
  process.env.DD_APPSEC_ENABLED,
136
127
  false
137
128
  )
129
+
130
+ appsec = appsec || {}
131
+
138
132
  const DD_APPSEC_RULES = coalesce(
139
- options.experimental && options.experimental.appsec && options.experimental.appsec.rules,
133
+ appsec.rules,
140
134
  process.env.DD_APPSEC_RULES,
141
135
  path.join(__dirname, 'appsec', 'recommended.json')
142
136
  )
137
+ const DD_APPSEC_TRACE_RATE_LIMIT = coalesce(
138
+ appsec.rateLimit,
139
+ process.env.DD_APPSEC_TRACE_RATE_LIMIT,
140
+ 100
141
+ )
143
142
 
144
143
  const sampler = (options.experimental && options.experimental.sampler) || {}
145
144
  const ingestion = options.ingestion || {}
146
145
  const dogstatsd = coalesce(options.dogstatsd, {})
147
146
 
148
147
  Object.assign(sampler, {
149
- sampleRate: coalesce(ingestion.sampleRate, sampler.sampleRate, process.env.DD_TRACE_SAMPLE_RATE),
148
+ sampleRate: coalesce(
149
+ options.sampleRate,
150
+ ingestion.sampleRate,
151
+ sampler.sampleRate,
152
+ process.env.DD_TRACE_SAMPLE_RATE
153
+ ),
150
154
  rateLimit: coalesce(ingestion.rateLimit, sampler.rateLimit, process.env.DD_TRACE_RATE_LIMIT)
151
155
  })
152
156
 
153
157
  const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
154
158
  const defaultFlushInterval = inAWSLambda ? 0 : 2000
155
159
 
156
- this.enabled = isTrue(DD_TRACE_ENABLED)
160
+ this.tracing = !isFalse(DD_TRACING_ENABLED)
157
161
  this.debug = isTrue(DD_TRACE_DEBUG)
158
162
  this.logInjection = isTrue(DD_LOGS_INJECTION)
159
163
  this.env = DD_ENV
@@ -162,7 +166,7 @@ class Config {
162
166
  this.hostname = DD_AGENT_HOST || (this.url && this.url.hostname)
163
167
  this.port = String(DD_TRACE_AGENT_PORT || (this.url && this.url.port))
164
168
  this.flushInterval = coalesce(parseInt(options.flushInterval, 10), defaultFlushInterval)
165
- this.sampleRate = coalesce(Math.min(Math.max(options.sampleRate, 0), 1), 1)
169
+ this.sampleRate = coalesce(Math.min(Math.max(sampler.sampleRate, 0), 1), 1)
166
170
  this.logger = options.logger
167
171
  this.plugins = !!coalesce(options.plugins, true)
168
172
  this.service = DD_SERVICE
@@ -180,8 +184,7 @@ class Config {
180
184
  runtimeId: isTrue(DD_TRACE_RUNTIME_ID_ENABLED),
181
185
  exporter: DD_TRACE_EXPORTER,
182
186
  enableGetRumData: isTrue(DD_TRACE_GET_RUM_DATA_ENABLED),
183
- sampler,
184
- internalErrors: isTrue(DD_TRACE_INTERNAL_ERRORS_ENABLED)
187
+ sampler
185
188
  }
186
189
  this.reportHostname = isTrue(coalesce(options.reportHostname, process.env.DD_TRACE_REPORT_HOSTNAME, false))
187
190
  this.scope = process.env.DD_TRACE_SCOPE
@@ -200,7 +203,8 @@ class Config {
200
203
  this.protocolVersion = DD_TRACE_AGENT_PROTOCOL_VERSION
201
204
  this.appsec = {
202
205
  enabled: isTrue(DD_APPSEC_ENABLED),
203
- rules: DD_APPSEC_RULES
206
+ rules: DD_APPSEC_RULES,
207
+ rateLimit: DD_APPSEC_TRACE_RATE_LIMIT
204
208
  }
205
209
 
206
210
  tagger.add(this.tags, {
@@ -1,14 +1,17 @@
1
1
  'use strict'
2
2
 
3
3
  module.exports = {
4
- SAMPLE_RATE_METRIC_KEY: '_sample_rate',
5
4
  SAMPLING_PRIORITY_KEY: '_sampling_priority_v1',
6
5
  ANALYTICS_KEY: '_dd1.sr.eausr',
7
6
  ORIGIN_KEY: '_dd.origin',
8
7
  HOSTNAME_KEY: '_dd.hostname',
9
- REFERENCE_NOOP: 'noop',
10
8
  SAMPLING_RULE_DECISION: '_dd.rule_psr',
11
9
  SAMPLING_LIMIT_DECISION: '_dd.limit_psr',
12
10
  SAMPLING_AGENT_DECISION: '_dd.agent_psr',
13
- DATADOG_LAMBDA_EXTENSION_PATH: '/opt/extensions/datadog-agent'
11
+ SAMPLING_MECHANISM_DEFAULT: 0,
12
+ SAMPLING_MECHANISM_AGENT: 1,
13
+ SAMPLING_MECHANISM_RULE: 3,
14
+ SAMPLING_MECHANISM_MANUAL: 4,
15
+ DATADOG_LAMBDA_EXTENSION_PATH: '/opt/extensions/datadog-agent',
16
+ UPSTREAM_SERVICES_KEY: '_dd.p.upstream_services'
14
17
  }
@@ -4,12 +4,17 @@ const http = require('http')
4
4
  const https = require('https')
5
5
  const docker = require('./docker')
6
6
  const log = require('../../log')
7
+ const { storage } = require('../../../../datadog-core')
7
8
 
8
9
  const httpAgent = new http.Agent({ keepAlive: true })
9
10
  const httpsAgent = new https.Agent({ keepAlive: true })
10
11
  const containerId = docker.id()
11
12
 
12
13
  function retriableRequest (options, callback, client, data) {
14
+ const store = storage.getStore()
15
+
16
+ storage.enterWith({ noop: true })
17
+
13
18
  const req = client.request(options, res => {
14
19
  let data = ''
15
20
 
@@ -29,6 +34,9 @@ function retriableRequest (options, callback, client, data) {
29
34
  })
30
35
  req.setTimeout(options.timeout, req.abort)
31
36
  data.forEach(buffer => req.write(buffer))
37
+
38
+ storage.enterWith(store)
39
+
32
40
  return req
33
41
  }
34
42
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  const constants = require('./constants')
4
4
  const tags = require('../../../ext/tags')
5
- const log = require('./log')
6
5
  const id = require('./id')
7
6
  const { isError } = require('./util')
8
7
 
@@ -25,6 +24,7 @@ function format (span) {
25
24
 
26
25
  extractError(formatted, span)
27
26
  extractRootTags(formatted, span)
27
+ extractChunkTags(formatted, span)
28
28
  extractTags(formatted, span)
29
29
 
30
30
  return formatted
@@ -37,8 +37,8 @@ function formatSpan (span) {
37
37
  trace_id: spanContext._traceId,
38
38
  span_id: spanContext._spanId,
39
39
  parent_id: spanContext._parentId || id('0'),
40
- name: serialize(spanContext._name),
41
- resource: serialize(spanContext._name),
40
+ name: String(spanContext._name),
41
+ resource: String(spanContext._name),
42
42
  error: 0,
43
43
  meta: {},
44
44
  metrics: {},
@@ -53,7 +53,6 @@ function extractTags (trace, span) {
53
53
  const tags = context._tags
54
54
  const hostname = context._hostname
55
55
  const priority = context._sampling.priority
56
- const internalErrors = span.tracer()._internalErrors
57
56
 
58
57
  if (tags['span.kind'] && tags['span.kind'] !== 'internal') {
59
58
  addTag({}, trace.metrics, MEASURED, 1)
@@ -75,7 +74,7 @@ function extractTags (trace, span) {
75
74
  addTag({}, trace.metrics, tag, tags[tag] === undefined || tags[tag] ? 1 : 0)
76
75
  break
77
76
  case 'error':
78
- if (tags[tag] && (context._name !== 'fs.operation' || internalErrors)) {
77
+ if (tags[tag] && (context._name !== 'fs.operation')) {
79
78
  trace.error = 1
80
79
  }
81
80
  break
@@ -83,7 +82,7 @@ function extractTags (trace, span) {
83
82
  case 'error.msg':
84
83
  case 'error.stack':
85
84
  // HACK: remove when implemented in the backend
86
- if (context._name !== 'fs.operation' || internalErrors) {
85
+ if (context._name !== 'fs.operation') {
87
86
  trace.error = 1
88
87
  }
89
88
  default: // eslint-disable-line no-fallthrough
@@ -112,6 +111,17 @@ function extractRootTags (trace, span) {
112
111
  addTag({}, trace.metrics, SAMPLING_AGENT_DECISION, context._trace[SAMPLING_AGENT_DECISION])
113
112
  }
114
113
 
114
+ function extractChunkTags (trace, span) {
115
+ const context = span.context()
116
+ const isLocalRoot = span === context._trace.started[0]
117
+
118
+ if (!isLocalRoot) return
119
+
120
+ for (const key in context._trace.tags) {
121
+ addTag(trace.meta, trace.metrics, key, context._trace.tags[key])
122
+ }
123
+ }
124
+
115
125
  function extractError (trace, span) {
116
126
  const error = span.context()._tags['error']
117
127
  if (isError(error)) {
@@ -121,7 +131,7 @@ function extractError (trace, span) {
121
131
  }
122
132
  }
123
133
 
124
- function addTag (meta, metrics, key, value, seen) {
134
+ function addTag (meta, metrics, key, value, nested) {
125
135
  switch (typeof value) {
126
136
  case 'string':
127
137
  if (!value) break
@@ -131,6 +141,9 @@ function addTag (meta, metrics, key, value, seen) {
131
141
  if (isNaN(value)) break
132
142
  metrics[key] = value
133
143
  break
144
+ case 'boolean':
145
+ metrics[key] = value ? 1 : 0
146
+ break
134
147
  case 'undefined':
135
148
  break
136
149
  case 'object':
@@ -139,41 +152,15 @@ function addTag (meta, metrics, key, value, seen) {
139
152
  // Special case for Node.js Buffer and URL
140
153
  if (isNodeBuffer(value) || isUrl(value)) {
141
154
  metrics[key] = value.toString()
142
- break
143
- }
155
+ } else if (!Array.isArray(value) && !nested) {
156
+ for (const prop in value) {
157
+ if (!value.hasOwnProperty(prop)) continue
144
158
 
145
- if (!Array.isArray(value)) {
146
- addObjectTag(meta, metrics, key, value, seen)
147
- break
159
+ addTag(meta, metrics, `${key}.${prop}`, value[prop], true)
160
+ }
148
161
  }
149
162
 
150
- default: // eslint-disable-line no-fallthrough
151
- addTag(meta, metrics, key, serialize(value))
152
- }
153
- }
154
-
155
- function addObjectTag (meta, metrics, key, value, seen) {
156
- seen = seen || []
157
-
158
- if (~seen.indexOf(value)) {
159
- meta[key] = '[Circular]'
160
- return
161
- }
162
-
163
- seen.push(value)
164
-
165
- for (const prop in value) {
166
- addTag(meta, metrics, `${key}.${prop}`, value[prop], seen)
167
- }
168
-
169
- seen.pop()
170
- }
171
-
172
- function serialize (obj) {
173
- try {
174
- return obj && typeof obj.toString !== 'function' ? JSON.stringify(obj) : String(obj)
175
- } catch (e) {
176
- log.error(e)
163
+ break
177
164
  }
178
165
  }
179
166
 
@@ -6,6 +6,7 @@ const metrics = require('./metrics')
6
6
  const Loader = require('./loader')
7
7
  const { isTrue } = require('./util')
8
8
  const plugins = require('./plugins')
9
+ const Plugin = require('./plugins/plugin')
9
10
 
10
11
  const disabledPlugins = process.env.DD_TRACE_DISABLED_PLUGINS
11
12
 
@@ -42,6 +43,9 @@ class Instrumenter {
42
43
  }
43
44
 
44
45
  use (name, config) {
46
+ if (typeof name !== 'string') return
47
+ const plugin = plugins[name.toLowerCase()]
48
+ if (plugin && plugin.prototype instanceof Plugin) return
45
49
  if (typeof config === 'boolean') {
46
50
  config = { enabled: config }
47
51
  }
@@ -49,7 +53,7 @@ class Instrumenter {
49
53
  config = getConfig(name, config)
50
54
 
51
55
  try {
52
- this._set(plugins[name.toLowerCase()], { name, config })
56
+ this._set(plugin, { name, config })
53
57
  } catch (e) {
54
58
  log.debug(`Could not find a plugin named "${name}".`)
55
59
  }
@@ -69,6 +73,7 @@ class Instrumenter {
69
73
  Object.keys(plugins)
70
74
  .filter(name => !this._plugins.has(plugins[name]))
71
75
  .forEach(name => {
76
+ if (plugins[name].prototype instanceof Plugin) return
72
77
  const pluginConfig = {}
73
78
  if (serviceMapping && serviceMapping[name]) {
74
79
  pluginConfig.service = serviceMapping[name]
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const NoopSpan = require('./noop/span')
3
+ const { storage } = require('../../datadog-core')
4
4
 
5
5
  const _default = {
6
6
  debug: msg => console.debug(msg), /* eslint-disable-line no-console */
@@ -45,11 +45,11 @@ function processMsg (msg) {
45
45
  }
46
46
 
47
47
  function withNoop (fn) {
48
- if (!log._tracer) {
49
- fn()
50
- } else {
51
- log._tracer.scope().activate(log._noopSpan(), fn)
52
- }
48
+ const store = storage.getStore()
49
+
50
+ storage.enterWith({ noop: true })
51
+ fn()
52
+ storage.enterWith(store)
53
53
  }
54
54
 
55
55
  const log = {
@@ -73,18 +73,9 @@ const log = {
73
73
  return this
74
74
  },
75
75
 
76
- _noopSpan () {
77
- if (!this.__noopSpan) {
78
- this.__noopSpan = new NoopSpan(this._tracer)
79
- }
80
- return this.__noopSpan
81
- },
82
-
83
76
  reset () {
84
77
  this._logger = _default
85
78
  this._enabled = false
86
- delete this._tracer
87
- delete this.__noopSpan
88
79
  this._deprecate = memoize((code, message) => {
89
80
  withNoop(() => this._logger.error(message))
90
81
  return this
@@ -9,7 +9,6 @@ class NoopSpanContext extends DatadogSpanContext {
9
9
  constructor (props) {
10
10
  super(props)
11
11
 
12
- this._traceFlags.sampled = false
13
12
  this._sampling.priority = USER_REJECT
14
13
  }
15
14
  }
@@ -1,7 +1,6 @@
1
1
  'use strict'
2
2
 
3
3
  const Tracer = require('opentracing').Tracer
4
- const ScopeManager = require('../scope/noop/scope_manager')
5
4
  const Scope = require('../noop/scope')
6
5
  const Span = require('./span')
7
6
 
@@ -9,7 +8,6 @@ class NoopTracer extends Tracer {
9
8
  constructor (config) {
10
9
  super(config)
11
10
 
12
- this._scopeManager = new ScopeManager()
13
11
  this._scope = new Scope()
14
12
  this._span = new Span(this)
15
13
  }
@@ -22,10 +20,6 @@ class NoopTracer extends Tracer {
22
20
  return fn
23
21
  }
24
22
 
25
- scopeManager () {
26
- return this._scopeManager
27
- }
28
-
29
23
  scope () {
30
24
  return this._scope
31
25
  }