dd-trace 2.11.0 → 2.12.2

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 (42) hide show
  1. package/LICENSE-3rdparty.csv +0 -2
  2. package/ext/formats.js +3 -5
  3. package/index.d.ts +3 -3
  4. package/package.json +4 -6
  5. package/packages/datadog-core/src/storage/async_hooks.js +4 -4
  6. package/packages/datadog-core/src/storage/async_resource.js +14 -4
  7. package/packages/datadog-instrumentations/src/connect.js +5 -5
  8. package/packages/datadog-instrumentations/src/couchbase.js +166 -61
  9. package/packages/datadog-instrumentations/src/fastify.js +12 -25
  10. package/packages/datadog-instrumentations/src/graphql.js +17 -5
  11. package/packages/datadog-instrumentations/src/koa.js +5 -5
  12. package/packages/datadog-instrumentations/src/mocha.js +92 -19
  13. package/packages/datadog-instrumentations/src/restify.js +28 -10
  14. package/packages/datadog-instrumentations/src/router.js +5 -5
  15. package/packages/datadog-plugin-aws-sdk/src/base.js +1 -2
  16. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -2
  17. package/packages/datadog-plugin-couchbase/src/index.js +8 -10
  18. package/packages/datadog-plugin-graphql/src/resolve.js +2 -0
  19. package/packages/datadog-plugin-http/src/server.js +3 -8
  20. package/packages/datadog-plugin-mocha/src/index.js +80 -3
  21. package/packages/datadog-plugin-next/src/index.js +1 -1
  22. package/packages/datadog-plugin-restify/src/index.js +7 -0
  23. package/packages/datadog-plugin-router/src/index.js +39 -10
  24. package/packages/dd-trace/src/encode/0.4.js +4 -0
  25. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +111 -15
  26. package/packages/dd-trace/src/exporters/common/request.js +49 -34
  27. package/packages/dd-trace/src/exporters/common/writer.js +8 -1
  28. package/packages/dd-trace/src/noop/span.js +12 -12
  29. package/packages/dd-trace/src/noop/tracer.js +8 -5
  30. package/packages/dd-trace/src/opentracing/span.js +63 -49
  31. package/packages/dd-trace/src/opentracing/span_context.js +1 -5
  32. package/packages/dd-trace/src/opentracing/tracer.js +31 -36
  33. package/packages/dd-trace/src/plugin_manager.js +49 -33
  34. package/packages/dd-trace/src/plugins/util/test.js +32 -1
  35. package/packages/dd-trace/src/plugins/util/web.js +26 -18
  36. package/packages/dd-trace/src/profiling/config.js +10 -2
  37. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -2
  38. package/packages/dd-trace/src/profiling/exporters/form-data.js +53 -0
  39. package/packages/dd-trace/src/profiling/index.js +2 -0
  40. package/packages/dd-trace/src/profiling/profiler.js +6 -1
  41. package/packages/dd-trace/src/profiling/profilers/cpu.js +126 -0
  42. package/packages/dd-trace/src/proxy.js +1 -4
@@ -3,13 +3,25 @@ const { truncateSpan, normalizeSpan } = require('./tags-processors')
3
3
  const Chunk = require('./chunk')
4
4
  const { AgentEncoder } = require('./0.4')
5
5
  const { version: ddTraceVersion } = require('../../../../package.json')
6
+ const id = require('../../../dd-trace/src/id')
6
7
 
7
8
  const ENCODING_VERSION = 1
8
9
 
10
+ const ALLOWED_CONTENT_TYPES = ['test_session_end', 'test_suite_end', 'test']
11
+
12
+ const TEST_SUITE_KEYS_LENGTH = 11
13
+ const TEST_SESSION_KEYS_LENGTH = 10
14
+
15
+ const CHUNK_SIZE = 4 * 1024 * 1024 // 4MB
16
+
9
17
  function formatSpan (span) {
18
+ let encodingVersion = ENCODING_VERSION
19
+ if (span.type === 'test' && span.meta && span.meta.test_session_id) {
20
+ encodingVersion = 2
21
+ }
10
22
  return {
11
- type: span.type === 'test' ? 'test' : 'span',
12
- version: ENCODING_VERSION,
23
+ type: ALLOWED_CONTENT_TYPES.includes(span.type) ? span.type : 'span',
24
+ version: encodingVersion,
13
25
  content: normalizeSpan(truncateSpan(span))
14
26
  }
15
27
  }
@@ -21,8 +33,8 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
21
33
  this.runtimeId = runtimeId
22
34
  this.service = service
23
35
  this.env = env
