dd-trace 3.0.0 → 3.1.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 (28) hide show
  1. package/LICENSE-3rdparty.csv +1 -0
  2. package/MIGRATING.md +6 -6
  3. package/package.json +2 -1
  4. package/packages/datadog-core/src/storage/async_resource.js +19 -1
  5. package/packages/datadog-instrumentations/src/cucumber.js +15 -0
  6. package/packages/datadog-instrumentations/src/helpers/instrumentations.js +5 -1
  7. package/packages/datadog-instrumentations/src/jest.js +33 -11
  8. package/packages/datadog-plugin-cucumber/src/index.js +4 -0
  9. package/packages/datadog-plugin-jest/src/index.js +25 -4
  10. package/packages/datadog-plugin-mongodb-core/src/index.js +21 -6
  11. package/packages/datadog-plugin-oracledb/src/index.js +12 -4
  12. package/packages/dd-trace/index.js +1 -1
  13. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +50 -0
  14. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +53 -8
  15. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +23 -24
  16. package/packages/dd-trace/src/config.js +7 -0
  17. package/packages/dd-trace/src/encode/0.4.js +51 -58
  18. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +13 -34
  19. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +84 -0
  20. package/packages/dd-trace/src/exporters/agent/index.js +13 -7
  21. package/packages/dd-trace/src/exporters/agent/writer.js +1 -1
  22. package/packages/dd-trace/src/exporters/common/request.js +20 -9
  23. package/packages/dd-trace/src/exporters/common/writer.js +9 -6
  24. package/packages/dd-trace/src/index.js +10 -0
  25. package/packages/dd-trace/src/noop/proxy.js +77 -0
  26. package/packages/dd-trace/src/plugin_manager.js +6 -4
  27. package/packages/dd-trace/src/proxy.js +5 -62
  28. package/packages/dd-trace/src/telemetry.js +1 -1
@@ -13,7 +13,8 @@ float64Array[0] = -1
13
13
  const bigEndian = uInt8Float64Array[7] === 0
14
14
 
