dd-trace 5.96.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 +60 -2
- package/package.json +9 -7
- package/packages/datadog-esbuild/index.js +20 -9
- package/packages/datadog-instrumentations/src/child_process.js +7 -17
- package/packages/datadog-instrumentations/src/crypto.js +1 -2
- package/packages/datadog-instrumentations/src/cucumber.js +69 -4
- package/packages/datadog-instrumentations/src/cypress-config.js +318 -0
- package/packages/datadog-instrumentations/src/cypress.js +86 -4
- package/packages/datadog-instrumentations/src/dns.js +1 -2
- package/packages/datadog-instrumentations/src/express.js +4 -4
- package/packages/datadog-instrumentations/src/fs.js +27 -29
- package/packages/datadog-instrumentations/src/graphql.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +41 -13
- package/packages/datadog-instrumentations/src/helpers/hook.js +31 -6
- package/packages/datadog-instrumentations/src/helpers/hooks.js +12 -19
- package/packages/datadog-instrumentations/src/helpers/instrument.js +27 -13
- package/packages/datadog-instrumentations/src/helpers/register.js +103 -142
- package/packages/datadog-instrumentations/src/http/client.js +2 -3
- package/packages/datadog-instrumentations/src/http/server.js +2 -5
- package/packages/datadog-instrumentations/src/http2/client.js +1 -3
- package/packages/datadog-instrumentations/src/http2/server.js +1 -3
- package/packages/datadog-instrumentations/src/jest.js +117 -16
- package/packages/datadog-instrumentations/src/limitd-client.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/utils.js +12 -1
- package/packages/datadog-instrumentations/src/net.js +2 -8
- package/packages/datadog-instrumentations/src/pino.js +1 -1
- package/packages/datadog-instrumentations/src/playwright.js +4 -1
- package/packages/datadog-instrumentations/src/prisma.js +1 -2
- package/packages/datadog-instrumentations/src/redis.js +12 -6
- package/packages/datadog-instrumentations/src/selenium.js +4 -1
- package/packages/datadog-instrumentations/src/sequelize.js +1 -1
- package/packages/datadog-instrumentations/src/url.js +1 -3
- package/packages/datadog-instrumentations/src/vitest.js +5 -1
- package/packages/datadog-instrumentations/src/vm.js +1 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +5 -4
- 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 +13 -3
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +166 -6
- 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-graphql/src/resolve.js +1 -1
- 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-jest/src/index.js +4 -2
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +31 -4
- package/packages/datadog-plugin-mocha/src/index.js +5 -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 +10 -16
- package/packages/datadog-plugin-openai/src/services.js +1 -0
- 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/datadog-webpack/index.js +3 -3
- package/packages/dd-trace/index.js +12 -10
- package/packages/dd-trace/src/agent/url.js +2 -2
- package/packages/dd-trace/src/aiguard/sdk.js +26 -22
- package/packages/dd-trace/src/appsec/blocked_templates.js +4 -3
- package/packages/dd-trace/src/appsec/blocking.js +64 -33
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +1 -1
- package/packages/dd-trace/src/appsec/remote_config.js +1 -0
- package/packages/dd-trace/src/appsec/sdk/index.js +4 -0
- 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/ci-visibility/dynamic-instrumentation/index.js +6 -1
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +4 -0
- package/packages/dd-trace/src/config/defaults.js +315 -146
- package/packages/dd-trace/src/config/generated-config-types.d.ts +9 -1
- package/packages/dd-trace/src/config/helper.js +59 -10
- package/packages/dd-trace/src/config/index.js +587 -1496
- package/packages/dd-trace/src/config/parsers.js +256 -0
- package/packages/dd-trace/src/config/remote_config.js +59 -2
- package/packages/dd-trace/src/config/supported-configurations.json +406 -432
- package/packages/dd-trace/src/constants.js +1 -0
- package/packages/dd-trace/src/crashtracking/crashtracker.js +7 -1
- package/packages/dd-trace/src/crashtracking/index.js +1 -7
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +5 -2
- package/packages/dd-trace/src/debugger/index.js +1 -1
- package/packages/dd-trace/src/dogstatsd.js +12 -9
- package/packages/dd-trace/src/encode/0.4.js +8 -7
- package/packages/dd-trace/src/encode/span-stats.js +4 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +7 -1
- package/packages/dd-trace/src/exporters/common/request.js +9 -0
- package/packages/dd-trace/src/exporters/common/writer.js +12 -2
- package/packages/dd-trace/src/heap_snapshots.js +3 -0
- package/packages/dd-trace/src/index.js +5 -2
- package/packages/dd-trace/src/lambda/runtime/ritm.js +6 -6
- package/packages/dd-trace/src/llmobs/index.js +4 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/index.js +5 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +60 -12
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +4 -2
- package/packages/dd-trace/src/llmobs/sdk.js +12 -8
- package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
- package/packages/dd-trace/src/llmobs/tagger.js +9 -6
- package/packages/dd-trace/src/llmobs/writers/base.js +2 -0
- package/packages/dd-trace/src/llmobs/writers/util.js +3 -0
- package/packages/dd-trace/src/log/index.js +20 -59
- package/packages/dd-trace/src/log/writer.js +7 -19
- package/packages/dd-trace/src/noop/proxy.js +8 -0
- 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/logs/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +1 -1
- 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/propagation/text_map.js +9 -4
- package/packages/dd-trace/src/opentracing/tracer.js +9 -4
- package/packages/dd-trace/src/payload-tagging/config/index.js +6 -5
- package/packages/dd-trace/src/plugin_manager.js +8 -6
- package/packages/dd-trace/src/plugins/ci_plugin.js +4 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +3 -0
- package/packages/dd-trace/src/plugins/plugin.js +11 -13
- 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/process-tags/index.js +3 -0
- package/packages/dd-trace/src/profiler.js +27 -2
- package/packages/dd-trace/src/profiling/config.js +73 -241
- package/packages/dd-trace/src/profiling/exporter_cli.js +1 -4
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +6 -2
- package/packages/dd-trace/src/profiling/profiler.js +78 -109
- package/packages/dd-trace/src/profiling/profilers/events.js +2 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +89 -6
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +4 -1
- package/packages/dd-trace/src/propagation-hash/index.js +2 -1
- package/packages/dd-trace/src/proxy.js +40 -6
- package/packages/dd-trace/src/remote_config/index.js +3 -0
- package/packages/dd-trace/src/require-package-json.js +8 -4
- package/packages/dd-trace/src/ritm.js +58 -26
- package/packages/dd-trace/src/runtime_metrics/index.js +3 -0
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +18 -11
- package/packages/dd-trace/src/sampler.js +1 -1
- 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/standalone/index.js +3 -0
- package/packages/dd-trace/src/telemetry/index.js +2 -3
- package/packages/dd-trace/src/telemetry/send-data.js +5 -19
- package/packages/dd-trace/src/telemetry/session-propagation.js +19 -44
- package/packages/dd-trace/src/telemetry/telemetry.js +28 -171
- package/packages/dd-trace/src/tracer.js +2 -2
- package/packages/dd-trace/src/util.js +0 -9
- 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
|
@@ -1,177 +1,346 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const { DD_MAJOR } = require('../../../../version')
|
|
6
|
-
const { getEnvironmentVariable: getEnv } = require('./helper')
|
|
3
|
+
const dns = require('dns')
|
|
4
|
+
const util = require('util')
|
|
7
5
|
|
|
6
|
+
const { DD_MAJOR } = require('../../../../version')
|
|
7
|
+
const { parsers, transformers, telemetryTransformers, setWarnInvalidValue } = require('./parsers')
|
|
8
8
|
const {
|
|
9
9
|
supportedConfigurations,
|
|
10
10
|
} = /** @type {import('./helper').SupportedConfigurationsJson} */ (require('./supported-configurations.json'))
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
let log
|
|
13
|
+
let seqId = 0
|
|
14
|
+
const configWithOrigin = new Map()
|
|
15
|
+
const parseErrors = new Map()
|
|
16
|
+
|
|
17
|
+
if (DD_MAJOR >= 6) {
|
|
18
|
+
// Programmatic configuration of DD_IAST_SECURITY_CONTROLS_CONFIGURATION is not supported
|
|
19
|
+
// in newer major versions. This is special handled here until a better solution is found.
|
|
20
|
+
// TODO: Remove the programmatic configuration from supported-configurations.json once v5 is not supported anymore.
|
|
21
|
+
supportedConfigurations.DD_IAST_SECURITY_CONTROLS_CONFIGURATION[0].internalPropertyName =
|
|
22
|
+
supportedConfigurations.DD_IAST_SECURITY_CONTROLS_CONFIGURATION[0].configurationNames?.[0]
|
|
23
|
+
delete supportedConfigurations.DD_IAST_SECURITY_CONTROLS_CONFIGURATION[0].configurationNames
|
|
24
|
+
} else {
|
|
25
|
+
// Default value for DD_TRACE_STARTUP_LOGS is 'false' in older major versions.
|
|
26
|
+
// This is special handled here until a better solution is found.
|
|
27
|
+
// TODO: Remove this here once v5 is not supported anymore.
|
|
28
|
+
supportedConfigurations.DD_TRACE_STARTUP_LOGS[0].default = 'false'
|
|
29
|
+
}
|
|
18
30
|
|
|
19
31
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
32
|
+
* Warns about an invalid value for an option and adds the error to the last telemetry entry if it is not already set.
|
|
33
|
+
* Logging happens only if the error is not already set or the option name is different from the last telemetry entry.
|
|
34
|
+
*
|
|
35
|
+
* @param {unknown} value - The value that is invalid.
|
|
36
|
+
* @param {string} optionName - The name of the option.
|
|
37
|
+
* @param {string} source - The source of the value.
|
|
38
|
+
* @param {string} baseMessage - The base message to use for the warning.
|
|
39
|
+
* @param {Error} [error] - An error that was thrown while parsing the value.
|
|
23
40
|
*/
|
|
24
|
-
function
|
|
25
|
-
|
|
26
|
-
|
|
41
|
+
function warnInvalidValue (value, optionName, source, baseMessage, error) {
|
|
42
|
+
const canonicalName = (optionsTable[optionName]?.canonicalName ?? optionName) + source
|
|
43
|
+
// Lazy load log module to avoid circular dependency
|
|
44
|
+
if (!parseErrors.has(canonicalName)) {
|
|
45
|
+
// TODO: Rephrase: It will fallback to former source (or default if not set)
|
|
46
|
+
let message = `${baseMessage}: ${util.inspect(value)} for ${optionName} (source: ${source}), picked default`
|
|
47
|
+
if (error) {
|
|
48
|
+
error.stack = error.toString()
|
|
49
|
+
message += `\n\n${util.inspect(error)}`
|
|
50
|
+
}
|
|
51
|
+
parseErrors.set(canonicalName, { message })
|
|
52
|
+
log ??= require('../log')
|
|
53
|
+
const logLevel = error ? 'error' : 'warn'
|
|
54
|
+
log[logLevel](message)
|
|
27
55
|
}
|
|
56
|
+
}
|
|
57
|
+
setWarnInvalidValue(warnInvalidValue)
|
|
28
58
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
59
|
+
/** @type {import('./config-types').ConfigDefaults} */
|
|
60
|
+
const defaults = {
|
|
61
|
+
instrumentationSource: 'manual',
|
|
62
|
+
isServiceUserProvided: false,
|
|
63
|
+
plugins: true,
|
|
64
|
+
isCiVisibility: false,
|
|
65
|
+
lookup: dns.lookup,
|
|
66
|
+
logger: undefined,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (const [name, value] of Object.entries(defaults)) {
|
|
70
|
+
configWithOrigin.set(`${name}default`, {
|
|
71
|
+
name,
|
|
72
|
+
value: value ?? null,
|
|
73
|
+
origin: 'default',
|
|
74
|
+
seq_id: seqId++,
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @param {unknown} value
|
|
80
|
+
* @param {string} origin
|
|
81
|
+
* @param {string} optionName
|
|
82
|
+
*/
|
|
83
|
+
function generateTelemetry (value = null, origin, optionName) {
|
|
84
|
+
const { type, canonicalName = optionName } = configurationsTable[optionName] ?? { type: typeof value }
|
|
85
|
+
// TODO: Consider adding a preParser hook to the parsers object.
|
|
86
|
+
if (canonicalName === 'OTEL_RESOURCE_ATTRIBUTES') {
|
|
87
|
+
value = telemetryTransformers.MAP(value)
|
|
88
|
+
}
|
|
89
|
+
// TODO: Should we not send defaults to telemetry to reduce size?
|
|
90
|
+
// TODO: How to handle aliases/actual names in the future? Optional fields? Normalize the name at intake?
|
|
91
|
+
// TODO: Validate that space separated tags are parsed by the backend. Optimizations would be possible with that.
|
|
92
|
+
// TODO: How to handle telemetry reporting for aliases?
|
|
93
|
+
if (value !== null) {
|
|
94
|
+
if (telemetryTransformers[type]) {
|
|
95
|
+
value = telemetryTransformers[type](value)
|
|
96
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
97
|
+
value = value instanceof URL
|
|
98
|
+
? String(value)
|
|
99
|
+
: JSON.stringify(value)
|
|
100
|
+
} else if (typeof value === 'function') {
|
|
101
|
+
value = value.name || 'function'
|
|
51
102
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
103
|
+
}
|
|
104
|
+
const telemetryEntry = {
|
|
105
|
+
name: canonicalName,
|
|
106
|
+
value,
|
|
107
|
+
origin,
|
|
108
|
+
seq_id: seqId++,
|
|
109
|
+
}
|
|
110
|
+
const error = parseErrors.get(`${canonicalName}${origin}`)
|
|
111
|
+
if (error) {
|
|
112
|
+
parseErrors.delete(`${canonicalName}${origin}`)
|
|
113
|
+
telemetryEntry.error = error
|
|
114
|
+
}
|
|
115
|
+
configWithOrigin.set(`${canonicalName}${origin}`, telemetryEntry)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Iterate over the object and always handle the leaf properties as lookup.
|
|
119
|
+
// Example entries:
|
|
120
|
+
//
|
|
121
|
+
// cloudPayloadTagging: {
|
|
122
|
+
// nestedProperties: [
|
|
123
|
+
// 'rules',
|
|
124
|
+
// 'requestsEnabled',
|
|
125
|
+
// 'responses',
|
|
126
|
+
// ],
|
|
127
|
+
// option: {
|
|
128
|
+
// property: 'rules',
|
|
129
|
+
// parser: parsers.JSON,
|
|
130
|
+
// canonicalName: 'DD_TRACE_CLOUD_REQUEST_PAYLOAD_TAGGING',
|
|
131
|
+
// transformer: transformers.toCamelCase,
|
|
132
|
+
// },
|
|
133
|
+
// },
|
|
134
|
+
// 'cloudPayloadTagging.responses': {
|
|
135
|
+
// nestedProperties: [
|
|
136
|
+
// 'enabled',
|
|
137
|
+
// ],
|
|
138
|
+
// },
|
|
139
|
+
// 'cloudPayloadTagging.rules': {},
|
|
140
|
+
// 'cloudPayloadTagging.requestsEnabled': {},
|
|
141
|
+
// 'cloudPayloadTagging.responses.enabled': {}
|
|
142
|
+
const optionsTable = {
|
|
143
|
+
// Additional properties that are not supported by the supported-configurations.json file.
|
|
144
|
+
lookup: {
|
|
145
|
+
transformer (value) {
|
|
146
|
+
if (typeof value === 'function') {
|
|
147
|
+
return value
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
property: 'lookup',
|
|
151
|
+
},
|
|
152
|
+
logger: {
|
|
153
|
+
transformer (object) {
|
|
154
|
+
// Create lazily to avoid the overhead when not used.
|
|
155
|
+
// Match at least one log level.
|
|
156
|
+
const knownLogLevels = new Set(supportedConfigurations.DD_TRACE_LOG_LEVEL[0].allowed?.split('|'))
|
|
157
|
+
if (typeof object !== 'object' || object === null) {
|
|
158
|
+
return object
|
|
159
|
+
}
|
|
160
|
+
let matched = false
|
|
161
|
+
for (const logLevel of knownLogLevels) {
|
|
162
|
+
if (object[logLevel] !== undefined) {
|
|
163
|
+
if (typeof object[logLevel] !== 'function') {
|
|
164
|
+
warnInvalidValue(object[logLevel], 'logger', 'default', `Invalid log level ${logLevel}`)
|
|
165
|
+
return
|
|
63
166
|
}
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
const key = item.slice(0, colonIndex).trim()
|
|
67
|
-
const value = item.slice(colonIndex + 1).trim()
|
|
68
|
-
if (key.length > 0) {
|
|
69
|
-
entries[key] = value
|
|
167
|
+
matched = true
|
|
70
168
|
}
|
|
71
169
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
170
|
+
if (matched) {
|
|
171
|
+
return object
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
property: 'logger',
|
|
175
|
+
},
|
|
176
|
+
isCiVisibility: {
|
|
177
|
+
property: 'isCiVisibility',
|
|
178
|
+
},
|
|
179
|
+
plugins: {
|
|
180
|
+
property: 'plugins',
|
|
181
|
+
},
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const parser = (value, optionName, source) => {
|
|
185
|
+
const { type, canonicalName = optionName } = configurationsTable[optionName]
|
|
186
|
+
const parsed = parsers[type](value, canonicalName)
|
|
187
|
+
if (parsed === undefined) {
|
|
188
|
+
warnInvalidValue(value, optionName, source, `Invalid ${type} input`)
|
|
76
189
|
}
|
|
190
|
+
return parsed
|
|
77
191
|
}
|
|
78
192
|
|
|
79
|
-
/**
|
|
80
|
-
|
|
81
|
-
|
|
193
|
+
/**
|
|
194
|
+
* @template {import('./config-types').ConfigPath} TPath
|
|
195
|
+
* @type {Partial<Record<TPath, {
|
|
196
|
+
* property?: string,
|
|
197
|
+
* parser: (value: unknown, optionName: string, source: string) => unknown,
|
|
198
|
+
* canonicalName?: string,
|
|
199
|
+
* transformer?: (value: unknown, optionName: string, source: string) => unknown,
|
|
200
|
+
* telemetryTransformer?: (value: unknown) => unknown
|
|
201
|
+
* }>>} ConfigurationsTable
|
|
202
|
+
*/
|
|
203
|
+
const configurationsTable = {}
|
|
204
|
+
|
|
205
|
+
// One way aliases. Must be applied in apply calculated entries.
|
|
206
|
+
const fallbackConfigurations = new Map()
|
|
207
|
+
|
|
208
|
+
const regExps = {}
|
|
209
|
+
|
|
210
|
+
for (const [canonicalName, entries] of Object.entries(supportedConfigurations)) {
|
|
211
|
+
if (entries.length !== 1) {
|
|
212
|
+
// TODO: Determine if we really want to support multiple entries for a canonical name.
|
|
213
|
+
// This would be needed to show official support for multiple diverging implementations
|
|
214
|
+
// at a time with by checking for another configuration that is not the canonical name.
|
|
215
|
+
throw new Error(
|
|
216
|
+
`Multiple entries found for canonical name: ${canonicalName}. ` +
|
|
217
|
+
'This is currently not supported and must be implemented, if needed.'
|
|
218
|
+
)
|
|
219
|
+
}
|
|
82
220
|
for (const entry of entries) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
221
|
+
const configurationNames = entry.internalPropertyName ? [entry.internalPropertyName] : entry.configurationNames
|
|
222
|
+
const fullPropertyName = configurationNames?.[0] ?? canonicalName
|
|
223
|
+
const type = entry.type.toUpperCase()
|
|
224
|
+
|
|
225
|
+
let transformer = transformers[entry.transform]
|
|
226
|
+
if (entry.allowed) {
|
|
227
|
+
regExps[entry.allowed] ??= new RegExp(`^(${entry.allowed})$`, 'i')
|
|
228
|
+
const allowed = regExps[entry.allowed]
|
|
229
|
+
const originalTransform = transformer
|
|
230
|
+
transformer = (value, optionName, source) => {
|
|
231
|
+
if (!allowed.test(value)) {
|
|
232
|
+
warnInvalidValue(value, optionName, source, 'Invalid value')
|
|
233
|
+
return
|
|
234
|
+
}
|
|
235
|
+
if (originalTransform) {
|
|
236
|
+
value = originalTransform(value)
|
|
237
|
+
}
|
|
238
|
+
return value
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const option = { parser, type }
|
|
243
|
+
|
|
244
|
+
if (fullPropertyName !== canonicalName) {
|
|
245
|
+
option.property = fullPropertyName
|
|
246
|
+
option.canonicalName = canonicalName
|
|
247
|
+
configurationsTable[fullPropertyName] = option
|
|
248
|
+
}
|
|
249
|
+
if (transformer) {
|
|
250
|
+
option.transformer = transformer
|
|
251
|
+
}
|
|
252
|
+
if (entry.configurationNames) {
|
|
253
|
+
addOption(option, type, entry.configurationNames)
|
|
254
|
+
}
|
|
255
|
+
configurationsTable[canonicalName] = option
|
|
256
|
+
|
|
257
|
+
if (entry.default === null) {
|
|
258
|
+
defaults[fullPropertyName] = undefined
|
|
259
|
+
} else {
|
|
260
|
+
let parsedDefault = parser(entry.default, fullPropertyName, 'default')
|
|
261
|
+
if (entry.transform) {
|
|
262
|
+
parsedDefault = transformer(parsedDefault, fullPropertyName, 'default')
|
|
263
|
+
}
|
|
264
|
+
defaults[fullPropertyName] = parsedDefault
|
|
91
265
|
}
|
|
266
|
+
generateTelemetry(defaults[fullPropertyName], 'default', fullPropertyName)
|
|
92
267
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
268
|
+
if (entry.aliases) {
|
|
269
|
+
for (const alias of entry.aliases) {
|
|
270
|
+
if (!supportedConfigurations[alias]) {
|
|
271
|
+
// An actual alias has no matching entry
|
|
272
|
+
continue
|
|
273
|
+
}
|
|
274
|
+
if (!supportedConfigurations[alias].aliases?.includes(canonicalName)) {
|
|
275
|
+
// Alias will be replaced with the full property name of the alias, if it exists.
|
|
276
|
+
fallbackConfigurations.set(fullPropertyName, alias)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
96
279
|
}
|
|
97
280
|
}
|
|
98
281
|
}
|
|
99
282
|
|
|
100
|
-
//
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
isAzureFunction: false,
|
|
106
|
-
isCiVisibility: false,
|
|
107
|
-
isGCPFunction: false,
|
|
108
|
-
instrumentationSource: 'manual',
|
|
109
|
-
isServiceUserProvided: false,
|
|
110
|
-
isServiceNameInferred: true,
|
|
111
|
-
lookup: undefined,
|
|
112
|
-
plugins: true,
|
|
283
|
+
// Replace the alias with the canonical property name.
|
|
284
|
+
for (const [fullPropertyName, alias] of fallbackConfigurations) {
|
|
285
|
+
if (configurationsTable[alias].property) {
|
|
286
|
+
fallbackConfigurations.set(fullPropertyName, configurationsTable[alias].property)
|
|
287
|
+
}
|
|
113
288
|
}
|
|
114
289
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
isManualApiEnabled: false,
|
|
126
|
-
isTestManagementEnabled: false,
|
|
127
|
-
// TODO: These are not conditional, they would just be of type number.
|
|
128
|
-
'dogstatsd.port': '8125',
|
|
129
|
-
port: '8126',
|
|
130
|
-
// Override due to expecting numbers, not strings. TODO: Replace later.
|
|
131
|
-
'grpc.client.error.statuses': [
|
|
132
|
-
1,
|
|
133
|
-
2,
|
|
134
|
-
3,
|
|
135
|
-
4,
|
|
136
|
-
5,
|
|
137
|
-
6,
|
|
138
|
-
7,
|
|
139
|
-
8,
|
|
140
|
-
9,
|
|
141
|
-
10,
|
|
142
|
-
11,
|
|
143
|
-
12,
|
|
144
|
-
13,
|
|
145
|
-
14,
|
|
146
|
-
15,
|
|
147
|
-
16,
|
|
148
|
-
],
|
|
149
|
-
'grpc.server.error.statuses': [
|
|
150
|
-
2,
|
|
151
|
-
3,
|
|
152
|
-
4,
|
|
153
|
-
5,
|
|
154
|
-
6,
|
|
155
|
-
7,
|
|
156
|
-
8,
|
|
157
|
-
9,
|
|
158
|
-
10,
|
|
159
|
-
11,
|
|
160
|
-
12,
|
|
161
|
-
13,
|
|
162
|
-
14,
|
|
163
|
-
15,
|
|
164
|
-
16,
|
|
165
|
-
],
|
|
166
|
-
}
|
|
290
|
+
function addOption (option, type, configurationNames) {
|
|
291
|
+
for (const name of configurationNames) {
|
|
292
|
+
let index = -1
|
|
293
|
+
let lastNestedProperties
|
|
294
|
+
while (true) {
|
|
295
|
+
const nextIndex = name.indexOf('.', index + 1)
|
|
296
|
+
const intermediateName = nextIndex === -1 ? name : name.slice(0, nextIndex)
|
|
297
|
+
if (lastNestedProperties) {
|
|
298
|
+
lastNestedProperties.add(intermediateName.slice(index + 1))
|
|
299
|
+
}
|
|
167
300
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
301
|
+
if (nextIndex === -1) {
|
|
302
|
+
if (optionsTable[name]) {
|
|
303
|
+
if (optionsTable[name].nestedProperties && !optionsTable[name].option) {
|
|
304
|
+
optionsTable[name].option = option
|
|
305
|
+
break
|
|
306
|
+
}
|
|
307
|
+
throw new Error(`Duplicate configuration name: ${name}`)
|
|
308
|
+
}
|
|
309
|
+
optionsTable[name] = option
|
|
310
|
+
break
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
lastNestedProperties = new Set()
|
|
314
|
+
index = nextIndex
|
|
315
|
+
|
|
316
|
+
if (!optionsTable[intermediateName]) {
|
|
317
|
+
optionsTable[intermediateName] = {
|
|
318
|
+
nestedProperties: lastNestedProperties,
|
|
319
|
+
}
|
|
320
|
+
} else if (optionsTable[intermediateName].nestedProperties) {
|
|
321
|
+
lastNestedProperties = optionsTable[intermediateName].nestedProperties
|
|
322
|
+
} else {
|
|
323
|
+
optionsTable[intermediateName] = {
|
|
324
|
+
nestedProperties: lastNestedProperties,
|
|
325
|
+
option: optionsTable[intermediateName],
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
175
330
|
}
|
|
176
331
|
|
|
177
|
-
module.exports =
|
|
332
|
+
module.exports = {
|
|
333
|
+
configurationsTable,
|
|
334
|
+
|
|
335
|
+
defaults,
|
|
336
|
+
|
|
337
|
+
fallbackConfigurations,
|
|
338
|
+
|
|
339
|
+
optionsTable,
|
|
340
|
+
|
|
341
|
+
configWithOrigin,
|
|
342
|
+
|
|
343
|
+
parseErrors,
|
|
344
|
+
|
|
345
|
+
generateTelemetry,
|
|
346
|
+
}
|
|
@@ -88,10 +88,12 @@ export interface GeneratedConfig {
|
|
|
88
88
|
DD_CIVISIBILITY_TEST_MODULE_ID: string | undefined;
|
|
89
89
|
DD_CIVISIBILITY_TEST_SESSION_ID: string | undefined;
|
|
90
90
|
DD_CUSTOM_TRACE_ID: string | undefined;
|
|
91
|
+
DD_ENABLE_LAGE_PACKAGE_NAME: boolean;
|
|
91
92
|
DD_ENABLE_NX_SERVICE_NAME: boolean;
|
|
92
93
|
DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_DIR: string;
|
|
93
94
|
DD_EXPERIMENTAL_TEST_OPT_GIT_CACHE_ENABLED: boolean;
|
|
94
95
|
DD_EXPERIMENTAL_TEST_OPT_SETTINGS_CACHE: string;
|
|
96
|
+
DD_EXPERIMENTAL_TEST_REQUESTS_FS_CACHE: boolean;
|
|
95
97
|
DD_EXTERNAL_ENV: string | undefined;
|
|
96
98
|
DD_GIT_BRANCH: string | undefined;
|
|
97
99
|
DD_GIT_COMMIT_AUTHOR_DATE: string | undefined;
|
|
@@ -379,6 +381,7 @@ export interface GeneratedConfig {
|
|
|
379
381
|
env: string | undefined;
|
|
380
382
|
experimental: {
|
|
381
383
|
aiguard: {
|
|
384
|
+
block: boolean;
|
|
382
385
|
enabled: boolean;
|
|
383
386
|
endpoint: string | undefined;
|
|
384
387
|
maxContentSize: number;
|
|
@@ -475,7 +478,6 @@ export interface GeneratedConfig {
|
|
|
475
478
|
};
|
|
476
479
|
openAiLogsEnabled: boolean;
|
|
477
480
|
OTEL_EXPORTER_OTLP_ENDPOINT: string | undefined;
|
|
478
|
-
OTEL_LOG_LEVEL: "debug" | "info" | "warn" | "error" | undefined;
|
|
479
481
|
OTEL_LOGS_EXPORTER: "none" | "otlp" | undefined;
|
|
480
482
|
OTEL_METRICS_EXPORTER: "none" | "otlp" | undefined;
|
|
481
483
|
OTEL_RESOURCE_ATTRIBUTES: Record<string, string>;
|
|
@@ -502,6 +504,10 @@ export interface GeneratedConfig {
|
|
|
502
504
|
otelMetricsUrl: string | undefined;
|
|
503
505
|
otelProtocol: string;
|
|
504
506
|
otelTimeout: number;
|
|
507
|
+
otelTracesHeaders: Record<string, string> | undefined;
|
|
508
|
+
otelTracesProtocol: string;
|
|
509
|
+
otelTracesTimeout: number;
|
|
510
|
+
otelTracesUrl: string | undefined;
|
|
505
511
|
peerServiceMapping: Record<string, string>;
|
|
506
512
|
port: string | number;
|
|
507
513
|
profiling: {
|
|
@@ -524,6 +530,7 @@ export interface GeneratedConfig {
|
|
|
524
530
|
enabled: boolean;
|
|
525
531
|
eventLoop: boolean;
|
|
526
532
|
gc: boolean;
|
|
533
|
+
native: boolean;
|
|
527
534
|
};
|
|
528
535
|
runtimeMetricsRuntimeId: boolean;
|
|
529
536
|
sampleRate: number | undefined;
|
|
@@ -547,6 +554,7 @@ export interface GeneratedConfig {
|
|
|
547
554
|
debug: boolean;
|
|
548
555
|
dependencyCollection: boolean;
|
|
549
556
|
enabled: boolean;
|
|
557
|
+
extendedHeartbeatInterval: number;
|
|
550
558
|
heartbeatInterval: number;
|
|
551
559
|
logCollection: boolean;
|
|
552
560
|
metrics: boolean;
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
* @property {string|number|boolean|null|object|unknown[]} default
|
|
10
10
|
* @property {string[]} [aliases]
|
|
11
11
|
* @property {string[]} [configurationNames]
|
|
12
|
+
* @property {string} [internalPropertyName]
|
|
13
|
+
* @property {string} [transform]
|
|
14
|
+
* @property {string} [allowed]
|
|
12
15
|
* @property {string|boolean} [deprecated]
|
|
13
16
|
*/
|
|
14
17
|
|
|
@@ -57,6 +60,13 @@ for (const [canonical, configuration] of Object.entries(supportedConfigurations)
|
|
|
57
60
|
const aliasToCanonical = {}
|
|
58
61
|
for (const canonical of Object.keys(aliases)) {
|
|
59
62
|
for (const alias of aliases[canonical]) {
|
|
63
|
+
if (supportedConfigurations[alias]) {
|
|
64
|
+
// Allow 'fallback' aliases to be used for other configurations.
|
|
65
|
+
// This is used to handle the case where an alias could be used for multiple configurations.
|
|
66
|
+
// For example, OTEL_EXPORTER_OTLP_ENDPOINT is used for OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
|
|
67
|
+
// and OTEL_EXPORTER_OTLP_METRICS_ENDPOINT.
|
|
68
|
+
continue
|
|
69
|
+
}
|
|
60
70
|
if (aliasToCanonical[alias]) {
|
|
61
71
|
throw new Error(`The alias ${alias} is already used for ${aliasToCanonical[alias]}.`)
|
|
62
72
|
}
|
|
@@ -99,22 +109,37 @@ function loadStableConfig () {
|
|
|
99
109
|
}
|
|
100
110
|
|
|
101
111
|
function getValueFromSource (name, source) {
|
|
102
|
-
|
|
112
|
+
if (source[name] !== undefined) {
|
|
113
|
+
return source[name]
|
|
114
|
+
}
|
|
103
115
|
|
|
104
|
-
if (
|
|
116
|
+
if (aliases[name]) {
|
|
105
117
|
for (const alias of aliases[name]) {
|
|
106
118
|
if (source[alias] !== undefined) {
|
|
107
119
|
return source[alias]
|
|
108
120
|
}
|
|
109
121
|
}
|
|
110
122
|
}
|
|
123
|
+
}
|
|
111
124
|
|
|
112
|
-
|
|
125
|
+
function getEnvNameFromSource (name, source) {
|
|
126
|
+
if (source[name] !== undefined) {
|
|
127
|
+
return name
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (aliases[name]) {
|
|
131
|
+
for (const alias of aliases[name]) {
|
|
132
|
+
if (source[alias] !== undefined) {
|
|
133
|
+
return alias
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
113
137
|
}
|
|
114
138
|
|
|
115
139
|
function validateAccess (name) {
|
|
116
|
-
if ((name.startsWith('DD_') || name.startsWith('OTEL_')
|
|
117
|
-
!supportedConfigurations[name]
|
|
140
|
+
if ((name.startsWith('DD_') || name.startsWith('OTEL_')) &&
|
|
141
|
+
!supportedConfigurations[name] &&
|
|
142
|
+
!aliasToCanonical[name]) {
|
|
118
143
|
throw new Error(`Missing ${name} env/configuration in "supported-configurations.json" file.`)
|
|
119
144
|
}
|
|
120
145
|
}
|
|
@@ -144,10 +169,9 @@ module.exports = {
|
|
|
144
169
|
*
|
|
145
170
|
* @returns {TracerEnv} The environment variables
|
|
146
171
|
*/
|
|
147
|
-
getEnvironmentVariables () {
|
|
172
|
+
getEnvironmentVariables (source = process.env, internalOnly = false) {
|
|
148
173
|
const configs = {}
|
|
149
|
-
for (const [key, value] of Object.entries(
|
|
150
|
-
// TODO(BridgeAR): Handle telemetry reporting for aliases.
|
|
174
|
+
for (const [key, value] of Object.entries(source)) {
|
|
151
175
|
if (key.startsWith('DD_') || key.startsWith('OTEL_') || aliasToCanonical[key]) {
|
|
152
176
|
if (supportedConfigurations[key]) {
|
|
153
177
|
configs[key] = value
|
|
@@ -155,7 +179,7 @@ module.exports = {
|
|
|
155
179
|
// The alias should only be used if the actual configuration is not set
|
|
156
180
|
// In case that more than a single alias exist, use the one defined first in our own order
|
|
157
181
|
for (const alias of aliases[aliasToCanonical[key]]) {
|
|
158
|
-
if (
|
|
182
|
+
if (source[alias] !== undefined) {
|
|
159
183
|
configs[aliasToCanonical[key]] = value
|
|
160
184
|
break
|
|
161
185
|
}
|
|
@@ -165,9 +189,10 @@ module.exports = {
|
|
|
165
189
|
// debug(
|
|
166
190
|
// `Missing configuration ${env} in supported-configurations file. The environment variable is ignored.`
|
|
167
191
|
// )
|
|
192
|
+
// This could be moved inside the main config logic.
|
|
168
193
|
}
|
|
169
194
|
deprecationMethods[key]?.()
|
|
170
|
-
} else {
|
|
195
|
+
} else if (!internalOnly) {
|
|
171
196
|
configs[key] = value
|
|
172
197
|
}
|
|
173
198
|
}
|
|
@@ -211,4 +236,28 @@ module.exports = {
|
|
|
211
236
|
return getValueFromSource(name, localStableConfig)
|
|
212
237
|
}
|
|
213
238
|
},
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Returns the actual environment variable name used for a supported configuration
|
|
242
|
+
* from a specific environment-based source.
|
|
243
|
+
*
|
|
244
|
+
* @param {string} name Environment variable name
|
|
245
|
+
* @returns {string|undefined}
|
|
246
|
+
*/
|
|
247
|
+
getConfiguredEnvName (name) {
|
|
248
|
+
validateAccess(name)
|
|
249
|
+
|
|
250
|
+
if (!stableConfigLoaded) {
|
|
251
|
+
loadStableConfig()
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
for (const source of [fleetStableConfig, process.env, localStableConfig]) {
|
|
255
|
+
if (source !== undefined) {
|
|
256
|
+
const fromSource = getEnvNameFromSource(name, source)
|
|
257
|
+
if (fromSource !== undefined) {
|
|
258
|
+
return fromSource
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
},
|
|
214
263
|
}
|