24
- this._traceBytes = new Chunk()
25
- this._stringBytes = new Chunk()
36
+ this._traceBytes = new Chunk(CHUNK_SIZE)
37
+ this._stringBytes = new Chunk(CHUNK_SIZE)
26
38
  this._stringCount = 0
27
39
  this._stringMap = {}
28
40
 
@@ -33,8 +45,69 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
33
45
  this.reset()
34
46
  }
35
47
 
48
+ _encodeTestSuite (bytes, content) {
49
+ this._encodeMapPrefix(bytes, TEST_SUITE_KEYS_LENGTH)
50
+ this._encodeString(bytes, 'type')
51
+ this._encodeString(bytes, content.type)
52
+
53
+ this._encodeString(bytes, 'test_session_id')
54
+ this._encodeId(bytes, content.trace_id)
55
+
56
+ this._encodeString(bytes, 'test_suite_id')
57
+ this._encodeId(bytes, content.span_id)
58
+
59
+ this._encodeString(bytes, 'error')
60
+ this._encodeNumber(bytes, content.error)
61
+ this._encodeString(bytes, 'name')
62
+ this._encodeString(bytes, content.name)
63
+ this._encodeString(bytes, 'service')
64
+ this._encodeString(bytes, content.service)
65
+ this._encodeString(bytes, 'resource')
66
+ this._encodeString(bytes, content.resource)
67
+ this._encodeString(bytes, 'start')
68
+ this._encodeNumber(bytes, content.start)
69
+ this._encodeString(bytes, 'duration')
70
+ this._encodeNumber(bytes, content.duration)
71
+ this._encodeString(bytes, 'meta')
72
+ this._encodeMap(bytes, content.meta)
73
+ this._encodeString(bytes, 'metrics')
74
+ this._encodeMap(bytes, content.metrics)
75
+ }
76
+
77
+ _encodeTestSession (bytes, content) {
78
+ this._encodeMapPrefix(bytes, TEST_SESSION_KEYS_LENGTH)
79
+ this._encodeString(bytes, 'type')
80
+ this._encodeString(bytes, content.type)
81
+
82
+ this._encodeString(bytes, 'test_session_id')
83
+ this._encodeId(bytes, content.trace_id)
84
+
85
+ this._encodeString(bytes, 'error')
86
+ this._encodeNumber(bytes, content.error)
87
+ this._encodeString(bytes, 'name')
88
+ this._encodeString(bytes, content.name)
89
+ this._encodeString(bytes, 'service')
90
+ this._encodeString(bytes, content.service)
91
+ this._encodeString(bytes, 'resource')
92
+ this._encodeString(bytes, content.resource)
93
+ this._encodeString(bytes, 'start')
94
+ this._encodeNumber(bytes, content.start)
95
+ this._encodeString(bytes, 'duration')
96
+ this._encodeNumber(bytes, content.duration)
97
+ this._encodeString(bytes, 'meta')
98
+ this._encodeMap(bytes, content.meta)
99
+ this._encodeString(bytes, 'metrics')
100
+ this._encodeMap(bytes, content.metrics)
101
+ }
102
+
36
103
  _encodeEventContent (bytes, content) {
37
- this._encodeMapPrefix(bytes, content)
104
+ const keysLength = Object.keys(content).length
105
+ if (content.meta.test_session_id) {
106
+ this._encodeMapPrefix(bytes, keysLength + 2)
107
+ } else {
108
+ this._encodeMapPrefix(bytes, keysLength)
109
+ }
110
+
38
111
  if (content.type) {
39
112
  this._encodeString(bytes, 'type')
40
113
  this._encodeString(bytes, content.type)
@@ -57,6 +130,24 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
57
130
  this._encodeNumber(bytes, content.start)
58
131
  this._encodeString(bytes, 'duration')
59
132
  this._encodeNumber(bytes, content.duration)
133
+ /**
134
+ * We include `test_session_id` and `test_suite_id`
135
+ * in the root of the event by passing them via the `meta` dict.
136
+ * This is to avoid changing the span format in packages/dd-trace/src/format.js,
137
+ * which can have undesired side effects in other products.
138
+ * But `test_session_id` and `test_suite_id` are *not* supposed to be in `meta`,
139
+ * so we delete them before enconding the dictionary.
140
+ * TODO: find a better way to do this.
141
+ */
142
+ if (content.meta.test_session_id) {
143
+ this._encodeString(bytes, 'test_session_id')
144
+ this._encodeId(bytes, id(content.meta.test_session_id))
145
+ delete content.meta.test_session_id
146
+
147
+ this._encodeString(bytes, 'test_suite_id')
148
+ this._encodeId(bytes, id(content.meta.test_suite_id))
149
+ delete content.meta.test_suite_id
150
+ }
60
151
  this._encodeString(bytes, 'meta')
61
152
  this._encodeMap(bytes, content.meta)
62
153
  this._encodeString(bytes, 'metrics')
@@ -64,7 +155,7 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
64
155
  }
65
156
 
66
157
  _encodeEvent (bytes, event) {
67
- this._encodeMapPrefix(bytes, event)
158
+ this._encodeMapPrefix(bytes, Object.keys(event).length)
68
159
  this._encodeString(bytes, 'type')
69
160
  this._encodeString(bytes, event.type)
70
161
 
@@ -72,7 +163,13 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
72
163
  this._encodeNumber(bytes, event.version)
73
164
 
74
165
  this._encodeString(bytes, 'content')
75
- this._encodeEventContent(bytes, event.content)
166
+ if (event.type === 'span' || event.type === 'test') {
167
+ this._encodeEventContent(bytes, event.content)
168
+ } else if (event.type === 'test_suite_end') {
169
+ this._encodeTestSuite(bytes, event.content)
170
+ } else if (event.type === 'test_session_end') {
171
+ this._encodeTestSession(bytes, event.content)
172
+ }
76
173
  }
77
174
 
78
175
  _encodeNumber (bytes, value) {
@@ -107,18 +204,17 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
107
204
  buffer[offset + 8] = lo
108
205
  }
109
206
 
110
- _encodeMapPrefix (bytes, map) {
111
- const keys = Object.keys(map)
207
+ _encodeMapPrefix (bytes, keysLength) {
112
208
  const buffer = bytes.buffer
113
209
  const offset = bytes.length
114
210
 
115
211
  bytes.reserve(5)
116
212
  bytes.length += 5
117
213
  buffer[offset] = 0xdf
118
- buffer[offset + 1] = keys.length >> 24
119
- buffer[offset + 2] = keys.length >> 16
120
- buffer[offset + 3] = keys.length >> 8
121
- buffer[offset + 4] = keys.length
214
+ buffer[offset + 1] = keysLength >> 24
215
+ buffer[offset + 2] = keysLength >> 16
216
+ buffer[offset + 3] = keysLength >> 8
217
+ buffer[offset + 4] = keysLength
122
218
  }
123
219
 
124
220
  _encode (bytes, trace) {
@@ -171,11 +267,11 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
171
267
  payload.metadata['*']['runtime-id'] = this.runtimeId
172
268
  }
173
269
 
174
- this._encodeMapPrefix(bytes, payload)
270
+ this._encodeMapPrefix(bytes, Object.keys(payload).length)
175
271
  this._encodeString(bytes, 'version')
176
272
  this._encodeNumber(bytes, payload.version)
177
273
  this._encodeString(bytes, 'metadata')
178
- this._encodeMapPrefix(bytes, payload.metadata)
274
+ this._encodeMapPrefix(bytes, Object.keys(payload.metadata).length)
179
275
  this._encodeString(bytes, '*')
180
276
  this._encodeMap(bytes, payload.metadata['*'])
181
277
  this._encodeString(bytes, 'events')
@@ -1,22 +1,33 @@
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 = 1
13
+ const maxActiveRequests = 8
14
+ const httpAgent = new http.Agent({ keepAlive, maxTotalSockets })
15
+ const httpsAgent = new https.Agent({ keepAlive, maxTotalSockets })
11
16
  const containerId = docker.id()
12
17
 
18
+ let activeRequests = 0
19
+
13
20
  function request (data, options, keepAlive, callback) {
14
21
  if (!options.headers) {
15
22
  options.headers = {}
16
23
  }
24
+
25
+ // The timeout should be kept low to avoid excessive queueing.
26
+ const timeout = options.timeout || 2000
17
27
  const isSecure = options.protocol === 'https:'
18
28
  const client = isSecure ? https : http
19
29
  const dataArray = [].concat(data)
30
+
20
31
  options.headers['Content-Length'] = byteLength(dataArray)
21
32
 
22
33
  if (containerId) {
@@ -27,39 +38,15 @@ function request (data, options, keepAlive, callback) {
27
38
  options.agent = isSecure ? httpsAgent : httpAgent
28
39
  }
29
40
 
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 => {
41
+ const onResponse = res => {
57
42
  let responseData = ''
58
43
 
59
44
  res.setTimeout(timeout)
60
45
 
61
46
  res.on('data', chunk => { responseData += chunk })
62
47
  res.on('end', () => {
48
+ activeRequests--
49
+
63
50
  if (res.statusCode >= 200 && res.statusCode <= 299) {
64
51
  callback(null, responseData, res.statusCode)
65
52
  } else {
@@ -69,15 +56,43 @@ function retriableRequest (options, client, callback) {
69
56
  callback(error, null, res.statusCode)
70
57
  }
71
58
  })
72
- })
73
- request.setTimeout(timeout, request.abort)
74
- storage.enterWith(store)
59
+ }
75
60
 
76
- return request
61
+ const makeRequest = onError => {
62
+ if (!request.writable) return callback(null)
63
+
64
+ activeRequests++
65
+
66
+ const store = storage.getStore()
67
+
68
+ storage.enterWith({ noop: true })
69
+
70
+ const req = client.request(options, onResponse)
71
+
72
+ req.once('error', err => {
73
+ activeRequests--
74
+ onError(err)
75
+ })
76
+
77
+ dataArray.forEach(buffer => req.write(buffer))
78
+
79
+ req.setTimeout(timeout, req.abort)
80
+ req.end()
81
+
82
+ storage.enterWith(store)
83
+ }
84
+
85
+ makeRequest(() => makeRequest(callback))
77
86
  }
78
87
 
79
88
  function byteLength (data) {
80
89
  return data.length > 0 ? data.reduce((prev, next) => prev + next.length, 0) : 0
81
90
  }
82
91
 
92
+ Object.defineProperty(request, 'writable', {
93
+ get () {
94
+ return activeRequests < maxActiveRequests
95
+ }
96
+ })
97
+
83
98
  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)
@@ -1,26 +1,26 @@
1
1
  'use strict'
2
2
 
3
- const Span = require('opentracing').Span
4
- const NoopSpanContext = require('../noop/span_context')
3
+ const NoopSpanContext = require('./span_context')
5
4
  const id = require('../id')
6
5
  const { storage } = require('../../../datadog-core') // TODO: noop storage?
7
6
 
8
- class NoopSpan extends Span {
7
+ class NoopSpan {
9
8
  constructor (tracer, parent) {
10
- super()
11
-
12
9
  this._store = storage.getStore()
13
10
  this._noopTracer = tracer
14
11
  this._noopContext = this._createContext(parent)
15
12
  }
16
13
 
17
- _context () {
18
- return this._noopContext
19
- }
20
-
21
- _tracer () {
22
- return this._noopTracer
23
- }
14
+ context () { return this._noopContext }
15
+ tracer () { return this._noopTracer }
16
+ setOperationName (name) { return this }
17
+ setBaggageItem (key, value) { return this }
18
+ getBaggageItem (key) {}
19
+ setTag (key, value) { return this }
20
+ addTags (keyValueMap) { return this }
21
+ log () { return this }
22
+ logEvent () {}
23
+ finish (finishTime) {}
24
24
 
25
25
  _createContext (parent) {
26
26
  const spanId = id()
@@ -1,13 +1,10 @@
1
1
  'use strict'
2
2
 
3
- const Tracer = require('opentracing').Tracer
4
3
  const Scope = require('../noop/scope')
5
4
  const Span = require('./span')
6
5
 
7
- class NoopTracer extends Tracer {
6
+ class NoopTracer {
8
7
  constructor (config) {
9
- super(config)
10
-
11
8
  this._scope = new Scope()
12
9
  this._span = new Span(this)
13
10
  }
@@ -35,10 +32,16 @@ class NoopTracer extends Tracer {
35
32
  setUrl () {
36
33
  }
37
34
 
38
- _startSpan (name, options) {
35
+ startSpan (name, options) {
39
36
  return this._span
40
37
  }
41
38
 
39
+ inject (spanContext, format, carrier) {}
40
+
41
+ extract (format, carrier) {
42
+ return this._span.context()
43
+ }
44
+
42
45
  setUser () {
43
46
  return this
44
47
  }
@@ -1,11 +1,9 @@
1
1
  'use strict'
2
2
 
3
3
  // TODO (new internal tracer): use DC events for lifecycle metrics and test them
4
-
5
- const opentracing = require('opentracing')
6
- const now = require('performance-now')
4
+ const now = require('perf_hooks').performance.now
5
+ const dateNow = Date.now
7
6
  const semver = require('semver')
8
- const Span = opentracing.Span
9
7
  const SpanContext = require('./span_context')
10
8
  const id = require('../id')
11
9
  const tagger = require('../tagger')
@@ -21,10 +19,8 @@ const {
21
19
  const unfinishedRegistry = createRegistry('unfinished')
22
20
  const finishedRegistry = createRegistry('finished')
23
21
 
24
- class DatadogSpan extends Span {
22
+ class DatadogSpan {
25
23
  constructor (tracer, processor, prioritySampler, fields, debug) {
26
- super()
27
-
28
24
  const operationName = fields.operationName
29
25
  const parent = fields.parent || null
30
26
  const tags = Object.assign({}, fields.tags)
@@ -70,66 +66,45 @@ class DatadogSpan extends Span {
70
66
  return `Span${json}`
71
67
  }
72
68
 
73
- _createContext (parent) {
74
- let spanContext
75
-
76
- if (parent) {
77
- spanContext = new SpanContext({
78
- traceId: parent._traceId,
79
- spanId: id(),
80
- parentId: parent._spanId,
81
- sampling: parent._sampling,
82
- baggageItems: Object.assign({}, parent._baggageItems),
83
- trace: parent._trace
84
- })
85
- } else {
86
- const spanId = id()
87
- spanContext = new SpanContext({
88
- traceId: spanId,
89
- spanId
90
- })
91
- }
92
-
93
- spanContext._trace.started.push(this)
94
- spanContext._trace.startTime = spanContext._trace.startTime || Date.now()
95
- spanContext._trace.ticks = spanContext._trace.ticks || now()
96
-
97
- return spanContext
98
- }
99
-
100
- _getTime () {
101
- const { startTime, ticks } = this._spanContext._trace
102
-
103
- return startTime + now() - ticks
104
- }
105
-
106
- _context () {
69
+ context () {
107
70
  return this._spanContext
108
71
  }
109
72
 
110
- _tracer () {
73
+ tracer () {
111
74
  return this._parentTracer
112
75
  }
113
76
 
114
- _setOperationName (name) {
77
+ setOperationName (name) {
115
78
  this._spanContext._name = name
79
+ return this
116
80
  }
117
81
 
118
- _setBaggageItem (key, value) {
82
+ setBaggageItem (key, value) {
119
83
  this._spanContext._baggageItems[key] = value
84
+ return this
120
85
  }
121
86
 
122
- _getBaggageItem (key) {
87
+ getBaggageItem (key) {
123
88
  return this._spanContext._baggageItems[key]
124
89
  }
125
90
 
126
- _addTags (keyValuePairs) {
127
- tagger.add(this._spanContext._tags, keyValuePairs)
91
+ setTag (key, value) {
92
+ this._addTags({ [key]: value })
93
+ return this
94
+ }
128
95
 
129
- this._prioritySampler.sample(this, false)
96
+ addTags (keyValueMap) {
97
+ this._addTags(keyValueMap)
98
+ return this
99
+ }
100
+
101
+ log () {
102
+ return this
130
103
  }
131
104
 
132
- _finish (finishTime) {
105
+ logEvent () {}
106
+
107
+ finish (finishTime) {
133
108
  if (this._duration !== undefined) {
134
109
  return
135
110
  }
@@ -157,6 +132,45 @@ class DatadogSpan extends Span {
157
132
  this._spanContext._isFinished = true
158
133
  this._processor.process(this)
159
134
  }
135
+
136
+ _createContext (parent) {
137
+ let spanContext
138
+
139
+ if (parent) {
140
+ spanContext = new SpanContext({
141
+ traceId: parent._traceId,
142
+ spanId: id(),
143
+ parentId: parent._spanId,
144
+ sampling: parent._sampling,
145
+ baggageItems: Object.assign({}, parent._baggageItems),
146
+ trace: parent._trace
147
+ })
148
+ } else {
149
+ const spanId = id()
150
+ spanContext = new SpanContext({
151
+ traceId: spanId,
152
+ spanId
153
+ })
154
+ }
155
+
156
+ spanContext._trace.started.push(this)
157
+ spanContext._trace.startTime = spanContext._trace.startTime || dateNow()
158
+ spanContext._trace.ticks = spanContext._trace.ticks || now()
159
+
160
+ return spanContext
161
+ }
162
+
163
+ _getTime () {
164
+ const { startTime, ticks } = this._spanContext._trace
165
+
166
+ return startTime + now() - ticks
167
+ }
168
+
169
+ _addTags (keyValuePairs) {
170
+ tagger.add(this._spanContext._tags, keyValuePairs)
171
+
172
+ this._prioritySampler.sample(this, false)
173
+ }
160
174
  }
161
175
 
162
176
  function createRegistry (type) {
@@ -1,11 +1,7 @@
1
1
  'use strict'
2
2
 
3
- const SpanContext = require('opentracing').SpanContext
4
-
5
- class DatadogSpanContext extends SpanContext {
3
+ class DatadogSpanContext {
6
4
  constructor (props) {
7
- super()
8
-
9
5
  props = props || {}
10
6
 
11
7
  this._traceId = props.traceId