dd-trace 2.12.0 → 3.0.0-pre.1

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.
package/ci/init.js CHANGED
@@ -1,10 +1,7 @@
1
1
  /* eslint-disable no-console */
2
-
3
- const path = require('path')
4
2
  const tracer = require('../packages/dd-trace')
5
3
  const { ORIGIN_KEY } = require('../packages/dd-trace/src/constants')
6
- const { mochaHook } = require('../packages/datadog-instrumentations/src/mocha')
7
- const { pickleHook, testCaseHook } = require('../packages/datadog-instrumentations/src/cucumber')
4
+ const { isTrue } = require('../packages/dd-trace/src/util')
8
5
 
9
6
  const options = {
10
7
  startupLogs: false,
@@ -15,9 +12,7 @@ const options = {
15
12
 
16
13
  let shouldInit = true
17
14
 
18
- const isAgentlessEnabled = process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED &&
19
- process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== 'false' &&
20
- process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== '0'
15
+ const isAgentlessEnabled = isTrue(process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED)
21
16
 
22
17
  if (isAgentlessEnabled) {
23
18
  if (process.env.DATADOG_API_KEY || process.env.DD_API_KEY) {
@@ -32,25 +27,6 @@ so dd-trace will not be initialized.`)
32
27
  }
33
28
  }
34
29
 
35
- // TODO: remove this in a later major version since we now recommend using
36
- // `NODE_OPTIONS='-r dd-trace/ci/init'`.
37
- try {
38
- for (const filename in require.cache) {
39
- const cache = require.cache[filename]
40
- const id = filename.split(path.sep).join('/')
41
-
42
- if (id.includes('/node_modules/mocha/lib/runner.js')) {
43
- cache.exports = mochaHook(cache.exports)
44
- } else if (id.includes('/node_modules/@cucumber/cucumber/lib/runtime/pickle_runner.js')) {
45
- cache.exports = pickleHook(cache.exports)
46
- } else if (id.includes('/node_modules/@cucumber/cucumber/lib/runtime/test_case_runner.js')) {
47
- cache.exports = testCaseHook(cache.exports)
48
- }
49
- }
50
- } catch (e) {
51
- // ignore error and let the tracer initialize anyway
52
- }
53
-
54
30
  if (shouldInit) {
55
31
  tracer.init(options)
56
32
  tracer.use('fs', false)
package/ci/jest/env.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  const tracer = require('../../packages/dd-trace')
4
4
  const { ORIGIN_KEY } = require('../../packages/dd-trace/src/constants')
5
+ const { isTrue } = require('../../packages/dd-trace/src/util')
5
6
 
6
7
  const options = {
7
8
  startupLogs: false,
@@ -10,9 +11,7 @@ const options = {
10
11
  }
11
12
  }
12
13
 
13
- const isAgentlessEnabled = process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED &&
14
- process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== 'false' &&
15
- process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED !== '0'
14
+ const isAgentlessEnabled = isTrue(process.env.DD_CIVISIBILITY_AGENTLESS_ENABLED)
16
15
 
17
16
  if (isAgentlessEnabled) {
18
17
  if (process.env.DATADOG_API_KEY || process.env.DD_API_KEY) {
package/index.d.ts CHANGED
@@ -562,7 +562,6 @@ interface Plugins {
562
562
  "elasticsearch": plugins.elasticsearch;
563
563
  "express": plugins.express;
564
564
  "fastify": plugins.fastify;
565
- "fs": plugins.fs;
566
565
  "generic-pool": plugins.generic_pool;
567
566
  "google-cloud-pubsub": plugins.google_cloud_pubsub;
568
567
  "graphql": plugins.graphql;
@@ -903,12 +902,6 @@ declare namespace plugins {
903
902
  */
904
903
  interface fastify extends HttpServer {}
905
904
 
906
- /**
907
- * This plugin automatically instruments the
908
- * [fs](https://nodejs.org/api/fs.html) module.
909
- */
910
- interface fs extends Instrumentation {}
911
-
912
905
  /**
913
906
  * This plugin patches the [generic-pool](https://github.com/coopernurse/node-pool)
914
907
  * module to bind the callbacks the the caller context.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "2.12.0",
3
+ "version": "3.0.0-pre.1",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -78,12 +78,12 @@ function wrapLayerHandle (layer) {
78
78
 
79
79
  try {
80
80
  return original.apply(this, arguments)
81
- } catch (e) {
82
- errorChannel.publish(e)
81
+ } catch (error) {
82
+ errorChannel.publish({ req, error })
83
83
  nextChannel.publish({ req })
84
84
  exitChannel.publish({ req })
85
85
 
86
- throw e
86
+ throw error
87
87
  }
88
88
  })
89
89
  })
@@ -92,7 +92,7 @@ function wrapLayerHandle (layer) {
92
92
  function wrapNext (req, next) {
93
93
  return function (error) {
94
94
  if (error) {
95
- errorChannel.publish(error)
95
+ errorChannel.publish({ req, error })
96
96
  }
97
97
 
98
98
  nextChannel.publish({ req })
@@ -6,7 +6,6 @@ const { addHook, channel, AsyncResource } = require('./helpers/instrument')
6
6
  const errorChannel = channel('apm:fastify:middleware:error')
7
7
  const handleChannel = channel('apm:fastify:request:handle')
8
8
 
9
- const requestResources = new WeakMap()
10
9
  const parsingResources = new WeakMap()
11
10
 
12
11
  function wrapFastify (fastify, hasParsingEvents) {
@@ -42,16 +41,13 @@ function wrapAddHook (addHook) {
42
41
 
43
42
  arguments[arguments.length - 1] = shimmer.wrap(fn, function (request, reply, done) {
44
43
  const req = getReq(request)
45
- const requestResource = requestResources.get(req)
46
-
47
- if (!requestResource) return fn.apply(this, arguments)
48
44
 
49
45
  try {
50
46
  if (typeof done === 'function') {
51
47
  done = arguments[arguments.length - 1]
52
48
 
53
49
  arguments[arguments.length - 1] = function (err) {
54
- publishError(err, requestResource)
50
+ publishError(err, req)
55
51
 
56
52
  if (name === 'onRequest' || name === 'preParsing') {
57
53
  const parsingResource = new AsyncResource('bound-anonymous-fn')
@@ -71,13 +67,13 @@ function wrapAddHook (addHook) {
71
67
  const promise = fn.apply(this, arguments)
72
68
 
73
69
  if (promise && typeof promise.catch === 'function') {
74
- return promise.catch(err => publishError(err, requestResource))
70
+ return promise.catch(err => publishError(err, req))
75
71
  }
76
72
 
77
73
  return promise
78
74
  }
79
75
  } catch (e) {
80
- throw publishError(e, requestResource)
76
+ throw publishError(e, req)
81
77
  }
82
78
  })
83
79
 
@@ -90,14 +86,10 @@ function onRequest (request, reply, done) {
90
86
 
91
87
  const req = getReq(request)
92
88
  const res = getRes(reply)
93
- const requestResource = new AsyncResource('bound-anonymous-fn')
94
89
 
95
- requestResources.set(req, requestResource)
90
+ handleChannel.publish({ req, res })
96
91
 
97
- return requestResource.runInAsyncScope(() => {
98
- handleChannel.publish({ req, res })
99
- return done()
100
- })
92
+ return done()
101
93
  }
102
94
 
103
95
  function preHandler (request, reply, done) {
@@ -105,9 +97,8 @@ function preHandler (request, reply, done) {
105
97
  if (!reply || typeof reply.send !== 'function') return done()
106
98
 
107
99
  const req = getReq(request)
108
- const requestResource = requestResources.get(req)
109
100
 
110
- reply.send = wrapSend(reply.send, requestResource)
101
+ reply.send = wrapSend(reply.send, req)
111
102
 
112
103
  done()
113
104
  }
@@ -133,12 +124,10 @@ function preParsing (request, reply, payload, done) {
133
124
  parsingResource.runInAsyncScope(() => done())
134
125
  }
135
126
 
136
- function wrapSend (send, resource) {
137
- return function sendWithTrace (payload) {
138
- if (payload instanceof Error) {
139
- resource.runInAsyncScope(() => {
140
- errorChannel.publish(payload)
141
- })
127
+ function wrapSend (send, req) {
128
+ return function sendWithTrace (error) {
129
+ if (error instanceof Error) {
130
+ errorChannel.publish({ req, error })
142
131
  }
143
132
 
144
133
  return send.apply(this, arguments)
@@ -153,11 +142,9 @@ function getRes (reply) {
153
142
  return reply && (reply.raw || reply.res || reply)
154
143
  }
155
144
 
156
- function publishError (error, resource) {
145
+ function publishError (error, req) {
157
146
  if (error) {
158
- resource.runInAsyncScope(() => {
159
- errorChannel.publish(error)
160
- })
147
+ errorChannel.publish({ error, req })
161
148
  }
162
149
 
163
150
  return error
@@ -126,13 +126,13 @@ function wrapMiddleware (fn, layer) {
126
126
  }
127
127
 
128
128
  function fulfill (ctx, error) {
129
- if (error) {
130
- errorChannel.publish(error)
131
- }
132
-
133
129
  const req = ctx.req
134
130
  const route = ctx.routePath
135
131
 
132
+ if (error) {
133
+ errorChannel.publish({ req, error })
134
+ }
135
+
136
136
  // TODO: make sure that the parent class cannot override this in `enter`
137
137
  if (route) {
138
138
  routeChannel.publish({ req, route })
@@ -49,12 +49,12 @@ function createWrapRouterMethod (name) {
49
49
 
50
50
  try {
51
51
  return original.apply(this, arguments)
52
- } catch (e) {
53
- errorChannel.publish(e)
52
+ } catch (error) {
53
+ errorChannel.publish({ req, error })
54
54
  nextChannel.publish({ req })
55
55
  exitChannel.publish({ req })
56
56
 
57
- throw e
57
+ throw error
58
58
  }
59
59
  })
60
60
  })
@@ -91,7 +91,7 @@ function createWrapRouterMethod (name) {
91
91
  function wrapNext (req, next) {
92
92
  return function (error) {
93
93
  if (error) {
94
- errorChannel.publish(error)
94
+ errorChannel.publish({ req, error })
95
95
  }
96
96
 
97
97
  nextChannel.publish({ req })
@@ -19,13 +19,13 @@ class GrpcClientPlugin extends Plugin {
19
19
  const metadataFilter = this.config.metadataFilter
20
20
  const store = storage.getStore()
21
21
  const childOf = store && store.span
22
- const span = this.tracer.startSpan('grpc.request', {
22
+ const span = this.tracer.startSpan('grpc.client', {
23
23
  childOf,
24
24
  tags: {
25
25
  [Tags.SPAN_KIND]: 'client',
26
26
  'span.type': 'http',
27
27
  'resource.name': path,
28
- 'service.name': this.config.service || `${this.tracer._service}-grpc-client`,
28
+ 'service.name': this.config.service || this.tracer._service,
29
29
  'component': 'grpc'
30
30
  }
31
31
  })
@@ -19,13 +19,13 @@ class GrpcServerPlugin extends Plugin {
19
19
  const metadataFilter = this.config.metadataFilter
20
20
  const store = storage.getStore()
21
21
  const childOf = extract(this.tracer, metadata)
22
- const span = this.tracer.startSpan('grpc.request', {
22
+ const span = this.tracer.startSpan('grpc.server', {
23
23
  childOf,
24
24
  tags: {
25
25
  [Tags.SPAN_KIND]: 'server',
26
26
  'span.type': 'web',
27
27
  'resource.name': name,
28
- 'service.name': this.config.service || `${this.tracer._service}`,
28
+ 'service.name': this.config.service || this.tracer._service,
29
29
  'component': 'grpc'
30
30
  }
31
31
  })
@@ -190,7 +190,7 @@ function getServiceName (tracer, config, options) {
190
190
  return config.service
191
191
  }
192
192
 
193
- return `${tracer._service}-http-client`
193
+ return tracer._service
194
194
  }
195
195
 
196
196
  function getHost (options) {
@@ -15,7 +15,7 @@ class HttpServerPlugin extends Plugin {
15
15
 
16
16
  this.addSub('apm:http:server:request:start', ({ req, res }) => {
17
17
  const store = storage.getStore()
18
- const span = web.startSpan(this.tracer, this.config, req, res, 'http.request')
18
+ const span = web.startSpan(this.tracer, this.config, req, res, 'web.request')
19
19
 
20
20
  this.enter(span, { ...store, req })
21
21
 
@@ -118,7 +118,7 @@ function getServiceName (tracer, config, sessionDetails) {
118
118
  return config.service
119
119
  }
120
120
 
121
- return `${tracer._service}-http-client`
121
+ return tracer._service
122
122
  }
123
123
 
124
124
  function hasAmazonSignature (headers, path) {
@@ -16,7 +16,10 @@ class RouterPlugin extends WebPlugin {
16
16
  this._contexts = new WeakMap()
17
17
 
18
18
  this.addSub(`apm:${this.constructor.name}:middleware:enter`, ({ req, name, route }) => {
19
- const childOf = this._getActive(req)
19
+ const childOf = this._getActive(req) || this._getStoreSpan()
20
+
21
+ if (!childOf) return
22
+
20
23
  const span = this._getMiddlewareSpan(name, childOf)
21
24
  const context = this._createContext(req, route, childOf)
22
25
 
@@ -46,14 +49,16 @@ class RouterPlugin extends WebPlugin {
46
49
  context.middleware.pop().finish()
47
50
  })
48
51
 
49
- this.addSub(`apm:${this.constructor.name}:middleware:error`, err => {
50
- const store = storage.getStore()
52
+ this.addSub(`apm:${this.constructor.name}:middleware:error`, ({ req, error }) => {
53
+ web.addError(req, error)
51
54
 
52
- web.addError(store.req, err)
55
+ if (!this.config.middleware) return
53
56
 
54
- if (this.config.middleware) {
55
- this.addError(err)
56
- }
57
+ const span = this._getActive(req)
58
+
59
+ if (!span) return
60
+
61
+ span.setTag('error', error)
57
62
  })
58
63
 
59
64
  this.addSub(`apm:http:server:request:finish`, ({ req }) => {
@@ -72,7 +77,7 @@ class RouterPlugin extends WebPlugin {
72
77
  _getActive (req) {
73
78
  const context = this._contexts.get(req)
74
79
 
75
- if (!context) return this._getStoreSpan()
80
+ if (!context) return
76
81
  if (context.middleware.length === 0) return context.span
77
82
 
78
83
  return context.middleware[context.middleware.length - 1]
@@ -13,6 +13,9 @@ const uuid = require('crypto-randomuuid')
13
13
  const fromEntries = Object.fromEntries || (entries =>
14
14
  entries.reduce((obj, [k, v]) => Object.assign(obj, { [k]: v }), {}))
15
15
 
16
+ // eslint-disable-next-line max-len
17
+ const qsRegex = '(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:(?:\\s|%20)*(?:=|%3D)[^&]+|(?:"|%22)(?:\\s|%20)*(?::|%3A)(?:\\s|%20)*(?:"|%22)(?:%2[^2]|%[^2]|[^"%])+(?:"|%22))|bearer(?:\\s|%20)+[a-z0-9\\._\\-]|token(?::|%3A)[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L](?:[\\w=-]|%3D)+\\.ey[I-L](?:[\\w=-]|%3D)+(?:\\.(?:[\\w.+\\/=-]|%3D|%2F|%2B)+)?|[\\-]{5}BEGIN(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY[\\-]{5}[^\\-]+[\\-]{5}END(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY|ssh-rsa(?:\\s|%20)*(?:[a-z0-9\\/\\.+]|%2F|%5C|%2B){100,}'
18
+
16
19
  class Config {
17
20
  constructor (options) {
18
21
  options = options || {}
@@ -109,6 +112,10 @@ class Config {
109
112
  parseInt(process.env.DD_TRACE_PARTIAL_FLUSH_MIN_SPANS),
110
113
  1000
111
114
  )
115
+ const DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP = coalesce(
116
+ process.env.DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
117
+ qsRegex
118
+ )
112
119
  const DD_TRACE_B3_ENABLED = coalesce(
113
120
  options.experimental && options.experimental.b3,
114
121
  process.env.DD_TRACE_EXPERIMENTAL_B3_ENABLED,
@@ -203,6 +210,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
203
210
  this.flushInterval = coalesce(parseInt(options.flushInterval, 10), defaultFlushInterval)
204
211
  this.flushMinSpans = DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
205
212
  this.sampleRate = coalesce(Math.min(Math.max(sampler.sampleRate, 0), 1), 1)
213
+ this.queryStringObfuscation = DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP
206
214
  this.logger = options.logger
207
215
  this.plugins = !!coalesce(options.plugins, true)
208
216
  this.service = DD_SERVICE
@@ -57,6 +57,10 @@ class AgentEncoder {
57
57
  return buffer
58
58
  }
59
59
 
60
+ reset () {
61
+ this._reset()
62
+ }
63
+
60
64
  _encode (bytes, trace) {
61
65
  this._encodeArrayPrefix(bytes, trace)
62
66
 
@@ -1,22 +1,32 @@
1
1
  'use strict'
2
2
 
3
+ // TODO: Add test with slow or unresponsive agent.
4
+ // TODO: Add telemetry for things like dropped requests, errors, etc.
5
+
3
6
  const http = require('http')
4
7
  const https = require('https')
5
- const log = require('../../log')
6
8
  const docker = require('./docker')
7
9
  const { storage } = require('../../../../datadog-core')
8
10
 
9
- const httpAgent = new http.Agent({ keepAlive: true })
10
- const httpsAgent = new https.Agent({ keepAlive: true })
11
+ const keepAlive = true
12
+ const maxTotalSockets = 8
13
+ const httpAgent = new http.Agent({ keepAlive, maxTotalSockets })
14
+ const httpsAgent = new https.Agent({ keepAlive, maxTotalSockets })
11
15
  const containerId = docker.id()
12
16
 
17
+ let activeRequests = 0
18
+
13
19
  function request (data, options, keepAlive, callback) {
14
20
  if (!options.headers) {
15
21
  options.headers = {}
16
22
  }
23
+
24
+ // The timeout should be kept low to avoid excessive queueing.
25
+ const timeout = options.timeout || 2000
17
26
  const isSecure = options.protocol === 'https:'
18
27
  const client = isSecure ? https : http
19
28
  const dataArray = [].concat(data)
29
+
20
30
  options.headers['Content-Length'] = byteLength(dataArray)
21
31
 
22
32
  if (containerId) {
@@ -27,39 +37,15 @@ function request (data, options, keepAlive, callback) {
27
37
  options.agent = isSecure ? httpsAgent : httpAgent
28
38
  }
29
39
 
30
- const firstRequest = retriableRequest(options, client, callback)
31
- dataArray.forEach(buffer => firstRequest.write(buffer))
32
-
33
- // The first request will be retried
34
- const firstRequestErrorHandler = () => {
35
- log.debug('Retrying request to the intake')
36
- const retriedReq = retriableRequest(options, client, callback)
37
- dataArray.forEach(buffer => retriedReq.write(buffer))
38
- // The retried request will fail normally
39
- retriedReq.on('error', e => callback(new Error(`Network error trying to reach the intake: ${e.message}`)))
40
- retriedReq.end()
41
- }
42
-
43
- firstRequest.on('error', firstRequestErrorHandler)
44
- firstRequest.end()
45
-
46
- return firstRequest
47
- }
48
-
49
- function retriableRequest (options, client, callback) {
50
- const store = storage.getStore()
51
-
52
- storage.enterWith({ noop: true })
53
-
54
- const timeout = options.timeout || 15000
55
-
56
- const request = client.request(options, res => {
40
+ const onResponse = res => {
57
41
  let responseData = ''
58
42
 
59
43
  res.setTimeout(timeout)
60
44
 
61
45
  res.on('data', chunk => { responseData += chunk })
62
46
  res.on('end', () => {
47
+ activeRequests--
48
+
63
49
  if (res.statusCode >= 200 && res.statusCode <= 299) {
64
50
  callback(null, responseData, res.statusCode)
65
51
  } else {
@@ -69,15 +55,43 @@ function retriableRequest (options, client, callback) {
69
55
  callback(error, null, res.statusCode)
70
56
  }
71
57
  })
72
- })
73
- request.setTimeout(timeout, request.abort)
74
- storage.enterWith(store)
58
+ }
75
59
 
76
- return request
60
+ const makeRequest = onError => {
61
+ if (!request.writable) return callback(null)
62
+
63
+ activeRequests++
64
+
65
+ const store = storage.getStore()
66
+
67
+ storage.enterWith({ noop: true })
68
+
69
+ const req = client.request(options, onResponse)
70
+
71
+ req.once('error', err => {
72
+ activeRequests--
73
+ onError(err)
74
+ })
75
+
76
+ dataArray.forEach(buffer => req.write(buffer))
77
+
78
+ req.setTimeout(timeout, req.abort)
79
+ req.end()
80
+
81
+ storage.enterWith(store)
82
+ }
83
+
84
+ makeRequest(() => makeRequest(callback))
77
85
  }
78
86
 
79
87
  function byteLength (data) {
80
88
  return data.length > 0 ? data.reduce((prev, next) => prev + next.length, 0) : 0
81
89
  }
82
90
 
91
+ Object.defineProperty(request, 'writable', {
92
+ get () {
93
+ return activeRequests < maxTotalSockets
94
+ }
95
+ })
96
+
83
97
  module.exports = request
@@ -1,4 +1,6 @@
1
1
  'use strict'
2
+
3
+ const request = require('./request')
2
4
  const log = require('../../log')
3
5
 
4
6
  class Writer {
@@ -9,7 +11,10 @@ class Writer {
9
11
  flush (done = () => {}) {
10
12
  const count = this._encoder.count()
11
13
 
12
- if (count > 0) {
14
+ if (!request.writable) {
15
+ this._encoder.reset()
16
+ done()
17
+ } else if (count > 0) {
13
18
  const payload = this._encoder.makePayload()
14
19
 
15
20
  this._sendPayload(payload, count, done)
@@ -19,6 +24,8 @@ class Writer {
19
24
  }
20
25
 
21
26
  append (spans) {
27
+ if (!request.writable) return
28
+
22
29
  log.debug(() => `Encoding trace: ${JSON.stringify(spans)}`)
23
30
 
24
31
  this._encode(spans)
@@ -24,10 +24,6 @@ class NoopTracer extends Tracer {
24
24
  return this._scope
25
25
  }
26
26
 
27
- currentSpan () {
28
- return null
29
- }
30
-
31
27
  getRumData () {
32
28
  return ''
33
29
  }
@@ -63,7 +63,7 @@ module.exports = class PluginManager {
63
63
 
64
64
  // like instrumenter.enable()
65
65
  configure (config = {}) {
66
- const { logInjection, serviceMapping, experimental } = config
66
+ const { logInjection, serviceMapping, experimental, queryStringObfuscation } = config
67
67
 
68
68
  for (const PluginClass of Object.values(plugins)) {
69
69
  const name = PluginClass.name
@@ -87,6 +87,10 @@ module.exports = class PluginManager {
87
87
  pluginConfig.logInjection = logInjection
88
88
  }
89
89
 
90
+ if (queryStringObfuscation !== undefined) {
91
+ pluginConfig.queryStringObfuscation = queryStringObfuscation
92
+ }
93
+
90
94
  // TODO: update so that it's available for every CI Visibility's plugin
91
95
  if (name === 'mocha') {
92
96
  pluginConfig.isAgentlessEnabled = experimental && experimental.exporter === 'datadog'
@@ -15,7 +15,6 @@ module.exports = {
15
15
  'express': require('../../../datadog-plugin-express/src'),
16
16
  'fastify': require('../../../datadog-plugin-fastify/src'),
17
17
  'find-my-way': require('../../../datadog-plugin-find-my-way/src'),
18
- 'fs': require('../../../datadog-plugin-fs/src'),
19
18
  'google-cloud-pubsub': require('../../../datadog-plugin-google-cloud-pubsub/src'),
20
19
  'graphql': require('../../../datadog-plugin-graphql/src'),
21
20
  'grpc': require('../../../datadog-plugin-grpc/src'),