dd-trace 1.5.0 → 1.7.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 (36) hide show
  1. package/ci/cypress/plugin.js +3 -0
  2. package/ci/cypress/support.js +1 -0
  3. package/ci/init.js +13 -0
  4. package/ci/jest/env.js +14 -0
  5. package/index.d.ts +5 -5
  6. package/package.json +6 -5
  7. package/packages/datadog-plugin-cucumber/src/index.js +6 -4
  8. package/packages/datadog-plugin-cypress/src/plugin.js +17 -5
  9. package/packages/datadog-plugin-cypress/src/support.js +21 -6
  10. package/packages/datadog-plugin-graphql/src/index.js +16 -10
  11. package/packages/datadog-plugin-grpc/src/client.js +1 -1
  12. package/packages/datadog-plugin-jest/src/jest-environment.js +9 -5
  13. package/packages/datadog-plugin-jest/src/jest-jasmine2.js +13 -4
  14. package/packages/datadog-plugin-mocha/src/index.js +12 -3
  15. package/packages/datadog-plugin-redis/src/index.js +31 -1
  16. package/packages/dd-trace/lib/version.js +1 -1
  17. package/packages/dd-trace/src/constants.js +6 -1
  18. package/packages/dd-trace/src/encode/0.4.js +84 -23
  19. package/packages/dd-trace/src/encode/chunk.js +12 -14
  20. package/packages/dd-trace/src/format.js +12 -0
  21. package/packages/dd-trace/src/id.js +22 -18
  22. package/packages/dd-trace/src/instrumenter.js +2 -2
  23. package/packages/dd-trace/src/opentracing/propagation/text_map.js +34 -0
  24. package/packages/dd-trace/src/opentracing/span_context.js +2 -1
  25. package/packages/dd-trace/src/{.DS_Store → plugins/.DS_Store} +0 -0
  26. package/packages/dd-trace/src/plugins/util/ci.js +22 -9
  27. package/packages/dd-trace/src/plugins/util/git.js +11 -25
  28. package/packages/dd-trace/src/plugins/util/redis.js +0 -2
  29. package/packages/dd-trace/src/plugins/util/test.js +22 -4
  30. package/packages/dd-trace/src/plugins/util/user-provided-git.js +72 -0
  31. package/packages/dd-trace/src/plugins/util/web.js +1 -1
  32. package/packages/dd-trace/src/priority_sampler.js +71 -19
  33. package/packages/dd-trace/src/profiling/exporters/agent.js +41 -33
  34. package/packages/dd-trace/src/profiling/profilers/cpu.js +1 -3
  35. package/packages/dd-trace/src/proxy.js +1 -1
  36. package/packages/dd-trace/src/plugins/util/ci-app-spec.json +0 -35
