dd-trace 3.48.0 → 3.50.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/CONTRIBUTING.md +98 -0
- package/README.md +4 -102
- package/ci/cypress/after-run.js +1 -0
- package/package.json +2 -2
- package/packages/datadog-instrumentations/src/cucumber.js +156 -42
- package/packages/datadog-instrumentations/src/jest.js +84 -49
- package/packages/datadog-instrumentations/src/mocha.js +139 -13
- package/packages/datadog-plugin-amqplib/src/consumer.js +5 -2
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +60 -50
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +40 -17
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +62 -26
- package/packages/datadog-plugin-cucumber/src/index.js +25 -9
- package/packages/datadog-plugin-cypress/src/after-run.js +3 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +560 -0
- package/packages/datadog-plugin-cypress/src/plugin.js +6 -533
- package/packages/datadog-plugin-jest/src/index.js +4 -8
- package/packages/datadog-plugin-kafkajs/src/consumer.js +16 -0
- package/packages/datadog-plugin-mocha/src/index.js +38 -17
- package/packages/datadog-plugin-rhea/src/consumer.js +4 -1
- package/packages/dd-trace/src/appsec/iast/context/context-plugin.js +90 -0
- package/packages/dd-trace/src/appsec/iast/context/kafka-ctx-plugin.js +14 -0
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +8 -0
- package/packages/dd-trace/src/appsec/iast/index.js +4 -4
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +1 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +10 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +53 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +10 -46
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +13 -9
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +47 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +3 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +29 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +1 -0
- package/packages/dd-trace/src/config.js +3 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -1
- package/packages/dd-trace/src/opentracing/span.js +4 -4
- package/packages/dd-trace/src/plugins/ci_plugin.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +17 -1
- package/packages/dd-trace/src/profiling/exporters/agent.js +40 -31
- package/packages/dd-trace/src/telemetry/index.js +3 -0
- package/packages/dd-trace/src/telemetry/logs/index.js +2 -2
- package/packages/dd-trace/src/telemetry/send-data.js +0 -3
|
@@ -14,6 +14,7 @@ function enable (config) {
|
|
|
14
14
|
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_HTTP_HEADER_TAGS, true)
|
|
15
15
|
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_LOGS_INJECTION, true)
|
|
16
16
|
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_SAMPLE_RATE, true)
|
|
17
|
+
rc.updateCapabilities(RemoteConfigCapabilities.APM_TRACING_ENABLED, true)
|
|
17
18
|
|
|
18
19
|
const activation = Activation.fromConfig(config)
|
|
19
20
|
|
|
@@ -209,10 +209,12 @@ class Config {
|
|
|
209
209
|
|
|
210
210
|
const inServerlessEnvironment = inAWSLambda || isGCPFunction || isAzureFunctionConsumptionPlan
|
|
211
211
|
|
|
212
|
+
const isJestWorker = !!process.env.JEST_WORKER_ID
|
|
213
|
+
|
|
212
214
|
const DD_INSTRUMENTATION_TELEMETRY_ENABLED = coalesce(
|
|
213
215
|
process.env.DD_TRACE_TELEMETRY_ENABLED, // for backward compatibility
|
|
214
216
|
process.env.DD_INSTRUMENTATION_TELEMETRY_ENABLED, // to comply with instrumentation telemetry specs
|
|
215
|
-
!inServerlessEnvironment
|
|
217
|
+
!(inServerlessEnvironment || isJestWorker)
|
|
216
218
|
)
|
|
217
219
|
const DD_TELEMETRY_HEARTBEAT_INTERVAL = process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL
|
|
218
220
|
? Math.floor(parseFloat(process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL) * 1000)
|
|
@@ -611,7 +613,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
611
613
|
this.peerServiceMapping = DD_TRACE_PEER_SERVICE_MAPPING
|
|
612
614
|
this.lookup = options.lookup
|
|
613
615
|
this.startupLogs = isTrue(DD_TRACE_STARTUP_LOGS)
|
|
614
|
-
// Disabled for CI Visibility's agentless
|
|
615
616
|
this.telemetry = {
|
|
616
617
|
enabled: isTrue(DD_INSTRUMENTATION_TELEMETRY_ENABLED),
|
|
617
618
|
heartbeatInterval: DD_TELEMETRY_HEARTBEAT_INTERVAL,
|
|
@@ -29,8 +29,8 @@ const OTEL_ENABLED = !!process.env.DD_TRACE_OTEL_ENABLED
|
|
|
29
29
|
const ALLOWED = ['string', 'number', 'boolean']
|
|
30
30
|
|
|
31
31
|
const integrationCounters = {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
spans_created: {},
|
|
33
|
+
spans_finished: {}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
const finishCh = channel('dd-trace:span:finish')
|
|
@@ -72,7 +72,7 @@ class DatadogSpan {
|
|
|
72
72
|
this._name = operationName
|
|
73
73
|
this._integrationName = fields.integrationName || 'opentracing'
|
|
74
74
|
|
|
75
|
-
getIntegrationCounter('
|
|
75
|
+
getIntegrationCounter('spans_created', this._integrationName).inc()
|
|
76
76
|
|
|
77
77
|
this._spanContext = this._createContext(parent, fields)
|
|
78
78
|
this._spanContext._name = operationName
|
|
@@ -172,7 +172,7 @@ class DatadogSpan {
|
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
getIntegrationCounter('
|
|
175
|
+
getIntegrationCounter('spans_finished', this._integrationName).inc()
|
|
176
176
|
|
|
177
177
|
if (DD_TRACE_EXPERIMENTAL_SPAN_COUNTS && finishedRegistry) {
|
|
178
178
|
runtimeMetrics.decrement('runtime.node.spans.unfinished')
|
|
@@ -51,7 +51,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
51
51
|
})
|
|
52
52
|
|
|
53
53
|
this.addSub(`ci:${this.constructor.id}:test-suite:skippable`, ({ onDone }) => {
|
|
54
|
-
if (!this.tracer._exporter
|
|
54
|
+
if (!this.tracer._exporter?.getSkippableSuites) {
|
|
55
55
|
return onDone({ err: new Error('CI Visibility was not initialized correctly') })
|
|
56
56
|
}
|
|
57
57
|
this.tracer._exporter.getSkippableSuites(this.testConfiguration, (err, skippableSuites, itrCorrelationId) => {
|
|
@@ -74,6 +74,10 @@ const TEST_CODE_COVERAGE_LINES_PCT = 'test.code_coverage.lines_pct'
|
|
|
74
74
|
const JEST_WORKER_TRACE_PAYLOAD_CODE = 60
|
|
75
75
|
const JEST_WORKER_COVERAGE_PAYLOAD_CODE = 61
|
|
76
76
|
|
|
77
|
+
// Early flake detection util strings
|
|
78
|
+
const EFD_STRING = "Retried by Datadog's Early Flake Detection"
|
|
79
|
+
const EFD_TEST_NAME_REGEX = new RegExp(EFD_STRING + ' \\(#\\d+\\): ', 'g')
|
|
80
|
+
|
|
77
81
|
module.exports = {
|
|
78
82
|
TEST_CODE_OWNERS,
|
|
79
83
|
TEST_FRAMEWORK,
|
|
@@ -131,7 +135,11 @@ module.exports = {
|
|
|
131
135
|
getTestLineStart,
|
|
132
136
|
getCallSites,
|
|
133
137
|
removeInvalidMetadata,
|
|
134
|
-
parseAnnotations
|
|
138
|
+
parseAnnotations,
|
|
139
|
+
EFD_STRING,
|
|
140
|
+
EFD_TEST_NAME_REGEX,
|
|
141
|
+
removeEfdStringFromTestName,
|
|
142
|
+
addEfdStringToTestName
|
|
135
143
|
}
|
|
136
144
|
|
|
137
145
|
// Returns pkg manager and its version, separated by '-', e.g. npm-8.15.0 or yarn-1.22.19
|
|
@@ -552,3 +560,11 @@ function parseAnnotations (annotations) {
|
|
|
552
560
|
return tags
|
|
553
561
|
}, {})
|
|
554
562
|
}
|
|
563
|
+
|
|
564
|
+
function addEfdStringToTestName (testName, numAttempt) {
|
|
565
|
+
return `${EFD_STRING} (#${numAttempt}): ${testName}`
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
function removeEfdStringFromTestName (testName) {
|
|
569
|
+
return testName.replace(EFD_TEST_NAME_REGEX, '')
|
|
570
|
+
}
|
|
@@ -61,45 +61,50 @@ class AgentExporter {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export ({ profiles, start, end, tags }) {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
const fields = [
|
|
67
|
-
['recording-start', start.toISOString()],
|
|
68
|
-
['recording-end', end.toISOString()],
|
|
69
|
-
['language', 'javascript'],
|
|
70
|
-
['runtime', 'nodejs'],
|
|
71
|
-
['runtime_version', process.version],
|
|
72
|
-
['profiler_version', version],
|
|
73
|
-
['format', 'pprof'],
|
|
74
|
-
|
|
75
|
-
['tags[]', 'language:javascript'],
|
|
76
|
-
['tags[]', 'runtime:nodejs'],
|
|
77
|
-
['tags[]', `runtime_version:${process.version}`],
|
|
78
|
-
['tags[]', `process_id:${process.pid}`],
|
|
79
|
-
['tags[]', `profiler_version:${version}`],
|
|
80
|
-
['tags[]', 'format:pprof'],
|
|
81
|
-
...Object.entries(tags).map(([key, value]) => ['tags[]', `${key}:${value}`])
|
|
82
|
-
]
|
|
64
|
+
const fields = []
|
|
83
65
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
66
|
+
function typeToFile (type) {
|
|
67
|
+
return `${type}.pprof`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const event = JSON.stringify({
|
|
71
|
+
attachments: Object.keys(profiles).map(typeToFile),
|
|
72
|
+
start: start.toISOString(),
|
|
73
|
+
end: end.toISOString(),
|
|
74
|
+
family: 'node',
|
|
75
|
+
version: '4',
|
|
76
|
+
tags_profiler: [
|
|
77
|
+
'language:javascript',
|
|
78
|
+
'runtime:nodejs',
|
|
79
|
+
`runtime_arch:${process.arch}`,
|
|
80
|
+
`runtime_os:${process.platform}`,
|
|
81
|
+
`runtime_version:${process.version}`,
|
|
82
|
+
`process_id:${process.pid}`,
|
|
83
|
+
`profiler_version:${version}`,
|
|
84
|
+
'format:pprof',
|
|
85
|
+
...Object.entries(tags).map(([key, value]) => `${key}:${value}`)
|
|
86
|
+
].join(',')
|
|
87
87
|
})
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
fields.push(['event', event, {
|
|
90
|
+
filename: 'event.json',
|
|
91
|
+
contentType: 'application/json'
|
|
92
|
+
}])
|
|
93
|
+
|
|
94
|
+
this._logger.debug(() => {
|
|
95
|
+
return `Building agent export report:\n${event}`
|
|
96
|
+
})
|
|
92
97
|
|
|
98
|
+
for (const [type, buffer] of Object.entries(profiles)) {
|
|
93
99
|
this._logger.debug(() => {
|
|
94
100
|
const bytes = buffer.toString('hex').match(/../g).join(' ')
|
|
95
101
|
return `Adding ${type} profile to agent export: ` + bytes
|
|
96
102
|
})
|
|
97
103
|
|
|
98
|
-
|
|
99
|
-
fields.push([
|
|
100
|
-
filename
|
|
101
|
-
contentType: 'application/octet-stream'
|
|
102
|
-
knownLength: buffer.length
|
|
104
|
+
const filename = typeToFile(type)
|
|
105
|
+
fields.push([filename, buffer, {
|
|
106
|
+
filename,
|
|
107
|
+
contentType: 'application/octet-stream'
|
|
103
108
|
}])
|
|
104
109
|
}
|
|
105
110
|
|
|
@@ -121,7 +126,11 @@ class AgentExporter {
|
|
|
121
126
|
const options = {
|
|
122
127
|
method: 'POST',
|
|
123
128
|
path: '/profiling/v1/input',
|
|
124
|
-
headers:
|
|
129
|
+
headers: {
|
|
130
|
+
'DD-EVP-ORIGIN': 'dd-trace-js',
|
|
131
|
+
'DD-EVP-ORIGIN-VERSION': version,
|
|
132
|
+
...form.getHeaders()
|
|
133
|
+
},
|
|
125
134
|
timeout: this._backoffTime * Math.pow(2, attempt)
|
|
126
135
|
}
|
|
127
136
|
|
|
@@ -6,6 +6,7 @@ const dependencies = require('./dependencies')
|
|
|
6
6
|
const { sendData } = require('./send-data')
|
|
7
7
|
const { errors } = require('../startup-log')
|
|
8
8
|
const { manager: metricsManager } = require('./metrics')
|
|
9
|
+
const logs = require('./logs')
|
|
9
10
|
|
|
10
11
|
const telemetryStartChannel = dc.channel('datadog:telemetry:start')
|
|
11
12
|
const telemetryStopChannel = dc.channel('datadog:telemetry:stop')
|
|
@@ -226,6 +227,7 @@ function createPayload (currReqType, currPayload = {}) {
|
|
|
226
227
|
function heartbeat (config, application, host) {
|
|
227
228
|
heartbeatTimeout = setTimeout(() => {
|
|
228
229
|
metricsManager.send(config, application, host)
|
|
230
|
+
logs.send(config, application, host)
|
|
229
231
|
|
|
230
232
|
const { reqType, payload } = createPayload('app-heartbeat')
|
|
231
233
|
sendData(config, application, host, reqType, payload, updateRetryData)
|
|
@@ -259,6 +261,7 @@ function start (aConfig, thePluginManager) {
|
|
|
259
261
|
integrations = getIntegrations()
|
|
260
262
|
|
|
261
263
|
dependencies.start(config, application, host, getRetryData, updateRetryData)
|
|
264
|
+
logs.start(config)
|
|
262
265
|
|
|
263
266
|
sendData(config, application, host, 'app-started', appStarted(config))
|
|
264
267
|
|
|
@@ -52,9 +52,9 @@ function stop () {
|
|
|
52
52
|
function send (config, application, host) {
|
|
53
53
|
if (!enabled) return
|
|
54
54
|
|
|
55
|
-
const logs =
|
|
55
|
+
const logs = logCollector.drain()
|
|
56
56
|
if (logs) {
|
|
57
|
-
sendData(config, application, host, 'logs', logs)
|
|
57
|
+
sendData(config, application, host, 'logs', { logs })
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -27,9 +27,6 @@ function getAgentlessTelemetryEndpoint (site) {
|
|
|
27
27
|
if (site === 'datad0g.com') { // staging
|
|
28
28
|
return 'https://all-http-intake.logs.datad0g.com'
|
|
29
29
|
}
|
|
30
|
-
if (site === 'datadoghq.eu') {
|
|
31
|
-
return 'https://instrumentation-telemetry-intake.eu1.datadoghq.com'
|
|
32
|
-
}
|
|
33
30
|
return `https://instrumentation-telemetry-intake.${site}`
|
|
34
31
|
}
|
|
35
32
|
|