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.
- package/ci/cypress/plugin.js +3 -0
- package/ci/cypress/support.js +1 -0
- package/ci/init.js +13 -0
- package/ci/jest/env.js +14 -0
- package/index.d.ts +5 -5
- package/package.json +6 -5
- package/packages/datadog-plugin-cucumber/src/index.js +6 -4
- package/packages/datadog-plugin-cypress/src/plugin.js +17 -5
- package/packages/datadog-plugin-cypress/src/support.js +21 -6
- package/packages/datadog-plugin-graphql/src/index.js +16 -10
- package/packages/datadog-plugin-grpc/src/client.js +1 -1
- package/packages/datadog-plugin-jest/src/jest-environment.js +9 -5
- package/packages/datadog-plugin-jest/src/jest-jasmine2.js +13 -4
- package/packages/datadog-plugin-mocha/src/index.js +12 -3
- package/packages/datadog-plugin-redis/src/index.js +31 -1
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/constants.js +6 -1
- package/packages/dd-trace/src/encode/0.4.js +84 -23
- package/packages/dd-trace/src/encode/chunk.js +12 -14
- package/packages/dd-trace/src/format.js +12 -0
- package/packages/dd-trace/src/id.js +22 -18
- package/packages/dd-trace/src/instrumenter.js +2 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +34 -0
- package/packages/dd-trace/src/opentracing/span_context.js +2 -1
- package/packages/dd-trace/src/{.DS_Store → plugins/.DS_Store} +0 -0
- package/packages/dd-trace/src/plugins/util/ci.js +22 -9
- package/packages/dd-trace/src/plugins/util/git.js +11 -25
- package/packages/dd-trace/src/plugins/util/redis.js +0 -2
- package/packages/dd-trace/src/plugins/util/test.js +22 -4
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +72 -0
- package/packages/dd-trace/src/plugins/util/web.js +1 -1
- package/packages/dd-trace/src/priority_sampler.js +71 -19
- package/packages/dd-trace/src/profiling/exporters/agent.js +41 -33
- package/packages/dd-trace/src/profiling/profilers/cpu.js +1 -3
- package/packages/dd-trace/src/proxy.js +1 -1
- 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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
188
|
+
const keys = Object.keys(value)
|
|
189
|
+
const buffer = bytes.buffer
|
|
190
|
+
const offset = bytes.length
|
|
137
191
|
|
|
138
|
-
|
|
192
|
+
bytes.reserve(5)
|
|
193
|
+
bytes.length += 5
|
|
139
194
|
|
|
140
|
-
|
|
141
|
-
key = allKeys[i]
|
|
142
|
-
if (typeof value[key] !== 'function') {
|
|
143
|
-
keys.push(key)
|
|
144
|
-
}
|
|
145
|
-
}
|
|
195
|
+
let length = 0
|
|
146
196
|
|
|
147
|
-
const
|
|
197
|
+
for (const key of keys) {
|
|
198
|
+
if (typeof value[key] !== 'string' && typeof value[key] !== 'number') return
|
|
148
199
|
|
|
149
|
-
|
|
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.
|
|
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
|
-
|
|
247
|
+
buffer[offset + i + 1] = uInt8Float64Array[i]
|
|
187
248
|
}
|
|
188
249
|
} else {
|
|
189
250
|
for (let i = 7; i >= 0; i--) {
|
|
190
|
-
bytes.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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 {
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const lo = randomUInt32(seed[1])
|
|
129
|
+
if (batch === 0) {
|
|
130
|
+
randomFillSync(data)
|
|
131
|
+
}
|
|
133
132
|
|
|
134
|
-
|
|
135
|
-
writeUInt32BE(buffer, lo, 4)
|
|
133
|
+
batch = (batch + 1) % 8192
|
|
136
134
|
|
|
137
|
-
|
|
138
|
-
}
|
|
135
|
+
const offset = batch * 8
|
|
139
136
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
|
10
|
+
const disabledPlugins = process.env.DD_TRACE_DISABLED_PLUGINS
|
|
11
11
|
|
|
12
12
|
const collectDisabledPlugins = () => {
|
|
13
|
-
return new Set(
|
|
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
|
|
Binary file
|
|
@@ -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
|
-
|
|
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]:
|
|
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 =
|
|
197
|
-
|
|
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]:
|
|
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
|
-
|
|
44
|
+
repositoryUrl || sanitizedExec('git ls-remote --get-url', { stdio: 'pipe' }),
|
|
59
45
|
[GIT_COMMIT_MESSAGE]:
|
|
60
|
-
|
|
61
|
-
[GIT_COMMIT_AUTHOR_DATE]:
|
|
62
|
-
[GIT_COMMIT_AUTHOR_NAME]:
|
|
63
|
-
[GIT_COMMIT_AUTHOR_EMAIL]:
|
|
64
|
-
[GIT_COMMIT_COMMITTER_DATE]:
|
|
65
|
-
[GIT_COMMIT_COMMITTER_NAME]:
|
|
66
|
-
[GIT_COMMIT_COMMITTER_EMAIL]:
|
|
67
|
-
[GIT_BRANCH]:
|
|
68
|
-
[GIT_COMMIT_SHA]:
|
|
69
|
-
[GIT_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
|
}
|
|
@@ -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
|
-
|
|
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
|
|
137
|
+
return sourceRoot
|
|
123
138
|
}
|
|
124
|
-
|
|
139
|
+
const testSuitePath = testSuiteAbsolutePath === sourceRoot
|
|
140
|
+
? testSuiteAbsolutePath : path.relative(sourceRoot, testSuiteAbsolutePath)
|
|
141
|
+
|
|
142
|
+
return testSuitePath.replace(path.sep, '/')
|
|
125
143
|
}
|