@@ -61,13 +61,15 @@ class AgentEncoder {
61
61
  this._encodeArrayPrefix(bytes, trace)
62
62
 
63
63
  for (const span of trace) {
64
+ bytes.reserve(1)
65
+
64
66
  if (span.type) {
65
- bytes.push(0x8c)
67
+ bytes.buffer[bytes.length++] = 0x8c
66
68
 
67
69
  this._encodeString(bytes, 'type')
68
70
  this._encodeString(bytes, span.type)
69
71
  } else {
70
- bytes.push(0x8b)
72
+ bytes.buffer[bytes.length++] = 0x8b
71
73
  }
72
74
 
73
75
  this._encodeString(bytes, 'trace_id')
@@ -107,52 +109,105 @@ class AgentEncoder {
107
109
 
108
110
  _encodeArrayPrefix (bytes, value) {
109
111
  const length = value.length
112
+ const buffer = bytes.buffer
113
+ const offset = bytes.length
114
+
115
+ bytes.reserve(5)
116
+ bytes.length += 5
110
117
 
111
- bytes.push(0xdd, length >> 24, length >> 16, length >> 8, length)
118
+ buffer[offset] = 0xdd
119
+ buffer[offset + 1] = length >> 24
120
+ buffer[offset + 2] = length >> 16
121
+ buffer[offset + 3] = length >> 8
122
+ buffer[offset + 4] = length
112
123
  }
113
124
 
114
125
  _encodeByte (bytes, value) {
115
- bytes.push(value)
126
+ const buffer = bytes.buffer
127
+
128
+ bytes.reserve(1)
129
+
130
+ buffer[bytes.length++] = value
116
131
  }
117
132
 
118
133
  _encodeId (bytes, id) {
134
+ const buffer = bytes.buffer
135
+ const offset = bytes.length
136
+
137
+ bytes.reserve(9)
138
+ bytes.length += 9
139
+
119
140
  id = id.toArray()
120
- bytes.push(0xcf, id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7])
141
+
142
+ buffer[offset] = 0xcf
143
+ buffer[offset + 1] = id[0]
144
+ buffer[offset + 2] = id[1]
145
+ buffer[offset + 3] = id[2]
146
+ buffer[offset + 4] = id[3]
147
+ buffer[offset + 5] = id[4]
148
+ buffer[offset + 6] = id[5]
149
+ buffer[offset + 7] = id[6]
150
+ buffer[offset + 8] = id[7]
121
151
  }
122
152
 
123
153
  _encodeInteger (bytes, value) {
124
- bytes.push(0xce, value >> 24, value >> 16, value >> 8, value)
154
+ const buffer = bytes.buffer
155
+ const offset = bytes.length
156
+
157
+ bytes.reserve(5)
158
+ bytes.length += 5
159
+
160
+ buffer[offset] = 0xce
161
+ buffer[offset + 1] = value >> 24
162
+ buffer[offset + 2] = value >> 16
163
+ buffer[offset + 3] = value >> 8
164
+ buffer[offset + 4] = value
125
165
  }
126
166
 
127
167
  _encodeLong (bytes, value) {
168
+ const buffer = bytes.buffer
169
+ const offset = bytes.length
128
170
  const hi = (value / Math.pow(2, 32)) >> 0
129
171
  const lo = value >>> 0
130
172
 
131
- bytes.push(0xcf, hi >> 24, hi >> 16, hi >> 8, hi, lo >> 24, lo >> 16, lo >> 8, lo)
173
+ bytes.reserve(9)
174
+ bytes.length += 9
175
+
176
+ buffer[offset] = 0xcf
177
+ buffer[offset + 1] = hi >> 24
178
+ buffer[offset + 2] = hi >> 16
179
+ buffer[offset + 3] = hi >> 8
180
+ buffer[offset + 4] = hi
181
+ buffer[offset + 5] = lo >> 24
182
+ buffer[offset + 6] = lo >> 16
183
+ buffer[offset + 7] = lo >> 8
184
+ buffer[offset + 8] = lo
132
185
  }
133
186
 
134
187
  _encodeMap (bytes, value) {
135
- const keys = []
136
- const allKeys = Object.keys(value)
188
+ const keys = Object.keys(value)
189
+ const buffer = bytes.buffer
190
+ const offset = bytes.length
137
191
 
138
- let key = ''
192
+ bytes.reserve(5)
193
+ bytes.length += 5
139
194
 
140
- for (let i = 0, l = allKeys.length; i < l; i++) {
141
- key = allKeys[i]
142
- if (typeof value[key] !== 'function') {
143
- keys.push(key)
144
- }
145
- }
195
+ let length = 0
146
196
 
147
- const length = keys.length
197
+ for (const key of keys) {
198
+ if (typeof value[key] !== 'string' && typeof value[key] !== 'number') return
148
199
 
149
- bytes.push(0xdf, length >> 24, length >> 16, length >> 8, length)
200
+ length++
150
201
 
151
- for (let i = 0; i < length; i++) {
152
- key = keys[i]
153
202
  this._encodeString(bytes, key)
154
203
  this._encodeValue(bytes, value[key])
155
204
  }
205
+
206
+ buffer[offset] = 0xdf
207
+ buffer[offset + 1] = length >> 24
208
+ buffer[offset + 2] = length >> 16
209
+ buffer[offset + 3] = length >> 8
210
+ buffer[offset + 4] = length
156
211
  }
157
212
 
158
213
  _encodeValue (bytes, value) {
@@ -179,15 +234,21 @@ class AgentEncoder {
179
234
  _encodeFloat (bytes, value) {
180
235
  float64Array[0] = value
181
236
 
182
- bytes.push(0xcb)
237
+ const buffer = bytes.buffer
238
+ const offset = bytes.length
239
+
240
+ bytes.reserve(9)
241
+ bytes.length += 9
242
+
243
+ buffer[offset] = 0xcb
183
244
 
184
245
  if (bigEndian) {
185
246
  for (let i = 0; i <= 7; i++) {
186
- bytes.push(uInt8Float64Array[i])
247
+ buffer[offset + i + 1] = uInt8Float64Array[i]
187
248
  }
188
249
  } else {
189
250
  for (let i = 7; i >= 0; i--) {
190
- bytes.push(uInt8Float64Array[i])
251
+ buffer[bytes.length - i - 1] = uInt8Float64Array[i]
191
252
  }
192
253
  }
193
254
  }
@@ -14,26 +14,24 @@ class Chunk {
14
14
  this._minSize = minSize
15
15
  }
16
16
 
17
- push (...bytes) {
18
- this._reserve(bytes.length)
19
-
20
- for (const byte of bytes) {
21
- this.buffer[this.length++] = byte
22
- }
23
- }
24
-
25
17
  write (value) {
26
18
  const length = Buffer.byteLength(value)
27
19
  const offset = this.length
28
20
 
29
21
  if (length < 0x20) { // fixstr
30
- this.push(length | 0xa0)
22
+ this.reserve(length + 1)
23
+ this.length += 1
24
+ this.buffer[offset] = length | 0xa0
31
25
  } else if (length < 0x100000000) { // str 32
32
- this.push(0xdb, length >> 24, length >> 16, length >> 8, length)
26
+ this.reserve(length + 5)
27
+ this.length += 5
28
+ this.buffer[offset] = 0xdb
29
+ this.buffer[offset + 1] = length >> 24
30
+ this.buffer[offset + 2] = length >> 16
31
+ this.buffer[offset + 3] = length >> 8
32
+ this.buffer[offset + 4] = length
33
33
  }
34
34
 
35
- this._reserve(length)
36
-
37
35
  this.length += this.buffer.utf8Write(value, this.length, length)
38
36
 
39
37
  return this.length - offset
@@ -44,13 +42,13 @@ class Chunk {
44
42
  }
45
43
 
46
44
  set (array) {
47
- this._reserve(array.length)
45
+ this.reserve(array.length)
48
46
 
49
47
  this.buffer.set(array, this.length)
50
48
  this.length += array.length
51
49
  }
52
50
 
53
- _reserve (size) {
51
+ reserve (size) {
54
52
  if (this.length + size > this.buffer.length) {
55
53
  this._resize(this._minSize * Math.ceil((this.length + size) / this._minSize))
56
54
  }
@@ -25,6 +25,7 @@ function format (span) {
25
25
 
26
26
  extractError(formatted, span)
27
27
  extractRootTags(formatted, span)
28
+ extractChunkTags(formatted, span)
28
29
  extractTags(formatted, span)
29
30
 
30
31
  return formatted
@@ -112,6 +113,17 @@ function extractRootTags (trace, span) {
112
113
  addTag({}, trace.metrics, SAMPLING_AGENT_DECISION, context._trace[SAMPLING_AGENT_DECISION])
113
114
  }
114
115
 
116
+ function extractChunkTags (trace, span) {
117
+ const context = span.context()
118
+ const isLocalRoot = span === context._trace.started[0]
119
+
120
+ if (!isLocalRoot) return
121
+
122
+ for (const key in context._trace.tags) {
123
+ addTag(trace.meta, trace.metrics, key, context._trace.tags[key])
124
+ }
125
+ }
126
+
115
127
  function extractError (trace, span) {
116
128
  const error = span.context()._tags['error']
117
129
  if (isError(error)) {
@@ -1,17 +1,17 @@
1
1
  'use strict'
2
2
 
3
- const { randomBytes } = require('crypto')
3
+ const { randomFillSync } = require('crypto')
4
4
 
5
5
  const UINT_MAX = 4294967296
6
6
 
7
+ const data = new Uint8Array(8 * 8192)
7
8
  const zeroId = new Uint8Array(8)
8
9
 
9
- // Cryptographically secure local seeds to mitigate Math.random() seed reuse.
10
- const seed = new Uint32Array(randomBytes(8).buffer)
11
-
12
10
  const map = Array.prototype.map
13
11
  const pad = byte => `${byte < 16 ? '0' : ''}${byte.toString(16)}`
14
12
 
13
+ let batch = 0
14
+
15
15
  // Internal representation of a trace or span ID.
16
16
  class Identifier {
17
17
  constructor (value, radix) {
@@ -36,7 +36,7 @@ class Identifier {
36
36
  if (this._buffer.length === 8) {
37
37
  return this._buffer
38
38
  }
39
- return this._buffer.subarray(-8)
39
+ return this._buffer.slice(-8)
40
40
  }
41
41
 
42
42
  toJSON () {
@@ -50,7 +50,7 @@ function createBuffer (value) {
50
50
  if (!value) return pseudoRandom()
51
51
 
52
52
  const size = Math.ceil(value.length / 2)
53
- const buffer = new Uint8Array(size)
53
+ const buffer = new Array(size)
54
54
 
55
55
  for (let i = 0; i < size; i++) {
56
56
  buffer[i] = parseInt(value.substring(i * 2, i * 2 + 2), 16)
@@ -61,7 +61,7 @@ function createBuffer (value) {
61
61
 
62
62
  // Convert a numerical string to a buffer using the specified radix.
63
63
  function fromString (str, raddix) {
64
- const buffer = new Uint8Array(8)
64
+ const buffer = new Array(8)
65
65
  const len = str.length
66
66
 
67
67
  let pos = 0
@@ -126,20 +126,24 @@ function toHexString (buffer) {
126
126
 
127
127
  // Simple pseudo-random 64-bit ID generator.
128
128
  function pseudoRandom () {
129
- const buffer = new Uint8Array(8)
130
-
131
- const hi = randomUInt32(seed[0]) & 0x7FFFFFFF // only positive int64
132
- const lo = randomUInt32(seed[1])
129
+ if (batch === 0) {
130
+ randomFillSync(data)
131
+ }
133
132
 
134
- writeUInt32BE(buffer, hi, 0)
135
- writeUInt32BE(buffer, lo, 4)
133
+ batch = (batch + 1) % 8192
136
134
 
137
- return buffer
138
- }
135
+ const offset = batch * 8
139
136
 
140
- // Generate a random unsigned 32-bit integer.
141
- function randomUInt32 (seed) {
142
- return seed ^ Math.floor(Math.random() * (0xFFFFFFFF + 1))
137
+ return [
138
+ data[offset] & 0x7F, // only positive int64,
139
+ data[offset + 1],
140
+ data[offset + 2],
141
+ data[offset + 3],
142
+ data[offset + 4],
143
+ data[offset + 5],
144
+ data[offset + 6],
145
+ data[offset + 7]
146
+ ]
143
147
  }
144
148
 
145
149
  // Read a buffer to unsigned integer bytes.
@@ -7,10 +7,10 @@ const Loader = require('./loader')
7
7
  const { isTrue } = require('./util')
8
8
  const plugins = require('./plugins')
9
9
 
10
- const disabldPlugins = process.env.DD_TRACE_DISABLED_PLUGINS
10
+ const disabledPlugins = process.env.DD_TRACE_DISABLED_PLUGINS
11
11
 
12
12
  const collectDisabledPlugins = () => {
13
- return new Set(disabldPlugins && disabldPlugins.split(',').map(plugin => plugin.trim()))
13
+ return new Set(disabledPlugins && disabledPlugins.split(',').map(plugin => plugin.trim()))
14
14
  }
15
15
 
16
16
  function cleanEnv (name) {
@@ -11,6 +11,7 @@ const spanKey = 'x-datadog-parent-id'
11
11
  const originKey = 'x-datadog-origin'
12
12
  const samplingKey = 'x-datadog-sampling-priority'
13
13
  const sampleKey = 'x-datadog-sampled'
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
@@ -41,6 +42,7 @@ class TextMapPropagator {
41
42
  this._injectSamplingPriority(spanContext, carrier)
42
43
  this._injectBaggageItems(spanContext, carrier)
43
44
  this._injectB3(spanContext, carrier)
45
+ this._injectTags(spanContext, carrier)
44
46
 
45
47
  log.debug(() => `Inject into carrier: ${JSON.stringify(pick(carrier, logKeys))}.`)
46
48
  }
@@ -53,6 +55,7 @@ class TextMapPropagator {
53
55
  this._extractOrigin(carrier, spanContext)
54
56
  this._extractBaggageItems(carrier, spanContext)
55
57
  this._extractSamplingPriority(carrier, spanContext)
58
+ this._extractTags(carrier, spanContext)
56
59
 
57
60
  log.debug(() => `Extract from carrier: ${JSON.stringify(pick(carrier, logKeys))}.`)
58
61
 
@@ -81,6 +84,25 @@ class TextMapPropagator {
81
84
  })
82
85
  }
83
86
 
87
+ _injectTags (spanContext, carrier) {
88
+ const trace = spanContext._trace
89
+ const tags = []
90
+
91
+ for (const key in trace.tags) {
92
+ if (!key.startsWith('_dd.p.')) continue
93
+
94
+ tags.push(`${key}=${trace.tags[key]}`)
95
+ }
96
+
97
+ const header = tags.join(',')
98
+
99
+ if (header.length <= 512) {
100
+ carrier[tagsKey] = header
101
+ } else {
102
+ trace.tags['_dd.propagation_error:max_size'] = 1
103
+ }
104
+ }
105
+
84
106
  _injectB3 (spanContext, carrier) {
85
107
  if (!this._config.experimental.b3) return
86
108
 
@@ -241,6 +263,18 @@ class TextMapPropagator {
241
263
  }
242
264
  }
243
265
 
266
+ _extractTags (carrier, spanContext) {
267
+ if (!carrier[tagsKey]) return
268
+
269
+ const pairs = carrier[tagsKey].split(',')
270
+
271
+ for (const pair of pairs) {
272
+ const [key, value] = pair.split('=')
273
+
274
+ spanContext._trace.tags[key] = value
275
+ }
276
+ }
277
+
244
278
  _isSampled (sampled, debug) {
245
279
  if (debug || sampled === '1') {
246
280
  return true
@@ -22,7 +22,8 @@ class DatadogSpanContext extends SpanContext {
22
22
  this._noop = props.noop || null
23
23
  this._trace = props.trace || {
24
24
  started: [],
25
- finished: []
25
+ finished: [],
26
+ tags: {}
26
27
  }
27
28
  }
28
29
 
@@ -70,6 +70,7 @@ function resolveTilde (filePath) {
70
70
  }
71
71
 
72
72
  module.exports = {
73
+ normalizeRef,
73
74
  getCIMetadata () {
74
75
  const { env } = process
75
76
 
@@ -124,7 +125,7 @@ module.exports = {
124
125
  CI_PIPELINE_IID,
125
126
  CI_PIPELINE_URL: GITLAB_PIPELINE_URL,
126
127
  CI_PROJECT_DIR,
127
- CI_COMMIT_BRANCH,
128
+ CI_COMMIT_REF_NAME,
128
129
  CI_COMMIT_TAG,
129
130
  CI_COMMIT_SHA,
130
131
  CI_REPOSITORY_URL,
@@ -143,7 +144,7 @@ module.exports = {
143
144
  [GIT_REPOSITORY_URL]: CI_REPOSITORY_URL,
144
145
  [CI_JOB_URL]: GITLAB_CI_JOB_URL,
145
146
  [GIT_TAG]: CI_COMMIT_TAG,
146
- [GIT_BRANCH]: CI_COMMIT_BRANCH,
147
+ [GIT_BRANCH]: CI_COMMIT_REF_NAME,
147
148
  [CI_WORKSPACE_PATH]: CI_PROJECT_DIR,
148
149
  [CI_PIPELINE_URL]: GITLAB_PIPELINE_URL && GITLAB_PIPELINE_URL.replace('/-/pipelines/', '/pipelines/'),
149
150
  [CI_STAGE_NAME]: CI_JOB_STAGE,
@@ -190,11 +191,19 @@ module.exports = {
190
191
  GITHUB_HEAD_REF,
191
192
  GITHUB_REF,
192
193
  GITHUB_SHA,
193
- GITHUB_REPOSITORY
194
+ GITHUB_REPOSITORY,
195
+ GITHUB_SERVER_URL,
196
+ GITHUB_RUN_ATTEMPT
194
197
  } = env
195
198
 
196
- const repositoryURL = `https://github.com/${GITHUB_REPOSITORY}.git`
197
- const pipelineURL = `https://github.com/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}/checks`
199
+ const repositoryURL = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git`
200
+ let pipelineURL = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}`
201
+
202
+ if (GITHUB_RUN_ATTEMPT) {
203
+ pipelineURL = `${pipelineURL}/attempts/${GITHUB_RUN_ATTEMPT}`
204
+ }
205
+
206
+ const jobUrl = `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/${GITHUB_SHA}/checks`
198
207
 
199
208
  const ref = GITHUB_HEAD_REF || GITHUB_REF || ''
200
209
  const refKey = ref.includes('tags') ? GIT_TAG : GIT_BRANCH
@@ -207,7 +216,7 @@ module.exports = {
207
216
  [CI_PROVIDER_NAME]: 'github',
208
217
  [GIT_COMMIT_SHA]: GITHUB_SHA,
209
218
  [GIT_REPOSITORY_URL]: repositoryURL,
210
- [CI_JOB_URL]: pipelineURL,
219
+ [CI_JOB_URL]: jobUrl,
211
220
  [CI_WORKSPACE_PATH]: GITHUB_WORKSPACE,
212
221
  [refKey]: ref
213
222
  }
@@ -274,11 +283,13 @@ module.exports = {
274
283
  BUILD_SOURCEVERSION,
275
284
  BUILD_REQUESTEDFORID,
276
285
  BUILD_REQUESTEDFOREMAIL,
277
- BUILD_SOURCEVERSIONMESSAGE
286
+ BUILD_SOURCEVERSIONMESSAGE,
287
+ SYSTEM_STAGEDISPLAYNAME,
288
+ SYSTEM_JOBDISPLAYNAME
278
289
  } = env
279
290
 
280
291
  const ref = SYSTEM_PULLREQUEST_SOURCEBRANCH || BUILD_SOURCEBRANCH || BUILD_SOURCEBRANCHNAME
281
- const refKey = ref.includes('tags') ? GIT_TAG : GIT_BRANCH
292
+ const refKey = (ref || '').includes('tags') ? GIT_TAG : GIT_BRANCH
282
293
 
283
294
  tags = {
284
295
  [CI_PROVIDER_NAME]: 'azurepipelines',
@@ -291,7 +302,9 @@ module.exports = {
291
302
  [refKey]: ref,
292
303
  [GIT_COMMIT_AUTHOR_NAME]: BUILD_REQUESTEDFORID,
293
304
  [GIT_COMMIT_AUTHOR_EMAIL]: BUILD_REQUESTEDFOREMAIL,
294
- [GIT_COMMIT_MESSAGE]: BUILD_SOURCEVERSIONMESSAGE
305
+ [GIT_COMMIT_MESSAGE]: BUILD_SOURCEVERSIONMESSAGE,
306
+ [CI_STAGE_NAME]: SYSTEM_STAGEDISPLAYNAME,
307
+ [CI_JOB_NAME]: SYSTEM_JOBDISPLAYNAME
295
308
  }
296
309
 
297
310
  if (SYSTEM_TEAMFOUNDATIONSERVERURI && SYSTEM_TEAMPROJECTID && BUILD_BUILDID) {
@@ -39,34 +39,20 @@ function getGitMetadata (ciMetadata) {
39
39
  committerDate
40
40
  ] = sanitizedExec('git show -s --format=%an,%ae,%ad,%cn,%ce,%cd', { stdio: 'pipe' }).split(',')
41
41
 
42
- const {
43
- DD_GIT_REPOSITORY_URL,
44
- DD_GIT_COMMIT_SHA,
45
- DD_GIT_BRANCH,
46
- DD_GIT_TAG,
47
- DD_GIT_COMMIT_MESSAGE,
48
- DD_GIT_COMMIT_AUTHOR_NAME,
49
- DD_GIT_COMMIT_AUTHOR_EMAIL,
50
- DD_GIT_COMMIT_AUTHOR_DATE,
51
- DD_GIT_COMMIT_COMMITTER_NAME,
52
- DD_GIT_COMMIT_COMMITTER_EMAIL,
53
- DD_GIT_COMMIT_COMMITTER_DATE
54
- } = process.env
55
-
56
42
  return {
57
43
  [GIT_REPOSITORY_URL]:
58
- DD_GIT_REPOSITORY_URL || repositoryUrl || sanitizedExec('git ls-remote --get-url', { stdio: 'pipe' }),
44
+ repositoryUrl || sanitizedExec('git ls-remote --get-url', { stdio: 'pipe' }),
59
45
  [GIT_COMMIT_MESSAGE]:
60
- DD_GIT_COMMIT_MESSAGE || commitMessage || sanitizedExec('git show -s --format=%s', { stdio: 'pipe' }),
61
- [GIT_COMMIT_AUTHOR_DATE]: DD_GIT_COMMIT_AUTHOR_DATE || authorDate,
62
- [GIT_COMMIT_AUTHOR_NAME]: DD_GIT_COMMIT_AUTHOR_NAME || ciAuthorName || authorName,
63
- [GIT_COMMIT_AUTHOR_EMAIL]: DD_GIT_COMMIT_AUTHOR_EMAIL || ciAuthorEmail || authorEmail,
64
- [GIT_COMMIT_COMMITTER_DATE]: DD_GIT_COMMIT_COMMITTER_DATE || committerDate,
65
- [GIT_COMMIT_COMMITTER_NAME]: DD_GIT_COMMIT_COMMITTER_NAME || committerName,
66
- [GIT_COMMIT_COMMITTER_EMAIL]: DD_GIT_COMMIT_COMMITTER_EMAIL || committerEmail,
67
- [GIT_BRANCH]: DD_GIT_BRANCH || branch || sanitizedExec('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }),
68
- [GIT_COMMIT_SHA]: DD_GIT_COMMIT_SHA || commitSHA || sanitizedExec('git rev-parse HEAD', { stdio: 'pipe' }),
69
- [GIT_TAG]: DD_GIT_TAG || tag,
46
+ commitMessage || sanitizedExec('git show -s --format=%s', { stdio: 'pipe' }),
47
+ [GIT_COMMIT_AUTHOR_DATE]: authorDate,
48
+ [GIT_COMMIT_AUTHOR_NAME]: ciAuthorName || authorName,
49
+ [GIT_COMMIT_AUTHOR_EMAIL]: ciAuthorEmail || authorEmail,
50
+ [GIT_COMMIT_COMMITTER_DATE]: committerDate,
51
+ [GIT_COMMIT_COMMITTER_NAME]: committerName,
52
+ [GIT_COMMIT_COMMITTER_EMAIL]: committerEmail,
53
+ [GIT_BRANCH]: branch || sanitizedExec('git rev-parse --abbrev-ref HEAD', { stdio: 'pipe' }),
54
+ [GIT_COMMIT_SHA]: commitSHA || sanitizedExec('git rev-parse HEAD', { stdio: 'pipe' }),
55
+ [GIT_TAG]: tag,
70
56
  [CI_WORKSPACE_PATH]: ciWorkspacePath || sanitizedExec('git rev-parse --show-toplevel', { stdio: 'pipe' })
71
57
  }
72
58
  }
@@ -25,8 +25,6 @@ const redis = {
25
25
  'span.type': 'redis',
26
26
  'db.type': 'redis',
27
27
  'db.name': db || '0',
28
- 'out.host': '127.0.0.1',
29
- 'out.port': String(6379),
30
28
  'redis.raw_command': formatCommand(command, args)
31
29
  }
32
30
  })
@@ -1,6 +1,7 @@
1
1
  const path = require('path')
2
2
 
3
3
  const { getGitMetadata } = require('./git')
4
+ const { getUserProviderGitMetadata } = require('./user-provided-git')
4
5
  const { getCIMetadata } = require('./ci')
5
6
  const { getRuntimeAndOSMetadata } = require('./env')
6
7
  const {
@@ -16,12 +17,14 @@ const {
16
17
  const id = require('../../id')
17
18
 
18
19
  const TEST_FRAMEWORK = 'test.framework'
20
+ const TEST_FRAMEWORK_VERSION = 'test.framework_version'
19
21
  const TEST_TYPE = 'test.type'
20
22
  const TEST_NAME = 'test.name'
21
23
  const TEST_SUITE = 'test.suite'
22
24
  const TEST_STATUS = 'test.status'
23
25
  const TEST_PARAMETERS = 'test.parameters'
24
26
  const TEST_SKIP_REASON = 'test.skip_reason'
27
+ const TEST_IS_RUM_ACTIVE = 'test.is_rum_active'
25
28
 
26
29
  const ERROR_TYPE = 'error.type'
27
30
  const ERROR_MESSAGE = 'error.msg'
@@ -29,14 +32,19 @@ const ERROR_STACK = 'error.stack'
29
32
 
30
33
  const CI_APP_ORIGIN = 'ciapp-test'
31
34
 
35
+ const JEST_TEST_RUNNER = 'test.jest.test_runner'
36
+
32
37
  module.exports = {
33
38
  TEST_FRAMEWORK,
39
+ TEST_FRAMEWORK_VERSION,
40
+ JEST_TEST_RUNNER,
34
41
  TEST_TYPE,
35
42
  TEST_NAME,
36
43
  TEST_SUITE,
37
44
  TEST_STATUS,
38
45
  TEST_PARAMETERS,
39
46
  TEST_SKIP_REASON,
47
+ TEST_IS_RUM_ACTIVE,
40
48
  ERROR_TYPE,
41
49
  ERROR_MESSAGE,
42
50
  ERROR_STACK,
@@ -48,7 +56,7 @@ module.exports = {
48
56
  getTestSuitePath
49
57
  }
50
58
 
51
- function getTestEnvironmentMetadata (testFramework) {
59
+ function getTestEnvironmentMetadata (testFramework, config) {
52
60
  // TODO: eventually these will come from the tracer (generally available)
53
61
  const ciMetadata = getCIMetadata()
54
62
  const {
@@ -73,14 +81,21 @@ function getTestEnvironmentMetadata (testFramework) {
73
81
  ciWorkspacePath
74
82
  })
75
83
 
84
+ const userProvidedGitMetadata = getUserProviderGitMetadata()
85
+
76
86
  const runtimeAndOSMetadata = getRuntimeAndOSMetadata()
77
87
 
78
- return {
88
+ const metadata = {
79
89
  [TEST_FRAMEWORK]: testFramework,
80
90
  ...gitMetadata,
81
91
  ...ciMetadata,
92
+ ...userProvidedGitMetadata,
82
93
  ...runtimeAndOSMetadata
83
94
  }
95
+ if (config && config.service) {
96
+ metadata['service.name'] = config.service
97
+ }
98
+ return metadata
84
99
  }
85
100
 
86
101
  function getTestParametersString (parametersByTestName, testName) {
@@ -119,7 +134,10 @@ function getTestParentSpan (tracer) {
119
134
  */
120
135
  function getTestSuitePath (testSuiteAbsolutePath, sourceRoot) {
121
136
  if (!testSuiteAbsolutePath) {
122
- return testSuiteAbsolutePath
137
+ return sourceRoot
123
138
  }
124
- return path.relative(sourceRoot, testSuiteAbsolutePath).replace(path.sep, '/')
139
+ const testSuitePath = testSuiteAbsolutePath === sourceRoot
140
+ ? testSuiteAbsolutePath : path.relative(sourceRoot, testSuiteAbsolutePath)
141
+
142
+ return testSuitePath.replace(path.sep, '/')
125
143
  }