dd-trace 5.41.1 → 5.43.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/LICENSE-3rdparty.csv +1 -0
- package/index.d.ts +8 -1
- package/package.json +7 -4
- package/packages/datadog-esbuild/index.js +3 -1
- package/packages/datadog-instrumentations/src/cucumber.js +37 -29
- package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +102 -0
- package/packages/datadog-instrumentations/src/{check_require_cache.js → helpers/check-require-cache.js} +2 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/register.js +4 -1
- package/packages/datadog-instrumentations/src/jest.js +72 -49
- package/packages/datadog-instrumentations/src/langchain.js +29 -10
- package/packages/datadog-instrumentations/src/mocha/main.js +53 -34
- package/packages/datadog-instrumentations/src/mocha/utils.js +34 -24
- package/packages/datadog-instrumentations/src/mocha/worker.js +7 -8
- package/packages/datadog-instrumentations/src/openai.js +1 -1
- package/packages/datadog-instrumentations/src/playwright.js +37 -30
- package/packages/datadog-instrumentations/src/vitest.js +83 -33
- package/packages/datadog-plugin-cucumber/src/index.js +13 -4
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +41 -35
- package/packages/datadog-plugin-cypress/src/plugin.js +10 -0
- package/packages/datadog-plugin-google-cloud-vertexai/src/index.js +195 -0
- package/packages/datadog-plugin-jest/src/index.js +18 -6
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +4 -1
- package/packages/datadog-plugin-mocha/src/index.js +13 -4
- package/packages/datadog-plugin-playwright/src/index.js +19 -5
- package/packages/datadog-plugin-vitest/src/index.js +41 -17
- package/packages/dd-trace/src/appsec/api_security_sampler.js +7 -3
- package/packages/dd-trace/src/appsec/blocking.js +23 -16
- package/packages/dd-trace/src/appsec/graphql.js +13 -6
- package/packages/dd-trace/src/appsec/rasp/utils.js +0 -1
- package/packages/dd-trace/src/appsec/reporter.js +35 -0
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -3
- package/packages/dd-trace/src/appsec/telemetry/common.js +2 -1
- package/packages/dd-trace/src/appsec/telemetry/index.js +5 -1
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +16 -1
- package/packages/dd-trace/src/appsec/telemetry/waf.js +62 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +43 -13
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +15 -14
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +1 -2
- package/packages/dd-trace/src/ci-visibility/telemetry.js +2 -1
- package/packages/dd-trace/src/ci-visibility/{quarantined-tests/get-quarantined-tests.js → test-management/get-test-management-tests.js} +5 -5
- package/packages/dd-trace/src/config.js +15 -1
- package/packages/dd-trace/src/dogstatsd.js +3 -3
- package/packages/dd-trace/src/encode/0.4.js +108 -12
- package/packages/dd-trace/src/encode/0.5.js +7 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +9 -2
- package/packages/dd-trace/src/exporters/agent/index.js +2 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +3 -2
- package/packages/dd-trace/src/format.js +34 -32
- package/packages/dd-trace/src/lambda/runtime/patch.js +5 -3
- package/packages/dd-trace/src/lambda/runtime/ritm.js +13 -18
- package/packages/dd-trace/src/llmobs/plugins/openai.js +27 -2
- package/packages/dd-trace/src/llmobs/sdk.js +3 -3
- package/packages/dd-trace/src/log/index.js +1 -13
- package/packages/dd-trace/src/log/utils.js +16 -0
- package/packages/dd-trace/src/opentracing/span.js +3 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +38 -10
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/git.js +7 -3
- package/packages/dd-trace/src/plugins/util/test.js +10 -0
- package/packages/dd-trace/src/plugins/util/web.js +5 -2
- package/packages/dd-trace/src/priority_sampler.js +116 -15
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +13 -14
- package/packages/dd-trace/src/sampler.js +9 -0
- package/packages/dd-trace/src/standalone/product.js +6 -2
- package/packages/dd-trace/src/startup-log.js +2 -1
- package/packages/dd-trace/src/telemetry/metrics.js +0 -8
- package/packages/dd-trace/src/tracer.js +1 -1
- /package/packages/datadog-instrumentations/src/{utils/src → helpers}/extract-package-and-module-path.js +0 -0
|
@@ -103,16 +103,34 @@ function reportWafInit (wafVersion, rulesVersion, diagnosticsRules = {}) {
|
|
|
103
103
|
function reportMetrics (metrics, raspRule) {
|
|
104
104
|
const store = storage('legacy').getStore()
|
|
105
105
|
const rootSpan = store?.req && web.root(store.req)
|
|
106
|
+
|
|
106
107
|
if (!rootSpan) return
|
|
107
108
|
|
|
108
109
|
if (metrics.rulesVersion) {
|
|
109
110
|
rootSpan.setTag('_dd.appsec.event_rules.version', metrics.rulesVersion)
|
|
110
111
|
}
|
|
112
|
+
|
|
111
113
|
if (raspRule) {
|
|
112
114
|
updateRaspRequestsMetricTags(metrics, store.req, raspRule)
|
|
113
115
|
} else {
|
|
114
116
|
updateWafRequestsMetricTags(metrics, store.req)
|
|
115
117
|
}
|
|
118
|
+
|
|
119
|
+
reportTruncationMetrics(rootSpan, metrics)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function reportTruncationMetrics (rootSpan, metrics) {
|
|
123
|
+
if (metrics.maxTruncatedString) {
|
|
124
|
+
rootSpan.setTag('_dd.appsec.truncated.string_length', metrics.maxTruncatedString)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (metrics.maxTruncatedContainerSize) {
|
|
128
|
+
rootSpan.setTag('_dd.appsec.truncated.container_size', metrics.maxTruncatedContainerSize)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (metrics.maxTruncatedContainerDepth) {
|
|
132
|
+
rootSpan.setTag('_dd.appsec.truncated.container_depth', metrics.maxTruncatedContainerDepth)
|
|
133
|
+
}
|
|
116
134
|
}
|
|
117
135
|
|
|
118
136
|
function reportAttack (attackData) {
|
|
@@ -189,6 +207,7 @@ function finishRequest (req, res) {
|
|
|
189
207
|
}
|
|
190
208
|
|
|
191
209
|
const metrics = getRequestMetrics(req)
|
|
210
|
+
|
|
192
211
|
if (metrics?.duration) {
|
|
193
212
|
rootSpan.setTag('_dd.appsec.waf.duration', metrics.duration)
|
|
194
213
|
}
|
|
@@ -197,6 +216,14 @@ function finishRequest (req, res) {
|
|
|
197
216
|
rootSpan.setTag('_dd.appsec.waf.duration_ext', metrics.durationExt)
|
|
198
217
|
}
|
|
199
218
|
|
|
219
|
+
if (metrics?.wafErrorCode) {
|
|
220
|
+
rootSpan.setTag('_dd.appsec.waf.error', metrics.wafErrorCode)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (metrics?.wafTimeouts) {
|
|
224
|
+
rootSpan.setTag('_dd.appsec.waf.timeouts', metrics.wafTimeouts)
|
|
225
|
+
}
|
|
226
|
+
|
|
200
227
|
if (metrics?.raspDuration) {
|
|
201
228
|
rootSpan.setTag('_dd.appsec.rasp.duration', metrics.raspDuration)
|
|
202
229
|
}
|
|
@@ -205,6 +232,14 @@ function finishRequest (req, res) {
|
|
|
205
232
|
rootSpan.setTag('_dd.appsec.rasp.duration_ext', metrics.raspDurationExt)
|
|
206
233
|
}
|
|
207
234
|
|
|
235
|
+
if (metrics?.raspErrorCode) {
|
|
236
|
+
rootSpan.setTag('_dd.appsec.rasp.error', metrics.raspErrorCode)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (metrics?.raspTimeouts) {
|
|
240
|
+
rootSpan.setTag('_dd.appsec.rasp.timeout', metrics.raspTimeouts)
|
|
241
|
+
}
|
|
242
|
+
|
|
208
243
|
if (metrics?.raspEvalCount) {
|
|
209
244
|
rootSpan.setTag('_dd.appsec.rasp.rule.eval', metrics.raspEvalCount)
|
|
210
245
|
}
|
|
@@ -7,7 +7,8 @@ const tags = {
|
|
|
7
7
|
RULE_TRIGGERED: 'rule_triggered',
|
|
8
8
|
WAF_TIMEOUT: 'waf_timeout',
|
|
9
9
|
WAF_VERSION: 'waf_version',
|
|
10
|
-
EVENT_RULES_VERSION: 'event_rules_version'
|
|
10
|
+
EVENT_RULES_VERSION: 'event_rules_version',
|
|
11
|
+
INPUT_TRUNCATED: 'input_truncated'
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
function getVersionsTags (wafVersion, rulesVersion) {
|
|
@@ -5,10 +5,25 @@ const { DD_TELEMETRY_REQUEST_METRICS } = require('./common')
|
|
|
5
5
|
|
|
6
6
|
const appsecMetrics = telemetryMetrics.manager.namespace('appsec')
|
|
7
7
|
|
|
8
|
-
function addRaspRequestMetrics (store, { duration, durationExt }) {
|
|
8
|
+
function addRaspRequestMetrics (store, { duration, durationExt, wafTimeout, errorCode }) {
|
|
9
9
|
store[DD_TELEMETRY_REQUEST_METRICS].raspDuration += duration || 0
|
|
10
10
|
store[DD_TELEMETRY_REQUEST_METRICS].raspDurationExt += durationExt || 0
|
|
11
11
|
store[DD_TELEMETRY_REQUEST_METRICS].raspEvalCount++
|
|
12
|
+
|
|
13
|
+
if (wafTimeout) {
|
|
14
|
+
store[DD_TELEMETRY_REQUEST_METRICS].raspTimeouts++
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (errorCode) {
|
|
18
|
+
if (store[DD_TELEMETRY_REQUEST_METRICS].raspErrorCode) {
|
|
19
|
+
store[DD_TELEMETRY_REQUEST_METRICS].raspErrorCode = Math.max(
|
|
20
|
+
errorCode,
|
|
21
|
+
store[DD_TELEMETRY_REQUEST_METRICS].raspErrorCode
|
|
22
|
+
)
|
|
23
|
+
} else {
|
|
24
|
+
store[DD_TELEMETRY_REQUEST_METRICS].raspErrorCode = errorCode
|
|
25
|
+
}
|
|
26
|
+
}
|
|
12
27
|
}
|
|
13
28
|
|
|
14
29
|
function trackRaspMetrics (metrics, raspRule) {
|
|
@@ -7,9 +7,30 @@ const appsecMetrics = telemetryMetrics.manager.namespace('appsec')
|
|
|
7
7
|
|
|
8
8
|
const DD_TELEMETRY_WAF_RESULT_TAGS = Symbol('_dd.appsec.telemetry.waf.result.tags')
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
const TRUNCATION_FLAGS = {
|
|
11
|
+
STRING: 1,
|
|
12
|
+
CONTAINER_SIZE: 2,
|
|
13
|
+
CONTAINER_DEPTH: 4
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function addWafRequestMetrics (store, { duration, durationExt, wafTimeout, errorCode }) {
|
|
11
17
|
store[DD_TELEMETRY_REQUEST_METRICS].duration += duration || 0
|
|
12
18
|
store[DD_TELEMETRY_REQUEST_METRICS].durationExt += durationExt || 0
|
|
19
|
+
|
|
20
|
+
if (wafTimeout) {
|
|
21
|
+
store[DD_TELEMETRY_REQUEST_METRICS].wafTimeouts++
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (errorCode) {
|
|
25
|
+
if (store[DD_TELEMETRY_REQUEST_METRICS].wafErrorCode) {
|
|
26
|
+
store[DD_TELEMETRY_REQUEST_METRICS].wafErrorCode = Math.max(
|
|
27
|
+
errorCode,
|
|
28
|
+
store[DD_TELEMETRY_REQUEST_METRICS].wafErrorCode
|
|
29
|
+
)
|
|
30
|
+
} else {
|
|
31
|
+
store[DD_TELEMETRY_REQUEST_METRICS].wafErrorCode = errorCode
|
|
32
|
+
}
|
|
33
|
+
}
|
|
13
34
|
}
|
|
14
35
|
|
|
15
36
|
function trackWafDurations ({ duration, durationExt }, versionsTags) {
|
|
@@ -43,6 +64,12 @@ function trackWafMetrics (store, metrics) {
|
|
|
43
64
|
metricTags[tags.WAF_TIMEOUT] = true
|
|
44
65
|
}
|
|
45
66
|
|
|
67
|
+
const truncationReason = getTruncationReason(metrics)
|
|
68
|
+
if (truncationReason > 0) {
|
|
69
|
+
metricTags[tags.INPUT_TRUNCATED] = true
|
|
70
|
+
incrementTruncatedMetrics(metrics, truncationReason)
|
|
71
|
+
}
|
|
72
|
+
|
|
46
73
|
return metricTags
|
|
47
74
|
}
|
|
48
75
|
|
|
@@ -54,6 +81,7 @@ function getOrCreateMetricTags (store, versionsTags) {
|
|
|
54
81
|
[tags.REQUEST_BLOCKED]: false,
|
|
55
82
|
[tags.RULE_TRIGGERED]: false,
|
|
56
83
|
[tags.WAF_TIMEOUT]: false,
|
|
84
|
+
[tags.INPUT_TRUNCATED]: false,
|
|
57
85
|
|
|
58
86
|
...versionsTags
|
|
59
87
|
}
|
|
@@ -83,6 +111,39 @@ function incrementWafRequests (store) {
|
|
|
83
111
|
}
|
|
84
112
|
}
|
|
85
113
|
|
|
114
|
+
function incrementTruncatedMetrics (metrics, truncationReason) {
|
|
115
|
+
const truncationTags = { truncation_reason: truncationReason }
|
|
116
|
+
appsecMetrics.count('waf.input_truncated', truncationTags).inc(1)
|
|
117
|
+
|
|
118
|
+
if (metrics?.maxTruncatedString) {
|
|
119
|
+
appsecMetrics.distribution('waf.truncated_value_size', {
|
|
120
|
+
truncation_reason: TRUNCATION_FLAGS.STRING
|
|
121
|
+
}).track(metrics.maxTruncatedString)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (metrics?.maxTruncatedContainerSize) {
|
|
125
|
+
appsecMetrics.distribution('waf.truncated_value_size', {
|
|
126
|
+
truncation_reason: TRUNCATION_FLAGS.CONTAINER_SIZE
|
|
127
|
+
}).track(metrics.maxTruncatedContainerSize)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (metrics?.maxTruncatedContainerDepth) {
|
|
131
|
+
appsecMetrics.distribution('waf.truncated_value_size', {
|
|
132
|
+
truncation_reason: TRUNCATION_FLAGS.CONTAINER_DEPTH
|
|
133
|
+
}).track(metrics.maxTruncatedContainerDepth)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function getTruncationReason ({ maxTruncatedString, maxTruncatedContainerSize, maxTruncatedContainerDepth }) {
|
|
138
|
+
let reason = 0
|
|
139
|
+
|
|
140
|
+
if (maxTruncatedString) reason |= TRUNCATION_FLAGS.STRING
|
|
141
|
+
if (maxTruncatedContainerSize) reason |= TRUNCATION_FLAGS.CONTAINER_SIZE
|
|
142
|
+
if (maxTruncatedContainerDepth) reason |= TRUNCATION_FLAGS.CONTAINER_DEPTH
|
|
143
|
+
|
|
144
|
+
return reason
|
|
145
|
+
}
|
|
146
|
+
|
|
86
147
|
module.exports = {
|
|
87
148
|
addWafRequestMetrics,
|
|
88
149
|
trackWafMetrics,
|
|
@@ -17,8 +17,8 @@ class WAFContextWrapper {
|
|
|
17
17
|
this.wafTimeout = wafTimeout
|
|
18
18
|
this.wafVersion = wafVersion
|
|
19
19
|
this.rulesVersion = rulesVersion
|
|
20
|
-
this.addressesToSkip = new Set()
|
|
21
20
|
this.knownAddresses = knownAddresses
|
|
21
|
+
this.addressesToSkip = new Set()
|
|
22
22
|
this.cachedUserIdActions = new Map()
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -77,6 +77,20 @@ class WAFContextWrapper {
|
|
|
77
77
|
|
|
78
78
|
if (!payloadHasData) return
|
|
79
79
|
|
|
80
|
+
const metrics = {
|
|
81
|
+
rulesVersion: this.rulesVersion,
|
|
82
|
+
wafVersion: this.wafVersion,
|
|
83
|
+
wafTimeout: false,
|
|
84
|
+
duration: 0,
|
|
85
|
+
durationExt: 0,
|
|
86
|
+
blockTriggered: false,
|
|
87
|
+
ruleTriggered: false,
|
|
88
|
+
errorCode: null,
|
|
89
|
+
maxTruncatedString: null,
|
|
90
|
+
maxTruncatedContainerSize: null,
|
|
91
|
+
maxTruncatedContainerDepth: null
|
|
92
|
+
}
|
|
93
|
+
|
|
80
94
|
try {
|
|
81
95
|
const start = process.hrtime.bigint()
|
|
82
96
|
|
|
@@ -84,6 +98,23 @@ class WAFContextWrapper {
|
|
|
84
98
|
|
|
85
99
|
const end = process.hrtime.bigint()
|
|
86
100
|
|
|
101
|
+
metrics.durationExt = parseInt(end - start) / 1e3
|
|
102
|
+
|
|
103
|
+
if (typeof result.errorCode === 'number' && result.errorCode < 0) {
|
|
104
|
+
const error = new Error('WAF code error')
|
|
105
|
+
error.errorCode = result.errorCode
|
|
106
|
+
|
|
107
|
+
throw error
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (result.metrics) {
|
|
111
|
+
const { maxTruncatedString, maxTruncatedContainerSize, maxTruncatedContainerDepth } = result.metrics
|
|
112
|
+
|
|
113
|
+
if (maxTruncatedString) metrics.maxTruncatedString = maxTruncatedString
|
|
114
|
+
if (maxTruncatedContainerSize) metrics.maxTruncatedContainerSize = maxTruncatedContainerSize
|
|
115
|
+
if (maxTruncatedContainerDepth) metrics.maxTruncatedContainerDepth = maxTruncatedContainerDepth
|
|
116
|
+
}
|
|
117
|
+
|
|
87
118
|
this.addressesToSkip = newAddressesToSkip
|
|
88
119
|
|
|
89
120
|
const ruleTriggered = !!result.events?.length
|
|
@@ -96,15 +127,10 @@ class WAFContextWrapper {
|
|
|
96
127
|
this.setUserIdCache(userId, result)
|
|
97
128
|
}
|
|
98
129
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
ruleTriggered,
|
|
104
|
-
blockTriggered,
|
|
105
|
-
wafVersion: this.wafVersion,
|
|
106
|
-
wafTimeout: result.timeout
|
|
107
|
-
}, raspRule)
|
|
130
|
+
metrics.duration = result.totalRuntime / 1e3
|
|
131
|
+
metrics.blockTriggered = blockTriggered
|
|
132
|
+
metrics.ruleTriggered = ruleTriggered
|
|
133
|
+
metrics.wafTimeout = result.timeout
|
|
108
134
|
|
|
109
135
|
if (ruleTriggered) {
|
|
110
136
|
Reporter.reportAttack(JSON.stringify(result.events))
|
|
@@ -112,13 +138,17 @@ class WAFContextWrapper {
|
|
|
112
138
|
|
|
113
139
|
Reporter.reportDerivatives(result.derivatives)
|
|
114
140
|
|
|
141
|
+
return result.actions
|
|
142
|
+
} catch (err) {
|
|
143
|
+
log.error('[ASM] Error while running the AppSec WAF', err)
|
|
144
|
+
|
|
145
|
+
metrics.errorCode = err.errorCode ?? -127
|
|
146
|
+
} finally {
|
|
115
147
|
if (wafRunFinished.hasSubscribers) {
|
|
116
148
|
wafRunFinished.publish({ payload })
|
|
117
149
|
}
|
|
118
150
|
|
|
119
|
-
|
|
120
|
-
} catch (err) {
|
|
121
|
-
log.error('[ASM] Error while running the AppSec WAF', err)
|
|
151
|
+
Reporter.reportMetrics(metrics, raspRule)
|
|
122
152
|
}
|
|
123
153
|
}
|
|
124
154
|
|
|
@@ -6,7 +6,8 @@ const { sendGitMetadata: sendGitMetadataRequest } = require('./git/git_metadata'
|
|
|
6
6
|
const { getLibraryConfiguration: getLibraryConfigurationRequest } = require('../requests/get-library-configuration')
|
|
7
7
|
const { getSkippableSuites: getSkippableSuitesRequest } = require('../intelligent-test-runner/get-skippable-suites')
|
|
8
8
|
const { getKnownTests: getKnownTestsRequest } = require('../early-flake-detection/get-known-tests')
|
|
9
|
-
const {
|
|
9
|
+
const { getTestManagementTests: getTestManagementTestsRequest } =
|
|
10
|
+
require('../test-management/get-test-management-tests')
|
|
10
11
|
const log = require('../../log')
|
|
11
12
|
const AgentInfoExporter = require('../../exporters/common/agent-info-exporter')
|
|
12
13
|
const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../../plugins/util/tags')
|
|
@@ -93,11 +94,11 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
93
94
|
)
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
|
|
97
|
+
shouldRequestTestManagementTests () {
|
|
97
98
|
return !!(
|
|
98
99
|
this._canUseCiVisProtocol &&
|
|
99
100
|
this._config.isTestManagementEnabled &&
|
|
100
|
-
this._libraryConfig?.
|
|
101
|
+
this._libraryConfig?.isTestManagementEnabled
|
|
101
102
|
)
|
|
102
103
|
}
|
|
103
104
|
|
|
@@ -147,11 +148,11 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
147
148
|
getKnownTestsRequest(this.getRequestConfiguration(testConfiguration), callback)
|
|
148
149
|
}
|
|
149
150
|
|
|
150
|
-
|
|
151
|
-
if (!this.
|
|
151
|
+
getTestManagementTests (testConfiguration, callback) {
|
|
152
|
+
if (!this.shouldRequestTestManagementTests()) {
|
|
152
153
|
return callback(null)
|
|
153
154
|
}
|
|
154
|
-
|
|
155
|
+
getTestManagementTestsRequest(this.getRequestConfiguration(testConfiguration), callback)
|
|
155
156
|
}
|
|
156
157
|
|
|
157
158
|
/**
|
|
@@ -214,7 +215,7 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
214
215
|
isFlakyTestRetriesEnabled,
|
|
215
216
|
isDiEnabled,
|
|
216
217
|
isKnownTestsEnabled,
|
|
217
|
-
|
|
218
|
+
isTestManagementEnabled
|
|
218
219
|
} = remoteConfiguration
|
|
219
220
|
return {
|
|
220
221
|
isCodeCoverageEnabled,
|
|
@@ -228,7 +229,7 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
228
229
|
flakyTestRetriesCount: this._config.flakyTestRetriesCount,
|
|
229
230
|
isDiEnabled: isDiEnabled && this._config.isTestDynamicInstrumentationEnabled,
|
|
230
231
|
isKnownTestsEnabled,
|
|
231
|
-
|
|
232
|
+
isTestManagementEnabled: isTestManagementEnabled && this._config.isTestManagementEnabled
|
|
232
233
|
}
|
|
233
234
|
}
|
|
234
235
|
|
|
@@ -374,14 +375,14 @@ class CiVisibilityExporter extends AgentInfoExporter {
|
|
|
374
375
|
return this._url
|
|
375
376
|
}
|
|
376
377
|
|
|
377
|
-
// By the time
|
|
378
|
-
|
|
379
|
-
if (this._writer?.
|
|
380
|
-
this._writer.
|
|
378
|
+
// By the time addMetadataTags is called, the agent info request might not have finished
|
|
379
|
+
addMetadataTags (tags) {
|
|
380
|
+
if (this._writer?.addMetadataTags) {
|
|
381
|
+
this._writer.addMetadataTags(tags)
|
|
381
382
|
} else {
|
|
382
383
|
this._canUseCiVisProtocolPromise.then(() => {
|
|
383
|
-
if (this._writer?.
|
|
384
|
-
this._writer.
|
|
384
|
+
if (this._writer?.addMetadataTags) {
|
|
385
|
+
this._writer.addMetadataTags(tags)
|
|
385
386
|
}
|
|
386
387
|
})
|
|
387
388
|
}
|
|
@@ -113,8 +113,7 @@ function getLibraryConfiguration ({
|
|
|
113
113
|
isFlakyTestRetriesEnabled,
|
|
114
114
|
isDiEnabled: isDiEnabled && isFlakyTestRetriesEnabled,
|
|
115
115
|
isKnownTestsEnabled,
|
|
116
|
-
|
|
117
|
-
isQuarantinedTestsEnabled: (testManagementConfig?.enabled ?? false)
|
|
116
|
+
isTestManagementEnabled: (testManagementConfig?.enabled ?? false)
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
log.debug(() => `Remote settings: ${JSON.stringify(settings)}`)
|
|
@@ -13,7 +13,8 @@ const formattedTags = {
|
|
|
13
13
|
isUnsupportedCIProvider: 'is_unsupported_ci',
|
|
14
14
|
isNew: 'is_new',
|
|
15
15
|
isRum: 'is_rum',
|
|
16
|
-
browserDriver: 'browser_driver'
|
|
16
|
+
browserDriver: 'browser_driver',
|
|
17
|
+
autoInjected: 'auto_injected'
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
// Transform tags dictionary to array of strings.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const request = require('../../exporters/common/request')
|
|
2
2
|
const id = require('../../id')
|
|
3
3
|
|
|
4
|
-
function
|
|
4
|
+
function getTestManagementTests ({
|
|
5
5
|
url,
|
|
6
6
|
isEvpProxy,
|
|
7
7
|
evpProxyPrefix,
|
|
@@ -28,7 +28,7 @@ function getQuarantinedTests ({
|
|
|
28
28
|
} else {
|
|
29
29
|
const apiKey = process.env.DATADOG_API_KEY || process.env.DD_API_KEY
|
|
30
30
|
if (!apiKey) {
|
|
31
|
-
return done(new Error('
|
|
31
|
+
return done(new Error('Test management tests were not fetched because Datadog API key is not defined.'))
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
options.headers['dd-api-key'] = apiKey
|
|
@@ -49,9 +49,9 @@ function getQuarantinedTests ({
|
|
|
49
49
|
done(err)
|
|
50
50
|
} else {
|
|
51
51
|
try {
|
|
52
|
-
const { data: { attributes: { modules:
|
|
52
|
+
const { data: { attributes: { modules: testManagementTests } } } = JSON.parse(res)
|
|
53
53
|
|
|
54
|
-
done(null,
|
|
54
|
+
done(null, testManagementTests)
|
|
55
55
|
} catch (err) {
|
|
56
56
|
done(err)
|
|
57
57
|
}
|
|
@@ -59,4 +59,4 @@ function getQuarantinedTests ({
|
|
|
59
59
|
})
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
module.exports = {
|
|
62
|
+
module.exports = { getTestManagementTests }
|
|
@@ -591,8 +591,11 @@ class Config {
|
|
|
591
591
|
this._setValue(defaults, 'url', undefined)
|
|
592
592
|
this._setValue(defaults, 'version', pkg.version)
|
|
593
593
|
this._setValue(defaults, 'instrumentation_config_id', undefined)
|
|
594
|
+
this._setValue(defaults, 'aws.dynamoDb.tablePrimaryKeys', undefined)
|
|
595
|
+
this._setValue(defaults, 'vertexai.spanCharLimit', 128)
|
|
596
|
+
this._setValue(defaults, 'vertexai.spanPromptCompletionSampleRate', 1.0)
|
|
594
597
|
this._setValue(defaults, 'trace.aws.addSpanPointers', true)
|
|
595
|
-
this._setValue(defaults, 'trace.
|
|
598
|
+
this._setValue(defaults, 'trace.nativeSpanEvents', false)
|
|
596
599
|
}
|
|
597
600
|
|
|
598
601
|
_applyLocalStableConfig () {
|
|
@@ -760,7 +763,10 @@ class Config {
|
|
|
760
763
|
DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
|
|
761
764
|
DD_TRACING_ENABLED,
|
|
762
765
|
DD_VERSION,
|
|
766
|
+
DD_VERTEXAI_SPAN_PROMPT_COMPLETION_SAMPLE_RATE,
|
|
767
|
+
DD_VERTEXAI_SPAN_CHAR_LIMIT,
|
|
763
768
|
DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED,
|
|
769
|
+
DD_TRACE_NATIVE_SPAN_EVENTS,
|
|
764
770
|
OTEL_METRICS_EXPORTER,
|
|
765
771
|
OTEL_PROPAGATORS,
|
|
766
772
|
OTEL_RESOURCE_ATTRIBUTES,
|
|
@@ -973,6 +979,13 @@ class Config {
|
|
|
973
979
|
this._setBoolean(env, 'trace.aws.addSpanPointers', DD_TRACE_AWS_ADD_SPAN_POINTERS)
|
|
974
980
|
this._setString(env, 'trace.dynamoDb.tablePrimaryKeys', DD_TRACE_DYNAMODB_TABLE_PRIMARY_KEYS)
|
|
975
981
|
this._setArray(env, 'graphqlErrorExtensions', DD_TRACE_GRAPHQL_ERROR_EXTENSIONS)
|
|
982
|
+
this._setBoolean(env, 'trace.nativeSpanEvents', DD_TRACE_NATIVE_SPAN_EVENTS)
|
|
983
|
+
this._setValue(
|
|
984
|
+
env,
|
|
985
|
+
'vertexai.spanPromptCompletionSampleRate',
|
|
986
|
+
maybeFloat(DD_VERTEXAI_SPAN_PROMPT_COMPLETION_SAMPLE_RATE)
|
|
987
|
+
)
|
|
988
|
+
this._setValue(env, 'vertexai.spanCharLimit', maybeInt(DD_VERTEXAI_SPAN_CHAR_LIMIT))
|
|
976
989
|
}
|
|
977
990
|
|
|
978
991
|
_applyOptions (options) {
|
|
@@ -1104,6 +1117,7 @@ class Config {
|
|
|
1104
1117
|
this._setString(opts, 'version', options.version || tags.version)
|
|
1105
1118
|
this._setBoolean(opts, 'inferredProxyServicesEnabled', options.inferredProxyServicesEnabled)
|
|
1106
1119
|
this._setBoolean(opts, 'graphqlErrorExtensions', options.graphqlErrorExtensions)
|
|
1120
|
+
this._setBoolean(opts, 'trace.nativeSpanEvents', options.trace?.nativeSpanEvents)
|
|
1107
1121
|
|
|
1108
1122
|
// For LLMObs, we want the environment variable to take precedence over the options.
|
|
1109
1123
|
// This is reliant on environment config being set before options.
|
|
@@ -234,7 +234,7 @@ class MetricsAggregationClient {
|
|
|
234
234
|
this._histograms[name].get(tag).record(value)
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
count (name, count, tag, monotonic =
|
|
237
|
+
count (name, count, tag, monotonic = true) {
|
|
238
238
|
if (typeof tag === 'boolean') {
|
|
239
239
|
monotonic = tag
|
|
240
240
|
tag = undefined
|
|
@@ -254,8 +254,8 @@ class MetricsAggregationClient {
|
|
|
254
254
|
this._gauges[name].set(tag, value)
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
increment (name, count = 1, tag
|
|
258
|
-
this.count(name, count, tag
|
|
257
|
+
increment (name, count = 1, tag) {
|
|
258
|
+
this.count(name, count, tag)
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
decrement (name, count = 1, tag) {
|