dd-trace 5.97.0 → 5.98.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/index.d.ts +26 -2
- package/package.json +1 -1
- package/packages/datadog-instrumentations/src/cucumber.js +65 -3
- package/packages/datadog-instrumentations/src/cypress-config.js +31 -37
- package/packages/datadog-instrumentations/src/jest.js +104 -12
- package/packages/datadog-instrumentations/src/mocha/utils.js +8 -0
- package/packages/datadog-instrumentations/src/redis.js +12 -6
- package/packages/datadog-plugin-aws-sdk/src/base.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
- package/packages/datadog-plugin-cucumber/src/index.js +6 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +109 -1
- package/packages/datadog-plugin-cypress/src/index.js +59 -2
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +2 -7
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-http/src/server.js +10 -2
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-http2/src/server.js +10 -2
- package/packages/datadog-plugin-mongodb-core/src/index.js +3 -3
- package/packages/datadog-plugin-mysql/src/index.js +1 -1
- package/packages/datadog-plugin-next/src/index.js +8 -2
- package/packages/datadog-plugin-pg/src/index.js +1 -1
- package/packages/datadog-plugin-tedious/src/index.js +1 -1
- package/packages/datadog-plugin-ws/src/close.js +1 -1
- package/packages/datadog-plugin-ws/src/receiver.js +1 -1
- package/packages/dd-trace/src/aiguard/sdk.js +22 -22
- package/packages/dd-trace/src/appsec/blocked_templates.js +4 -3
- package/packages/dd-trace/src/appsec/blocking.js +62 -34
- package/packages/dd-trace/src/appsec/sdk/set_user.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/track_event.js +5 -5
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +2 -2
- package/packages/dd-trace/src/appsec/sdk/utils.js +4 -2
- package/packages/dd-trace/src/config/defaults.js +0 -1
- package/packages/dd-trace/src/config/generated-config-types.d.ts +5 -0
- package/packages/dd-trace/src/config/index.js +55 -28
- package/packages/dd-trace/src/config/supported-configurations.json +61 -4
- package/packages/dd-trace/src/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +5 -2
- package/packages/dd-trace/src/encode/0.4.js +7 -6
- package/packages/dd-trace/src/encode/span-stats.js +4 -1
- package/packages/dd-trace/src/log/index.js +0 -10
- package/packages/dd-trace/src/openfeature/remote_config.js +6 -1
- package/packages/dd-trace/src/opentelemetry/context_manager.js +6 -4
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +17 -2
- package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +14 -2
- package/packages/dd-trace/src/opentelemetry/otlp/trace.proto +358 -0
- package/packages/dd-trace/src/opentelemetry/otlp/trace_service.proto +78 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +75 -0
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +66 -0
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +332 -0
- package/packages/dd-trace/src/opentracing/tracer.js +9 -4
- package/packages/dd-trace/src/plugins/log_plugin.js +3 -0
- package/packages/dd-trace/src/plugins/plugin.js +6 -11
- package/packages/dd-trace/src/plugins/storage.js +2 -2
- package/packages/dd-trace/src/plugins/tracing.js +22 -5
- package/packages/dd-trace/src/plugins/util/test.js +2 -0
- package/packages/dd-trace/src/plugins/util/web.js +6 -88
- package/packages/dd-trace/src/profiling/profiler.js +34 -77
- package/packages/dd-trace/src/proxy.js +8 -3
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +15 -11
- package/packages/dd-trace/src/service-naming/index.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/definition.js +4 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +15 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +24 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +60 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +17 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/websocket.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +17 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +11 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/websocket.js +6 -0
- package/packages/dd-trace/src/span_stats.js +5 -1
- package/packages/dd-trace/src/tracer.js +2 -2
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +28 -6
- package/vendor/dist/protobufjs/index.js +1 -1
- package/packages/dd-trace/src/log/utils.js +0 -16
|
@@ -6,9 +6,27 @@ const { updateBlockFailureMetric } = require('./telemetry')
|
|
|
6
6
|
|
|
7
7
|
const detectedSpecificEndpoints = {}
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const templateKeyword = '[security_response_id]'
|
|
10
|
+
|
|
11
|
+
const templates = {
|
|
12
|
+
html: {
|
|
13
|
+
body: null,
|
|
14
|
+
idIndex: -1,
|
|
15
|
+
type: 'text/html; charset=utf-8',
|
|
16
|
+
},
|
|
17
|
+
json: {
|
|
18
|
+
body: null,
|
|
19
|
+
idIndex: -1,
|
|
20
|
+
type: 'application/json',
|
|
21
|
+
},
|
|
22
|
+
graphqlJson: {
|
|
23
|
+
body: null,
|
|
24
|
+
idIndex: -1,
|
|
25
|
+
type: 'application/json',
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setTemplates()
|
|
12
30
|
|
|
13
31
|
let defaultBlockingActionParameters
|
|
14
32
|
|
|
@@ -17,7 +35,7 @@ const responseBlockedSet = new WeakSet()
|
|
|
17
35
|
const blockDelegations = new WeakMap()
|
|
18
36
|
|
|
19
37
|
const specificBlockingTypes = {
|
|
20
|
-
GRAPHQL: '
|
|
38
|
+
GRAPHQL: 'graphqlJson',
|
|
21
39
|
}
|
|
22
40
|
|
|
23
41
|
function getSpecificKey (method, url) {
|
|
@@ -33,21 +51,14 @@ function getBlockWithRedirectData (actionParameters) {
|
|
|
33
51
|
if (!statusCode || statusCode < 300 || statusCode >= 400) {
|
|
34
52
|
statusCode = 303
|
|
35
53
|
}
|
|
36
|
-
const headers = {
|
|
37
|
-
Location: actionParameters.location,
|
|
38
|
-
}
|
|
39
54
|
|
|
40
|
-
|
|
41
|
-
}
|
|
55
|
+
const headers = { Location: actionParameters.location }
|
|
42
56
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
case specificBlockingTypes.GRAPHQL:
|
|
46
|
-
return {
|
|
47
|
-
type: 'application/json',
|
|
48
|
-
body: templateGraphqlJson,
|
|
49
|
-
}
|
|
57
|
+
if (headers.Location) {
|
|
58
|
+
headers.Location = headers.Location.replace(templateKeyword, actionParameters.security_response_id ?? '')
|
|
50
59
|
}
|
|
60
|
+
|
|
61
|
+
return { headers, statusCode }
|
|
51
62
|
}
|
|
52
63
|
|
|
53
64
|
function getBlockWithContentData (req, specificType, actionParameters) {
|
|
@@ -56,7 +67,7 @@ function getBlockWithContentData (req, specificType, actionParameters) {
|
|
|
56
67
|
|
|
57
68
|
const specificBlockingType = specificType || detectedSpecificEndpoints[getSpecificKey(req.method, req.url)]
|
|
58
69
|
if (specificBlockingType) {
|
|
59
|
-
const specificBlockingContent =
|
|
70
|
+
const specificBlockingContent = getTemplate(specificBlockingType, actionParameters)
|
|
60
71
|
type = specificBlockingContent?.type
|
|
61
72
|
body = specificBlockingContent?.body
|
|
62
73
|
}
|
|
@@ -65,23 +76,17 @@ function getBlockWithContentData (req, specificType, actionParameters) {
|
|
|
65
76
|
// parse the Accept header, ex: Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
|
|
66
77
|
const accept = req.headers.accept?.split(',').map((str) => str.split(';', 1)[0].trim())
|
|
67
78
|
|
|
79
|
+
let templateName = 'json'
|
|
80
|
+
|
|
68
81
|
if (!actionParameters || actionParameters.type === 'auto') {
|
|
69
82
|
if (accept?.includes('text/html') && !accept.includes('application/json')) {
|
|
70
|
-
|
|
71
|
-
body = templateHtml
|
|
72
|
-
} else {
|
|
73
|
-
type = 'application/json'
|
|
74
|
-
body = templateJson
|
|
75
|
-
}
|
|
76
|
-
} else {
|
|
77
|
-
if (actionParameters.type === 'html') {
|
|
78
|
-
type = 'text/html; charset=utf-8'
|
|
79
|
-
body = templateHtml
|
|
80
|
-
} else {
|
|
81
|
-
type = 'application/json'
|
|
82
|
-
body = templateJson
|
|
83
|
+
templateName = 'html'
|
|
83
84
|
}
|
|
85
|
+
} else if (actionParameters.type === 'html') {
|
|
86
|
+
templateName = 'html'
|
|
84
87
|
}
|
|
88
|
+
|
|
89
|
+
({ type, body } = getTemplate(templateName, actionParameters))
|
|
85
90
|
}
|
|
86
91
|
|
|
87
92
|
const statusCode = actionParameters?.status_code || 403
|
|
@@ -165,14 +170,37 @@ function getBlockingAction (actions) {
|
|
|
165
170
|
}
|
|
166
171
|
|
|
167
172
|
/**
|
|
168
|
-
* @param {import('../config/config-base')} config - Tracer configuration
|
|
173
|
+
* @param {import('../config/config-base')} [config] - Tracer configuration
|
|
169
174
|
*/
|
|
170
175
|
function setTemplates (config) {
|
|
171
|
-
|
|
176
|
+
templates.html.body = config?.appsec?.blockedTemplateHtml
|
|
177
|
+
templates.json.body = config?.appsec?.blockedTemplateJson
|
|
178
|
+
templates.graphqlJson.body = config?.appsec?.blockedTemplateGraphql
|
|
179
|
+
|
|
180
|
+
for (const type of Object.keys(templates)) {
|
|
181
|
+
const template = templates[type]
|
|
182
|
+
|
|
183
|
+
// set default template if not set by config
|
|
184
|
+
if (!template.body) template.body = blockedTemplates[type]
|
|
185
|
+
|
|
186
|
+
template.idIndex = template.body.indexOf(templateKeyword)
|
|
187
|
+
|
|
188
|
+
if (template.idIndex !== -1) {
|
|
189
|
+
template.body = [
|
|
190
|
+
template.body.slice(0, template.idIndex),
|
|
191
|
+
template.body.slice(template.idIndex + templateKeyword.length),
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function getTemplate (type, actionParameters) {
|
|
198
|
+
const template = templates[type]
|
|
199
|
+
if (template.idIndex === -1) return template
|
|
172
200
|
|
|
173
|
-
|
|
201
|
+
const body = template.body[0] + (actionParameters?.security_response_id ?? '') + template.body[1]
|
|
174
202
|
|
|
175
|
-
|
|
203
|
+
return { body, type: template.type }
|
|
176
204
|
}
|
|
177
205
|
|
|
178
206
|
function isBlocked (res) {
|
|
@@ -21,7 +21,7 @@ function trackUserLoginSuccessEvent (tracer, user, metadata) {
|
|
|
21
21
|
|
|
22
22
|
incrementSdkEventMetric('login_success', 'v1')
|
|
23
23
|
|
|
24
|
-
const rootSpan = getRootSpan(
|
|
24
|
+
const rootSpan = getRootSpan()
|
|
25
25
|
if (!rootSpan) {
|
|
26
26
|
log.warn('[ASM] Root span not available in trackUserLoginSuccessEvent')
|
|
27
27
|
return
|
|
@@ -54,7 +54,7 @@ function trackUserLoginFailureEvent (tracer, userId, exists, metadata) {
|
|
|
54
54
|
...metadata,
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
trackEvent('users.login.failure', fields, 'trackUserLoginFailureEvent', getRootSpan(
|
|
57
|
+
trackEvent('users.login.failure', fields, 'trackUserLoginFailureEvent', getRootSpan())
|
|
58
58
|
|
|
59
59
|
runWaf('users.login.failure', { login: userId })
|
|
60
60
|
|
|
@@ -67,7 +67,7 @@ function trackCustomEvent (tracer, eventName, metadata) {
|
|
|
67
67
|
return
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
trackEvent(eventName, metadata, 'trackCustomEvent', getRootSpan(
|
|
70
|
+
trackEvent(eventName, metadata, 'trackCustomEvent', getRootSpan())
|
|
71
71
|
|
|
72
72
|
incrementSdkEventMetric('custom', 'v1')
|
|
73
73
|
|
|
@@ -84,7 +84,7 @@ function trackUserLoginSuccessV2 (tracer, login, user, metadata) {
|
|
|
84
84
|
|
|
85
85
|
incrementSdkEventMetric('login_success', 'v2')
|
|
86
86
|
|
|
87
|
-
const rootSpan = getRootSpan(
|
|
87
|
+
const rootSpan = getRootSpan()
|
|
88
88
|
if (!rootSpan) {
|
|
89
89
|
log.warn('[ASM] Root span not available in eventTrackingV2.trackUserLoginSuccess')
|
|
90
90
|
return
|
|
@@ -122,7 +122,7 @@ function trackUserLoginFailureV2 (tracer, login, exists, metadata) {
|
|
|
122
122
|
|
|
123
123
|
incrementSdkEventMetric('login_failure', 'v2')
|
|
124
124
|
|
|
125
|
-
const rootSpan = getRootSpan(
|
|
125
|
+
const rootSpan = getRootSpan()
|
|
126
126
|
if (!rootSpan) {
|
|
127
127
|
log.warn('[ASM] Root span not available in eventTrackingV2.trackUserLoginFailure')
|
|
128
128
|
return
|
|
@@ -19,7 +19,7 @@ function checkUserAndSetUser (tracer, user) {
|
|
|
19
19
|
return false
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const rootSpan = getRootSpan(
|
|
22
|
+
const rootSpan = getRootSpan()
|
|
23
23
|
if (rootSpan) {
|
|
24
24
|
if (!rootSpan.context()._tags['usr.id']) {
|
|
25
25
|
setUserTags(user, rootSpan)
|
|
@@ -45,7 +45,7 @@ function blockRequest (tracer, req, res) {
|
|
|
45
45
|
return false
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const rootSpan = getRootSpan(
|
|
48
|
+
const rootSpan = getRootSpan()
|
|
49
49
|
if (!rootSpan) {
|
|
50
50
|
log.warn('[ASM] Root span not available in blockRequest')
|
|
51
51
|
return false
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const { storage } = require('../../../../datadog-core')
|
|
4
|
+
|
|
5
|
+
function getRootSpan () {
|
|
6
|
+
let span = storage('legacy').getStore()?.span
|
|
5
7
|
if (!span) return
|
|
6
8
|
|
|
7
9
|
const context = span.context()
|
|
@@ -504,6 +504,10 @@ export interface GeneratedConfig {
|
|
|
504
504
|
otelMetricsUrl: string | undefined;
|
|
505
505
|
otelProtocol: string;
|
|
506
506
|
otelTimeout: number;
|
|
507
|
+
otelTracesHeaders: Record<string, string> | undefined;
|
|
508
|
+
otelTracesProtocol: string;
|
|
509
|
+
otelTracesTimeout: number;
|
|
510
|
+
otelTracesUrl: string | undefined;
|
|
507
511
|
peerServiceMapping: Record<string, string>;
|
|
508
512
|
port: string | number;
|
|
509
513
|
profiling: {
|
|
@@ -526,6 +530,7 @@ export interface GeneratedConfig {
|
|
|
526
530
|
enabled: boolean;
|
|
527
531
|
eventLoop: boolean;
|
|
528
532
|
gc: boolean;
|
|
533
|
+
native: boolean;
|
|
529
534
|
};
|
|
530
535
|
runtimeMetricsRuntimeId: boolean;
|
|
531
536
|
sampleRate: number | undefined;
|
|
@@ -29,7 +29,6 @@ const {
|
|
|
29
29
|
getEnvironmentVariable,
|
|
30
30
|
getEnvironmentVariables,
|
|
31
31
|
getStableConfigSources,
|
|
32
|
-
getValueFromEnvSources,
|
|
33
32
|
} = require('./helper')
|
|
34
33
|
const {
|
|
35
34
|
defaults,
|
|
@@ -229,22 +228,6 @@ class Config extends ConfigBase {
|
|
|
229
228
|
#applyEnvs (envs, source) {
|
|
230
229
|
for (const [name, value] of Object.entries(envs)) {
|
|
231
230
|
const entry = configurationsTable[name]
|
|
232
|
-
// TracePropagationStyle is a special case. It is a single option that is used to set both inject and extract.
|
|
233
|
-
// TODO: Consider what to do with this later
|
|
234
|
-
if (name === 'DD_TRACE_PROPAGATION_STYLE') {
|
|
235
|
-
if (
|
|
236
|
-
getValueFromEnvSources('DD_TRACE_PROPAGATION_STYLE_INJECT') !== undefined ||
|
|
237
|
-
getValueFromEnvSources('DD_TRACE_PROPAGATION_STYLE_EXTRACT') !== undefined
|
|
238
|
-
) {
|
|
239
|
-
log.warn(
|
|
240
|
-
// eslint-disable-next-line @stylistic/max-len
|
|
241
|
-
'Use either DD_TRACE_PROPAGATION_STYLE or separate DD_TRACE_PROPAGATION_STYLE_INJECT and DD_TRACE_PROPAGATION_STYLE_EXTRACT environment variables'
|
|
242
|
-
)
|
|
243
|
-
continue
|
|
244
|
-
}
|
|
245
|
-
this.#applyEnvs({ DD_TRACE_PROPAGATION_STYLE_INJECT: value, DD_TRACE_PROPAGATION_STYLE_EXTRACT: value }, source)
|
|
246
|
-
continue
|
|
247
|
-
}
|
|
248
231
|
const parsed = entry.parser(value, name, source)
|
|
249
232
|
const transformed = parsed !== undefined && entry.transformer ? entry.transformer(parsed, name, source) : parsed
|
|
250
233
|
const rawValue = transformed !== null && typeof transformed === 'object' ? value : parsed
|
|
@@ -293,6 +276,7 @@ class Config extends ConfigBase {
|
|
|
293
276
|
} else {
|
|
294
277
|
if (fullName === 'tracePropagationStyle') {
|
|
295
278
|
// TracePropagationStyle is special. It is a single option that is used to set both inject and extract.
|
|
279
|
+
// TODO: Consider what to do with this later
|
|
296
280
|
// @ts-expect-error - Difficult to type this correctly.
|
|
297
281
|
this.#applyOptions({ inject: value, extract: value }, source, 'tracePropagationStyle')
|
|
298
282
|
} else {
|
|
@@ -374,6 +358,23 @@ class Config extends ConfigBase {
|
|
|
374
358
|
setAndTrack(this, 'otelMetricsEnabled', false)
|
|
375
359
|
}
|
|
376
360
|
|
|
361
|
+
const otelTracesEnabled = trackedConfigOrigins.has('OTEL_TRACES_EXPORTER') &&
|
|
362
|
+
this.OTEL_TRACES_EXPORTER === 'otlp'
|
|
363
|
+
if (this.protocolVersion && this.protocolVersion !== '0.4' && otelTracesEnabled) {
|
|
364
|
+
log.warn('DD_TRACE_AGENT_PROTOCOL_VERSION is set, disabling OTLP traces export')
|
|
365
|
+
setAndTrack(this, 'otelTracesEnabled', false)
|
|
366
|
+
} else {
|
|
367
|
+
setAndTrack(this, 'otelTracesEnabled', otelTracesEnabled)
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (this.otelTracesProtocol && this.otelTracesProtocol !== 'http/json') {
|
|
371
|
+
log.warn(
|
|
372
|
+
'OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=%s is not yet supported; only http/json is currently implemented',
|
|
373
|
+
this.otelTracesProtocol
|
|
374
|
+
)
|
|
375
|
+
setAndTrack(this, 'otelTracesProtocol', 'http/json')
|
|
376
|
+
}
|
|
377
|
+
|
|
377
378
|
if (this.telemetry.heartbeatInterval) {
|
|
378
379
|
setAndTrack(this, 'telemetry.heartbeatInterval', Math.floor(this.telemetry.heartbeatInterval * 1000))
|
|
379
380
|
}
|
|
@@ -440,8 +441,16 @@ class Config extends ConfigBase {
|
|
|
440
441
|
setAndTrack(this, 'runtimeMetrics.enabled', false)
|
|
441
442
|
}
|
|
442
443
|
|
|
443
|
-
if (!trackedConfigOrigins.has('sampleRate')
|
|
444
|
-
|
|
444
|
+
if (!trackedConfigOrigins.has('sampleRate')) {
|
|
445
|
+
const effectiveSampler = (trackedConfigOrigins.has('OTEL_TRACES_EXPORTER') &&
|
|
446
|
+
this.OTEL_TRACES_EXPORTER === 'otlp' &&
|
|
447
|
+
!trackedConfigOrigins.has('OTEL_TRACES_SAMPLER'))
|
|
448
|
+
? 'parentbased_always_on'
|
|
449
|
+
: this.OTEL_TRACES_SAMPLER
|
|
450
|
+
if (effectiveSampler && (trackedConfigOrigins.has('OTEL_TRACES_SAMPLER') ||
|
|
451
|
+
trackedConfigOrigins.has('OTEL_TRACES_EXPORTER'))) {
|
|
452
|
+
setAndTrack(this, 'sampleRate', getFromOtelSamplerMap(effectiveSampler, this.OTEL_TRACES_SAMPLER_ARG))
|
|
453
|
+
}
|
|
445
454
|
}
|
|
446
455
|
|
|
447
456
|
if (this.DD_SPAN_SAMPLING_RULES_FILE) {
|
|
@@ -541,7 +550,10 @@ class Config extends ConfigBase {
|
|
|
541
550
|
isServiceNameInferred = true
|
|
542
551
|
}
|
|
543
552
|
}
|
|
544
|
-
|
|
553
|
+
|
|
554
|
+
// This should not be tracked.
|
|
555
|
+
// TODO: Consider moving this outside of the config.
|
|
556
|
+
set(this, 'isServiceNameInferred', isServiceNameInferred)
|
|
545
557
|
|
|
546
558
|
// Add missing tags, in case they are defined otherwise.
|
|
547
559
|
if (this.service) {
|
|
@@ -600,6 +612,13 @@ class Config extends ConfigBase {
|
|
|
600
612
|
if (!this.otelMetricsUrl) {
|
|
601
613
|
setAndTrack(this, 'otelMetricsUrl', `http://${agentHostname}:${DEFAULT_OTLP_PORT}/v1/metrics`)
|
|
602
614
|
}
|
|
615
|
+
if (!trackedConfigOrigins.has('otelTracesUrl') && this.OTEL_EXPORTER_OTLP_ENDPOINT) {
|
|
616
|
+
// Generic OTLP endpoint: per spec, append /v1/traces signal-specific subpath
|
|
617
|
+
setAndTrack(this, 'otelTracesUrl', this.OTEL_EXPORTER_OTLP_ENDPOINT.replace(/\/$/, '') + '/v1/traces')
|
|
618
|
+
} else if (!this.otelTracesUrl) {
|
|
619
|
+
const tracesHostname = agentHostname === '127.0.0.1' ? 'localhost' : agentHostname
|
|
620
|
+
setAndTrack(this, 'otelTracesUrl', `http://${tracesHostname}:${DEFAULT_OTLP_PORT}/v1/traces`)
|
|
621
|
+
}
|
|
603
622
|
|
|
604
623
|
if (process.platform === 'win32') {
|
|
605
624
|
// OOM monitoring does not work properly on Windows, so it will be disabled.
|
|
@@ -691,13 +710,25 @@ function increaseCounter (event, ddVar, otelVar) {
|
|
|
691
710
|
}
|
|
692
711
|
|
|
693
712
|
function getFromOtelSamplerMap (otelTracesSampler, otelTracesSamplerArg) {
|
|
713
|
+
const NON_PARENTBASED_TO_PARENTBASED = {
|
|
714
|
+
always_on: 'parentbased_always_on',
|
|
715
|
+
always_off: 'parentbased_always_off',
|
|
716
|
+
traceidratio: 'parentbased_traceidratio',
|
|
717
|
+
}
|
|
694
718
|
const OTEL_TRACES_SAMPLER_MAPPING = {
|
|
695
|
-
always_on: 1,
|
|
696
|
-
always_off: 0,
|
|
697
719
|
parentbased_always_on: 1,
|
|
698
720
|
parentbased_always_off: 0,
|
|
699
721
|
}
|
|
700
722
|
|
|
723
|
+
const parentBasedEquivalent = NON_PARENTBASED_TO_PARENTBASED[otelTracesSampler]
|
|
724
|
+
if (parentBasedEquivalent) {
|
|
725
|
+
log.info(
|
|
726
|
+
'OTEL_TRACES_SAMPLER=%s does not respect upstream sampling decisions; using parent-based equivalent %s instead',
|
|
727
|
+
otelTracesSampler, parentBasedEquivalent
|
|
728
|
+
)
|
|
729
|
+
otelTracesSampler = parentBasedEquivalent
|
|
730
|
+
}
|
|
731
|
+
|
|
701
732
|
const result = OTEL_TRACES_SAMPLER_MAPPING[otelTracesSampler] ?? otelTracesSamplerArg
|
|
702
733
|
if (result === undefined) {
|
|
703
734
|
increaseCounter('otel.env.invalid', 'DD_TRACE_SAMPLE_RATE', 'OTEL_TRACES_SAMPLER')
|
|
@@ -712,7 +743,7 @@ function warnWrongOtelSettings () {
|
|
|
712
743
|
// eslint-disable-next-line eslint-rules/eslint-env-aliases
|
|
713
744
|
['OTEL_LOG_LEVEL', 'DD_TRACE_LOG_LEVEL', 'logLevel'],
|
|
714
745
|
// eslint-disable-next-line eslint-rules/eslint-env-aliases
|
|
715
|
-
['OTEL_PROPAGATORS', 'DD_TRACE_PROPAGATION_STYLE'],
|
|
746
|
+
['OTEL_PROPAGATORS', 'DD_TRACE_PROPAGATION_STYLE', 'DD_TRACE_PROPAGATION_STYLE'],
|
|
716
747
|
// eslint-disable-next-line eslint-rules/eslint-env-aliases
|
|
717
748
|
['OTEL_SERVICE_NAME', 'DD_SERVICE', 'service'],
|
|
718
749
|
['OTEL_TRACES_SAMPLER', 'DD_TRACE_SAMPLE_RATE'],
|
|
@@ -733,11 +764,7 @@ function warnWrongOtelSettings () {
|
|
|
733
764
|
increaseCounter('otel.env.hiding', ddEnvVar, otelEnvVar)
|
|
734
765
|
}
|
|
735
766
|
|
|
736
|
-
|
|
737
|
-
const invalidOtelValue = otelEnvVar === 'OTEL_PROPAGATORS'
|
|
738
|
-
? trackedConfigOrigins.get(/** @type {ConfigPath} */ ('tracePropagationStyle.inject')) !== otelSource &&
|
|
739
|
-
!envs[ddEnvVar]
|
|
740
|
-
: !otelSource
|
|
767
|
+
const invalidOtelValue = !otelSource
|
|
741
768
|
if (invalidOtelValue) {
|
|
742
769
|
increaseCounter('otel.env.invalid', ddEnvVar, otelEnvVar)
|
|
743
770
|
}
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
],
|
|
47
47
|
"DD_AI_GUARD_BLOCK": [
|
|
48
48
|
{
|
|
49
|
-
"implementation": "
|
|
49
|
+
"implementation": "C",
|
|
50
50
|
"type": "boolean",
|
|
51
51
|
"configurationNames": [
|
|
52
52
|
"experimental.aiguard.block"
|
|
53
53
|
],
|
|
54
|
-
"default": "
|
|
54
|
+
"default": "true"
|
|
55
55
|
}
|
|
56
56
|
],
|
|
57
57
|
"DD_AI_GUARD_ENABLED": [
|
|
@@ -1573,6 +1573,16 @@
|
|
|
1573
1573
|
"default": "10000"
|
|
1574
1574
|
}
|
|
1575
1575
|
],
|
|
1576
|
+
"DD_RUNTIME_METRICS_NATIVE": [
|
|
1577
|
+
{
|
|
1578
|
+
"implementation": "A",
|
|
1579
|
+
"type": "boolean",
|
|
1580
|
+
"configurationNames": [
|
|
1581
|
+
"runtimeMetrics.native"
|
|
1582
|
+
],
|
|
1583
|
+
"default": "true"
|
|
1584
|
+
}
|
|
1585
|
+
],
|
|
1576
1586
|
"DD_RUNTIME_METRICS_GC_ENABLED": [
|
|
1577
1587
|
{
|
|
1578
1588
|
"implementation": "A",
|
|
@@ -3442,7 +3452,10 @@
|
|
|
3442
3452
|
"tracePropagationStyle.extract"
|
|
3443
3453
|
],
|
|
3444
3454
|
"default": "datadog, tracecontext, baggage",
|
|
3445
|
-
"transform": "toLowerCase"
|
|
3455
|
+
"transform": "toLowerCase",
|
|
3456
|
+
"aliases": [
|
|
3457
|
+
"DD_TRACE_PROPAGATION_STYLE"
|
|
3458
|
+
]
|
|
3446
3459
|
}
|
|
3447
3460
|
],
|
|
3448
3461
|
"DD_TRACE_PROPAGATION_STYLE_INJECT": [
|
|
@@ -3453,7 +3466,10 @@
|
|
|
3453
3466
|
"tracePropagationStyle.inject"
|
|
3454
3467
|
],
|
|
3455
3468
|
"default": "datadog, tracecontext, baggage",
|
|
3456
|
-
"transform": "toLowerCase"
|
|
3469
|
+
"transform": "toLowerCase",
|
|
3470
|
+
"aliases": [
|
|
3471
|
+
"DD_TRACE_PROPAGATION_STYLE"
|
|
3472
|
+
]
|
|
3457
3473
|
}
|
|
3458
3474
|
],
|
|
3459
3475
|
"DD_TRACE_PROTOBUFJS_ENABLED": [
|
|
@@ -3886,6 +3902,47 @@
|
|
|
3886
3902
|
"internalPropertyName": "otelHeaders"
|
|
3887
3903
|
}
|
|
3888
3904
|
],
|
|
3905
|
+
"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": [
|
|
3906
|
+
{
|
|
3907
|
+
"implementation": "A",
|
|
3908
|
+
"type": "string",
|
|
3909
|
+
"default": null,
|
|
3910
|
+
"internalPropertyName": "otelTracesUrl"
|
|
3911
|
+
}
|
|
3912
|
+
],
|
|
3913
|
+
"OTEL_EXPORTER_OTLP_TRACES_HEADERS": [
|
|
3914
|
+
{
|
|
3915
|
+
"implementation": "B",
|
|
3916
|
+
"type": "map",
|
|
3917
|
+
"default": null,
|
|
3918
|
+
"internalPropertyName": "otelTracesHeaders",
|
|
3919
|
+
"aliases": [
|
|
3920
|
+
"OTEL_EXPORTER_OTLP_HEADERS"
|
|
3921
|
+
]
|
|
3922
|
+
}
|
|
3923
|
+
],
|
|
3924
|
+
"OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": [
|
|
3925
|
+
{
|
|
3926
|
+
"implementation": "B",
|
|
3927
|
+
"type": "string",
|
|
3928
|
+
"default": "http/json",
|
|
3929
|
+
"internalPropertyName": "otelTracesProtocol",
|
|
3930
|
+
"aliases": [
|
|
3931
|
+
"OTEL_EXPORTER_OTLP_PROTOCOL"
|
|
3932
|
+
]
|
|
3933
|
+
}
|
|
3934
|
+
],
|
|
3935
|
+
"OTEL_EXPORTER_OTLP_TRACES_TIMEOUT": [
|
|
3936
|
+
{
|
|
3937
|
+
"implementation": "B",
|
|
3938
|
+
"type": "int",
|
|
3939
|
+
"internalPropertyName": "otelTracesTimeout",
|
|
3940
|
+
"default": "10000",
|
|
3941
|
+
"aliases": [
|
|
3942
|
+
"OTEL_EXPORTER_OTLP_TIMEOUT"
|
|
3943
|
+
]
|
|
3944
|
+
}
|
|
3945
|
+
],
|
|
3889
3946
|
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT": [
|
|
3890
3947
|
{
|
|
3891
3948
|
"implementation": "A",
|
|
@@ -21,6 +21,7 @@ module.exports = {
|
|
|
21
21
|
SPAN_SAMPLING_MECHANISM: '_dd.span_sampling.mechanism',
|
|
22
22
|
SPAN_SAMPLING_RULE_RATE: '_dd.span_sampling.rule_rate',
|
|
23
23
|
SPAN_SAMPLING_MAX_PER_SECOND: '_dd.span_sampling.max_per_second',
|
|
24
|
+
SVC_SRC_KEY: '_dd.svc_src',
|
|
24
25
|
DATADOG_LAMBDA_EXTENSION_PATH: '/opt/extensions/datadog-agent',
|
|
25
26
|
DATADOG_MINI_AGENT_PATH: '/tmp/datadog/mini_agent_ready',
|
|
26
27
|
DECISION_MAKER_KEY: '_dd.p.dm',
|
|
@@ -105,10 +105,13 @@ function getObjectValue (obj, maxLength) {
|
|
|
105
105
|
// case 'node': // TODO: What does this subtype represent?
|
|
106
106
|
case 'regexp':
|
|
107
107
|
return { type: obj.className, value: obj.description }
|
|
108
|
-
case 'date':
|
|
108
|
+
case 'date': {
|
|
109
109
|
// TODO: This looses millisecond resolution, as that's not retained in the `.toString()` representation contained
|
|
110
110
|
// in the `description` field. Unfortunately that's all we get from the Chrome DevTools Protocol.
|
|
111
|
-
|
|
111
|
+
const date = new Date(obj.description)
|
|
112
|
+
const value = Number.isNaN(date.getTime()) ? obj.description : `${date.toISOString().slice(0, -5)}Z`
|
|
113
|
+
return { type: obj.className, value }
|
|
114
|
+
}
|
|
112
115
|
case 'map':
|
|
113
116
|
return toMap(obj.className, obj.properties, maxLength, timeBudgetReached)
|
|
114
117
|
case 'set':
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const { MsgpackChunk, MsgpackEncoder } = require('../msgpack')
|
|
4
4
|
const log = require('../log')
|
|
5
5
|
const { isTrue } = require('../util')
|
|
6
|
-
const { memoize } = require('../log/utils')
|
|
7
6
|
const { getValueFromEnvSources } = require('../config/helper')
|
|
8
7
|
const { truncateSpan, normalizeSpan } = require('./tags-processors')
|
|
9
8
|
|
|
@@ -338,11 +337,13 @@ class AgentEncoder {
|
|
|
338
337
|
}
|
|
339
338
|
}
|
|
340
339
|
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
340
|
+
const seenKeys = new Set()
|
|
341
|
+
const memoizedLogDebug = (key, message) => {
|
|
342
|
+
if (!seenKeys.has(key)) {
|
|
343
|
+
seenKeys.add(key)
|
|
344
|
+
log.debug(message)
|
|
345
|
+
}
|
|
346
|
+
}
|
|
346
347
|
|
|
347
348
|
function formatSpanEvents (span) {
|
|
348
349
|
for (const spanEvent of span.span_events) {
|
|
@@ -31,7 +31,7 @@ class SpanStatsEncoder extends AgentEncoder {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
_encodeStat (bytes, stat) {
|
|
34
|
-
this._encodeMapPrefix(bytes,
|
|
34
|
+
this._encodeMapPrefix(bytes, 15)
|
|
35
35
|
|
|
36
36
|
this._encodeString(bytes, 'Service')
|
|
37
37
|
const service = stat.Service || DEFAULT_SERVICE_NAME
|
|
@@ -76,6 +76,9 @@ class SpanStatsEncoder extends AgentEncoder {
|
|
|
76
76
|
|
|
77
77
|
this._encodeString(bytes, 'HTTPEndpoint')
|
|
78
78
|
this._encodeString(bytes, stat.HTTPEndpoint)
|
|
79
|
+
|
|
80
|
+
this._encodeString(bytes, 'srv_src')
|
|
81
|
+
this._encodeString(bytes, stat.srv_src || '')
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
_encodeBucket (bytes, bucket) {
|
|
@@ -8,7 +8,6 @@ const { getValueFromEnvSources } = require('../config/helper')
|
|
|
8
8
|
const { traceChannel, debugChannel, infoChannel, warnChannel, errorChannel } = require('./channels')
|
|
9
9
|
const logWriter = require('./writer')
|
|
10
10
|
const { Log, LogConfig, NoTransmitError } = require('./log')
|
|
11
|
-
const { memoize } = require('./utils')
|
|
12
11
|
|
|
13
12
|
const config = {
|
|
14
13
|
enabled: defaults.DD_TRACE_DEBUG,
|
|
@@ -16,11 +15,6 @@ const config = {
|
|
|
16
15
|
logLevel: defaults.logLevel,
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
const deprecate = memoize((code, message) => {
|
|
20
|
-
publishFormatted(errorChannel, null, message)
|
|
21
|
-
return true
|
|
22
|
-
})
|
|
23
|
-
|
|
24
18
|
// In most places where we know we want to mute a log we use log.error() directly
|
|
25
19
|
const NO_TRANSMIT = new LogConfig(false)
|
|
26
20
|
|
|
@@ -82,10 +76,6 @@ const log = {
|
|
|
82
76
|
return log
|
|
83
77
|
},
|
|
84
78
|
|
|
85
|
-
deprecate (code, message) {
|
|
86
|
-
return deprecate(code, message)
|
|
87
|
-
},
|
|
88
|
-
|
|
89
79
|
configure (options) {
|
|
90
80
|
config.logger = options.logger
|
|
91
81
|
config.logLevel = options.logLevel ??
|
|
@@ -19,9 +19,14 @@ function enable (rc, config, getOpenfeatureProxy) {
|
|
|
19
19
|
|
|
20
20
|
// Set product handler for FFE_FLAGS
|
|
21
21
|
rc.setProductHandler('FFE_FLAGS', (action, conf) => {
|
|
22
|
-
// Feed UFC config directly to OpenFeature provider
|
|
23
22
|
if (action === 'apply' || action === 'modify') {
|
|
23
|
+
// Feed UFC config directly to OpenFeature provider
|
|
24
24
|
getOpenfeatureProxy()._setConfiguration(conf)
|
|
25
|
+
} else if (action === 'unapply') {
|
|
26
|
+
// Clear the configuration so evaluations return PROVIDER_NOT_READY,
|
|
27
|
+
// consistent with Go and Python which also set config to null on RC deletion.
|
|
28
|
+
// The evaluator returns PROVIDER_NOT_READY when config is null/undefined.
|
|
29
|
+
getOpenfeatureProxy()._setConfiguration(null)
|
|
25
30
|
}
|
|
26
31
|
})
|
|
27
32
|
}
|