dd-trace 3.19.0 → 3.20.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/package.json +1 -1
- package/packages/datadog-instrumentations/src/mocha.js +8 -4
- package/packages/datadog-instrumentations/src/pg.js +3 -4
- package/packages/datadog-instrumentations/src/playwright.js +11 -1
- package/packages/datadog-plugin-amqp10/src/consumer.js +3 -1
- package/packages/datadog-plugin-amqp10/src/producer.js +3 -1
- package/packages/datadog-plugin-amqplib/src/client.js +3 -4
- package/packages/datadog-plugin-amqplib/src/consumer.js +3 -1
- package/packages/datadog-plugin-amqplib/src/producer.js +3 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +3 -4
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +3 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +3 -1
- package/packages/datadog-plugin-kafkajs/src/consumer.js +6 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -1
- package/packages/datadog-plugin-pg/src/index.js +5 -5
- package/packages/datadog-plugin-rhea/src/consumer.js +3 -1
- package/packages/datadog-plugin-rhea/src/producer.js +5 -1
- package/packages/dd-trace/src/config.js +1 -17
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +14 -4
- package/packages/dd-trace/src/plugin_manager.js +0 -2
- package/packages/dd-trace/src/plugins/client.js +2 -3
- package/packages/dd-trace/src/plugins/consumer.js +2 -17
- package/packages/dd-trace/src/plugins/incoming.js +7 -0
- package/packages/dd-trace/src/plugins/{outbound.js → outgoing.js} +2 -2
- package/packages/dd-trace/src/plugins/producer.js +2 -17
- package/packages/dd-trace/src/plugins/server.js +2 -2
- package/packages/dd-trace/src/plugins/tracing.js +0 -11
- package/packages/dd-trace/src/plugins/util/test.js +34 -17
- package/packages/dd-trace/src/telemetry/send-data.js +13 -3
- package/packages/dd-trace/src/plugins/inbound.js +0 -7
- package/packages/dd-trace/src/service-naming/index.js +0 -41
- package/packages/dd-trace/src/service-naming/schemas/definition.js +0 -28
- package/packages/dd-trace/src/service-naming/schemas/index.js +0 -6
- package/packages/dd-trace/src/service-naming/schemas/v0.js +0 -66
- package/packages/dd-trace/src/service-naming/schemas/v1.js +0 -58
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@ const {
|
|
|
10
10
|
mergeCoverage,
|
|
11
11
|
getTestSuitePath,
|
|
12
12
|
fromCoverageMapToCoverage,
|
|
13
|
-
|
|
13
|
+
getCallSites
|
|
14
14
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
15
15
|
|
|
16
16
|
const testStartCh = channel('ci:mocha:test:start')
|
|
@@ -393,9 +393,13 @@ addHook({
|
|
|
393
393
|
file: 'lib/suite.js'
|
|
394
394
|
}, (Suite) => {
|
|
395
395
|
shimmer.wrap(Suite.prototype, 'addTest', addTest => function (test) {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
396
|
+
const callSites = getCallSites()
|
|
397
|
+
let startLine
|
|
398
|
+
const testCallSite = callSites.find(site => site.getFileName() === test.file)
|
|
399
|
+
if (testCallSite) {
|
|
400
|
+
startLine = testCallSite.getLineNumber()
|
|
401
|
+
testToStartLine.set(test, startLine)
|
|
402
|
+
}
|
|
399
403
|
return addTest.apply(this, arguments)
|
|
400
404
|
})
|
|
401
405
|
return Suite
|
|
@@ -30,9 +30,8 @@ function wrapQuery (query) {
|
|
|
30
30
|
const callbackResource = new AsyncResource('bound-anonymous-fn')
|
|
31
31
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
32
32
|
const processId = this.processID
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
33
|
+
|
|
34
|
+
let pgQuery = arguments[0] && typeof arguments[0] === 'object' ? arguments[0] : { text: arguments[0] }
|
|
36
35
|
|
|
37
36
|
return asyncResource.runInAsyncScope(() => {
|
|
38
37
|
startCh.publish({
|
|
@@ -41,7 +40,7 @@ function wrapQuery (query) {
|
|
|
41
40
|
processId
|
|
42
41
|
})
|
|
43
42
|
|
|
44
|
-
arguments[0] = pgQuery
|
|
43
|
+
arguments[0] = pgQuery
|
|
45
44
|
|
|
46
45
|
const finish = asyncResource.bind(function (error) {
|
|
47
46
|
if (error) {
|
|
@@ -214,10 +214,20 @@ function runnerHook (runnerExport, playwrightVersion) {
|
|
|
214
214
|
})
|
|
215
215
|
|
|
216
216
|
const runAllTestsReturn = await runAllTests.apply(this, arguments)
|
|
217
|
+
|
|
218
|
+
Object.values(remainingTestsByFile).forEach(tests => {
|
|
219
|
+
// `tests` should normally be empty, but if it isn't,
|
|
220
|
+
// there were tests that did not go through `testBegin` or `testEnd`,
|
|
221
|
+
// because they were skipped
|
|
222
|
+
tests.forEach(test => {
|
|
223
|
+
testBeginHandler(test)
|
|
224
|
+
testEndHandler(test, 'skip')
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
|
|
217
228
|
const sessionStatus = runAllTestsReturn.status || runAllTestsReturn
|
|
218
229
|
|
|
219
230
|
let onDone
|
|
220
|
-
|
|
221
231
|
const flushWait = new Promise(resolve => {
|
|
222
232
|
onDone = resolve
|
|
223
233
|
})
|
|
@@ -11,9 +11,11 @@ class Amqp10ConsumerPlugin extends ConsumerPlugin {
|
|
|
11
11
|
const source = getShortName(link)
|
|
12
12
|
const address = getAddress(link)
|
|
13
13
|
|
|
14
|
-
this.startSpan({
|
|
14
|
+
this.startSpan('amqp.receive', {
|
|
15
|
+
service: this.config.service || `${this.tracer._service}-amqp`,
|
|
15
16
|
resource: ['receive', source].filter(v => v).join(' '),
|
|
16
17
|
type: 'worker',
|
|
18
|
+
kind: 'consumer',
|
|
17
19
|
meta: {
|
|
18
20
|
'amqp.link.source.address': source,
|
|
19
21
|
'amqp.link.role': 'receiver',
|
|
@@ -13,8 +13,10 @@ class Amqp10ProducerPlugin extends ProducerPlugin {
|
|
|
13
13
|
const address = getAddress(link)
|
|
14
14
|
const target = getShortName(link)
|
|
15
15
|
|
|
16
|
-
this.startSpan({
|
|
16
|
+
this.startSpan('amqp.send', {
|
|
17
|
+
service: this.config.service || `${this.tracer._service}-amqp`,
|
|
17
18
|
resource: ['send', target].filter(v => v).join(' '),
|
|
19
|
+
kind: 'producer',
|
|
18
20
|
meta: {
|
|
19
21
|
'amqp.link.target.address': target,
|
|
20
22
|
'amqp.link.role': 'sender',
|
|
@@ -7,7 +7,6 @@ const { getResourceName } = require('./util')
|
|
|
7
7
|
|
|
8
8
|
class AmqplibClientPlugin extends ClientPlugin {
|
|
9
9
|
static get id () { return 'amqplib' }
|
|
10
|
-
static get type () { return 'messaging' }
|
|
11
10
|
static get operation () { return 'command' }
|
|
12
11
|
|
|
13
12
|
start ({ channel = {}, method, fields }) {
|
|
@@ -15,10 +14,10 @@ class AmqplibClientPlugin extends ClientPlugin {
|
|
|
15
14
|
if (method === 'basic.publish') return
|
|
16
15
|
|
|
17
16
|
const stream = (channel.connection && channel.connection.stream) || {}
|
|
18
|
-
const span = this.startSpan(
|
|
19
|
-
service: this.config.service || this.
|
|
17
|
+
const span = this.startSpan('amqp.command', {
|
|
18
|
+
service: this.config.service || `${this.tracer._service}-amqp`,
|
|
20
19
|
resource: getResourceName(method, fields),
|
|
21
|
-
kind:
|
|
20
|
+
kind: 'client',
|
|
22
21
|
meta: {
|
|
23
22
|
'out.host': stream._host,
|
|
24
23
|
[CLIENT_PORT_KEY]: stream.remotePort,
|
|
@@ -13,9 +13,11 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
|
13
13
|
|
|
14
14
|
const childOf = extract(this.tracer, message)
|
|
15
15
|
|
|
16
|
-
this.startSpan({
|
|
16
|
+
this.startSpan('amqp.command', {
|
|
17
17
|
childOf,
|
|
18
|
+
service: this.config.service || `${this.tracer._service}-amqp`,
|
|
18
19
|
resource: getResourceName(method, fields),
|
|
20
|
+
kind: 'consumer',
|
|
19
21
|
type: 'worker',
|
|
20
22
|
meta: {
|
|
21
23
|
'amqp.queue': fields.queue,
|
|
@@ -13,8 +13,10 @@ class AmqplibProducerPlugin extends ProducerPlugin {
|
|
|
13
13
|
if (method !== 'basic.publish') return
|
|
14
14
|
|
|
15
15
|
const stream = (channel.connection && channel.connection.stream) || {}
|
|
16
|
-
const span = this.startSpan({
|
|
16
|
+
const span = this.startSpan('amqp.command', {
|
|
17
|
+
service: this.config.service || `${this.tracer._service}-amqp`,
|
|
17
18
|
resource: getResourceName(method, fields),
|
|
19
|
+
kind: 'producer',
|
|
18
20
|
meta: {
|
|
19
21
|
'out.host': stream._host,
|
|
20
22
|
[CLIENT_PORT_KEY]: stream.remotePort,
|
|
@@ -4,16 +4,15 @@ const ClientPlugin = require('../../dd-trace/src/plugins/client')
|
|
|
4
4
|
|
|
5
5
|
class GoogleCloudPubsubClientPlugin extends ClientPlugin {
|
|
6
6
|
static get id () { return 'google-cloud-pubsub' }
|
|
7
|
-
static get type () { return 'messaging' }
|
|
8
7
|
static get operation () { return 'request' }
|
|
9
8
|
|
|
10
9
|
start ({ request, api, projectId }) {
|
|
11
10
|
if (api === 'publish') return
|
|
12
11
|
|
|
13
|
-
this.startSpan(
|
|
14
|
-
service: this.config.service || this.
|
|
12
|
+
this.startSpan('pubsub.request', {
|
|
13
|
+
service: this.config.service || `${this.tracer._service}-pubsub`,
|
|
15
14
|
resource: [api, request.name].filter(x => x).join(' '),
|
|
16
|
-
kind:
|
|
15
|
+
kind: 'client',
|
|
17
16
|
meta: {
|
|
18
17
|
'pubsub.method': api,
|
|
19
18
|
'gcloud.project_id': projectId
|
|
@@ -11,9 +11,11 @@ class GoogleCloudPubsubConsumerPlugin extends ConsumerPlugin {
|
|
|
11
11
|
const topic = subscription.metadata && subscription.metadata.topic
|
|
12
12
|
const childOf = this.tracer.extract('text_map', message.attributes) || null
|
|
13
13
|
|
|
14
|
-
this.startSpan({
|
|
14
|
+
this.startSpan('pubsub.receive', {
|
|
15
15
|
childOf,
|
|
16
|
+
service: this.config.service,
|
|
16
17
|
resource: topic,
|
|
18
|
+
kind: 'consumer',
|
|
17
19
|
type: 'worker',
|
|
18
20
|
meta: {
|
|
19
21
|
'gcloud.project_id': subscription.pubsub.projectId,
|
|
@@ -11,8 +11,10 @@ class GoogleCloudPubsubProducerPlugin extends ProducerPlugin {
|
|
|
11
11
|
|
|
12
12
|
const messages = request.messages || []
|
|
13
13
|
const topic = request.topic
|
|
14
|
-
const span = this.startSpan({ // TODO: rename
|
|
14
|
+
const span = this.startSpan('pubsub.request', { // TODO: rename
|
|
15
|
+
service: this.config.service || `${this.tracer._service}-pubsub`,
|
|
15
16
|
resource: `${api} ${topic}`,
|
|
17
|
+
kind: 'producer',
|
|
16
18
|
meta: {
|
|
17
19
|
'gcloud.project_id': projectId,
|
|
18
20
|
'pubsub.method': api, // TODO: remove
|
|
@@ -8,9 +8,12 @@ class KafkajsConsumerPlugin extends ConsumerPlugin {
|
|
|
8
8
|
|
|
9
9
|
start ({ topic, partition, message }) {
|
|
10
10
|
const childOf = extract(this.tracer, message.headers)
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
this.startSpan('kafka.consume', {
|
|
12
13
|
childOf,
|
|
14
|
+
service: this.config.service || `${this.tracer._service}-kafka`,
|
|
13
15
|
resource: topic,
|
|
16
|
+
kind: 'consumer',
|
|
14
17
|
type: 'worker',
|
|
15
18
|
meta: {
|
|
16
19
|
'component': 'kafkajs',
|
|
@@ -30,6 +33,8 @@ function extract (tracer, bufferMap) {
|
|
|
30
33
|
const textMap = {}
|
|
31
34
|
|
|
32
35
|
for (const key of Object.keys(bufferMap)) {
|
|
36
|
+
if (bufferMap[key] === null || bufferMap[key] === undefined) continue
|
|
37
|
+
|
|
33
38
|
textMap[key] = bufferMap[key].toString()
|
|
34
39
|
}
|
|
35
40
|
|
|
@@ -7,8 +7,10 @@ class KafkajsProducerPlugin extends ProducerPlugin {
|
|
|
7
7
|
static get operation () { return 'produce' }
|
|
8
8
|
|
|
9
9
|
start ({ topic, messages }) {
|
|
10
|
-
const span = this.startSpan({
|
|
10
|
+
const span = this.startSpan('kafka.produce', {
|
|
11
|
+
service: this.config.service || `${this.tracer._service}-kafka`,
|
|
11
12
|
resource: topic,
|
|
13
|
+
kind: 'producer',
|
|
12
14
|
meta: {
|
|
13
15
|
'component': 'kafkajs',
|
|
14
16
|
'kafka.topic': topic
|
|
@@ -9,7 +9,7 @@ class PGPlugin extends DatabasePlugin {
|
|
|
9
9
|
static get system () { return 'postgres' }
|
|
10
10
|
|
|
11
11
|
start ({ params = {}, query, processId }) {
|
|
12
|
-
const service = getServiceName(this
|
|
12
|
+
const service = getServiceName(this, params)
|
|
13
13
|
const originalStatement = query.text
|
|
14
14
|
|
|
15
15
|
this.startSpan('pg.query', {
|
|
@@ -31,12 +31,12 @@ class PGPlugin extends DatabasePlugin {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
function getServiceName (
|
|
35
|
-
if (typeof config.service === 'function') {
|
|
36
|
-
return config.service(params)
|
|
34
|
+
function getServiceName (tracer, params) {
|
|
35
|
+
if (typeof tracer.config.service === 'function') {
|
|
36
|
+
return tracer.config.service(params)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
return config.service
|
|
39
|
+
return tracer.config.service || `${tracer._tracer._tracer._service}-postgres`
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
module.exports = PGPlugin
|
|
@@ -19,10 +19,12 @@ class RheaConsumerPlugin extends ConsumerPlugin {
|
|
|
19
19
|
const name = getResourceNameFromMessage(msgObj)
|
|
20
20
|
const childOf = extractTextMap(msgObj, this.tracer)
|
|
21
21
|
|
|
22
|
-
this.startSpan({
|
|
22
|
+
this.startSpan('amqp.receive', {
|
|
23
23
|
childOf,
|
|
24
|
+
service: this.config.service,
|
|
24
25
|
resource: name,
|
|
25
26
|
type: 'worker',
|
|
27
|
+
kind: 'consumer',
|
|
26
28
|
meta: {
|
|
27
29
|
'component': 'rhea',
|
|
28
30
|
'amqp.link.source.address': name,
|
|
@@ -9,13 +9,17 @@ class RheaProducerPlugin extends ProducerPlugin {
|
|
|
9
9
|
|
|
10
10
|
constructor (...args) {
|
|
11
11
|
super(...args)
|
|
12
|
+
|
|
12
13
|
this.addTraceSub('encode', this.encode.bind(this))
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
start ({ targetAddress, host, port }) {
|
|
16
17
|
const name = targetAddress || 'amq.topic'
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
this.startSpan('amqp.send', {
|
|
20
|
+
service: this.config.service || `${this.tracer._service}-amqp-producer`,
|
|
18
21
|
resource: name,
|
|
22
|
+
kind: 'producer',
|
|
19
23
|
meta: {
|
|
20
24
|
'component': 'rhea',
|
|
21
25
|
'amqp.link.target.address': name,
|
|
@@ -34,19 +34,6 @@ function safeJsonParse (input) {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
const namingVersions = ['v0', 'v1']
|
|
38
|
-
const defaultVersion = 'v0'
|
|
39
|
-
|
|
40
|
-
function validateNamingVersion (versionString) {
|
|
41
|
-
if (!namingVersions.includes(versionString)) {
|
|
42
|
-
log.warn(
|
|
43
|
-
`Unexpected input for config.spanAttributeSchema, picked default ${defaultVersion}`
|
|
44
|
-
)
|
|
45
|
-
return defaultVersion
|
|
46
|
-
}
|
|
47
|
-
return versionString
|
|
48
|
-
}
|
|
49
|
-
|
|
50
37
|
// Shallow clone with property name remapping
|
|
51
38
|
function remapify (input, mappings) {
|
|
52
39
|
if (!input) return
|
|
@@ -273,9 +260,7 @@ class Config {
|
|
|
273
260
|
process.env.DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
|
|
274
261
|
false
|
|
275
262
|
)
|
|
276
|
-
|
|
277
|
-
process.env.DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
|
|
278
|
-
)
|
|
263
|
+
|
|
279
264
|
const DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH = coalesce(
|
|
280
265
|
process.env.DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
|
|
281
266
|
'512'
|
|
@@ -482,7 +467,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
482
467
|
sourceMap: !isFalse(DD_PROFILING_SOURCE_MAP),
|
|
483
468
|
exporters: DD_PROFILING_EXPORTERS
|
|
484
469
|
}
|
|
485
|
-
this.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
|
|
486
470
|
this.lookup = options.lookup
|
|
487
471
|
this.startupLogs = isTrue(DD_TRACE_STARTUP_LOGS)
|
|
488
472
|
// Disabled for CI Visibility's agentless
|
|
@@ -129,12 +129,17 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
129
129
|
_encodeEventContent (bytes, content) {
|
|
130
130
|
const keysLength = Object.keys(content).length
|
|
131
131
|
|
|
132
|
+
let totalKeysLength = keysLength
|
|
132
133
|
if (content.meta.test_session_id) {
|
|
133
|
-
|
|
134
|
-
} else {
|
|
135
|
-
this._encodeMapPrefix(bytes, keysLength)
|
|
134
|
+
totalKeysLength = totalKeysLength + 1
|
|
136
135
|
}
|
|
137
|
-
|
|
136
|
+
if (content.meta.test_module_id) {
|
|
137
|
+
totalKeysLength = totalKeysLength + 1
|
|
138
|
+
}
|
|
139
|
+
if (content.meta.test_suite_id) {
|
|
140
|
+
totalKeysLength = totalKeysLength + 1
|
|
141
|
+
}
|
|
142
|
+
this._encodeMapPrefix(bytes, totalKeysLength)
|
|
138
143
|
if (content.type) {
|
|
139
144
|
this._encodeString(bytes, 'type')
|
|
140
145
|
this._encodeString(bytes, content.type)
|
|
@@ -170,15 +175,20 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
170
175
|
this._encodeString(bytes, 'test_session_id')
|
|
171
176
|
this._encodeId(bytes, id(content.meta.test_session_id, 10))
|
|
172
177
|
delete content.meta.test_session_id
|
|
178
|
+
}
|
|
173
179
|
|
|
180
|
+
if (content.meta.test_module_id) {
|
|
174
181
|
this._encodeString(bytes, 'test_module_id')
|
|
175
182
|
this._encodeId(bytes, id(content.meta.test_module_id, 10))
|
|
176
183
|
delete content.meta.test_module_id
|
|
184
|
+
}
|
|
177
185
|
|
|
186
|
+
if (content.meta.test_suite_id) {
|
|
178
187
|
this._encodeString(bytes, 'test_suite_id')
|
|
179
188
|
this._encodeId(bytes, id(content.meta.test_suite_id, 10))
|
|
180
189
|
delete content.meta.test_suite_id
|
|
181
190
|
}
|
|
191
|
+
|
|
182
192
|
this._encodeString(bytes, 'meta')
|
|
183
193
|
this._encodeMap(bytes, content.meta)
|
|
184
194
|
this._encodeString(bytes, 'metrics')
|
|
@@ -4,7 +4,6 @@ const { channel } = require('../../diagnostics_channel')
|
|
|
4
4
|
const { isFalse } = require('./util')
|
|
5
5
|
const plugins = require('./plugins')
|
|
6
6
|
const log = require('./log')
|
|
7
|
-
const Nomenclature = require('./service-naming')
|
|
8
7
|
|
|
9
8
|
const loadChannel = channel('dd-trace:instrumentation:load')
|
|
10
9
|
|
|
@@ -97,7 +96,6 @@ module.exports = class PluginManager {
|
|
|
97
96
|
// like instrumenter.enable()
|
|
98
97
|
configure (config = {}) {
|
|
99
98
|
this._tracerConfig = config
|
|
100
|
-
Nomenclature.configure(config)
|
|
101
99
|
|
|
102
100
|
for (const name in pluginClasses) {
|
|
103
101
|
this.loadPlugin(name)
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const OutgoingPlugin = require('./outgoing')
|
|
4
4
|
|
|
5
|
-
class ClientPlugin extends
|
|
5
|
+
class ClientPlugin extends OutgoingPlugin {
|
|
6
6
|
static get operation () { return 'request' }
|
|
7
|
-
static get kind () { return 'client' }
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
module.exports = ClientPlugin
|
|
@@ -1,24 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const IncomingPlugin = require('./incoming')
|
|
4
4
|
|
|
5
|
-
class ConsumerPlugin extends
|
|
5
|
+
class ConsumerPlugin extends IncomingPlugin {
|
|
6
6
|
static get operation () { return 'receive' }
|
|
7
|
-
static get kind () { return 'consumer' }
|
|
8
|
-
static get type () { return 'messaging' }
|
|
9
|
-
|
|
10
|
-
startSpan (options) {
|
|
11
|
-
const spanDefaults = {
|
|
12
|
-
service: this.config.service || this.serviceName(),
|
|
13
|
-
kind: this.constructor.kind
|
|
14
|
-
}
|
|
15
|
-
Object.keys(spanDefaults).forEach(
|
|
16
|
-
key => {
|
|
17
|
-
if (!options[key]) options[key] = spanDefaults[key]
|
|
18
|
-
}
|
|
19
|
-
)
|
|
20
|
-
return super.startSpan(this.operationName(), options)
|
|
21
|
-
}
|
|
22
7
|
}
|
|
23
8
|
|
|
24
9
|
module.exports = ConsumerPlugin
|
|
@@ -4,7 +4,7 @@ const { CLIENT_PORT_KEY } = require('../constants')
|
|
|
4
4
|
const TracingPlugin = require('./tracing')
|
|
5
5
|
|
|
6
6
|
// TODO: Exit span on finish when AsyncResource instances are removed.
|
|
7
|
-
class
|
|
7
|
+
class OutgoingPlugin extends TracingPlugin {
|
|
8
8
|
constructor (...args) {
|
|
9
9
|
super(...args)
|
|
10
10
|
|
|
@@ -29,4 +29,4 @@ class OutboundPlugin extends TracingPlugin {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
module.exports =
|
|
32
|
+
module.exports = OutgoingPlugin
|
|
@@ -1,24 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const OutgoingPlugin = require('./outgoing')
|
|
4
4
|
|
|
5
|
-
class ProducerPlugin extends
|
|
5
|
+
class ProducerPlugin extends OutgoingPlugin {
|
|
6
6
|
static get operation () { return 'publish' }
|
|
7
|
-
static get kind () { return 'producer' }
|
|
8
|
-
static get type () { return 'messaging' }
|
|
9
|
-
|
|
10
|
-
startSpan (options) {
|
|
11
|
-
const spanDefaults = {
|
|
12
|
-
service: this.config.service || this.serviceName(),
|
|
13
|
-
kind: this.constructor.kind
|
|
14
|
-
}
|
|
15
|
-
Object.keys(spanDefaults).forEach(
|
|
16
|
-
key => {
|
|
17
|
-
if (!options[key]) options[key] = spanDefaults[key]
|
|
18
|
-
}
|
|
19
|
-
)
|
|
20
|
-
return super.startSpan(this.operationName(), options)
|
|
21
|
-
}
|
|
22
7
|
}
|
|
23
8
|
|
|
24
9
|
module.exports = ProducerPlugin
|
|
@@ -4,7 +4,6 @@ const Plugin = require('./plugin')
|
|
|
4
4
|
const { storage } = require('../../../datadog-core')
|
|
5
5
|
const analyticsSampler = require('../analytics_sampler')
|
|
6
6
|
const { COMPONENT } = require('../constants')
|
|
7
|
-
const Nomenclature = require('../service-naming')
|
|
8
7
|
|
|
9
8
|
class TracingPlugin extends Plugin {
|
|
10
9
|
constructor (...args) {
|
|
@@ -32,16 +31,6 @@ class TracingPlugin extends Plugin {
|
|
|
32
31
|
return store && store.span
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
serviceName (serviceArgs) {
|
|
36
|
-
const { type, id, kind } = this.constructor
|
|
37
|
-
return Nomenclature.serviceName(type, kind, id, serviceArgs)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
operationName (opNameArgs) {
|
|
41
|
-
const { type, id, kind } = this.constructor
|
|
42
|
-
return Nomenclature.opName(type, kind, id, opNameArgs)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
34
|
configure (config) {
|
|
46
35
|
return super.configure({
|
|
47
36
|
...config,
|
|
@@ -50,12 +50,10 @@ const CI_APP_ORIGIN = 'ciapp-test'
|
|
|
50
50
|
const JEST_TEST_RUNNER = 'test.jest.test_runner'
|
|
51
51
|
|
|
52
52
|
const TEST_ITR_TESTS_SKIPPED = '_dd.ci.itr.tests_skipped'
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
const TEST_MODULE_ITR_SKIPPING_ENABLED = 'test_module.itr.tests_skipping.enabled'
|
|
56
|
-
const TEST_MODULE_CODE_COVERAGE_ENABLED = 'test_module.code_coverage.enabled'
|
|
53
|
+
const TEST_ITR_SKIPPING_ENABLED = 'test.itr.tests_skipping.enabled'
|
|
54
|
+
const TEST_CODE_COVERAGE_ENABLED = 'test.code_coverage.enabled'
|
|
57
55
|
|
|
58
|
-
const
|
|
56
|
+
const TEST_CODE_COVERAGE_LINES_PCT = 'test.code_coverage.lines_pct'
|
|
59
57
|
|
|
60
58
|
// jest worker variables
|
|
61
59
|
const JEST_WORKER_TRACE_PAYLOAD_CODE = 60
|
|
@@ -97,17 +95,16 @@ module.exports = {
|
|
|
97
95
|
TEST_SUITE_ID,
|
|
98
96
|
TEST_ITR_TESTS_SKIPPED,
|
|
99
97
|
TEST_MODULE,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
TEST_MODULE_CODE_COVERAGE_ENABLED,
|
|
104
|
-
TEST_CODE_COVERAGE_LINES_TOTAL,
|
|
98
|
+
TEST_ITR_SKIPPING_ENABLED,
|
|
99
|
+
TEST_CODE_COVERAGE_ENABLED,
|
|
100
|
+
TEST_CODE_COVERAGE_LINES_PCT,
|
|
105
101
|
addIntelligentTestRunnerSpanTags,
|
|
106
102
|
getCoveredFilenamesFromCoverage,
|
|
107
103
|
resetCoverage,
|
|
108
104
|
mergeCoverage,
|
|
109
105
|
fromCoverageMapToCoverage,
|
|
110
|
-
getTestLineStart
|
|
106
|
+
getTestLineStart,
|
|
107
|
+
getCallSites
|
|
111
108
|
}
|
|
112
109
|
|
|
113
110
|
// Returns pkg manager and its version, separated by '-', e.g. npm-8.15.0 or yarn-1.22.19
|
|
@@ -316,17 +313,17 @@ function addIntelligentTestRunnerSpanTags (
|
|
|
316
313
|
{ isSuitesSkipped, isSuitesSkippingEnabled, isCodeCoverageEnabled, testCodeCoverageLinesTotal }
|
|
317
314
|
) {
|
|
318
315
|
testSessionSpan.setTag(TEST_ITR_TESTS_SKIPPED, isSuitesSkipped ? 'true' : 'false')
|
|
319
|
-
testSessionSpan.setTag(
|
|
320
|
-
testSessionSpan.setTag(
|
|
316
|
+
testSessionSpan.setTag(TEST_ITR_SKIPPING_ENABLED, isSuitesSkippingEnabled ? 'true' : 'false')
|
|
317
|
+
testSessionSpan.setTag(TEST_CODE_COVERAGE_ENABLED, isCodeCoverageEnabled ? 'true' : 'false')
|
|
321
318
|
|
|
322
319
|
testModuleSpan.setTag(TEST_ITR_TESTS_SKIPPED, isSuitesSkipped ? 'true' : 'false')
|
|
323
|
-
testModuleSpan.setTag(
|
|
324
|
-
testModuleSpan.setTag(
|
|
320
|
+
testModuleSpan.setTag(TEST_ITR_SKIPPING_ENABLED, isSuitesSkippingEnabled ? 'true' : 'false')
|
|
321
|
+
testModuleSpan.setTag(TEST_CODE_COVERAGE_ENABLED, isCodeCoverageEnabled ? 'true' : 'false')
|
|
325
322
|
|
|
326
323
|
// If suites have been skipped we don't want to report the total coverage, as it will be wrong
|
|
327
324
|
if (testCodeCoverageLinesTotal !== undefined && !isSuitesSkipped) {
|
|
328
|
-
testSessionSpan.setTag(
|
|
329
|
-
testModuleSpan.setTag(
|
|
325
|
+
testSessionSpan.setTag(TEST_CODE_COVERAGE_LINES_PCT, testCodeCoverageLinesTotal)
|
|
326
|
+
testModuleSpan.setTag(TEST_CODE_COVERAGE_LINES_PCT, testCodeCoverageLinesTotal)
|
|
330
327
|
}
|
|
331
328
|
}
|
|
332
329
|
|
|
@@ -399,3 +396,23 @@ function getTestLineStart (err, testSuitePath) {
|
|
|
399
396
|
return null
|
|
400
397
|
}
|
|
401
398
|
}
|
|
399
|
+
|
|
400
|
+
// From https://github.com/felixge/node-stack-trace/blob/ba06dcdb50d465cd440d84a563836e293b360427/index.js#L1
|
|
401
|
+
function getCallSites () {
|
|
402
|
+
const oldLimit = Error.stackTraceLimit
|
|
403
|
+
Error.stackTraceLimit = Infinity
|
|
404
|
+
|
|
405
|
+
const dummy = {}
|
|
406
|
+
|
|
407
|
+
const v8Handler = Error.prepareStackTrace
|
|
408
|
+
Error.prepareStackTrace = function (_, v8StackTrace) {
|
|
409
|
+
return v8StackTrace
|
|
410
|
+
}
|
|
411
|
+
Error.captureStackTrace(dummy)
|
|
412
|
+
|
|
413
|
+
const v8StackTrace = dummy.stack
|
|
414
|
+
Error.prepareStackTrace = v8Handler
|
|
415
|
+
Error.stackTraceLimit = oldLimit
|
|
416
|
+
|
|
417
|
+
return v8StackTrace
|
|
418
|
+
}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
const request = require('../exporters/common/request')
|
|
2
2
|
let seqId = 0
|
|
3
|
+
|
|
4
|
+
function getPayload (payload) {
|
|
5
|
+
// Some telemetry endpoints payloads accept collections of elements such as the 'logs' endpoint.
|
|
6
|
+
// 'logs' request type payload is meant to send library logs to Datadog’s backend.
|
|
7
|
+
if (Array.isArray(payload)) {
|
|
8
|
+
return payload
|
|
9
|
+
} else {
|
|
10
|
+
const { logger, tags, serviceMapping, ...trimmedPayload } = payload
|
|
11
|
+
return trimmedPayload
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
3
15
|
function sendData (config, application, host, reqType, payload = {}) {
|
|
4
16
|
const {
|
|
5
17
|
hostname,
|
|
@@ -7,8 +19,6 @@ function sendData (config, application, host, reqType, payload = {}) {
|
|
|
7
19
|
url
|
|
8
20
|
} = config
|
|
9
21
|
|
|
10
|
-
const { logger, tags, serviceMapping, ...trimmedPayload } = payload
|
|
11
|
-
|
|
12
22
|
const options = {
|
|
13
23
|
url,
|
|
14
24
|
hostname,
|
|
@@ -27,7 +37,7 @@ function sendData (config, application, host, reqType, payload = {}) {
|
|
|
27
37
|
tracer_time: Math.floor(Date.now() / 1000),
|
|
28
38
|
runtime_id: config.tags['runtime-id'],
|
|
29
39
|
seq_id: ++seqId,
|
|
30
|
-
payload:
|
|
40
|
+
payload: getPayload(payload),
|
|
31
41
|
application,
|
|
32
42
|
host
|
|
33
43
|
})
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
const { schemaDefinitions } = require('./schemas')
|
|
2
|
-
|
|
3
|
-
const kindMap = {
|
|
4
|
-
messaging: {
|
|
5
|
-
client: 'controlPlane',
|
|
6
|
-
consumer: 'inbound',
|
|
7
|
-
producer: 'outbound'
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
class SchemaManager {
|
|
12
|
-
constructor () {
|
|
13
|
-
this.schemas = schemaDefinitions
|
|
14
|
-
this.config = { spanAttributeSchema: 'v0' }
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
get schema () {
|
|
18
|
-
return this.schemas[this.version]
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
get version () {
|
|
22
|
-
return this.config.spanAttributeSchema
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
opName (type, kind, plugin, opNameArgs) {
|
|
26
|
-
return this.schema.getOpName(type, kindMap[type][kind], plugin, opNameArgs)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
serviceName (type, kind, plugin, serviceNameArgs) {
|
|
30
|
-
return this.schema.getServiceName(type, kindMap[type][kind], plugin, serviceNameArgs)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
configure (config = {}) {
|
|
34
|
-
this.config = config
|
|
35
|
-
Object.values(this.schemas).forEach(schemaDef => {
|
|
36
|
-
schemaDef.configure(config)
|
|
37
|
-
})
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
module.exports = new SchemaManager()
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
class SchemaDefinition {
|
|
2
|
-
constructor (schema) {
|
|
3
|
-
this.schema = schema
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
getSchemaItem (type, subType, plugin) {
|
|
7
|
-
const schema = this.schema
|
|
8
|
-
if (schema && schema[type] && schema[type][subType] && schema[type][subType][plugin]) {
|
|
9
|
-
return schema[type][subType][plugin]
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
getOpName (type, subType, plugin, opNameArgs) {
|
|
14
|
-
const item = this.getSchemaItem(type, subType, plugin)
|
|
15
|
-
return item.opName(opNameArgs)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
getServiceName (type, subType, plugin, serviceNameArgs) {
|
|
19
|
-
const item = this.getSchemaItem(type, subType, plugin)
|
|
20
|
-
return item.serviceName(this.service, serviceNameArgs)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
configure ({ service }) {
|
|
24
|
-
this.service = service
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
module.exports = SchemaDefinition
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
const SchemaDefinition = require('./definition')
|
|
2
|
-
|
|
3
|
-
function amqpServiceName (service) {
|
|
4
|
-
return `${service}-amqp`
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const schema = {
|
|
8
|
-
messaging: {
|
|
9
|
-
outbound: {
|
|
10
|
-
amqplib: {
|
|
11
|
-
opName: () => 'amqp.command',
|
|
12
|
-
serviceName: amqpServiceName
|
|
13
|
-
},
|
|
14
|
-
amqp10: {
|
|
15
|
-
opName: () => 'amqp.send',
|
|
16
|
-
serviceName: amqpServiceName
|
|
17
|
-
},
|
|
18
|
-
'google-cloud-pubsub': {
|
|
19
|
-
opName: () => 'pubsub.request',
|
|
20
|
-
serviceName: service => `${service}-pubsub`
|
|
21
|
-
},
|
|
22
|
-
kafkajs: {
|
|
23
|
-
opName: () => 'kafka.produce',
|
|
24
|
-
serviceName: service => `${service}-kafka`
|
|
25
|
-
},
|
|
26
|
-
rhea: {
|
|
27
|
-
opName: () => 'amqp.send',
|
|
28
|
-
serviceName: service => `${service}-amqp-producer`
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
inbound: {
|
|
32
|
-
amqplib: {
|
|
33
|
-
opName: () => 'amqp.command',
|
|
34
|
-
serviceName: amqpServiceName
|
|
35
|
-
},
|
|
36
|
-
amqp10: {
|
|
37
|
-
opName: () => 'amqp.receive',
|
|
38
|
-
serviceName: amqpServiceName
|
|
39
|
-
},
|
|
40
|
-
'google-cloud-pubsub': {
|
|
41
|
-
opName: () => 'pubsub.receive',
|
|
42
|
-
serviceName: service => service
|
|
43
|
-
},
|
|
44
|
-
kafkajs: {
|
|
45
|
-
opName: () => 'kafka.consume',
|
|
46
|
-
serviceName: service => `${service}-kafka`
|
|
47
|
-
},
|
|
48
|
-
rhea: {
|
|
49
|
-
opName: () => 'amqp.receive',
|
|
50
|
-
serviceName: service => service
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
controlPlane: {
|
|
54
|
-
amqplib: {
|
|
55
|
-
opName: () => 'amqp.command',
|
|
56
|
-
serviceName: amqpServiceName
|
|
57
|
-
},
|
|
58
|
-
'google-cloud-pubsub': {
|
|
59
|
-
opName: () => 'pubsub.request',
|
|
60
|
-
serviceName: service => `${service}-pubsub`
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
module.exports = new SchemaDefinition(schema)
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
const SchemaDefinition = require('./definition')
|
|
2
|
-
|
|
3
|
-
function identityService (service) {
|
|
4
|
-
return service
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const amqpInbound = {
|
|
8
|
-
opName: () => 'amqp.process',
|
|
9
|
-
serviceName: identityService
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const amqpOutbound = {
|
|
13
|
-
opName: () => 'amqp.send',
|
|
14
|
-
serviceName: identityService
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const schema = {
|
|
18
|
-
messaging: {
|
|
19
|
-
outbound: {
|
|
20
|
-
amqplib: amqpOutbound,
|
|
21
|
-
amqp10: amqpOutbound,
|
|
22
|
-
'google-cloud-pubsub': {
|
|
23
|
-
opName: () => 'gcp.pubsub.send',
|
|
24
|
-
serviceName: identityService
|
|
25
|
-
},
|
|
26
|
-
kafkajs: {
|
|
27
|
-
opName: () => 'kafka.send',
|
|
28
|
-
serviceName: identityService
|
|
29
|
-
},
|
|
30
|
-
rhea: amqpOutbound
|
|
31
|
-
},
|
|
32
|
-
inbound: {
|
|
33
|
-
amqplib: amqpInbound,
|
|
34
|
-
amqp10: amqpInbound,
|
|
35
|
-
'google-cloud-pubsub': {
|
|
36
|
-
opName: () => 'gcp.pubsub.process',
|
|
37
|
-
serviceName: identityService
|
|
38
|
-
},
|
|
39
|
-
kafkajs: {
|
|
40
|
-
opName: () => 'kafka.process',
|
|
41
|
-
serviceName: identityService
|
|
42
|
-
},
|
|
43
|
-
rhea: amqpInbound
|
|
44
|
-
},
|
|
45
|
-
controlPlane: {
|
|
46
|
-
amqplib: {
|
|
47
|
-
opName: () => 'amqp.command',
|
|
48
|
-
serviceName: identityService
|
|
49
|
-
},
|
|
50
|
-
'google-cloud-pubsub': {
|
|
51
|
-
opName: () => 'gcp.pubsub.request',
|
|
52
|
-
serviceName: identityService
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
module.exports = new SchemaDefinition(schema)
|