15
15
  class AgentEncoder {
16
- constructor (writer) {
16
+ constructor (writer, limit = SOFT_LIMIT) {
17
+ this._limit = limit
17
18
  this._traceBytes = new Chunk()
18
19
  this._stringBytes = new Chunk()
19
20
  this._writer = writer
@@ -41,7 +42,8 @@ class AgentEncoder {
41
42
  })
42
43
 
43
44
  // we can go over the soft limit since the agent has a 50MB hard limit
44
- if (this._traceBytes.length > SOFT_LIMIT || this._stringBytes.length > SOFT_LIMIT) {
45
+ if (this._traceBytes.length > this._limit || this._stringBytes.length > this._limit) {
46
+ log.debug('Buffer went over soft limit, flushing')
45
47
  this._writer.flush()
46
48
  }
47
49
  }
@@ -113,29 +115,37 @@ class AgentEncoder {
113
115
 
114
116
  _encodeArrayPrefix (bytes, value) {
115
117
  const length = value.length
116
- const buffer = bytes.buffer
117
118
  const offset = bytes.length
118
119
 
119
120
  bytes.reserve(5)
120
121
  bytes.length += 5
121
122
 
122
- buffer[offset] = 0xdd
123
- buffer[offset + 1] = length >> 24
124
- buffer[offset + 2] = length >> 16
125
- buffer[offset + 3] = length >> 8
126
- buffer[offset + 4] = length
123
+ bytes.buffer[offset] = 0xdd
124
+ bytes.buffer[offset + 1] = length >> 24
125
+ bytes.buffer[offset + 2] = length >> 16
126
+ bytes.buffer[offset + 3] = length >> 8
127
+ bytes.buffer[offset + 4] = length
127
128
  }
128
129
 
129
- _encodeByte (bytes, value) {
130
- const buffer = bytes.buffer
130
+ _encodeMapPrefix (bytes, keysLength) {
131
+ const offset = bytes.length
131
132
 
133
+ bytes.reserve(5)
134
+ bytes.length += 5
135
+ bytes.buffer[offset] = 0xdf
136
+ bytes.buffer[offset + 1] = keysLength >> 24
137
+ bytes.buffer[offset + 2] = keysLength >> 16
138
+ bytes.buffer[offset + 3] = keysLength >> 8
139
+ bytes.buffer[offset + 4] = keysLength
140
+ }
141
+
142
+ _encodeByte (bytes, value) {
132
143
  bytes.reserve(1)
133
144
 
134
- buffer[bytes.length++] = value
145
+ bytes.buffer[bytes.length++] = value
135
146
  }
136
147
 
137
148
  _encodeId (bytes, id) {
138
- const buffer = bytes.buffer
139
149
  const offset = bytes.length
140
150
 
141
151
  bytes.reserve(9)
@@ -143,33 +153,31 @@ class AgentEncoder {
143
153
 
144
154
  id = id.toArray()
145
155
 
146
- buffer[offset] = 0xcf
147
- buffer[offset + 1] = id[0]
148
- buffer[offset + 2] = id[1]
149
- buffer[offset + 3] = id[2]
150
- buffer[offset + 4] = id[3]
151
- buffer[offset + 5] = id[4]
152
- buffer[offset + 6] = id[5]
153
- buffer[offset + 7] = id[6]
154
- buffer[offset + 8] = id[7]
156
+ bytes.buffer[offset] = 0xcf
157
+ bytes.buffer[offset + 1] = id[0]
158
+ bytes.buffer[offset + 2] = id[1]
159
+ bytes.buffer[offset + 3] = id[2]
160
+ bytes.buffer[offset + 4] = id[3]
161
+ bytes.buffer[offset + 5] = id[4]
162
+ bytes.buffer[offset + 6] = id[5]
163
+ bytes.buffer[offset + 7] = id[6]
164
+ bytes.buffer[offset + 8] = id[7]
155
165
  }
156
166
 
157
167
  _encodeInteger (bytes, value) {
158
- const buffer = bytes.buffer
159
168
  const offset = bytes.length
160
169
 
161
170
  bytes.reserve(5)
162
171
  bytes.length += 5
163
172
 
164
- buffer[offset] = 0xce
165
- buffer[offset + 1] = value >> 24
166
- buffer[offset + 2] = value >> 16
167
- buffer[offset + 3] = value >> 8
168
- buffer[offset + 4] = value
173
+ bytes.buffer[offset] = 0xce
174
+ bytes.buffer[offset + 1] = value >> 24
175
+ bytes.buffer[offset + 2] = value >> 16
176
+ bytes.buffer[offset + 3] = value >> 8
177
+ bytes.buffer[offset + 4] = value
169
178
  }
170
179
 
171
180
  _encodeLong (bytes, value) {
172
- const buffer = bytes.buffer
173
181
  const offset = bytes.length
174
182
  const hi = (value / Math.pow(2, 32)) >> 0
175
183
  const lo = value >>> 0
@@ -177,40 +185,27 @@ class AgentEncoder {
177
185
  bytes.reserve(9)
178
186
  bytes.length += 9
179
187
 
180
- buffer[offset] = 0xcf
181
- buffer[offset + 1] = hi >> 24
182
- buffer[offset + 2] = hi >> 16
183
- buffer[offset + 3] = hi >> 8
184
- buffer[offset + 4] = hi
185
- buffer[offset + 5] = lo >> 24
186
- buffer[offset + 6] = lo >> 16
187
- buffer[offset + 7] = lo >> 8
188
- buffer[offset + 8] = lo
188
+ bytes.buffer[offset] = 0xcf
189
+ bytes.buffer[offset + 1] = hi >> 24
190
+ bytes.buffer[offset + 2] = hi >> 16
191
+ bytes.buffer[offset + 3] = hi >> 8
192
+ bytes.buffer[offset + 4] = hi
193
+ bytes.buffer[offset + 5] = lo >> 24
194
+ bytes.buffer[offset + 6] = lo >> 16
195
+ bytes.buffer[offset + 7] = lo >> 8
196
+ bytes.buffer[offset + 8] = lo
189
197
  }
190
198
 
191
199
  _encodeMap (bytes, value) {
192
200
  const keys = Object.keys(value)
193
- const buffer = bytes.buffer
194
- const offset = bytes.length
195
-
196
- bytes.reserve(5)
197
- bytes.length += 5
201
+ const validKeys = keys.filter(key => typeof value[key] === 'string' || typeof value[key] === 'number')
198
202
 
199
- let length = 0
200
-
201
- for (const key of keys) {
202
- if (typeof value[key] !== 'string' && typeof value[key] !== 'number') return
203
- length++
203
+ this._encodeMapPrefix(bytes, validKeys.length)
204
204
 
205
+ for (const key of validKeys) {
205
206
  this._encodeString(bytes, key)
206
207
  this._encodeValue(bytes, value[key])
207
208
  }
208
-
209
- buffer[offset] = 0xdf
210
- buffer[offset + 1] = length >> 24
211
- buffer[offset + 2] = length >> 16
212
- buffer[offset + 3] = length >> 8
213
- buffer[offset + 4] = length
214
209
  }
215
210
 
216
211
  _encodeValue (bytes, value) {
@@ -237,21 +232,19 @@ class AgentEncoder {
237
232
  _encodeFloat (bytes, value) {
238
233
  float64Array[0] = value
239
234
 
240
- const buffer = bytes.buffer
241
235
  const offset = bytes.length
242
-
243
236
  bytes.reserve(9)
244
237
  bytes.length += 9
245
238
 
246
- buffer[offset] = 0xcb
239
+ bytes.buffer[offset] = 0xcb
247
240
 
248
241
  if (bigEndian) {
249
242
  for (let i = 0; i <= 7; i++) {
250
- buffer[offset + i + 1] = uInt8Float64Array[i]
243
+ bytes.buffer[offset + i + 1] = uInt8Float64Array[i]
251
244
  }
252
245
  } else {
253
246
  for (let i = 7; i >= 0; i--) {
254
- buffer[bytes.length - i - 1] = uInt8Float64Array[i]
247
+ bytes.buffer[bytes.length - i - 1] = uInt8Float64Array[i]
255
248
  }
256
249
  }
257
250
  }
@@ -1,10 +1,8 @@
1
1
  'use strict'
2
2
  const { truncateSpan, normalizeSpan } = require('./tags-processors')
3
- const Chunk = require('./chunk')
4
3
  const { AgentEncoder } = require('./0.4')
5
4
  const { version: ddTraceVersion } = require('../../../../package.json')
6
5
  const id = require('../../../dd-trace/src/id')
7
-
8
6
  const ENCODING_VERSION = 1
9
7
 
10
8
  const ALLOWED_CONTENT_TYPES = ['test_session_end', 'test_suite_end', 'test']
@@ -12,7 +10,7 @@ const ALLOWED_CONTENT_TYPES = ['test_session_end', 'test_suite_end', 'test']
12
10
  const TEST_SUITE_KEYS_LENGTH = 11
13
11
  const TEST_SESSION_KEYS_LENGTH = 10
14
12
 
15
- const CHUNK_SIZE = 4 * 1024 * 1024 // 4MB
13
+ const INTAKE_SOFT_LIMIT = 2 * 1024 * 1024 // 2MB
16
14
 
17
15
  function formatSpan (span) {
18
16
  let encodingVersion = ENCODING_VERSION
@@ -27,16 +25,11 @@ function formatSpan (span) {
27
25
  }
28
26
 
29
27
  class AgentlessCiVisibilityEncoder extends AgentEncoder {
30
- constructor ({ runtimeId, service, env }) {
31
- super(...arguments)
32
- this._events = []
28
+ constructor (writer, { runtimeId, service, env }) {
29
+ super(writer, INTAKE_SOFT_LIMIT)
33
30
  this.runtimeId = runtimeId
34
31
  this.service = service
35
32
  this.env = env
36
- this._traceBytes = new Chunk(CHUNK_SIZE)
37
- this._stringBytes = new Chunk(CHUNK_SIZE)
38
- this._stringCount = 0
39
- this._stringMap = {}
40
33
 
41
34
  // Used to keep track of the number of encoded events to update the
42
35
  // length of `payload.events` when calling `makePayload`
@@ -186,35 +179,21 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
186
179
  const lo = value >>> 0
187
180
  const flag = isPositive ? 0xcf : 0xd3
188
181
 
189
- const buffer = bytes.buffer
190
182
  const offset = bytes.length
191
183
 
192
184
  // int 64
193
185
  bytes.reserve(9)
194
186
  bytes.length += 9
195
187
 
196
- buffer[offset] = flag
197
- buffer[offset + 1] = hi >> 24
198
- buffer[offset + 2] = hi >> 16
199
- buffer[offset + 3] = hi >> 8
200
- buffer[offset + 4] = hi
201
- buffer[offset + 5] = lo >> 24
202
- buffer[offset + 6] = lo >> 16
203
- buffer[offset + 7] = lo >> 8
204
- buffer[offset + 8] = lo
205
- }
206
-
207
- _encodeMapPrefix (bytes, keysLength) {
208
- const buffer = bytes.buffer
209
- const offset = bytes.length
210
-
211
- bytes.reserve(5)
212
- bytes.length += 5
213
- buffer[offset] = 0xdf
214
- buffer[offset + 1] = keysLength >> 24
215
- buffer[offset + 2] = keysLength >> 16
216
- buffer[offset + 3] = keysLength >> 8
217
- buffer[offset + 4] = keysLength
188
+ bytes.buffer[offset] = flag
189
+ bytes.buffer[offset + 1] = hi >> 24
190
+ bytes.buffer[offset + 2] = hi >> 16
191
+ bytes.buffer[offset + 3] = hi >> 8
192
+ bytes.buffer[offset + 4] = hi
193
+ bytes.buffer[offset + 5] = lo >> 24
194
+ bytes.buffer[offset + 6] = lo >> 16
195
+ bytes.buffer[offset + 7] = lo >> 8
196
+ bytes.buffer[offset + 8] = lo
218
197
  }
219
198
 
220
199
  _encode (bytes, trace) {
@@ -240,7 +219,7 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
240
219
  const traceSize = bytes.length
241
220
  const buffer = Buffer.allocUnsafe(traceSize)
242
221
 
243
- bytes.buffer.copy(buffer, 0, 0, bytes.length)
222
+ bytes.buffer.copy(buffer, 0, 0, traceSize)
244
223
 
245
224
  this.reset()
246
225
 
@@ -0,0 +1,84 @@
1
+ 'use strict'
2
+ const { AgentEncoder } = require('./0.4')
3
+ const Chunk = require('./chunk')
4
+
5
+ const FormData = require('../exporters/common/form-data')
6
+
7
+ const COVERAGE_PAYLOAD_VERSION = 1
8
+ const COVERAGE_KEYS_LENGTH = 4
9
+ const MAXIMUM_NUM_COVERAGE_FILES = 100
10
+
11
+ class CoverageCIVisibilityEncoder extends AgentEncoder {
12
+ constructor () {
13
+ super(...arguments)
14
+ this.codeCoverageBuffers = []
15
+ this._coverageBytes = new Chunk()
16
+ this.reset()
17
+ }
18
+
19
+ count () {
20
+ return this.codeCoverageBuffers.length
21
+ }
22
+
23
+ encode (coverage) {
24
+ const bytes = this._coverageBytes
25
+ const coverageBuffer = this.encodeCodeCoverage(bytes, coverage)
26
+ this.codeCoverageBuffers.push(coverageBuffer)
27
+ this.reset()
28
+ }
29
+
30
+ encodeCodeCoverage (bytes, coverage) {
31
+ this._encodeMapPrefix(bytes, COVERAGE_KEYS_LENGTH)
32
+ this._encodeString(bytes, 'version')
33
+ this._encodeInteger(bytes, COVERAGE_PAYLOAD_VERSION)
34
+ this._encodeString(bytes, 'trace_id')
35
+ this._encodeId(bytes, coverage.traceId)
36
+ this._encodeString(bytes, 'span_id')
37
+ this._encodeId(bytes, coverage.spanId)
38
+ this._encodeString(bytes, 'files')
39
+ this._encodeArrayPrefix(bytes, coverage.files)
40
+ for (const filename of coverage.files) {
41
+ this._encodeMapPrefix(bytes, 1)
42
+ this._encodeString(bytes, 'filename')
43
+ this._encodeString(bytes, filename)
44
+ }
45
+ const traceSize = bytes.length
46
+ const buffer = Buffer.allocUnsafe(traceSize)
47
+
48
+ bytes.buffer.copy(buffer, 0, 0, bytes.length)
49
+
50
+ return buffer
51
+ }
52
+
53
+ reset () {
54
+ this._reset()
55
+ if (this._coverageBytes) {
56
+ this._coverageBytes.length = 0
57
+ }
58
+ }
59
+
60
+ makePayload () {
61
+ const form = new FormData()
62
+
63
+ let coverageFileIndex = 1
64
+
65
+ for (const coverageBuffer of this.codeCoverageBuffers.slice(0, MAXIMUM_NUM_COVERAGE_FILES)) {
66
+ const coverageFilename = `coverage${coverageFileIndex++}`
67
+ form.append(
68
+ coverageFilename,
69
+ coverageBuffer,
70
+ {
71
+ filename: `${coverageFilename}.msgpack`,
72
+ contentType: 'application/msgpack'
73
+ }
74
+ )
75
+ }
76
+ // 'event' is a backend requirement
77
+ form.append('event', JSON.stringify({}), { filename: 'event.json', contentType: 'application/json' })
78
+ this.codeCoverageBuffers = this.codeCoverageBuffers.slice(MAXIMUM_NUM_COVERAGE_FILES)
79
+
80
+ return form
81
+ }
82
+ }
83
+
84
+ module.exports = { CoverageCIVisibilityEncoder }
@@ -3,17 +3,16 @@
3
3
  const URL = require('url').URL
4
4
  const log = require('../../log')
5
5
  const Writer = require('./writer')
6
- const Scheduler = require('../scheduler')
7
6
 
8
7
  class AgentExporter {
9
- constructor ({ url, hostname, port, flushInterval, lookup, protocolVersion }, prioritySampler) {
8
+ constructor (config, prioritySampler) {
9
+ this._config = config
10
+ const { url, hostname, port, lookup, protocolVersion } = config
10
11
  this._url = url || new URL(`http://${hostname || 'localhost'}:${port}`)
11
12
  this._writer = new Writer({ url: this._url, prioritySampler, lookup, protocolVersion })
12
13
 
13
- if (flushInterval > 0) {
14
- this._scheduler = new Scheduler(() => this._writer.flush(), flushInterval)
15
- }
16
- this._scheduler && this._scheduler.start()
14
+ this._timer = undefined
15
+ process.once('beforeExit', () => this._writer.flush())
17
16
  }
18
17
 
19
18
  setUrl (url) {
@@ -29,8 +28,15 @@ class AgentExporter {
29
28
  export (spans) {
30
29
  this._writer.append(spans)
31
30
 
32
- if (!this._scheduler) {
31
+ const { flushInterval } = this._config
32
+
33
+ if (flushInterval === 0) {
33
34
  this._writer.flush()
35
+ } else if (flushInterval > 0 && !this._timer) {
36
+ this._timer = setTimeout(() => {
37
+ this._writer.flush()
38
+ this._timer = clearTimeout(this._timer)
39
+ }, flushInterval).unref()
34
40
  }
35
41
  }
36
42
  }
@@ -99,7 +99,7 @@ function makeRequest (version, data, count, url, lookup, needsStartupLog, cb) {
99
99
 
100
100
  log.debug(() => `Request to the agent: ${JSON.stringify(options)}`)
101
101
 
102
- request(data, options, true, (err, res, status) => {
102
+ request(data, options, (err, res, status) => {
103
103
  if (needsStartupLog) {
104
104
  // Note that logging will only happen once, regardless of how many times this is called.
105
105
  startupLog({
@@ -3,10 +3,12 @@
3
3
  // TODO: Add test with slow or unresponsive agent.
4
4
  // TODO: Add telemetry for things like dropped requests, errors, etc.
5
5
 
6
+ const { Readable } = require('stream')
6
7
  const http = require('http')
7
8
  const https = require('https')
8
9
  const docker = require('./docker')
9
10
  const { storage } = require('../../../../datadog-core')
11
+ const log = require('../../log')
10
12
 
11
13
  const keepAlive = true
12
14
  const maxTotalSockets = 1
@@ -17,26 +19,28 @@ const containerId = docker.id()
17
19
 
18
20
  let activeRequests = 0
19
21
 
20
- function request (data, options, keepAlive, callback) {
22
+ function request (data, options, callback) {
21
23
  if (!options.headers) {
22
24
  options.headers = {}
23
25
  }
24
26
 
27
+ const isReadable = data instanceof Readable
28
+
25
29
  // The timeout should be kept low to avoid excessive queueing.
26
30
  const timeout = options.timeout || 2000
27
31
  const isSecure = options.protocol === 'https:'
28
32
  const client = isSecure ? https : http
29
33
  const dataArray = [].concat(data)
30
34
 
31
- options.headers['Content-Length'] = byteLength(dataArray)
35
+ if (!isReadable) {
36
+ options.headers['Content-Length'] = byteLength(dataArray)
37
+ }
32
38
 
33
39
  if (containerId) {
34
40
  options.headers['Datadog-Container-ID'] = containerId
35
41
  }
36
42
 
37
- if (keepAlive) {
38
- options.agent = isSecure ? httpsAgent : httpAgent
39
- }
43
+ options.agent = isSecure ? httpsAgent : httpAgent
40
44
 
41
45
  const onResponse = res => {
42
46
  let responseData = ''
@@ -59,7 +63,10 @@ function request (data, options, keepAlive, callback) {
59
63
  }
60
64
 
61
65
  const makeRequest = onError => {
62
- if (!request.writable) return callback(null)
66
+ if (!request.writable) {
67
+ log.debug('Maximum number of active requests reached: payload is discarded.')
68
+ return callback(null)
69
+ }
63
70
 
64
71
  activeRequests++
65
72
 
@@ -74,10 +81,14 @@ function request (data, options, keepAlive, callback) {
74
81
  onError(err)
75
82
  })
76
83
 
77
- dataArray.forEach(buffer => req.write(buffer))
78
-
79
84
  req.setTimeout(timeout, req.abort)
80
- req.end()
85
+
86
+ if (isReadable) {
87
+ data.pipe(req)
88
+ } else {
89
+ dataArray.forEach(buffer => req.write(buffer))
90
+ req.end()
91
+ }
81
92
 
82
93
  storage.enterWith(store)
83
94
  }
@@ -23,16 +23,19 @@ class Writer {
23
23
  }
24
24
  }
25
25
 
26
- append (spans) {
27
- if (!request.writable) return
26
+ append (payload) {
27
+ if (!request.writable) {
28
+ log.debug(() => `Maximum number of active requests reached. Payload discarded: ${JSON.stringify(payload)}`)
29
+ return
30
+ }
28
31
 
29
- log.debug(() => `Encoding trace: ${JSON.stringify(spans)}`)
32
+ log.debug(() => `Encoding payload: ${JSON.stringify(payload)}`)
30
33
 
31
- this._encode(spans)
34
+ this._encode(payload)
32
35
  }
33
36
 
34
- _encode (trace) {
35
- this._encoder.encode(trace)
37
+ _encode (payload) {
38
+ this._encoder.encode(payload)
36
39
  }
37
40
 
38
41
  setUrl (url) {
@@ -0,0 +1,10 @@
1
+ 'use strict'
2
+
3
+ const { isFalse } = require('./util')
4
+
5
+ // Global `jest` is only present in Jest workers.
6
+ const inJestWorker = typeof jest !== 'undefined'
7
+
8
+ module.exports = isFalse(process.env.DD_TRACE_ENABLED) || inJestWorker
9
+ ? require('./noop/proxy')
10
+ : require('./proxy')
@@ -0,0 +1,77 @@
1
+ 'use strict'
2
+
3
+ const NoopTracer = require('./tracer')
4
+
5
+ const noop = new NoopTracer()
6
+
7
+ class Tracer {
8
+ constructor () {
9
+ this._tracer = noop
10
+ }
11
+
12
+ init () {
13
+ return this
14
+ }
15
+
16
+ use () {
17
+ return this
18
+ }
19
+
20
+ trace (name, options, fn) {
21
+ if (!fn) {
22
+ fn = options
23
+ options = {}
24
+ }
25
+
26
+ if (typeof fn !== 'function') return
27
+
28
+ options = options || {}
29
+
30
+ return this._tracer.trace(name, options, fn)
31
+ }
32
+
33
+ wrap (name, options, fn) {
34
+ if (!fn) {
35
+ fn = options
36
+ options = {}
37
+ }
38
+
39
+ if (typeof fn !== 'function') return fn
40
+
41
+ options = options || {}
42
+
43
+ return this._tracer.wrap(name, options, fn)
44
+ }
45
+
46
+ setUrl () {
47
+ this._tracer.setUrl.apply(this._tracer, arguments)
48
+ return this
49
+ }
50
+
51
+ startSpan () {
52
+ return this._tracer.startSpan.apply(this._tracer, arguments)
53
+ }
54
+
55
+ inject () {
56
+ return this._tracer.inject.apply(this._tracer, arguments)
57
+ }
58
+
59
+ extract () {
60
+ return this._tracer.extract.apply(this._tracer, arguments)
61
+ }
62
+
63
+ scope () {
64
+ return this._tracer.scope.apply(this._tracer, arguments)
65
+ }
66
+
67
+ getRumData () {
68
+ return this._tracer.getRumData.apply(this._tracer, arguments)
69
+ }
70
+
71
+ setUser () {
72
+ this._tracer.setUser.apply(this._tracer, arguments)
73
+ return this
74
+ }
75
+ }
76
+
77
+ module.exports = Tracer
@@ -120,7 +120,8 @@ module.exports = class PluginManager {
120
120
  logInjection,
121
121
  serviceMapping,
122
122
  experimental,
123
- queryStringObfuscation
123
+ queryStringObfuscation,
124
+ isIntelligentTestRunnerEnabled
124
125
  } = this._tracerConfig
125
126
 
126
127
  const sharedConfig = {}
@@ -133,11 +134,12 @@ module.exports = class PluginManager {
133
134
  sharedConfig.queryStringObfuscation = queryStringObfuscation
134
135
  }
135
136
 
136
- // TODO: update so that it's available for every CI Visibility's plugin
137
- if (name === 'mocha') {
138
- sharedConfig.isAgentlessEnabled = experimental && experimental.exporter === 'datadog'
137
+ if (experimental) {
138
+ sharedConfig.isAgentlessEnabled = experimental.exporter === 'datadog'
139
139
  }
140
140
 
141
+ sharedConfig.isIntelligentTestRunnerEnabled = isIntelligentTestRunnerEnabled
142
+
141
143
  if (serviceMapping && serviceMapping[name]) {
142
144
  sharedConfig.service = serviceMapping[name]
143
145
  }