dd-trace 5.95.0 → 5.97.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 +43 -0
- package/package.json +10 -8
- package/packages/datadog-esbuild/index.js +20 -9
- package/packages/datadog-instrumentations/src/ai.js +112 -0
- 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 +4 -1
- package/packages/datadog-instrumentations/src/cypress-config.js +324 -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/ai-messages.js +182 -0
- 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/helpers/rewriter/instrumentations/ai.js +25 -0
- 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 +13 -4
- package/packages/datadog-instrumentations/src/limitd-client.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/utils.js +14 -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/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 +4 -3
- package/packages/datadog-plugin-cucumber/src/index.js +7 -3
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +57 -5
- package/packages/datadog-plugin-graphql/src/resolve.js +1 -1
- 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-next/src/index.js +2 -14
- package/packages/datadog-plugin-openai/src/services.js +1 -0
- 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/index.js +64 -0
- package/packages/dd-trace/src/aiguard/sdk.js +4 -0
- package/packages/dd-trace/src/appsec/blocking.js +3 -0
- 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/ci-visibility/dynamic-instrumentation/index.js +6 -1
- package/packages/dd-trace/src/ci-visibility/lage.js +39 -0
- 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 +316 -146
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -1
- package/packages/dd-trace/src/config/helper.js +59 -10
- package/packages/dd-trace/src/config/index.js +570 -1503
- 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 +367 -433
- 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/index.js +1 -1
- package/packages/dd-trace/src/dogstatsd.js +12 -9
- package/packages/dd-trace/src/encode/0.4.js +1 -1
- package/packages/dd-trace/src/exporter.js +5 -2
- 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/constants/text.js +3 -0
- package/packages/dd-trace/src/llmobs/index.js +13 -5
- 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 +26 -55
- 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/opentelemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.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/plugin.js +7 -4
- package/packages/dd-trace/src/plugins/util/test.js +5 -0
- 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 +56 -44
- 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 +36 -3
- 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 +3 -0
- package/packages/dd-trace/src/sampler.js +1 -1
- package/packages/dd-trace/src/standalone/index.js +3 -0
- package/packages/dd-trace/src/startup-log.js +9 -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/util.js +0 -9
|
@@ -5,1682 +5,749 @@ const os = require('node:os')
|
|
|
5
5
|
const { URL } = require('node:url')
|
|
6
6
|
const path = require('node:path')
|
|
7
7
|
|
|
8
|
+
const rfdc = require('../../../../vendor/dist/rfdc')({ proto: false, circles: false })
|
|
8
9
|
const uuid = require('../../../../vendor/dist/crypto-randomuuid') // we need to keep the old uuid dep because of cypress
|
|
9
|
-
|
|
10
10
|
const set = require('../../../datadog-core/src/utils/src/set')
|
|
11
11
|
const { DD_MAJOR } = require('../../../../version')
|
|
12
12
|
const log = require('../log')
|
|
13
|
-
const
|
|
14
|
-
const { isTrue
|
|
13
|
+
const pkg = require('../pkg')
|
|
14
|
+
const { isTrue } = require('../util')
|
|
15
15
|
const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('../plugins/util/tags')
|
|
16
|
-
const
|
|
16
|
+
const telemetry = require('../telemetry')
|
|
17
17
|
const telemetryMetrics = require('../telemetry/metrics')
|
|
18
18
|
const {
|
|
19
19
|
IS_SERVERLESS,
|
|
20
20
|
getIsGCPFunction,
|
|
21
21
|
getIsAzureFunction,
|
|
22
|
-
enableGCPPubSubPushSubscription,
|
|
23
22
|
} = require('../serverless')
|
|
24
|
-
const { ORIGIN_KEY } = require('../constants')
|
|
23
|
+
const { ORIGIN_KEY, DATADOG_MINI_AGENT_PATH } = require('../constants')
|
|
25
24
|
const { appendRules } = require('../payload-tagging/config')
|
|
26
25
|
const { getGitMetadataFromGitProperties, removeUserSensitiveInfo, getRemoteOriginURL, resolveGitHeadSHA } =
|
|
27
26
|
require('./git_properties')
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
])
|
|
47
|
-
const VALID_PROPAGATION_STYLES = new Set(['datadog', 'tracecontext', 'b3', 'b3 single header', 'none'])
|
|
48
|
-
const VALID_PROPAGATION_BEHAVIOR_EXTRACT = new Set(['continue', 'restart', 'ignore'])
|
|
49
|
-
const VALID_LOG_LEVELS = new Set(['debug', 'info', 'warn', 'error'])
|
|
50
|
-
const DEFAULT_OTLP_PORT = 4318
|
|
27
|
+
const ConfigBase = require('./config-base')
|
|
28
|
+
const {
|
|
29
|
+
getEnvironmentVariable,
|
|
30
|
+
getEnvironmentVariables,
|
|
31
|
+
getStableConfigSources,
|
|
32
|
+
getValueFromEnvSources,
|
|
33
|
+
} = require('./helper')
|
|
34
|
+
const {
|
|
35
|
+
defaults,
|
|
36
|
+
fallbackConfigurations,
|
|
37
|
+
configurationsTable,
|
|
38
|
+
optionsTable,
|
|
39
|
+
configWithOrigin,
|
|
40
|
+
parseErrors,
|
|
41
|
+
generateTelemetry,
|
|
42
|
+
} = require('./defaults')
|
|
43
|
+
const { transformers } = require('./parsers')
|
|
44
|
+
|
|
51
45
|
const RUNTIME_ID = uuid()
|
|
52
|
-
// eslint-disable-next-line eslint-rules/eslint-process-env -- internal propagation, not user config
|
|
53
|
-
const ROOT_SESSION_ID = process.env.DD_ROOT_JS_SESSION_ID || RUNTIME_ID
|
|
54
|
-
const NAMING_VERSIONS = new Set(['v0', 'v1'])
|
|
55
|
-
const DEFAULT_NAMING_VERSION = 'v0'
|
|
56
46
|
|
|
57
47
|
const tracerMetrics = telemetryMetrics.manager.namespace('tracers')
|
|
58
|
-
const changeTracker = {}
|
|
59
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @typedef {'default'
|
|
51
|
+
* | 'code'
|
|
52
|
+
* | 'remote_config'
|
|
53
|
+
* | 'calculated'
|
|
54
|
+
* | 'env_var'
|
|
55
|
+
* | 'local_stable_config'
|
|
56
|
+
* | 'fleet_stable_config'} TelemetrySource
|
|
57
|
+
* @typedef {'remote_config' | 'calculated'} RevertibleTelemetrySource
|
|
58
|
+
* @typedef {import('../../../../index').TracerOptions} TracerOptions
|
|
59
|
+
* @typedef {import('./config-types').ConfigKey} ConfigKey
|
|
60
|
+
* @typedef {import('./config-types').ConfigPath} ConfigPath
|
|
61
|
+
* @typedef {{
|
|
62
|
+
* value: import('./config-types').ConfigPathValue<ConfigPath>,
|
|
63
|
+
* source: TelemetrySource
|
|
64
|
+
* }} TrackedConfigEntry
|
|
65
|
+
* @typedef {{
|
|
66
|
+
* baseValuesByPath: Partial<Record<ConfigPath, TrackedConfigEntry>>,
|
|
67
|
+
* remote_config: Set<ConfigPath>,
|
|
68
|
+
* calculated: Set<ConfigPath>,
|
|
69
|
+
* }} ChangeTracker
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
/** @type {Config | null} */
|
|
60
73
|
let configInstance = null
|
|
61
74
|
|
|
75
|
+
// An entry that is undefined means it is the default value.
|
|
76
|
+
/** @type {Map<ConfigPath, TelemetrySource>} */
|
|
77
|
+
const trackedConfigOrigins = new Map()
|
|
78
|
+
|
|
79
|
+
// ChangeTracker tracks the changes to the config up to programmatic options (code).
|
|
80
|
+
/** @type {ChangeTracker} */
|
|
81
|
+
const changeTracker = {
|
|
82
|
+
baseValuesByPath: {},
|
|
83
|
+
remote_config: new Set(),
|
|
84
|
+
calculated: new Set(),
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param {Config} config
|
|
89
|
+
* @param {RevertibleTelemetrySource} source
|
|
90
|
+
*/
|
|
91
|
+
function undo (config, source) {
|
|
92
|
+
for (const name of changeTracker[source]) {
|
|
93
|
+
const entry = changeTracker.baseValuesByPath[name] ?? { source: 'default', value: defaults[name] }
|
|
94
|
+
setAndTrack(config, name, entry.value, undefined, entry.source)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function get (object, path) {
|
|
99
|
+
// Fast path for simple property access.
|
|
100
|
+
if (object[path] !== undefined) {
|
|
101
|
+
return object[path]
|
|
102
|
+
}
|
|
103
|
+
let index = 0
|
|
104
|
+
while (true) {
|
|
105
|
+
const nextIndex = path.indexOf('.', index)
|
|
106
|
+
if (nextIndex === -1) {
|
|
107
|
+
return object[path.slice(index)]
|
|
108
|
+
}
|
|
109
|
+
object = object[path.slice(index, nextIndex)]
|
|
110
|
+
index = nextIndex + 1
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @param {Config} config
|
|
116
|
+
* @template {ConfigPath} TPath
|
|
117
|
+
* @param {TPath} name
|
|
118
|
+
* @param {import('./config-types').ConfigPathValue<TPath>} value
|
|
119
|
+
* @param {unknown} [rawValue]
|
|
120
|
+
* @param {TelemetrySource} [source]
|
|
121
|
+
*/
|
|
122
|
+
function setAndTrack (config, name, value, rawValue = value, source = 'calculated') {
|
|
123
|
+
// envs can not be undefined
|
|
124
|
+
if (value == null) {
|
|
125
|
+
// TODO: This works as before while ignoring undefined programmatic options is not ideal.
|
|
126
|
+
if (source !== 'default') {
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
} else if (source === 'calculated' || source === 'remote_config') {
|
|
130
|
+
if (source === 'calculated' && value === get(config, name)) {
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
changeTracker[source].add(name)
|
|
134
|
+
} else {
|
|
135
|
+
const copy = typeof value === 'object' && value !== null ? rfdc(value) : value
|
|
136
|
+
changeTracker.baseValuesByPath[name] = { value: copy, source }
|
|
137
|
+
}
|
|
138
|
+
set(config, name, value)
|
|
139
|
+
|
|
140
|
+
generateTelemetry(rawValue, source, name)
|
|
141
|
+
if (source === 'default') {
|
|
142
|
+
trackedConfigOrigins.delete(name)
|
|
143
|
+
} else {
|
|
144
|
+
trackedConfigOrigins.set(name, source)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
62
148
|
module.exports = getConfig
|
|
63
149
|
|
|
64
|
-
|
|
150
|
+
// We extend from ConfigBase to make our types work
|
|
151
|
+
class Config extends ConfigBase {
|
|
65
152
|
/**
|
|
66
153
|
* parsed DD_TAGS, usable as a standalone tag set across products
|
|
67
154
|
* @type {Record<string, string>}
|
|
68
155
|
*/
|
|
69
|
-
#parsedDdTags
|
|
70
|
-
#envUnprocessed = {}
|
|
71
|
-
#optsUnprocessed = {}
|
|
72
|
-
#remoteUnprocessed = {}
|
|
73
|
-
#env = {}
|
|
74
|
-
#options = {}
|
|
75
|
-
#remote = {}
|
|
76
|
-
#defaults = {}
|
|
77
|
-
#optionsArg = {}
|
|
78
|
-
#localStableConfig = {}
|
|
79
|
-
#fleetStableConfig = {}
|
|
80
|
-
#calculated = {}
|
|
156
|
+
#parsedDdTags
|
|
81
157
|
|
|
158
|
+
/**
|
|
159
|
+
* @type {Record<string, string>}
|
|
160
|
+
*/
|
|
161
|
+
get parsedDdTags () {
|
|
162
|
+
return this.#parsedDdTags
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @param {TracerOptions} [options={}]
|
|
167
|
+
*/
|
|
82
168
|
constructor (options = {}) {
|
|
83
|
-
|
|
84
|
-
const configEnvSources = getStableConfigSources()
|
|
85
|
-
this.stableConfig = {
|
|
86
|
-
fleetEntries: configEnvSources.fleetStableConfig,
|
|
87
|
-
localEntries: configEnvSources.localStableConfig,
|
|
88
|
-
warnings: configEnvSources.stableConfigWarnings,
|
|
89
|
-
}
|
|
90
|
-
}
|
|
169
|
+
super()
|
|
91
170
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
iast: options.iast == null ? options.experimental?.iast : options.iast,
|
|
171
|
+
const configEnvSources = getStableConfigSources()
|
|
172
|
+
this.stableConfig = {
|
|
173
|
+
fleetEntries: configEnvSources.fleetStableConfig ?? {},
|
|
174
|
+
localEntries: configEnvSources.localStableConfig ?? {},
|
|
175
|
+
warnings: configEnvSources.stableConfigWarnings,
|
|
98
176
|
}
|
|
99
177
|
|
|
100
178
|
// Configure the logger first so it can be used to warn about other configs
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
this.stableConfig?.fleetEntries?.DD_TRACE_LOG_LEVEL,
|
|
110
|
-
this.stableConfig?.localEntries?.DD_TRACE_LOG_LEVEL
|
|
111
|
-
)
|
|
112
|
-
log.use(this.logger)
|
|
113
|
-
log.toggle(this.debug, this.logLevel)
|
|
179
|
+
// TODO: Implement auto buffering of inside of log module before first
|
|
180
|
+
// configure call. That way the logger is always available and the
|
|
181
|
+
// application doesn't need to configure it first and the configuration
|
|
182
|
+
// happens inside of config instead of inside of log module. If the logger
|
|
183
|
+
// is not deactivated, the buffered logs would be discarded. That way stable
|
|
184
|
+
// config warnings can also be logged directly and do not need special
|
|
185
|
+
// handling.
|
|
186
|
+
this.debug = log.configure(options)
|
|
114
187
|
|
|
115
188
|
// Process stable config warnings, if any
|
|
116
189
|
for (const warning of this.stableConfig?.warnings ?? []) {
|
|
117
190
|
log.warn(warning)
|
|
118
191
|
}
|
|
119
192
|
|
|
120
|
-
checkIfBothOtelAndDdEnvVarSet()
|
|
121
|
-
|
|
122
|
-
if (typeof options.appsec === 'boolean') {
|
|
123
|
-
options.appsec = {
|
|
124
|
-
enabled: options.appsec,
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (typeof options.runtimeMetrics === 'boolean') {
|
|
129
|
-
options.runtimeMetrics = {
|
|
130
|
-
enabled: options.runtimeMetrics,
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
this.#defaults = defaults
|
|
135
193
|
this.#applyDefaults()
|
|
136
|
-
|
|
137
|
-
this.#
|
|
138
|
-
this.#
|
|
139
|
-
this.#
|
|
194
|
+
// TODO: Update origin documentation to list all valid sources. Add local_stable_config and fleet_stable_config.
|
|
195
|
+
this.#applyEnvs(getEnvironmentVariables(this.stableConfig.localEntries, true), 'local_stable_config')
|
|
196
|
+
this.#applyEnvs(getEnvironmentVariables(undefined, true), 'env_var')
|
|
197
|
+
this.#applyEnvs(getEnvironmentVariables(this.stableConfig.fleetEntries, true), 'fleet_stable_config')
|
|
198
|
+
|
|
199
|
+
// Experimental options are applied first, so they can be overridden by non-experimental options.
|
|
200
|
+
// TODO: When using programmatic options, check if there is a higher
|
|
201
|
+
// priority name in the same options object. Use the highest priority name.
|
|
202
|
+
const { experimental, ...rest } = options
|
|
203
|
+
if (experimental) {
|
|
204
|
+
// @ts-expect-error - Difficult to type this correctly.
|
|
205
|
+
this.#applyOptions(experimental, 'code', 'experimental')
|
|
206
|
+
}
|
|
207
|
+
this.#applyOptions(rest, 'code')
|
|
140
208
|
this.#applyCalculated()
|
|
141
|
-
this.#merge()
|
|
142
209
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
})
|
|
210
|
+
warnWrongOtelSettings()
|
|
211
|
+
|
|
212
|
+
if (this.gitMetadataEnabled) {
|
|
213
|
+
this.#loadGitMetadata()
|
|
214
|
+
}
|
|
149
215
|
|
|
150
|
-
|
|
216
|
+
parseErrors.clear()
|
|
217
|
+
}
|
|
151
218
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
})
|
|
219
|
+
#applyDefaults () {
|
|
220
|
+
for (const [name, value] of Object.entries(defaults)) {
|
|
221
|
+
set(this, name, value)
|
|
156
222
|
}
|
|
223
|
+
}
|
|
157
224
|
|
|
158
|
-
|
|
159
|
-
|
|
225
|
+
/**
|
|
226
|
+
* @param {import('./helper').TracerEnv} envs
|
|
227
|
+
* @param {'env_var' | 'local_stable_config' | 'fleet_stable_config'} source
|
|
228
|
+
*/
|
|
229
|
+
#applyEnvs (envs, source) {
|
|
230
|
+
for (const [name, value] of Object.entries(envs)) {
|
|
231
|
+
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
|
+
const parsed = entry.parser(value, name, source)
|
|
249
|
+
const transformed = parsed !== undefined && entry.transformer ? entry.transformer(parsed, name, source) : parsed
|
|
250
|
+
const rawValue = transformed !== null && typeof transformed === 'object' ? value : parsed
|
|
251
|
+
setAndTrack(this, entry.property ?? name, transformed, rawValue, source)
|
|
160
252
|
}
|
|
161
253
|
}
|
|
162
254
|
|
|
163
|
-
|
|
164
|
-
|
|
255
|
+
/**
|
|
256
|
+
* @param {TracerOptions} options
|
|
257
|
+
* @param {'code' | 'remote_config'} source
|
|
258
|
+
* @param {string} [root]
|
|
259
|
+
*/
|
|
260
|
+
#applyOptions (options, source, root = '') {
|
|
261
|
+
for (const [name, value] of Object.entries(options)) {
|
|
262
|
+
const fullName = root ? `${root}.${name}` : name
|
|
263
|
+
let entry = optionsTable[fullName]
|
|
264
|
+
if (!entry) {
|
|
265
|
+
// TODO: Fix this by by changing remote config to use env styles.
|
|
266
|
+
if (name !== 'tracing' || source !== 'remote_config') {
|
|
267
|
+
log.warn('Unknown option %s with value %o', fullName, value)
|
|
268
|
+
continue
|
|
269
|
+
}
|
|
270
|
+
// @ts-expect-error - The entry is defined in the configurationsTable.
|
|
271
|
+
entry = configurationsTable.tracing
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (entry.nestedProperties) {
|
|
275
|
+
let matched = false
|
|
276
|
+
if (typeof value === 'object' && value !== null) {
|
|
277
|
+
for (const nestedProperty of entry.nestedProperties) {
|
|
278
|
+
// WARNING: if the property name might be part of the value we look at, this could conflict!
|
|
279
|
+
// Defining an option that receives an object as value may not contain a property that is also
|
|
280
|
+
// potentially a nested property!
|
|
281
|
+
if (Object.hasOwn(value, nestedProperty)) {
|
|
282
|
+
this.#applyOptions(value, source, fullName)
|
|
283
|
+
matched = true
|
|
284
|
+
break
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (matched) {
|
|
289
|
+
continue
|
|
290
|
+
}
|
|
291
|
+
if (entry.option) {
|
|
292
|
+
entry = entry.option
|
|
293
|
+
} else {
|
|
294
|
+
if (fullName === 'tracePropagationStyle') {
|
|
295
|
+
// TracePropagationStyle is special. It is a single option that is used to set both inject and extract.
|
|
296
|
+
// @ts-expect-error - Difficult to type this correctly.
|
|
297
|
+
this.#applyOptions({ inject: value, extract: value }, source, 'tracePropagationStyle')
|
|
298
|
+
} else {
|
|
299
|
+
log.warn('Unknown option %s with value %o', fullName, value)
|
|
300
|
+
}
|
|
301
|
+
continue
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
// TODO: Coerce mismatched types to the expected type, if possible. E.g., strings <> numbers
|
|
305
|
+
const transformed = value !== undefined && entry.transformer ? entry.transformer(value, fullName, source) : value
|
|
306
|
+
setAndTrack(this, entry.property, transformed, value, source)
|
|
307
|
+
}
|
|
165
308
|
}
|
|
166
309
|
|
|
167
310
|
/**
|
|
168
311
|
* Set the configuration with remote config settings.
|
|
169
312
|
* Applies remote configuration, recalculates derived values, and merges all configuration sources.
|
|
170
313
|
*
|
|
171
|
-
* @param {
|
|
314
|
+
* @param {TracerOptions|null} options - Configurations received via Remote
|
|
172
315
|
* Config or null to reset all remote configuration
|
|
173
316
|
*/
|
|
174
317
|
setRemoteConfig (options) {
|
|
175
318
|
// Clear all RC-managed fields to ensure previous values don't persist.
|
|
176
319
|
// State is instead managed by the `RCClientLibConfigManager` class
|
|
177
|
-
this
|
|
178
|
-
this.#remoteUnprocessed = {}
|
|
320
|
+
undo(this, 'remote_config')
|
|
179
321
|
|
|
180
322
|
// Special case: if options is null, nothing to apply
|
|
181
323
|
// This happens when all remote configs are removed
|
|
182
324
|
if (options !== null) {
|
|
183
|
-
this.#
|
|
325
|
+
this.#applyOptions(options, 'remote_config')
|
|
184
326
|
}
|
|
185
327
|
|
|
186
328
|
this.#applyCalculated()
|
|
187
|
-
this.#merge()
|
|
188
329
|
}
|
|
189
330
|
|
|
190
|
-
// TODO: Remove the `updateOptions` method. We don't want to support updating the config this way
|
|
191
331
|
/**
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* @deprecated This method should not be used and will be removed in a future version.
|
|
195
|
-
* @param {object} options - Configuration options to apply (same format as tracer init options)
|
|
332
|
+
* @param {ConfigPath} name
|
|
196
333
|
*/
|
|
197
|
-
updateOptions (options) {
|
|
198
|
-
this.#applyOptions(options)
|
|
199
|
-
this.#applyCalculated()
|
|
200
|
-
this.#merge()
|
|
201
|
-
}
|
|
202
|
-
|
|
203
334
|
getOrigin (name) {
|
|
204
|
-
|
|
205
|
-
const value = container[name]
|
|
206
|
-
if (value != null || container === this.#defaults) {
|
|
207
|
-
return origin
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
#getSourcesInOrder () {
|
|
213
|
-
return [
|
|
214
|
-
{ container: this.#remote, origin: 'remote_config', unprocessed: this.#remoteUnprocessed },
|
|
215
|
-
{ container: this.#options, origin: 'code', unprocessed: this.#optsUnprocessed },
|
|
216
|
-
{ container: this.#fleetStableConfig, origin: 'fleet_stable_config' },
|
|
217
|
-
{ container: this.#env, origin: 'env_var', unprocessed: this.#envUnprocessed },
|
|
218
|
-
{ container: this.#localStableConfig, origin: 'local_stable_config' },
|
|
219
|
-
{ container: this.#calculated, origin: 'calculated' },
|
|
220
|
-
{ container: this.#defaults, origin: 'default' },
|
|
221
|
-
]
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
#applyStableConfig (config, obj) {
|
|
225
|
-
this.#applyConfigValues(config, obj, {})
|
|
335
|
+
return trackedConfigOrigins.get(name) ?? 'default'
|
|
226
336
|
}
|
|
227
337
|
|
|
228
|
-
//
|
|
229
|
-
#
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if (
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
338
|
+
// Handles values calculated from a mixture of options and env vars
|
|
339
|
+
#applyCalculated () {
|
|
340
|
+
undo(this, 'calculated')
|
|
341
|
+
|
|
342
|
+
if (this.DD_CIVISIBILITY_AGENTLESS_URL ||
|
|
343
|
+
this.url ||
|
|
344
|
+
os.type() !== 'Windows_NT' &&
|
|
345
|
+
!trackedConfigOrigins.has('hostname') &&
|
|
346
|
+
!trackedConfigOrigins.has('port') &&
|
|
347
|
+
!this.DD_CIVISIBILITY_AGENTLESS_ENABLED &&
|
|
348
|
+
fs.existsSync('/var/run/datadog/apm.socket')) {
|
|
349
|
+
setAndTrack(
|
|
350
|
+
this,
|
|
351
|
+
'url',
|
|
352
|
+
new URL(this.DD_CIVISIBILITY_AGENTLESS_URL || this.url || 'unix:///var/run/datadog/apm.socket')
|
|
353
|
+
)
|
|
239
354
|
}
|
|
240
355
|
|
|
241
|
-
if (
|
|
242
|
-
|
|
356
|
+
if (this.isCiVisibility) {
|
|
357
|
+
setAndTrack(this, 'isServiceUserProvided', trackedConfigOrigins.has('service'))
|
|
358
|
+
this.tags[ORIGIN_KEY] = 'ciapp-test'
|
|
243
359
|
}
|
|
244
|
-
|
|
360
|
+
// Compute OTLP logs and metrics URLs to send payloads to the active Datadog Agent
|
|
361
|
+
const agentHostname = this.hostname || /** @type {URL} */ (this.url).hostname
|
|
245
362
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
363
|
+
if (!trackedConfigOrigins.has('dogstatsd.hostname')) {
|
|
364
|
+
setAndTrack(this, 'dogstatsd.hostname', agentHostname)
|
|
365
|
+
}
|
|
366
|
+
// Disable log injection when OTEL logs are enabled
|
|
367
|
+
// OTEL logs and DD log injection are mutually exclusive
|
|
368
|
+
if (this.otelLogsEnabled) {
|
|
369
|
+
setAndTrack(this, 'logInjection', false)
|
|
370
|
+
}
|
|
371
|
+
if (this.otelMetricsEnabled &&
|
|
372
|
+
trackedConfigOrigins.has('OTEL_METRICS_EXPORTER') &&
|
|
373
|
+
this.OTEL_METRICS_EXPORTER === 'none') {
|
|
374
|
+
setAndTrack(this, 'otelMetricsEnabled', false)
|
|
375
|
+
}
|
|
249
376
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
AWS_LAMBDA_FUNCTION_NAME,
|
|
253
|
-
DD_AGENT_HOST,
|
|
254
|
-
DD_AI_GUARD_ENABLED,
|
|
255
|
-
DD_AI_GUARD_ENDPOINT,
|
|
256
|
-
DD_AI_GUARD_MAX_CONTENT_SIZE,
|
|
257
|
-
DD_AI_GUARD_MAX_MESSAGES_LENGTH,
|
|
258
|
-
DD_AI_GUARD_TIMEOUT,
|
|
259
|
-
DD_API_KEY,
|
|
260
|
-
DD_API_SECURITY_ENABLED,
|
|
261
|
-
DD_API_SECURITY_SAMPLE_DELAY,
|
|
262
|
-
DD_API_SECURITY_ENDPOINT_COLLECTION_ENABLED,
|
|
263
|
-
DD_API_SECURITY_ENDPOINT_COLLECTION_MESSAGE_LIMIT,
|
|
264
|
-
DD_API_SECURITY_DOWNSTREAM_BODY_ANALYSIS_SAMPLE_RATE,
|
|
265
|
-
DD_API_SECURITY_MAX_DOWNSTREAM_REQUEST_BODY_ANALYSIS,
|
|
266
|
-
DD_APM_TRACING_ENABLED,
|
|
267
|
-
DD_APP_KEY,
|
|
268
|
-
DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE,
|
|
269
|
-
DD_APPSEC_COLLECT_ALL_HEADERS,
|
|
270
|
-
DD_APPSEC_ENABLED,
|
|
271
|
-
DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON,
|
|
272
|
-
DD_APPSEC_HEADER_COLLECTION_REDACTION_ENABLED,
|
|
273
|
-
DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML,
|
|
274
|
-
DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON,
|
|
275
|
-
DD_APPSEC_MAX_COLLECTED_HEADERS,
|
|
276
|
-
DD_APPSEC_MAX_STACK_TRACES,
|
|
277
|
-
DD_APPSEC_MAX_STACK_TRACE_DEPTH,
|
|
278
|
-
DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP,
|
|
279
|
-
DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP,
|
|
280
|
-
DD_APPSEC_RULES,
|
|
281
|
-
DD_APPSEC_SCA_ENABLED,
|
|
282
|
-
DD_APPSEC_STACK_TRACE_ENABLED,
|
|
283
|
-
DD_APPSEC_RASP_ENABLED,
|
|
284
|
-
DD_APPSEC_RASP_COLLECT_REQUEST_BODY,
|
|
285
|
-
DD_APPSEC_TRACE_RATE_LIMIT,
|
|
286
|
-
DD_APPSEC_WAF_TIMEOUT,
|
|
287
|
-
DD_CRASHTRACKING_ENABLED,
|
|
288
|
-
DD_CODE_ORIGIN_FOR_SPANS_ENABLED,
|
|
289
|
-
DD_CODE_ORIGIN_FOR_SPANS_EXPERIMENTAL_EXIT_SPANS_ENABLED,
|
|
290
|
-
DD_DATA_STREAMS_ENABLED,
|
|
291
|
-
DD_DBM_PROPAGATION_MODE,
|
|
292
|
-
DD_DBM_INJECT_SQL_BASEHASH,
|
|
293
|
-
DD_DOGSTATSD_HOST,
|
|
294
|
-
DD_DOGSTATSD_PORT,
|
|
295
|
-
DD_DYNAMIC_INSTRUMENTATION_CAPTURE_TIMEOUT_MS,
|
|
296
|
-
DD_DYNAMIC_INSTRUMENTATION_ENABLED,
|
|
297
|
-
DD_DYNAMIC_INSTRUMENTATION_PROBE_FILE,
|
|
298
|
-
DD_DYNAMIC_INSTRUMENTATION_REDACTED_IDENTIFIERS,
|
|
299
|
-
DD_DYNAMIC_INSTRUMENTATION_REDACTION_EXCLUDED_IDENTIFIERS,
|
|
300
|
-
DD_DYNAMIC_INSTRUMENTATION_UPLOAD_INTERVAL_SECONDS,
|
|
301
|
-
DD_ENV,
|
|
302
|
-
DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED,
|
|
303
|
-
DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED,
|
|
304
|
-
DD_PROFILING_ENABLED,
|
|
305
|
-
DD_GRPC_CLIENT_ERROR_STATUSES,
|
|
306
|
-
DD_GRPC_SERVER_ERROR_STATUSES,
|
|
307
|
-
DD_HEAP_SNAPSHOT_COUNT,
|
|
308
|
-
DD_HEAP_SNAPSHOT_DESTINATION,
|
|
309
|
-
DD_HEAP_SNAPSHOT_INTERVAL,
|
|
310
|
-
DD_IAST_DB_ROWS_TO_TAINT,
|
|
311
|
-
DD_IAST_DEDUPLICATION_ENABLED,
|
|
312
|
-
DD_IAST_ENABLED,
|
|
313
|
-
DD_IAST_MAX_CONCURRENT_REQUESTS,
|
|
314
|
-
DD_IAST_MAX_CONTEXT_OPERATIONS,
|
|
315
|
-
DD_IAST_REDACTION_ENABLED,
|
|
316
|
-
DD_IAST_REDACTION_NAME_PATTERN,
|
|
317
|
-
DD_IAST_REDACTION_VALUE_PATTERN,
|
|
318
|
-
DD_IAST_REQUEST_SAMPLING,
|
|
319
|
-
DD_IAST_SECURITY_CONTROLS_CONFIGURATION,
|
|
320
|
-
DD_IAST_TELEMETRY_VERBOSITY,
|
|
321
|
-
DD_IAST_STACK_TRACE_ENABLED,
|
|
322
|
-
DD_INJECTION_ENABLED,
|
|
323
|
-
DD_INJECT_FORCE,
|
|
324
|
-
DD_ENABLE_NX_SERVICE_NAME,
|
|
325
|
-
DD_INSTRUMENTATION_TELEMETRY_ENABLED,
|
|
326
|
-
DD_INSTRUMENTATION_CONFIG_ID,
|
|
327
|
-
DD_LOGS_INJECTION,
|
|
328
|
-
DD_LOGS_OTEL_ENABLED,
|
|
329
|
-
DD_METRICS_OTEL_ENABLED,
|
|
330
|
-
DD_LANGCHAIN_SPAN_CHAR_LIMIT,
|
|
331
|
-
DD_LANGCHAIN_SPAN_PROMPT_COMPLETION_SAMPLE_RATE,
|
|
332
|
-
DD_LLMOBS_AGENTLESS_ENABLED,
|
|
333
|
-
DD_LLMOBS_ENABLED,
|
|
334
|
-
DD_LLMOBS_ML_APP,
|
|
335
|
-
DD_OPENAI_LOGS_ENABLED,
|
|
336
|
-
DD_OPENAI_SPAN_CHAR_LIMIT,
|
|
337
|
-
DD_PROFILING_EXPORTERS,
|
|
338
|
-
DD_PROFILING_SOURCE_MAP,
|
|
339
|
-
DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD,
|
|
340
|
-
DD_INSTRUMENTATION_INSTALL_ID,
|
|
341
|
-
DD_INSTRUMENTATION_INSTALL_TIME,
|
|
342
|
-
DD_INSTRUMENTATION_INSTALL_TYPE,
|
|
343
|
-
DD_REMOTE_CONFIGURATION_ENABLED,
|
|
344
|
-
DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS,
|
|
345
|
-
DD_RUNTIME_METRICS_ENABLED,
|
|
346
|
-
DD_RUNTIME_METRICS_EVENT_LOOP_ENABLED,
|
|
347
|
-
DD_RUNTIME_METRICS_GC_ENABLED,
|
|
348
|
-
DD_SERVICE,
|
|
349
|
-
DD_SERVICE_MAPPING,
|
|
350
|
-
DD_SITE,
|
|
351
|
-
DD_SPAN_SAMPLING_RULES,
|
|
352
|
-
DD_SPAN_SAMPLING_RULES_FILE,
|
|
353
|
-
DD_TAGS,
|
|
354
|
-
DD_TELEMETRY_DEBUG,
|
|
355
|
-
DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED,
|
|
356
|
-
DD_TELEMETRY_HEARTBEAT_INTERVAL,
|
|
357
|
-
DD_TELEMETRY_LOG_COLLECTION_ENABLED,
|
|
358
|
-
DD_TELEMETRY_METRICS_ENABLED,
|
|
359
|
-
DD_TEST_TIA_KEEP_COV_CONFIG,
|
|
360
|
-
DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED,
|
|
361
|
-
DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED,
|
|
362
|
-
DD_TRACE_AGENT_PORT,
|
|
363
|
-
DD_TRACE_AGENT_PROTOCOL_VERSION,
|
|
364
|
-
DD_TRACE_AWS_ADD_SPAN_POINTERS,
|
|
365
|
-
DD_TRACE_BAGGAGE_MAX_BYTES,
|
|
366
|
-
DD_TRACE_BAGGAGE_MAX_ITEMS,
|
|
367
|
-
DD_TRACE_BAGGAGE_TAG_KEYS,
|
|
368
|
-
DD_TRACE_CLIENT_IP_ENABLED,
|
|
369
|
-
DD_TRACE_CLIENT_IP_HEADER,
|
|
370
|
-
DD_TRACE_CLOUD_REQUEST_PAYLOAD_TAGGING,
|
|
371
|
-
DD_TRACE_CLOUD_RESPONSE_PAYLOAD_TAGGING,
|
|
372
|
-
DD_TRACE_CLOUD_PAYLOAD_TAGGING_MAX_DEPTH,
|
|
373
|
-
DD_TRACE_DYNAMODB_TABLE_PRIMARY_KEYS,
|
|
374
|
-
DD_TRACE_ENABLED,
|
|
375
|
-
DD_TRACE_EXPERIMENTAL_EXPORTER,
|
|
376
|
-
DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
|
|
377
|
-
DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED,
|
|
378
|
-
DD_TRACE_GIT_METADATA_ENABLED,
|
|
379
|
-
DD_TRACE_GRAPHQL_ERROR_EXTENSIONS,
|
|
380
|
-
DD_TRACE_HEADER_TAGS,
|
|
381
|
-
DD_TRACE_LEGACY_BAGGAGE_ENABLED,
|
|
382
|
-
DD_TRACE_MEMCACHED_COMMAND_ENABLED,
|
|
383
|
-
DD_TRACE_MIDDLEWARE_TRACING_ENABLED,
|
|
384
|
-
DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
|
|
385
|
-
DD_TRACE_PARTIAL_FLUSH_MIN_SPANS,
|
|
386
|
-
DD_TRACE_FLUSH_INTERVAL,
|
|
387
|
-
DD_TRACE_PEER_SERVICE_MAPPING,
|
|
388
|
-
DD_TRACE_PROPAGATION_EXTRACT_FIRST,
|
|
389
|
-
DD_TRACE_PROPAGATION_BEHAVIOR_EXTRACT,
|
|
390
|
-
DD_TRACE_PROPAGATION_STYLE,
|
|
391
|
-
DD_TRACE_PROPAGATION_STYLE_INJECT,
|
|
392
|
-
DD_TRACE_PROPAGATION_STYLE_EXTRACT,
|
|
393
|
-
DD_TRACE_RATE_LIMIT,
|
|
394
|
-
DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED,
|
|
395
|
-
DD_TRACE_REPORT_HOSTNAME,
|
|
396
|
-
DD_TRACE_RESOURCE_RENAMING_ENABLED,
|
|
397
|
-
DD_TRACE_SAMPLE_RATE,
|
|
398
|
-
DD_TRACE_SAMPLING_RULES,
|
|
399
|
-
DD_TRACE_SCOPE,
|
|
400
|
-
DD_TRACE_SPAN_ATTRIBUTE_SCHEMA,
|
|
401
|
-
DD_TRACE_SPAN_LEAK_DEBUG,
|
|
402
|
-
DD_TRACE_STARTUP_LOGS,
|
|
403
|
-
DD_TRACE_TAGS,
|
|
404
|
-
DD_TRACE_WEBSOCKET_MESSAGES_ENABLED,
|
|
405
|
-
DD_TRACE_WEBSOCKET_MESSAGES_INHERIT_SAMPLING,
|
|
406
|
-
DD_TRACE_WEBSOCKET_MESSAGES_SEPARATE_TRACES,
|
|
407
|
-
DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
|
|
408
|
-
DD_TRACING_ENABLED,
|
|
409
|
-
DD_VERSION,
|
|
410
|
-
DD_VERTEXAI_SPAN_PROMPT_COMPLETION_SAMPLE_RATE,
|
|
411
|
-
DD_VERTEXAI_SPAN_CHAR_LIMIT,
|
|
412
|
-
DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED,
|
|
413
|
-
DD_TRACE_NATIVE_SPAN_EVENTS,
|
|
414
|
-
OTEL_METRICS_EXPORTER,
|
|
415
|
-
OTEL_PROPAGATORS,
|
|
416
|
-
OTEL_RESOURCE_ATTRIBUTES,
|
|
417
|
-
OTEL_SERVICE_NAME,
|
|
418
|
-
OTEL_TRACES_SAMPLER,
|
|
419
|
-
OTEL_TRACES_SAMPLER_ARG,
|
|
420
|
-
DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED,
|
|
421
|
-
DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS,
|
|
422
|
-
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
|
|
423
|
-
OTEL_EXPORTER_OTLP_LOGS_HEADERS,
|
|
424
|
-
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL,
|
|
425
|
-
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT,
|
|
426
|
-
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,
|
|
427
|
-
OTEL_EXPORTER_OTLP_METRICS_HEADERS,
|
|
428
|
-
OTEL_EXPORTER_OTLP_METRICS_PROTOCOL,
|
|
429
|
-
OTEL_EXPORTER_OTLP_METRICS_TIMEOUT,
|
|
430
|
-
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE,
|
|
431
|
-
OTEL_METRIC_EXPORT_TIMEOUT,
|
|
432
|
-
OTEL_EXPORTER_OTLP_PROTOCOL,
|
|
433
|
-
OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
434
|
-
OTEL_EXPORTER_OTLP_HEADERS,
|
|
435
|
-
OTEL_EXPORTER_OTLP_TIMEOUT,
|
|
436
|
-
OTEL_BSP_SCHEDULE_DELAY,
|
|
437
|
-
OTEL_BSP_MAX_EXPORT_BATCH_SIZE,
|
|
438
|
-
OTEL_BSP_MAX_QUEUE_SIZE,
|
|
439
|
-
OTEL_METRIC_EXPORT_INTERVAL,
|
|
440
|
-
NX_TASK_TARGET_PROJECT,
|
|
441
|
-
} = source
|
|
442
|
-
|
|
443
|
-
const tags = {}
|
|
444
|
-
|
|
445
|
-
tagger.add(tags, parseSpaceSeparatedTags(handleOtel(OTEL_RESOURCE_ATTRIBUTES)))
|
|
446
|
-
tagger.add(tags, parseSpaceSeparatedTags(DD_TAGS))
|
|
447
|
-
tagger.add(tags, DD_TRACE_TAGS)
|
|
448
|
-
|
|
449
|
-
Object.assign(this.#parsedDdTags, tags)
|
|
450
|
-
|
|
451
|
-
setString(target, 'apiKey', DD_API_KEY)
|
|
452
|
-
setBoolean(target, 'otelLogsEnabled', DD_LOGS_OTEL_ENABLED)
|
|
453
|
-
// Set OpenTelemetry logs configuration with specific _LOGS_ vars taking precedence over generic _EXPORTERS_ vars
|
|
454
|
-
if (OTEL_EXPORTER_OTLP_ENDPOINT) {
|
|
455
|
-
// Only set if there's a custom URL, otherwise let calc phase handle the default
|
|
456
|
-
setString(target, 'otelUrl', OTEL_EXPORTER_OTLP_ENDPOINT)
|
|
377
|
+
if (this.telemetry.heartbeatInterval) {
|
|
378
|
+
setAndTrack(this, 'telemetry.heartbeatInterval', Math.floor(this.telemetry.heartbeatInterval * 1000))
|
|
457
379
|
}
|
|
458
|
-
if (
|
|
459
|
-
|
|
380
|
+
if (this.telemetry.extendedHeartbeatInterval) {
|
|
381
|
+
setAndTrack(this, 'telemetry.extendedHeartbeatInterval',
|
|
382
|
+
Math.floor(this.telemetry.extendedHeartbeatInterval * 1000))
|
|
460
383
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
if (otelTimeout !== undefined) {
|
|
467
|
-
target.otelTimeout = otelTimeout
|
|
384
|
+
|
|
385
|
+
// Enable resourceRenamingEnabled when appsec is enabled and only
|
|
386
|
+
// if DD_TRACE_RESOURCE_RENAMING_ENABLED is not explicitly set
|
|
387
|
+
if (!trackedConfigOrigins.has('resourceRenamingEnabled')) {
|
|
388
|
+
setAndTrack(this, 'resourceRenamingEnabled', this.appsec.enabled ?? false)
|
|
468
389
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
if (otelBatchTimeout !== undefined) {
|
|
473
|
-
target.otelBatchTimeout = otelBatchTimeout
|
|
390
|
+
|
|
391
|
+
if (!trackedConfigOrigins.has('spanComputePeerService') && this.spanAttributeSchema !== 'v0') {
|
|
392
|
+
setAndTrack(this, 'spanComputePeerService', true)
|
|
474
393
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
target,
|
|
481
|
-
'otelMetricsEnabled',
|
|
482
|
-
DD_METRICS_OTEL_ENABLED && isTrue(DD_METRICS_OTEL_ENABLED) && otelMetricsExporterEnabled
|
|
483
|
-
)
|
|
484
|
-
// Set OpenTelemetry metrics configuration with specific _METRICS_ vars
|
|
485
|
-
// taking precedence over generic _EXPORTERS_ vars
|
|
486
|
-
if (OTEL_EXPORTER_OTLP_ENDPOINT || OTEL_EXPORTER_OTLP_METRICS_ENDPOINT) {
|
|
487
|
-
setString(target, 'otelMetricsUrl', OTEL_EXPORTER_OTLP_METRICS_ENDPOINT || target.otelUrl)
|
|
394
|
+
|
|
395
|
+
if (!this.apmTracingEnabled) {
|
|
396
|
+
setAndTrack(this, 'stats.enabled', false)
|
|
397
|
+
} else if (!trackedConfigOrigins.has('stats.enabled')) {
|
|
398
|
+
setAndTrack(this, 'stats.enabled', getIsGCPFunction() || getIsAzureFunction())
|
|
488
399
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
target.otelMetricsExportInterval = nonNegInt(OTEL_METRIC_EXPORT_INTERVAL, 'OTEL_METRIC_EXPORT_INTERVAL', false)
|
|
495
|
-
|
|
496
|
-
// Parse temporality preference (default to DELTA for Datadog)
|
|
497
|
-
if (OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE) {
|
|
498
|
-
const temporalityPref = OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE.toUpperCase()
|
|
499
|
-
if (['DELTA', 'CUMULATIVE', 'LOWMEMORY'].includes(temporalityPref)) {
|
|
500
|
-
setString(target, 'otelMetricsTemporalityPreference', temporalityPref)
|
|
400
|
+
|
|
401
|
+
// TODO: Remove the experimental env vars as a major or deprecate the option?
|
|
402
|
+
if (this.experimental?.b3) {
|
|
403
|
+
if (!this.tracePropagationStyle.inject.includes('b3')) {
|
|
404
|
+
this.tracePropagationStyle.inject.push('b3')
|
|
501
405
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
target,
|
|
505
|
-
'apmTracingEnabled',
|
|
506
|
-
DD_APM_TRACING_ENABLED ??
|
|
507
|
-
(DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED && isFalse(DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED))
|
|
508
|
-
)
|
|
509
|
-
setBoolean(target, 'propagateProcessTags.enabled', DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED)
|
|
510
|
-
setString(target, 'appKey', DD_APP_KEY)
|
|
511
|
-
setBoolean(target, 'appsec.apiSecurity.enabled', DD_API_SECURITY_ENABLED && isTrue(DD_API_SECURITY_ENABLED))
|
|
512
|
-
target['appsec.apiSecurity.sampleDelay'] = maybeFloat(DD_API_SECURITY_SAMPLE_DELAY)
|
|
513
|
-
setBoolean(target, 'appsec.apiSecurity.endpointCollectionEnabled',
|
|
514
|
-
DD_API_SECURITY_ENDPOINT_COLLECTION_ENABLED)
|
|
515
|
-
target['appsec.apiSecurity.endpointCollectionMessageLimit'] =
|
|
516
|
-
maybeInt(DD_API_SECURITY_ENDPOINT_COLLECTION_MESSAGE_LIMIT)
|
|
517
|
-
target['appsec.blockedTemplateGraphql'] = maybeFile(DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON)
|
|
518
|
-
target['appsec.blockedTemplateHtml'] = maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML)
|
|
519
|
-
unprocessedTarget['appsec.blockedTemplateHtml'] = DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML
|
|
520
|
-
target['appsec.blockedTemplateJson'] = maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON)
|
|
521
|
-
unprocessedTarget['appsec.blockedTemplateJson'] = DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON
|
|
522
|
-
setBoolean(target, 'appsec.enabled', DD_APPSEC_ENABLED)
|
|
523
|
-
setString(target, 'appsec.eventTracking.mode', DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE)
|
|
524
|
-
// TODO appsec.extendedHeadersCollection are deprecated, to delete in a major
|
|
525
|
-
setBoolean(target, 'appsec.extendedHeadersCollection.enabled', DD_APPSEC_COLLECT_ALL_HEADERS)
|
|
526
|
-
setBoolean(
|
|
527
|
-
target,
|
|
528
|
-
'appsec.extendedHeadersCollection.redaction',
|
|
529
|
-
DD_APPSEC_HEADER_COLLECTION_REDACTION_ENABLED
|
|
530
|
-
)
|
|
531
|
-
target['appsec.extendedHeadersCollection.maxHeaders'] = maybeInt(DD_APPSEC_MAX_COLLECTED_HEADERS)
|
|
532
|
-
unprocessedTarget['appsec.extendedHeadersCollection.maxHeaders'] = DD_APPSEC_MAX_COLLECTED_HEADERS
|
|
533
|
-
setString(target, 'appsec.obfuscatorKeyRegex', DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP)
|
|
534
|
-
setString(target, 'appsec.obfuscatorValueRegex', DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP)
|
|
535
|
-
setBoolean(target, 'appsec.rasp.enabled', DD_APPSEC_RASP_ENABLED)
|
|
536
|
-
// TODO Deprecated, to delete in a major
|
|
537
|
-
setBoolean(target, 'appsec.rasp.bodyCollection', DD_APPSEC_RASP_COLLECT_REQUEST_BODY)
|
|
538
|
-
target['appsec.rateLimit'] = maybeInt(DD_APPSEC_TRACE_RATE_LIMIT)
|
|
539
|
-
unprocessedTarget['appsec.rateLimit'] = DD_APPSEC_TRACE_RATE_LIMIT
|
|
540
|
-
setString(target, 'appsec.rules', DD_APPSEC_RULES)
|
|
541
|
-
// DD_APPSEC_SCA_ENABLED is never used locally, but only sent to the backend
|
|
542
|
-
setBoolean(target, 'appsec.sca.enabled', DD_APPSEC_SCA_ENABLED)
|
|
543
|
-
setBoolean(target, 'appsec.stackTrace.enabled', DD_APPSEC_STACK_TRACE_ENABLED)
|
|
544
|
-
target['appsec.stackTrace.maxDepth'] = maybeInt(DD_APPSEC_MAX_STACK_TRACE_DEPTH)
|
|
545
|
-
unprocessedTarget['appsec.stackTrace.maxDepth'] = DD_APPSEC_MAX_STACK_TRACE_DEPTH
|
|
546
|
-
target['appsec.stackTrace.maxStackTraces'] = maybeInt(DD_APPSEC_MAX_STACK_TRACES)
|
|
547
|
-
unprocessedTarget['appsec.stackTrace.maxStackTraces'] = DD_APPSEC_MAX_STACK_TRACES
|
|
548
|
-
target['appsec.wafTimeout'] = maybeInt(DD_APPSEC_WAF_TIMEOUT)
|
|
549
|
-
unprocessedTarget['appsec.wafTimeout'] = DD_APPSEC_WAF_TIMEOUT
|
|
550
|
-
target['appsec.apiSecurity.downstreamBodyAnalysisSampleRate'] =
|
|
551
|
-
maybeFloat(DD_API_SECURITY_DOWNSTREAM_BODY_ANALYSIS_SAMPLE_RATE)
|
|
552
|
-
target['appsec.apiSecurity.maxDownstreamRequestBodyAnalysis'] =
|
|
553
|
-
maybeInt(DD_API_SECURITY_MAX_DOWNSTREAM_REQUEST_BODY_ANALYSIS)
|
|
554
|
-
target.baggageMaxBytes = DD_TRACE_BAGGAGE_MAX_BYTES
|
|
555
|
-
target.baggageMaxItems = DD_TRACE_BAGGAGE_MAX_ITEMS
|
|
556
|
-
setArray(target, 'baggageTagKeys', DD_TRACE_BAGGAGE_TAG_KEYS)
|
|
557
|
-
setBoolean(target, 'clientIpEnabled', DD_TRACE_CLIENT_IP_ENABLED)
|
|
558
|
-
setString(target, 'clientIpHeader', DD_TRACE_CLIENT_IP_HEADER?.toLowerCase())
|
|
559
|
-
if (DD_TRACE_CLOUD_REQUEST_PAYLOAD_TAGGING || DD_TRACE_CLOUD_RESPONSE_PAYLOAD_TAGGING) {
|
|
560
|
-
if (DD_TRACE_CLOUD_REQUEST_PAYLOAD_TAGGING) {
|
|
561
|
-
setBoolean(target, 'cloudPayloadTagging.requestsEnabled', true)
|
|
406
|
+
if (!this.tracePropagationStyle.extract.includes('b3')) {
|
|
407
|
+
this.tracePropagationStyle.extract.push('b3')
|
|
562
408
|
}
|
|
563
|
-
if (
|
|
564
|
-
|
|
409
|
+
if (!this.tracePropagationStyle.inject.includes('b3 single header')) {
|
|
410
|
+
this.tracePropagationStyle.inject.push('b3 single header')
|
|
565
411
|
}
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
)
|
|
570
|
-
|
|
571
|
-
if (DD_TRACE_CLOUD_PAYLOAD_TAGGING_MAX_DEPTH) {
|
|
572
|
-
target['cloudPayloadTagging.maxDepth'] = maybeInt(DD_TRACE_CLOUD_PAYLOAD_TAGGING_MAX_DEPTH)
|
|
573
|
-
}
|
|
574
|
-
setBoolean(target, 'crashtracking.enabled', DD_CRASHTRACKING_ENABLED)
|
|
575
|
-
setBoolean(target, 'codeOriginForSpans.enabled', DD_CODE_ORIGIN_FOR_SPANS_ENABLED)
|
|
576
|
-
setBoolean(
|
|
577
|
-
target,
|
|
578
|
-
'codeOriginForSpans.experimental.exit_spans.enabled',
|
|
579
|
-
DD_CODE_ORIGIN_FOR_SPANS_EXPERIMENTAL_EXIT_SPANS_ENABLED
|
|
580
|
-
)
|
|
581
|
-
setString(target, 'dbmPropagationMode', DD_DBM_PROPAGATION_MODE)
|
|
582
|
-
setBoolean(target, 'dbm.injectSqlBaseHash', DD_DBM_INJECT_SQL_BASEHASH)
|
|
583
|
-
setString(target, 'dogstatsd.hostname', DD_DOGSTATSD_HOST)
|
|
584
|
-
setString(target, 'dogstatsd.port', DD_DOGSTATSD_PORT)
|
|
585
|
-
setBoolean(target, 'dsmEnabled', DD_DATA_STREAMS_ENABLED)
|
|
586
|
-
target['dynamicInstrumentation.captureTimeoutMs'] = maybeInt(DD_DYNAMIC_INSTRUMENTATION_CAPTURE_TIMEOUT_MS)
|
|
587
|
-
unprocessedTarget['dynamicInstrumentation.captureTimeoutMs'] = DD_DYNAMIC_INSTRUMENTATION_CAPTURE_TIMEOUT_MS
|
|
588
|
-
setBoolean(target, 'dynamicInstrumentation.enabled', DD_DYNAMIC_INSTRUMENTATION_ENABLED)
|
|
589
|
-
setString(target, 'dynamicInstrumentation.probeFile', DD_DYNAMIC_INSTRUMENTATION_PROBE_FILE)
|
|
590
|
-
setArray(target, 'dynamicInstrumentation.redactedIdentifiers',
|
|
591
|
-
DD_DYNAMIC_INSTRUMENTATION_REDACTED_IDENTIFIERS)
|
|
592
|
-
setArray(
|
|
593
|
-
target,
|
|
594
|
-
'dynamicInstrumentation.redactionExcludedIdentifiers',
|
|
595
|
-
DD_DYNAMIC_INSTRUMENTATION_REDACTION_EXCLUDED_IDENTIFIERS
|
|
596
|
-
)
|
|
597
|
-
target['dynamicInstrumentation.uploadIntervalSeconds'] =
|
|
598
|
-
maybeFloat(DD_DYNAMIC_INSTRUMENTATION_UPLOAD_INTERVAL_SECONDS)
|
|
599
|
-
unprocessedTarget['dynamicInstrumentation.uploadInterval'] = DD_DYNAMIC_INSTRUMENTATION_UPLOAD_INTERVAL_SECONDS
|
|
600
|
-
setString(target, 'env', DD_ENV || tags.env)
|
|
601
|
-
setBoolean(
|
|
602
|
-
target,
|
|
603
|
-
'experimental.flaggingProvider.enabled',
|
|
604
|
-
DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED
|
|
605
|
-
)
|
|
606
|
-
if (DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS != null) {
|
|
607
|
-
target['experimental.flaggingProvider.initializationTimeoutMs'] =
|
|
608
|
-
maybeInt(DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS)
|
|
412
|
+
if (!this.tracePropagationStyle.extract.includes('b3 single header')) {
|
|
413
|
+
this.tracePropagationStyle.extract.push('b3 single header')
|
|
414
|
+
}
|
|
415
|
+
setAndTrack(this, 'tracePropagationStyle.inject', this.tracePropagationStyle.inject)
|
|
416
|
+
setAndTrack(this, 'tracePropagationStyle.extract', this.tracePropagationStyle.extract)
|
|
609
417
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
target['experimental.aiguard.maxContentSize'] = maybeInt(DD_AI_GUARD_MAX_CONTENT_SIZE)
|
|
614
|
-
unprocessedTarget['experimental.aiguard.maxContentSize'] = DD_AI_GUARD_MAX_CONTENT_SIZE
|
|
615
|
-
target['experimental.aiguard.maxMessagesLength'] = maybeInt(DD_AI_GUARD_MAX_MESSAGES_LENGTH)
|
|
616
|
-
unprocessedTarget['experimental.aiguard.maxMessagesLength'] = DD_AI_GUARD_MAX_MESSAGES_LENGTH
|
|
617
|
-
target['experimental.aiguard.timeout'] = maybeInt(DD_AI_GUARD_TIMEOUT)
|
|
618
|
-
unprocessedTarget['experimental.aiguard.timeout'] = DD_AI_GUARD_TIMEOUT
|
|
619
|
-
setBoolean(target, 'experimental.enableGetRumData', DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED)
|
|
620
|
-
setString(target, 'experimental.exporter', DD_TRACE_EXPERIMENTAL_EXPORTER)
|
|
621
|
-
if (AWS_LAMBDA_FUNCTION_NAME) {
|
|
622
|
-
target.flushInterval = 0
|
|
623
|
-
} else if (DD_TRACE_FLUSH_INTERVAL) {
|
|
624
|
-
target.flushInterval = maybeInt(DD_TRACE_FLUSH_INTERVAL)
|
|
418
|
+
|
|
419
|
+
if (getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') && !fs.existsSync(DATADOG_MINI_AGENT_PATH)) {
|
|
420
|
+
setAndTrack(this, 'flushInterval', 0)
|
|
625
421
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
setIntegerRangeSet(target, 'grpc.server.error.statuses', DD_GRPC_SERVER_ERROR_STATUSES)
|
|
631
|
-
setArray(target, 'headerTags', DD_TRACE_HEADER_TAGS)
|
|
632
|
-
target['heapSnapshot.count'] = maybeInt(DD_HEAP_SNAPSHOT_COUNT)
|
|
633
|
-
setString(target, 'heapSnapshot.destination', DD_HEAP_SNAPSHOT_DESTINATION)
|
|
634
|
-
target['heapSnapshot.interval'] = maybeInt(DD_HEAP_SNAPSHOT_INTERVAL)
|
|
635
|
-
setString(target, 'hostname', DD_AGENT_HOST)
|
|
636
|
-
target['iast.dbRowsToTaint'] = maybeInt(DD_IAST_DB_ROWS_TO_TAINT)
|
|
637
|
-
setBoolean(target, 'iast.deduplicationEnabled', DD_IAST_DEDUPLICATION_ENABLED)
|
|
638
|
-
setBoolean(target, 'iast.enabled', DD_IAST_ENABLED)
|
|
639
|
-
target['iast.maxConcurrentRequests'] = maybeInt(DD_IAST_MAX_CONCURRENT_REQUESTS)
|
|
640
|
-
unprocessedTarget['iast.maxConcurrentRequests'] = DD_IAST_MAX_CONCURRENT_REQUESTS
|
|
641
|
-
target['iast.maxContextOperations'] = maybeInt(DD_IAST_MAX_CONTEXT_OPERATIONS)
|
|
642
|
-
unprocessedTarget['iast.maxContextOperations'] = DD_IAST_MAX_CONTEXT_OPERATIONS
|
|
643
|
-
setBoolean(target, 'iast.redactionEnabled', DD_IAST_REDACTION_ENABLED && !isFalse(DD_IAST_REDACTION_ENABLED))
|
|
644
|
-
setString(target, 'iast.redactionNamePattern', DD_IAST_REDACTION_NAME_PATTERN)
|
|
645
|
-
setString(target, 'iast.redactionValuePattern', DD_IAST_REDACTION_VALUE_PATTERN)
|
|
646
|
-
const iastRequestSampling = maybeInt(DD_IAST_REQUEST_SAMPLING)
|
|
647
|
-
if (iastRequestSampling !== undefined && iastRequestSampling > -1 && iastRequestSampling < 101) {
|
|
648
|
-
target['iast.requestSampling'] = iastRequestSampling
|
|
422
|
+
|
|
423
|
+
if (!trackedConfigOrigins.has('apmTracingEnabled') &&
|
|
424
|
+
trackedConfigOrigins.has('experimental.appsec.standalone.enabled')) {
|
|
425
|
+
setAndTrack(this, 'apmTracingEnabled', !this.experimental.appsec.standalone.enabled)
|
|
649
426
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
setString(target, 'installSignature.type', DD_INSTRUMENTATION_INSTALL_TYPE)
|
|
657
|
-
// TODO: Why is DD_INJECTION_ENABLED a comma separated list?
|
|
658
|
-
setArray(target, 'injectionEnabled', DD_INJECTION_ENABLED)
|
|
659
|
-
if (DD_INJECTION_ENABLED !== undefined) {
|
|
660
|
-
setString(target, 'instrumentationSource', DD_INJECTION_ENABLED ? 'ssi' : 'manual')
|
|
427
|
+
|
|
428
|
+
if (this.cloudPayloadTagging?.request || this.cloudPayloadTagging?.response) {
|
|
429
|
+
setAndTrack(this, 'cloudPayloadTagging.rules', appendRules(
|
|
430
|
+
this.cloudPayloadTagging.request,
|
|
431
|
+
this.cloudPayloadTagging.response
|
|
432
|
+
))
|
|
661
433
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
setBoolean(target, 'gcpPubSubPushSubscriptionEnabled', enableGCPPubSubPushSubscription())
|
|
666
|
-
target['langchain.spanCharLimit'] = maybeInt(DD_LANGCHAIN_SPAN_CHAR_LIMIT)
|
|
667
|
-
target['langchain.spanPromptCompletionSampleRate'] = maybeFloat(DD_LANGCHAIN_SPAN_PROMPT_COMPLETION_SAMPLE_RATE)
|
|
668
|
-
setBoolean(target, 'legacyBaggageEnabled', DD_TRACE_LEGACY_BAGGAGE_ENABLED)
|
|
669
|
-
setBoolean(target, 'llmobs.agentlessEnabled', DD_LLMOBS_AGENTLESS_ENABLED)
|
|
670
|
-
setBoolean(target, 'llmobs.enabled', DD_LLMOBS_ENABLED)
|
|
671
|
-
setString(target, 'llmobs.mlApp', DD_LLMOBS_ML_APP)
|
|
672
|
-
setBoolean(target, 'logInjection', DD_LOGS_INJECTION)
|
|
673
|
-
// Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
|
|
674
|
-
setBoolean(target, 'memcachedCommandEnabled', DD_TRACE_MEMCACHED_COMMAND_ENABLED)
|
|
675
|
-
setBoolean(target, 'middlewareTracingEnabled', DD_TRACE_MIDDLEWARE_TRACING_ENABLED)
|
|
676
|
-
setBoolean(target, 'openAiLogsEnabled', DD_OPENAI_LOGS_ENABLED)
|
|
677
|
-
target['openai.spanCharLimit'] = maybeInt(DD_OPENAI_SPAN_CHAR_LIMIT)
|
|
678
|
-
unprocessedTarget.openaiSpanCharLimit = DD_OPENAI_SPAN_CHAR_LIMIT
|
|
679
|
-
if (DD_TRACE_PEER_SERVICE_MAPPING) {
|
|
680
|
-
target.peerServiceMapping = Object.fromEntries(
|
|
681
|
-
DD_TRACE_PEER_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
|
|
682
|
-
)
|
|
683
|
-
unprocessedTarget.peerServiceMapping = DD_TRACE_PEER_SERVICE_MAPPING
|
|
434
|
+
|
|
435
|
+
if (this.injectionEnabled) {
|
|
436
|
+
setAndTrack(this, 'instrumentationSource', 'ssi')
|
|
684
437
|
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
setString(target, 'profiling.exporters', DD_PROFILING_EXPORTERS)
|
|
689
|
-
setBoolean(target, 'profiling.sourceMap', DD_PROFILING_SOURCE_MAP && !isFalse(DD_PROFILING_SOURCE_MAP))
|
|
690
|
-
if (DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD) {
|
|
691
|
-
// This is only used in testing to not have to wait 30s
|
|
692
|
-
target['profiling.longLivedThreshold'] = Number(DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD)
|
|
438
|
+
|
|
439
|
+
if (!trackedConfigOrigins.has('runtimeMetrics.enabled') && this.OTEL_METRICS_EXPORTER === 'none') {
|
|
440
|
+
setAndTrack(this, 'runtimeMetrics.enabled', false)
|
|
693
441
|
}
|
|
694
442
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
setBoolean(target, 'remoteConfig.enabled', DD_REMOTE_CONFIGURATION_ENABLED)
|
|
698
|
-
target['remoteConfig.pollInterval'] = maybeFloat(DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS)
|
|
699
|
-
unprocessedTarget['remoteConfig.pollInterval'] = DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS
|
|
700
|
-
setBoolean(target, 'reportHostname', DD_TRACE_REPORT_HOSTNAME)
|
|
701
|
-
if (DD_TRACE_RESOURCE_RENAMING_ENABLED !== undefined) {
|
|
702
|
-
setBoolean(target, 'resourceRenamingEnabled', DD_TRACE_RESOURCE_RENAMING_ENABLED)
|
|
443
|
+
if (!trackedConfigOrigins.has('sampleRate') && trackedConfigOrigins.has('OTEL_TRACES_SAMPLER')) {
|
|
444
|
+
setAndTrack(this, 'sampleRate', getFromOtelSamplerMap(this.OTEL_TRACES_SAMPLER, this.OTEL_TRACES_SAMPLER_ARG))
|
|
703
445
|
}
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
setBoolean(target, 'runtimeMetrics.gc', DD_RUNTIME_METRICS_GC_ENABLED)
|
|
712
|
-
setBoolean(target, 'runtimeMetricsRuntimeId', DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED)
|
|
713
|
-
setArray(target, 'sampler.spanSamplingRules', reformatSpanSamplingRules(
|
|
714
|
-
maybeJsonFile(DD_SPAN_SAMPLING_RULES_FILE) ??
|
|
715
|
-
safeJsonParse(DD_SPAN_SAMPLING_RULES)
|
|
716
|
-
))
|
|
717
|
-
setUnit(
|
|
718
|
-
target,
|
|
719
|
-
'sampleRate',
|
|
720
|
-
DD_TRACE_SAMPLE_RATE || getFromOtelSamplerMap(OTEL_TRACES_SAMPLER, OTEL_TRACES_SAMPLER_ARG)
|
|
721
|
-
)
|
|
722
|
-
target['sampler.rateLimit'] = DD_TRACE_RATE_LIMIT
|
|
723
|
-
setSamplingRule(target, 'sampler.rules', safeJsonParse(DD_TRACE_SAMPLING_RULES))
|
|
724
|
-
unprocessedTarget['sampler.rules'] = DD_TRACE_SAMPLING_RULES
|
|
725
|
-
setString(target, 'scope', DD_TRACE_SCOPE)
|
|
726
|
-
// Priority:
|
|
727
|
-
// DD_SERVICE > tags.service > OTEL_SERVICE_NAME > NX_TASK_TARGET_PROJECT (if DD_ENABLE_NX_SERVICE_NAME) > default
|
|
728
|
-
let serviceName = DD_SERVICE || tags.service || OTEL_SERVICE_NAME
|
|
729
|
-
let isServiceNameInferred
|
|
730
|
-
if (!serviceName && NX_TASK_TARGET_PROJECT) {
|
|
731
|
-
if (isTrue(DD_ENABLE_NX_SERVICE_NAME)) {
|
|
732
|
-
isServiceNameInferred = true
|
|
733
|
-
serviceName = NX_TASK_TARGET_PROJECT
|
|
734
|
-
} else if (DD_MAJOR < 6) {
|
|
735
|
-
// Warn about v6 behavior change for Nx projects
|
|
736
|
-
log.warn(
|
|
737
|
-
// eslint-disable-next-line @stylistic/max-len
|
|
738
|
-
'NX_TASK_TARGET_PROJECT is set but no service name was configured. In v6, NX_TASK_TARGET_PROJECT will be used as the default service name. Set DD_ENABLE_NX_SERVICE_NAME=true to opt-in to this behavior now, or set a service name explicitly.'
|
|
739
|
-
)
|
|
446
|
+
|
|
447
|
+
if (this.DD_SPAN_SAMPLING_RULES_FILE) {
|
|
448
|
+
try {
|
|
449
|
+
// TODO: Should we log a warning in case this is defined next to spanSamplingRules?
|
|
450
|
+
setAndTrack(this, 'spanSamplingRules', transformers.toCamelCase(JSON.parse(this.DD_SPAN_SAMPLING_RULES_FILE)))
|
|
451
|
+
} catch (error) {
|
|
452
|
+
log.warn('Error reading span sampling rules file %s; %o', this.DD_SPAN_SAMPLING_RULES_FILE, error)
|
|
740
453
|
}
|
|
741
454
|
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
setString(target, 'site', DD_SITE)
|
|
750
|
-
if (DD_TRACE_SPAN_ATTRIBUTE_SCHEMA) {
|
|
751
|
-
setString(target, 'spanAttributeSchema', validateNamingVersion(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA))
|
|
752
|
-
unprocessedTarget.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
|
|
753
|
-
}
|
|
754
|
-
// 0: disabled, 1: logging, 2: garbage collection + logging
|
|
755
|
-
target.spanLeakDebug = maybeInt(DD_TRACE_SPAN_LEAK_DEBUG)
|
|
756
|
-
setBoolean(target, 'spanRemoveIntegrationFromService', DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED)
|
|
757
|
-
setBoolean(target, 'startupLogs', DD_TRACE_STARTUP_LOGS)
|
|
758
|
-
setTags(target, 'tags', tags)
|
|
759
|
-
target.tagsHeaderMaxLength = DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH
|
|
760
|
-
setBoolean(target, 'telemetry.enabled', DD_INSTRUMENTATION_TELEMETRY_ENABLED)
|
|
761
|
-
setString(target, 'instrumentation_config_id', DD_INSTRUMENTATION_CONFIG_ID)
|
|
762
|
-
setBoolean(target, 'telemetry.debug', DD_TELEMETRY_DEBUG)
|
|
763
|
-
setBoolean(target, 'telemetry.dependencyCollection', DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED)
|
|
764
|
-
target['telemetry.heartbeatInterval'] = maybeInt(Math.floor(DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000))
|
|
765
|
-
unprocessedTarget['telemetry.heartbeatInterval'] = DD_TELEMETRY_HEARTBEAT_INTERVAL
|
|
766
|
-
setBoolean(target, 'telemetry.logCollection', DD_TELEMETRY_LOG_COLLECTION_ENABLED)
|
|
767
|
-
setBoolean(target, 'telemetry.metrics', DD_TELEMETRY_METRICS_ENABLED)
|
|
768
|
-
setBoolean(target, 'isKeepingCoverageConfiguration', DD_TEST_TIA_KEEP_COV_CONFIG)
|
|
769
|
-
setBoolean(target, 'traceId128BitGenerationEnabled', DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
|
|
770
|
-
setBoolean(target, 'traceId128BitLoggingEnabled', DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
|
|
771
|
-
warnIfPropagationStyleConflict(
|
|
772
|
-
DD_TRACE_PROPAGATION_STYLE,
|
|
773
|
-
DD_TRACE_PROPAGATION_STYLE_INJECT,
|
|
774
|
-
DD_TRACE_PROPAGATION_STYLE_EXTRACT
|
|
775
|
-
)
|
|
776
|
-
if (DD_TRACE_PROPAGATION_STYLE !== undefined) {
|
|
777
|
-
setArray(target, 'tracePropagationStyle.inject', normalizePropagationStyle(DD_TRACE_PROPAGATION_STYLE))
|
|
778
|
-
setArray(target, 'tracePropagationStyle.extract', normalizePropagationStyle(DD_TRACE_PROPAGATION_STYLE))
|
|
779
|
-
}
|
|
780
|
-
if (DD_TRACE_PROPAGATION_STYLE_INJECT !== undefined) {
|
|
781
|
-
setArray(target, 'tracePropagationStyle.inject',
|
|
782
|
-
normalizePropagationStyle(DD_TRACE_PROPAGATION_STYLE_INJECT))
|
|
455
|
+
|
|
456
|
+
// All sampler options are tracked as individual values. No need to track the sampler object as a whole.
|
|
457
|
+
this.sampler = {
|
|
458
|
+
rules: this.samplingRules,
|
|
459
|
+
rateLimit: this.rateLimit,
|
|
460
|
+
sampleRate: this.sampleRate,
|
|
461
|
+
spanSamplingRules: this.spanSamplingRules,
|
|
783
462
|
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
463
|
+
|
|
464
|
+
// For LLMObs, we want to auto enable it when other llmobs options are defined.
|
|
465
|
+
if (!this.llmobs.enabled &&
|
|
466
|
+
!trackedConfigOrigins.has('llmobs.enabled') &&
|
|
467
|
+
(trackedConfigOrigins.has('llmobs.agentlessEnabled') ||
|
|
468
|
+
trackedConfigOrigins.has('llmobs.mlApp'))) {
|
|
469
|
+
setAndTrack(this, 'llmobs.enabled', true)
|
|
787
470
|
}
|
|
788
|
-
|
|
789
|
-
if (
|
|
790
|
-
const
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
471
|
+
|
|
472
|
+
if (this.OTEL_RESOURCE_ATTRIBUTES) {
|
|
473
|
+
for (const [key, value] of Object.entries(this.OTEL_RESOURCE_ATTRIBUTES)) {
|
|
474
|
+
// Not replacing existing tags keeps the order of the tags as before.
|
|
475
|
+
if (!this.tags[key]) {
|
|
476
|
+
this.tags[key] = value
|
|
477
|
+
}
|
|
478
|
+
}
|
|
795
479
|
}
|
|
796
|
-
if (
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
setBoolean(target, 'tracePropagationStyle.otelPropagators',
|
|
805
|
-
useDdStyle ? false : !!OTEL_PROPAGATORS)
|
|
806
|
-
|
|
807
|
-
// Use OTEL_PROPAGATORS if no DD-specific vars are set
|
|
808
|
-
if (!useDdStyle && OTEL_PROPAGATORS) {
|
|
809
|
-
const otelStyles = normalizePropagationStyle(OTEL_PROPAGATORS)
|
|
810
|
-
// Validate OTEL propagators
|
|
811
|
-
for (const style of otelStyles || []) {
|
|
812
|
-
if (!VALID_PROPAGATION_STYLES.has(style)) {
|
|
813
|
-
log.warn('unexpected value %s for OTEL_PROPAGATORS environment variable', style)
|
|
814
|
-
getCounter('otel.env.invalid', 'DD_TRACE_PROPAGATION_STYLE', 'OTEL_PROPAGATORS').inc()
|
|
480
|
+
if (this.DD_TRACE_TAGS) {
|
|
481
|
+
// TODO: This is a hack to keep the order of the tags as before.
|
|
482
|
+
// That hack is not sufficient, since it does not handle other cases where the tags are set by the user.
|
|
483
|
+
if (trackedConfigOrigins.get('tags') === 'code') {
|
|
484
|
+
for (const [key, value] of Object.entries(this.DD_TRACE_TAGS)) {
|
|
485
|
+
// Not replacing existing tags keeps the order of the tags as before.
|
|
486
|
+
if (!this.tags[key]) {
|
|
487
|
+
this.tags[key] = value
|
|
815
488
|
}
|
|
816
489
|
}
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
setArray(target, 'tracePropagationStyle.inject', otelStyles)
|
|
820
|
-
setArray(target, 'tracePropagationStyle.extract', otelStyles)
|
|
821
|
-
}
|
|
490
|
+
} else {
|
|
491
|
+
Object.assign(this.tags, this.DD_TRACE_TAGS)
|
|
822
492
|
}
|
|
823
493
|
}
|
|
824
|
-
setBoolean(target, 'traceWebsocketMessagesEnabled', DD_TRACE_WEBSOCKET_MESSAGES_ENABLED)
|
|
825
|
-
setBoolean(target, 'traceWebsocketMessagesInheritSampling', DD_TRACE_WEBSOCKET_MESSAGES_INHERIT_SAMPLING)
|
|
826
|
-
setBoolean(target, 'traceWebsocketMessagesSeparateTraces', DD_TRACE_WEBSOCKET_MESSAGES_SEPARATE_TRACES)
|
|
827
|
-
setBoolean(target, 'tracing', DD_TRACING_ENABLED)
|
|
828
|
-
setString(target, 'version', DD_VERSION || tags.version)
|
|
829
|
-
setBoolean(target, 'inferredProxyServicesEnabled', DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED)
|
|
830
|
-
setBoolean(target, 'trace.aws.addSpanPointers', DD_TRACE_AWS_ADD_SPAN_POINTERS)
|
|
831
|
-
setString(target, 'trace.dynamoDb.tablePrimaryKeys', DD_TRACE_DYNAMODB_TABLE_PRIMARY_KEYS)
|
|
832
|
-
setArray(target, 'graphqlErrorExtensions', DD_TRACE_GRAPHQL_ERROR_EXTENSIONS)
|
|
833
|
-
setBoolean(target, 'trace.nativeSpanEvents', DD_TRACE_NATIVE_SPAN_EVENTS)
|
|
834
|
-
target['vertexai.spanPromptCompletionSampleRate'] = maybeFloat(DD_VERTEXAI_SPAN_PROMPT_COMPLETION_SAMPLE_RATE)
|
|
835
|
-
target['vertexai.spanCharLimit'] = maybeInt(DD_VERTEXAI_SPAN_CHAR_LIMIT)
|
|
836
|
-
}
|
|
837
494
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
const tags = {}
|
|
841
|
-
|
|
842
|
-
options = this.#optionsArg = { ingestion: {}, ...options, ...opts }
|
|
843
|
-
|
|
844
|
-
tagger.add(tags, options.tags)
|
|
845
|
-
|
|
846
|
-
setBoolean(opts, 'apmTracingEnabled', options.apmTracingEnabled ??
|
|
847
|
-
(options.experimental?.appsec?.standalone && !options.experimental.appsec.standalone.enabled)
|
|
848
|
-
)
|
|
849
|
-
setBoolean(opts, 'appsec.apiSecurity.enabled', options.appsec?.apiSecurity?.enabled)
|
|
850
|
-
setBoolean(opts, 'appsec.apiSecurity.endpointCollectionEnabled',
|
|
851
|
-
options.appsec?.apiSecurity?.endpointCollectionEnabled)
|
|
852
|
-
opts['appsec.apiSecurity.endpointCollectionMessageLimit'] =
|
|
853
|
-
maybeInt(options.appsec?.apiSecurity?.endpointCollectionMessageLimit)
|
|
854
|
-
opts['appsec.blockedTemplateGraphql'] = maybeFile(options.appsec?.blockedTemplateGraphql)
|
|
855
|
-
opts['appsec.blockedTemplateHtml'] = maybeFile(options.appsec?.blockedTemplateHtml)
|
|
856
|
-
this.#optsUnprocessed['appsec.blockedTemplateHtml'] = options.appsec?.blockedTemplateHtml
|
|
857
|
-
opts['appsec.blockedTemplateJson'] = maybeFile(options.appsec?.blockedTemplateJson)
|
|
858
|
-
this.#optsUnprocessed['appsec.blockedTemplateJson'] = options.appsec?.blockedTemplateJson
|
|
859
|
-
setBoolean(opts, 'appsec.enabled', options.appsec?.enabled)
|
|
860
|
-
setString(opts, 'appsec.eventTracking.mode', options.appsec?.eventTracking?.mode)
|
|
861
|
-
setBoolean(
|
|
862
|
-
opts,
|
|
863
|
-
'appsec.extendedHeadersCollection.enabled',
|
|
864
|
-
options.appsec?.extendedHeadersCollection?.enabled
|
|
865
|
-
)
|
|
866
|
-
setBoolean(
|
|
867
|
-
opts,
|
|
868
|
-
'appsec.extendedHeadersCollection.redaction',
|
|
869
|
-
options.appsec?.extendedHeadersCollection?.redaction
|
|
870
|
-
)
|
|
871
|
-
opts['appsec.extendedHeadersCollection.maxHeaders'] = options.appsec?.extendedHeadersCollection?.maxHeaders
|
|
872
|
-
setString(opts, 'appsec.obfuscatorKeyRegex', options.appsec?.obfuscatorKeyRegex)
|
|
873
|
-
setString(opts, 'appsec.obfuscatorValueRegex', options.appsec?.obfuscatorValueRegex)
|
|
874
|
-
setBoolean(opts, 'appsec.rasp.enabled', options.appsec?.rasp?.enabled)
|
|
875
|
-
setBoolean(opts, 'appsec.rasp.bodyCollection', options.appsec?.rasp?.bodyCollection)
|
|
876
|
-
opts['appsec.rateLimit'] = maybeInt(options.appsec?.rateLimit)
|
|
877
|
-
this.#optsUnprocessed['appsec.rateLimit'] = options.appsec?.rateLimit
|
|
878
|
-
setString(opts, 'appsec.rules', options.appsec?.rules)
|
|
879
|
-
setBoolean(opts, 'appsec.stackTrace.enabled', options.appsec?.stackTrace?.enabled)
|
|
880
|
-
opts['appsec.stackTrace.maxDepth'] = maybeInt(options.appsec?.stackTrace?.maxDepth)
|
|
881
|
-
this.#optsUnprocessed['appsec.stackTrace.maxDepth'] = options.appsec?.stackTrace?.maxDepth
|
|
882
|
-
opts['appsec.stackTrace.maxStackTraces'] = maybeInt(options.appsec?.stackTrace?.maxStackTraces)
|
|
883
|
-
this.#optsUnprocessed['appsec.stackTrace.maxStackTraces'] = options.appsec?.stackTrace?.maxStackTraces
|
|
884
|
-
opts['appsec.wafTimeout'] = maybeInt(options.appsec?.wafTimeout)
|
|
885
|
-
this.#optsUnprocessed['appsec.wafTimeout'] = options.appsec?.wafTimeout
|
|
886
|
-
setBoolean(opts, 'clientIpEnabled', options.clientIpEnabled)
|
|
887
|
-
setString(opts, 'clientIpHeader', options.clientIpHeader?.toLowerCase())
|
|
888
|
-
if (options.cloudPayloadTagging?.request || options.cloudPayloadTagging?.response) {
|
|
889
|
-
if (options.cloudPayloadTagging.request) {
|
|
890
|
-
setBoolean(opts, 'cloudPayloadTagging.requestsEnabled', true)
|
|
891
|
-
}
|
|
892
|
-
if (options.cloudPayloadTagging.response) {
|
|
893
|
-
setBoolean(opts, 'cloudPayloadTagging.responsesEnabled', true)
|
|
894
|
-
}
|
|
895
|
-
opts['cloudPayloadTagging.rules'] = appendRules(
|
|
896
|
-
splitJSONPathRules(options.cloudPayloadTagging.request),
|
|
897
|
-
splitJSONPathRules(options.cloudPayloadTagging.response)
|
|
898
|
-
)
|
|
899
|
-
}
|
|
900
|
-
if (options.cloudPayloadTagging?.requestsEnabled !== undefined) {
|
|
901
|
-
setBoolean(opts, 'cloudPayloadTagging.requestsEnabled', options.cloudPayloadTagging.requestsEnabled)
|
|
902
|
-
}
|
|
903
|
-
if (options.cloudPayloadTagging?.responsesEnabled !== undefined) {
|
|
904
|
-
setBoolean(opts, 'cloudPayloadTagging.responsesEnabled', options.cloudPayloadTagging.responsesEnabled)
|
|
905
|
-
}
|
|
906
|
-
opts['cloudPayloadTagging.maxDepth'] = maybeInt(options.cloudPayloadTagging?.maxDepth)
|
|
907
|
-
opts.baggageMaxBytes = options.baggageMaxBytes
|
|
908
|
-
opts.baggageMaxItems = options.baggageMaxItems
|
|
909
|
-
setArray(opts, 'baggageTagKeys', options.baggageTagKeys)
|
|
910
|
-
setBoolean(opts, 'codeOriginForSpans.enabled', options.codeOriginForSpans?.enabled)
|
|
911
|
-
setBoolean(
|
|
912
|
-
opts,
|
|
913
|
-
'codeOriginForSpans.experimental.exit_spans.enabled',
|
|
914
|
-
options.codeOriginForSpans?.experimental?.exit_spans?.enabled
|
|
915
|
-
)
|
|
916
|
-
setString(opts, 'dbmPropagationMode', options.dbmPropagationMode)
|
|
917
|
-
setBoolean(opts, 'dbm.injectSqlBaseHash', options.dbm?.injectSqlBaseHash)
|
|
918
|
-
if (options.dogstatsd) {
|
|
919
|
-
setString(opts, 'dogstatsd.hostname', options.dogstatsd.hostname)
|
|
920
|
-
setString(opts, 'dogstatsd.port', options.dogstatsd.port)
|
|
495
|
+
if (!this.#parsedDdTags) {
|
|
496
|
+
this.#parsedDdTags = rfdc(this.tags)
|
|
921
497
|
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
setBoolean(opts, 'dynamicInstrumentation.enabled', options.dynamicInstrumentation?.enabled)
|
|
926
|
-
setString(opts, 'dynamicInstrumentation.probeFile', options.dynamicInstrumentation?.probeFile)
|
|
927
|
-
setArray(
|
|
928
|
-
opts,
|
|
929
|
-
'dynamicInstrumentation.redactedIdentifiers',
|
|
930
|
-
options.dynamicInstrumentation?.redactedIdentifiers
|
|
931
|
-
)
|
|
932
|
-
setArray(
|
|
933
|
-
opts,
|
|
934
|
-
'dynamicInstrumentation.redactionExcludedIdentifiers',
|
|
935
|
-
options.dynamicInstrumentation?.redactionExcludedIdentifiers
|
|
936
|
-
)
|
|
937
|
-
opts['dynamicInstrumentation.uploadIntervalSeconds'] =
|
|
938
|
-
maybeFloat(options.dynamicInstrumentation?.uploadIntervalSeconds)
|
|
939
|
-
this.#optsUnprocessed['dynamicInstrumentation.uploadIntervalSeconds'] =
|
|
940
|
-
options.dynamicInstrumentation?.uploadIntervalSeconds
|
|
941
|
-
setString(opts, 'env', options.env || tags.env)
|
|
942
|
-
setBoolean(opts, 'experimental.aiguard.enabled', options.experimental?.aiguard?.enabled)
|
|
943
|
-
setString(opts, 'experimental.aiguard.endpoint', options.experimental?.aiguard?.endpoint)
|
|
944
|
-
opts['experimental.aiguard.maxMessagesLength'] = maybeInt(options.experimental?.aiguard?.maxMessagesLength)
|
|
945
|
-
this.#optsUnprocessed['experimental.aiguard.maxMessagesLength'] = options.experimental?.aiguard?.maxMessagesLength
|
|
946
|
-
opts['experimental.aiguard.maxContentSize'] = maybeInt(options.experimental?.aiguard?.maxContentSize)
|
|
947
|
-
this.#optsUnprocessed['experimental.aiguard.maxContentSize'] = options.experimental?.aiguard?.maxContentSize
|
|
948
|
-
opts['experimental.aiguard.timeout'] = maybeInt(options.experimental?.aiguard?.timeout)
|
|
949
|
-
this.#optsUnprocessed['experimental.aiguard.timeout'] = options.experimental?.aiguard?.timeout
|
|
950
|
-
setBoolean(opts, 'experimental.enableGetRumData', options.experimental?.enableGetRumData)
|
|
951
|
-
setString(opts, 'experimental.exporter', options.experimental?.exporter)
|
|
952
|
-
setBoolean(opts, 'experimental.flaggingProvider.enabled', options.experimental?.flaggingProvider?.enabled)
|
|
953
|
-
opts['experimental.flaggingProvider.initializationTimeoutMs'] = maybeInt(
|
|
954
|
-
options.experimental?.flaggingProvider?.initializationTimeoutMs
|
|
955
|
-
)
|
|
956
|
-
this.#optsUnprocessed['experimental.flaggingProvider.initializationTimeoutMs'] =
|
|
957
|
-
options.experimental?.flaggingProvider?.initializationTimeoutMs
|
|
958
|
-
opts.flushInterval = maybeInt(options.flushInterval)
|
|
959
|
-
this.#optsUnprocessed.flushInterval = options.flushInterval
|
|
960
|
-
opts.flushMinSpans = maybeInt(options.flushMinSpans)
|
|
961
|
-
this.#optsUnprocessed.flushMinSpans = options.flushMinSpans
|
|
962
|
-
setArray(opts, 'headerTags', options.headerTags)
|
|
963
|
-
setString(opts, 'hostname', options.hostname)
|
|
964
|
-
opts['iast.dbRowsToTaint'] = maybeInt(options.iast?.dbRowsToTaint)
|
|
965
|
-
setBoolean(opts, 'iast.deduplicationEnabled', options.iast && options.iast.deduplicationEnabled)
|
|
966
|
-
setBoolean(opts, 'iast.enabled',
|
|
967
|
-
options.iast && (options.iast === true || options.iast.enabled === true))
|
|
968
|
-
opts['iast.maxConcurrentRequests'] = maybeInt(options.iast?.maxConcurrentRequests)
|
|
969
|
-
this.#optsUnprocessed['iast.maxConcurrentRequests'] = options.iast?.maxConcurrentRequests
|
|
970
|
-
opts['iast.maxContextOperations'] = maybeInt(options.iast?.maxContextOperations)
|
|
971
|
-
this.#optsUnprocessed['iast.maxContextOperations'] = options.iast?.maxContextOperations
|
|
972
|
-
setBoolean(opts, 'iast.redactionEnabled', options.iast?.redactionEnabled)
|
|
973
|
-
setString(opts, 'iast.redactionNamePattern', options.iast?.redactionNamePattern)
|
|
974
|
-
setString(opts, 'iast.redactionValuePattern', options.iast?.redactionValuePattern)
|
|
975
|
-
const iastRequestSampling = maybeInt(options.iast?.requestSampling)
|
|
976
|
-
if (iastRequestSampling !== undefined && iastRequestSampling > -1 && iastRequestSampling < 101) {
|
|
977
|
-
opts['iast.requestSampling'] = iastRequestSampling
|
|
978
|
-
this.#optsUnprocessed['iast.requestSampling'] = options.iast?.requestSampling
|
|
979
|
-
}
|
|
980
|
-
if (DD_MAJOR < 6) {
|
|
981
|
-
opts['iast.securityControlsConfiguration'] = options.iast?.securityControlsConfiguration
|
|
498
|
+
|
|
499
|
+
if (!this.env && this.tags.env !== undefined) {
|
|
500
|
+
setAndTrack(this, 'env', this.tags.env)
|
|
982
501
|
}
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
setBoolean(opts, 'llmobs.agentlessEnabled', options.llmobs?.agentlessEnabled)
|
|
988
|
-
setString(opts, 'llmobs.mlApp', options.llmobs?.mlApp)
|
|
989
|
-
setBoolean(opts, 'logInjection', options.logInjection)
|
|
990
|
-
opts.lookup = options.lookup
|
|
991
|
-
setBoolean(opts, 'middlewareTracingEnabled', options.middlewareTracingEnabled)
|
|
992
|
-
setBoolean(opts, 'openAiLogsEnabled', options.openAiLogsEnabled)
|
|
993
|
-
opts.peerServiceMapping = options.peerServiceMapping
|
|
994
|
-
setBoolean(opts, 'plugins', options.plugins)
|
|
995
|
-
setString(opts, 'port', options.port)
|
|
996
|
-
const strProfiling = String(options.profiling)
|
|
997
|
-
if (['true', 'false', 'auto'].includes(strProfiling)) {
|
|
998
|
-
setString(opts, 'profiling.enabled', strProfiling)
|
|
502
|
+
|
|
503
|
+
if (!this.version) {
|
|
504
|
+
setAndTrack(this, 'version', this.tags.version || pkg.version)
|
|
505
|
+
this.tags.version ??= pkg.version
|
|
999
506
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
this
|
|
507
|
+
|
|
508
|
+
let isServiceNameInferred = false
|
|
509
|
+
if (!trackedConfigOrigins.has('service')) {
|
|
510
|
+
if (this.tags.service) {
|
|
511
|
+
setAndTrack(this, 'service', this.tags.service)
|
|
512
|
+
} else {
|
|
513
|
+
const NX_TASK_TARGET_PROJECT = getEnvironmentVariable('NX_TASK_TARGET_PROJECT')
|
|
514
|
+
if (NX_TASK_TARGET_PROJECT) {
|
|
515
|
+
if (this.DD_ENABLE_NX_SERVICE_NAME) {
|
|
516
|
+
setAndTrack(this, 'service', NX_TASK_TARGET_PROJECT)
|
|
517
|
+
isServiceNameInferred = true
|
|
518
|
+
} else if (DD_MAJOR < 6) {
|
|
519
|
+
log.warn(
|
|
520
|
+
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
521
|
+
'NX_TASK_TARGET_PROJECT is set but no service name was configured. In v6, NX_TASK_TARGET_PROJECT will ' +
|
|
522
|
+
'be used as the default service name. Set DD_ENABLE_NX_SERVICE_NAME=true to opt-in to this behavior ' +
|
|
523
|
+
'now, or set a service name explicitly.'
|
|
524
|
+
)
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
if (!this.service) {
|
|
530
|
+
const serverlessName = IS_SERVERLESS
|
|
531
|
+
? (
|
|
532
|
+
getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') ||
|
|
533
|
+
getEnvironmentVariable('FUNCTION_NAME') || // Google Cloud Function Name set by deprecated runtimes
|
|
534
|
+
getEnvironmentVariable('K_SERVICE') || // Google Cloud Function Name set by newer runtimes
|
|
535
|
+
getEnvironmentVariable('WEBSITE_SITE_NAME') // set by Azure Functions
|
|
536
|
+
)
|
|
537
|
+
: undefined
|
|
538
|
+
|
|
539
|
+
setAndTrack(this, 'service', serverlessName || pkg.name || 'node')
|
|
540
|
+
this.tags.service ??= /** @type {string} */ (this.service)
|
|
541
|
+
isServiceNameInferred = true
|
|
542
|
+
}
|
|
1004
543
|
}
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
setArray(opts, 'sampler.spanSamplingRules', reformatSpanSamplingRules(options.spanSamplingRules))
|
|
1011
|
-
setUnit(opts, 'sampleRate', options.sampleRate ?? options.ingestion.sampleRate)
|
|
1012
|
-
opts['sampler.rateLimit'] = maybeInt(options.rateLimit ?? options.ingestion.rateLimit)
|
|
1013
|
-
setSamplingRule(opts, 'sampler.rules', options.samplingRules)
|
|
1014
|
-
const optService = options.service || tags.service
|
|
1015
|
-
setString(opts, 'service', optService)
|
|
1016
|
-
if (optService) {
|
|
1017
|
-
setBoolean(opts, 'isServiceNameInferred', false)
|
|
544
|
+
setAndTrack(this, 'isServiceNameInferred', isServiceNameInferred)
|
|
545
|
+
|
|
546
|
+
// Add missing tags, in case they are defined otherwise.
|
|
547
|
+
if (this.service) {
|
|
548
|
+
this.tags.service = this.service
|
|
1018
549
|
}
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
if (options.spanAttributeSchema) {
|
|
1022
|
-
setString(opts, 'spanAttributeSchema', validateNamingVersion(options.spanAttributeSchema))
|
|
1023
|
-
this.#optsUnprocessed.spanAttributeSchema = options.spanAttributeSchema
|
|
550
|
+
if (this.env) {
|
|
551
|
+
this.tags.env = this.env
|
|
1024
552
|
}
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
setTags(opts, 'tags', tags)
|
|
1028
|
-
setBoolean(opts, 'traceId128BitGenerationEnabled', options.traceId128BitGenerationEnabled)
|
|
1029
|
-
setBoolean(opts, 'traceId128BitLoggingEnabled', options.traceId128BitLoggingEnabled)
|
|
1030
|
-
setBoolean(opts, 'traceWebsocketMessagesEnabled', options.traceWebsocketMessagesEnabled)
|
|
1031
|
-
setBoolean(opts, 'traceWebsocketMessagesInheritSampling', options.traceWebsocketMessagesInheritSampling)
|
|
1032
|
-
setBoolean(opts, 'traceWebsocketMessagesSeparateTraces', options.traceWebsocketMessagesSeparateTraces)
|
|
1033
|
-
setString(opts, 'version', options.version || tags.version)
|
|
1034
|
-
setBoolean(opts, 'inferredProxyServicesEnabled', options.inferredProxyServicesEnabled)
|
|
1035
|
-
setBoolean(opts, 'graphqlErrorExtensions', options.graphqlErrorExtensions)
|
|
1036
|
-
setBoolean(opts, 'trace.nativeSpanEvents', options.trace?.nativeSpanEvents)
|
|
1037
|
-
if (options.tracePropagationStyle) {
|
|
1038
|
-
setArray(opts, 'tracePropagationStyle.inject',
|
|
1039
|
-
normalizePropagationStyle(options.tracePropagationStyle.inject ?? options.tracePropagationStyle))
|
|
1040
|
-
setArray(opts, 'tracePropagationStyle.extract',
|
|
1041
|
-
normalizePropagationStyle(options.tracePropagationStyle.extract ?? options.tracePropagationStyle))
|
|
553
|
+
if (this.version) {
|
|
554
|
+
this.tags.version = this.version
|
|
1042
555
|
}
|
|
556
|
+
this.tags['runtime-id'] = RUNTIME_ID
|
|
1043
557
|
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
if (this.#env['llmobs.enabled'] == null && options.llmobs) {
|
|
1049
|
-
setBoolean(opts, 'llmobs.enabled', true)
|
|
558
|
+
if (IS_SERVERLESS) {
|
|
559
|
+
setAndTrack(this, 'telemetry.enabled', false)
|
|
560
|
+
setAndTrack(this, 'crashtracking.enabled', false)
|
|
561
|
+
setAndTrack(this, 'remoteConfig.enabled', false)
|
|
1050
562
|
}
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
#isCiVisibility () {
|
|
1054
|
-
return this.#optionsArg.isCiVisibility ?? this.#defaults.isCiVisibility
|
|
1055
|
-
}
|
|
1056
|
-
|
|
1057
|
-
#getHostname () {
|
|
1058
|
-
const DD_CIVISIBILITY_AGENTLESS_URL = getEnv('DD_CIVISIBILITY_AGENTLESS_URL')
|
|
1059
|
-
const url = DD_CIVISIBILITY_AGENTLESS_URL
|
|
1060
|
-
? new URL(DD_CIVISIBILITY_AGENTLESS_URL)
|
|
1061
|
-
: getAgentUrl(this.#getTraceAgentUrl(), this.#optionsArg)
|
|
1062
|
-
const DD_AGENT_HOST = this.#optionsArg.hostname ??
|
|
1063
|
-
getEnv('DD_AGENT_HOST') ??
|
|
1064
|
-
defaults.hostname
|
|
1065
|
-
return DD_AGENT_HOST || url?.hostname
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
#getSpanComputePeerService () {
|
|
1069
|
-
const DD_TRACE_SPAN_ATTRIBUTE_SCHEMA = validateNamingVersion(
|
|
1070
|
-
this.#optionsArg.spanAttributeSchema ??
|
|
1071
|
-
getEnv('DD_TRACE_SPAN_ATTRIBUTE_SCHEMA')
|
|
1072
|
-
)
|
|
1073
|
-
|
|
1074
|
-
const peerServiceSet = (
|
|
1075
|
-
this.#optionsArg.hasOwnProperty('spanComputePeerService') ||
|
|
1076
|
-
getEnv('DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED') !== undefined
|
|
1077
|
-
)
|
|
1078
|
-
const peerServiceValue = this.#optionsArg.spanComputePeerService ??
|
|
1079
|
-
getEnv('DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED')
|
|
1080
|
-
|
|
1081
|
-
const spanComputePeerService = (
|
|
1082
|
-
DD_TRACE_SPAN_ATTRIBUTE_SCHEMA === 'v0'
|
|
1083
|
-
// In v0, peer service is computed only if it is explicitly set to true
|
|
1084
|
-
? peerServiceSet && isTrue(peerServiceValue)
|
|
1085
|
-
// In >v0, peer service is false only if it is explicitly set to false
|
|
1086
|
-
: (peerServiceSet ? !isFalse(peerServiceValue) : true)
|
|
1087
|
-
)
|
|
1088
|
-
|
|
1089
|
-
return spanComputePeerService
|
|
1090
|
-
}
|
|
1091
563
|
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
this
|
|
1095
|
-
|
|
1096
|
-
return apmTracingEnabled && (
|
|
1097
|
-
this.#optionsArg.stats ??
|
|
1098
|
-
getEnv('DD_TRACE_STATS_COMPUTATION_ENABLED') ??
|
|
1099
|
-
(getIsGCPFunction() || getIsAzureFunction())
|
|
1100
|
-
)
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
#getTraceAgentUrl () {
|
|
1104
|
-
return this.#optionsArg.url ??
|
|
1105
|
-
getEnv('DD_TRACE_AGENT_URL') ??
|
|
1106
|
-
null
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
// handles values calculated from a mixture of options and env vars
|
|
1110
|
-
#applyCalculated () {
|
|
1111
|
-
const calc = this.#calculated
|
|
1112
|
-
|
|
1113
|
-
const DD_CIVISIBILITY_AGENTLESS_URL = getEnv('DD_CIVISIBILITY_AGENTLESS_URL')
|
|
1114
|
-
|
|
1115
|
-
calc.url = DD_CIVISIBILITY_AGENTLESS_URL
|
|
1116
|
-
? new URL(DD_CIVISIBILITY_AGENTLESS_URL)
|
|
1117
|
-
: getAgentUrl(this.#getTraceAgentUrl(), this.#optionsArg)
|
|
564
|
+
// TODO: Should this unconditionally be disabled?
|
|
565
|
+
if (getEnvironmentVariable('JEST_WORKER_ID') && !trackedConfigOrigins.has('telemetry.enabled')) {
|
|
566
|
+
setAndTrack(this, 'telemetry.enabled', false)
|
|
567
|
+
}
|
|
1118
568
|
|
|
1119
569
|
// Experimental agentless APM span intake
|
|
1120
570
|
// When enabled, sends spans directly to Datadog intake without an agent
|
|
1121
|
-
|
|
571
|
+
// TODO: Replace this with a proper configuration
|
|
572
|
+
const agentlessEnabled = isTrue(getEnvironmentVariable('_DD_APM_TRACING_AGENTLESS_ENABLED'))
|
|
1122
573
|
if (agentlessEnabled) {
|
|
1123
|
-
|
|
1124
|
-
// Disable rate limiting - server-side sampling will be used
|
|
1125
|
-
calc['sampler.rateLimit'] = -1
|
|
574
|
+
setAndTrack(this, 'experimental.exporter', 'agentless')
|
|
1126
575
|
// Disable client-side stats computation
|
|
1127
|
-
|
|
576
|
+
setAndTrack(this, 'stats.enabled', false)
|
|
1128
577
|
// Enable hostname reporting
|
|
1129
|
-
|
|
578
|
+
setAndTrack(this, 'reportHostname', true)
|
|
579
|
+
// Disable rate limiting - server-side sampling will be used
|
|
580
|
+
setAndTrack(this, 'sampler.rateLimit', -1)
|
|
1130
581
|
// Clear sampling rules - server-side sampling handles this
|
|
1131
|
-
|
|
582
|
+
setAndTrack(this, 'sampler.rules', [])
|
|
1132
583
|
// Agentless intake only accepts 64-bit trace IDs; disable 128-bit generation
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
if (this.#isCiVisibility()) {
|
|
1137
|
-
setBoolean(calc, 'isEarlyFlakeDetectionEnabled',
|
|
1138
|
-
getEnv('DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED') ?? true)
|
|
1139
|
-
setBoolean(calc, 'isFlakyTestRetriesEnabled', getEnv('DD_CIVISIBILITY_FLAKY_RETRY_ENABLED') ?? true)
|
|
1140
|
-
calc.flakyTestRetriesCount = maybeInt(getEnv('DD_CIVISIBILITY_FLAKY_RETRY_COUNT')) ?? 5
|
|
1141
|
-
setBoolean(calc, 'isIntelligentTestRunnerEnabled', isTrue(isCiVisibilityItrEnabled()))
|
|
1142
|
-
setBoolean(calc, 'isManualApiEnabled', !isFalse(getEnv('DD_CIVISIBILITY_MANUAL_API_ENABLED')))
|
|
1143
|
-
setString(calc, 'ciVisibilityTestSessionName', getEnv('DD_TEST_SESSION_NAME'))
|
|
1144
|
-
setBoolean(calc, 'ciVisAgentlessLogSubmissionEnabled',
|
|
1145
|
-
isTrue(getEnv('DD_AGENTLESS_LOG_SUBMISSION_ENABLED')))
|
|
1146
|
-
setBoolean(calc, 'isTestDynamicInstrumentationEnabled',
|
|
1147
|
-
!isFalse(getEnv('DD_TEST_FAILED_TEST_REPLAY_ENABLED')))
|
|
1148
|
-
setBoolean(calc, 'isServiceUserProvided', !!this.#env.service)
|
|
1149
|
-
setBoolean(calc, 'isTestManagementEnabled', !isFalse(getEnv('DD_TEST_MANAGEMENT_ENABLED')))
|
|
1150
|
-
calc.testManagementAttemptToFixRetries = maybeInt(getEnv('DD_TEST_MANAGEMENT_ATTEMPT_TO_FIX_RETRIES')) ?? 20
|
|
1151
|
-
setBoolean(calc, 'isImpactedTestsEnabled',
|
|
1152
|
-
!isFalse(getEnv('DD_CIVISIBILITY_IMPACTED_TESTS_DETECTION_ENABLED')))
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
// Disable log injection when OTEL logs are enabled
|
|
1156
|
-
// OTEL logs and DD log injection are mutually exclusive
|
|
1157
|
-
if (this.#env.otelLogsEnabled) {
|
|
1158
|
-
setBoolean(calc, 'logInjection', false)
|
|
584
|
+
if (!trackedConfigOrigins.has('traceId128BitGenerationEnabled')) {
|
|
585
|
+
setAndTrack(this, 'traceId128BitGenerationEnabled', false)
|
|
586
|
+
}
|
|
1159
587
|
}
|
|
1160
588
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
calc.otelLogsUrl = `http://${agentHostname}:${DEFAULT_OTLP_PORT}`
|
|
1166
|
-
calc.otelMetricsUrl = `http://${agentHostname}:${DEFAULT_OTLP_PORT}/v1/metrics`
|
|
1167
|
-
calc.otelUrl = `http://${agentHostname}:${DEFAULT_OTLP_PORT}`
|
|
1168
|
-
calc['telemetry.heartbeatInterval'] = maybeInt(Math.floor(this.#defaults['telemetry.heartbeatInterval'] * 1000))
|
|
1169
|
-
|
|
1170
|
-
setBoolean(calc, 'isGitUploadEnabled',
|
|
1171
|
-
calc.isIntelligentTestRunnerEnabled && !isFalse(getEnv('DD_CIVISIBILITY_GIT_UPLOAD_ENABLED')))
|
|
1172
|
-
|
|
1173
|
-
// Enable resourceRenamingEnabled when appsec is enabled and only
|
|
1174
|
-
// if DD_TRACE_RESOURCE_RENAMING_ENABLED is not explicitly set
|
|
1175
|
-
if (this.#env.resourceRenamingEnabled === undefined) {
|
|
1176
|
-
const appsecEnabled = this.#options['appsec.enabled'] ?? this.#env['appsec.enabled']
|
|
1177
|
-
if (appsecEnabled) {
|
|
1178
|
-
setBoolean(calc, 'resourceRenamingEnabled', true)
|
|
589
|
+
// Apply all fallbacks to the calculated config.
|
|
590
|
+
for (const [configName, alias] of fallbackConfigurations) {
|
|
591
|
+
if (!trackedConfigOrigins.has(configName) && trackedConfigOrigins.has(alias)) {
|
|
592
|
+
setAndTrack(this, configName, this[alias])
|
|
1179
593
|
}
|
|
1180
594
|
}
|
|
1181
595
|
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
if (defaultPropagationStyle.length > 2) {
|
|
1186
|
-
// b3 was added, so update defaults to include it
|
|
1187
|
-
// This will only be used if no other source (options, env, stable config) set the value
|
|
1188
|
-
calc['tracePropagationStyle.inject'] = defaultPropagationStyle
|
|
1189
|
-
calc['tracePropagationStyle.extract'] = defaultPropagationStyle
|
|
596
|
+
const DEFAULT_OTLP_PORT = '4318'
|
|
597
|
+
if (!this.otelLogsUrl) {
|
|
598
|
+
setAndTrack(this, 'otelLogsUrl', `http://${agentHostname}:${DEFAULT_OTLP_PORT}`)
|
|
1190
599
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
/**
|
|
1194
|
-
* Applies remote configuration options from APM_TRACING configs.
|
|
1195
|
-
*
|
|
1196
|
-
* @param {import('./remote_config').RemoteConfigOptions} options - Configurations received via Remote Config
|
|
1197
|
-
*/
|
|
1198
|
-
#applyRemoteConfig (options) {
|
|
1199
|
-
const opts = this.#remote
|
|
1200
|
-
|
|
1201
|
-
setBoolean(opts, 'dynamicInstrumentation.enabled', options.dynamic_instrumentation_enabled)
|
|
1202
|
-
setBoolean(opts, 'codeOriginForSpans.enabled', options.code_origin_enabled)
|
|
1203
|
-
setUnit(opts, 'sampleRate', options.tracing_sampling_rate)
|
|
1204
|
-
setBoolean(opts, 'logInjection', options.log_injection_enabled)
|
|
1205
|
-
setBoolean(opts, 'tracing', options.tracing_enabled)
|
|
1206
|
-
this.#remoteUnprocessed['sampler.rules'] = options.tracing_sampling_rules
|
|
1207
|
-
setSamplingRule(opts, 'sampler.rules', reformatTagsFromRC(options.tracing_sampling_rules))
|
|
1208
|
-
|
|
1209
|
-
opts.headerTags = options.tracing_header_tags?.map(tag => {
|
|
1210
|
-
return tag.tag_name ? `${tag.header}:${tag.tag_name}` : tag.header
|
|
1211
|
-
})
|
|
1212
|
-
|
|
1213
|
-
const tags = {}
|
|
1214
|
-
tagger.add(tags, options.tracing_tags)
|
|
1215
|
-
if (Object.keys(tags).length) {
|
|
1216
|
-
tags['runtime-id'] = RUNTIME_ID
|
|
600
|
+
if (!this.otelMetricsUrl) {
|
|
601
|
+
setAndTrack(this, 'otelMetricsUrl', `http://${agentHostname}:${DEFAULT_OTLP_PORT}/v1/metrics`)
|
|
1217
602
|
}
|
|
1218
|
-
setTags(opts, 'tags', tags)
|
|
1219
|
-
}
|
|
1220
603
|
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
604
|
+
if (process.platform === 'win32') {
|
|
605
|
+
// OOM monitoring does not work properly on Windows, so it will be disabled.
|
|
606
|
+
deactivateIfEnabledAndWarnOnWindows(this, 'DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED')
|
|
607
|
+
// Profiler sampling contexts are not available on Windows, so features
|
|
608
|
+
// depending on those (code hotspots and endpoint collection) need to be disabled on Windows.
|
|
609
|
+
deactivateIfEnabledAndWarnOnWindows(this, 'DD_PROFILING_CODEHOTSPOTS_ENABLED')
|
|
610
|
+
deactivateIfEnabledAndWarnOnWindows(this, 'DD_PROFILING_ENDPOINT_COLLECTION_ENABLED')
|
|
611
|
+
deactivateIfEnabledAndWarnOnWindows(this, 'DD_PROFILING_CPU_ENABLED')
|
|
612
|
+
deactivateIfEnabledAndWarnOnWindows(this, 'DD_PROFILING_TIMELINE_ENABLED')
|
|
613
|
+
deactivateIfEnabledAndWarnOnWindows(this, 'DD_PROFILING_ASYNC_CONTEXT_FRAME_ENABLED')
|
|
1226
614
|
}
|
|
1227
615
|
|
|
1228
|
-
|
|
1229
|
-
|
|
616
|
+
// Single tags update is tracked as a calculated value.
|
|
617
|
+
setAndTrack(this, 'tags', this.tags)
|
|
1230
618
|
|
|
1231
|
-
|
|
1232
|
-
changeTracker[name][origin] = value
|
|
1233
|
-
changes.push({
|
|
1234
|
-
name,
|
|
1235
|
-
value: unprocessedValue || value,
|
|
1236
|
-
origin,
|
|
1237
|
-
})
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
// TODO: Report origin changes and errors to telemetry.
|
|
1242
|
-
// TODO: Deeply merge configurations.
|
|
1243
|
-
// TODO: Move change tracking to telemetry.
|
|
1244
|
-
// for telemetry reporting, `name`s in `containers` need to be keys from:
|
|
1245
|
-
// https://github.com/DataDog/dd-go/blob/prod/trace/apps/tracer-telemetry-intake/telemetry-payload/static/config_norm_rules.json
|
|
1246
|
-
#merge () {
|
|
1247
|
-
const changes = []
|
|
1248
|
-
const sources = this.#getSourcesInOrder()
|
|
1249
|
-
|
|
1250
|
-
for (const name of Object.keys(this.#defaults)) {
|
|
1251
|
-
// Use reverse order for merge (lowest priority first)
|
|
1252
|
-
for (let i = sources.length - 1; i >= 0; i--) {
|
|
1253
|
-
const { container, origin, unprocessed } = sources[i]
|
|
1254
|
-
const value = container[name]
|
|
1255
|
-
if (value != null || container === this.#defaults) {
|
|
1256
|
-
this.#setAndTrackChange({
|
|
1257
|
-
name,
|
|
1258
|
-
value,
|
|
1259
|
-
origin,
|
|
1260
|
-
unprocessedValue: unprocessed?.[name],
|
|
1261
|
-
changes,
|
|
1262
|
-
})
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
this.sampler.sampleRate = this.sampleRate
|
|
1267
|
-
updateConfig(changes, this)
|
|
619
|
+
telemetry.updateConfig([...configWithOrigin.values()], this)
|
|
1268
620
|
}
|
|
1269
621
|
|
|
622
|
+
// TODO: Move outside of config. This is unrelated to the config system.
|
|
1270
623
|
#loadGitMetadata () {
|
|
1271
|
-
//
|
|
1272
|
-
this.repositoryUrl = removeUserSensitiveInfo(
|
|
1273
|
-
|
|
1274
|
-
)
|
|
1275
|
-
this.commitSHA = getEnv('DD_GIT_COMMIT_SHA') ?? this.tags[GIT_COMMIT_SHA]
|
|
624
|
+
// Try to read Git metadata from the environment variables
|
|
625
|
+
this.repositoryUrl = removeUserSensitiveInfo(this.DD_GIT_REPOSITORY_URL ?? this.tags[GIT_REPOSITORY_URL])
|
|
626
|
+
this.commitSHA = this.DD_GIT_COMMIT_SHA ?? this.tags[GIT_COMMIT_SHA]
|
|
1276
627
|
|
|
1277
|
-
//
|
|
628
|
+
// Otherwise, try to read Git metadata from the git.properties file
|
|
1278
629
|
if (!this.repositoryUrl || !this.commitSHA) {
|
|
1279
|
-
const DD_GIT_PROPERTIES_FILE =
|
|
630
|
+
const DD_GIT_PROPERTIES_FILE = this.DD_GIT_PROPERTIES_FILE
|
|
1280
631
|
const gitPropertiesFile = DD_GIT_PROPERTIES_FILE ?? `${process.cwd()}/git.properties`
|
|
1281
|
-
let gitPropertiesString
|
|
1282
632
|
try {
|
|
1283
|
-
gitPropertiesString = fs.readFileSync(gitPropertiesFile, 'utf8')
|
|
1284
|
-
|
|
633
|
+
const gitPropertiesString = fs.readFileSync(gitPropertiesFile, 'utf8')
|
|
634
|
+
const { commitSHA, repositoryUrl } = getGitMetadataFromGitProperties(gitPropertiesString)
|
|
635
|
+
this.commitSHA ??= commitSHA
|
|
636
|
+
this.repositoryUrl ??= repositoryUrl
|
|
637
|
+
} catch (error) {
|
|
1285
638
|
// Only log error if the user has set a git.properties path
|
|
1286
639
|
if (DD_GIT_PROPERTIES_FILE) {
|
|
1287
|
-
log.error('Error reading DD_GIT_PROPERTIES_FILE: %s', gitPropertiesFile,
|
|
640
|
+
log.error('Error reading DD_GIT_PROPERTIES_FILE: %s', gitPropertiesFile, error)
|
|
1288
641
|
}
|
|
1289
642
|
}
|
|
1290
|
-
if (gitPropertiesString) {
|
|
1291
|
-
const { commitSHA, repositoryUrl } = getGitMetadataFromGitProperties(gitPropertiesString)
|
|
1292
|
-
this.commitSHA = this.commitSHA || commitSHA
|
|
1293
|
-
this.repositoryUrl = this.repositoryUrl || repositoryUrl
|
|
1294
|
-
}
|
|
1295
643
|
}
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
} catch (e) {
|
|
1309
|
-
// Only log error if the user has set a .git/ path
|
|
1310
|
-
if (DD_GIT_FOLDER_PATH) {
|
|
1311
|
-
log.error('Error reading git config: %s', gitConfigPath, e)
|
|
1312
|
-
}
|
|
644
|
+
|
|
645
|
+
// Otherwise, try to read Git metadata from the .git/ folder
|
|
646
|
+
const DD_GIT_FOLDER_PATH = this.DD_GIT_FOLDER_PATH
|
|
647
|
+
const gitFolderPath = DD_GIT_FOLDER_PATH ?? path.join(process.cwd(), '.git')
|
|
648
|
+
|
|
649
|
+
if (!this.repositoryUrl) {
|
|
650
|
+
// Try to read git config (repository URL)
|
|
651
|
+
const gitConfigPath = path.join(gitFolderPath, 'config')
|
|
652
|
+
try {
|
|
653
|
+
const gitConfigContent = fs.readFileSync(gitConfigPath, 'utf8')
|
|
654
|
+
if (gitConfigContent) {
|
|
655
|
+
this.repositoryUrl = getRemoteOriginURL(gitConfigContent)
|
|
1313
656
|
}
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
if (gitHeadSha) {
|
|
1319
|
-
this.commitSHA = gitHeadSha
|
|
657
|
+
} catch (error) {
|
|
658
|
+
// Only log error if the user has set a .git/ path
|
|
659
|
+
if (DD_GIT_FOLDER_PATH) {
|
|
660
|
+
log.error('Error reading git config: %s', gitConfigPath, error)
|
|
1320
661
|
}
|
|
1321
662
|
}
|
|
1322
663
|
}
|
|
664
|
+
// Try to read git HEAD (commit SHA)
|
|
665
|
+
this.commitSHA ??= resolveGitHeadSHA(gitFolderPath)
|
|
1323
666
|
}
|
|
1324
667
|
}
|
|
1325
668
|
|
|
1326
|
-
function getCounter (event, ddVar, otelVar) {
|
|
1327
|
-
const counters = TELEMETRY_COUNTERS.get(event)
|
|
1328
|
-
const tags = []
|
|
1329
|
-
const ddVarPrefix = 'config_datadog:'
|
|
1330
|
-
const otelVarPrefix = 'config_opentelemetry:'
|
|
1331
|
-
if (ddVar) {
|
|
1332
|
-
ddVar = ddVarPrefix + ddVar.toLowerCase()
|
|
1333
|
-
tags.push(ddVar)
|
|
1334
|
-
}
|
|
1335
|
-
if (otelVar) {
|
|
1336
|
-
otelVar = otelVarPrefix + otelVar.toLowerCase()
|
|
1337
|
-
tags.push(otelVar)
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
if (!(otelVar in counters)) counters[otelVar] = {}
|
|
1341
|
-
|
|
1342
|
-
const counter = tracerMetrics.count(event, tags)
|
|
1343
|
-
counters[otelVar][ddVar] = counter
|
|
1344
|
-
return counter
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
|
-
function getFromOtelSamplerMap (otelTracesSampler, otelTracesSamplerArg) {
|
|
1348
|
-
const OTEL_TRACES_SAMPLER_MAPPING = {
|
|
1349
|
-
always_on: '1.0',
|
|
1350
|
-
always_off: '0.0',
|
|
1351
|
-
traceidratio: otelTracesSamplerArg,
|
|
1352
|
-
parentbased_always_on: '1.0',
|
|
1353
|
-
parentbased_always_off: '0.0',
|
|
1354
|
-
parentbased_traceidratio: otelTracesSamplerArg,
|
|
1355
|
-
}
|
|
1356
|
-
return OTEL_TRACES_SAMPLER_MAPPING[otelTracesSampler]
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
669
|
/**
|
|
1360
|
-
*
|
|
1361
|
-
* @param {
|
|
1362
|
-
* @param {string} [value] - The value of the environment variable
|
|
1363
|
-
* @returns {boolean} - True if the value is valid, false otherwise
|
|
670
|
+
* @param {Config} config
|
|
671
|
+
* @param {ConfigKey} envVar
|
|
1364
672
|
*/
|
|
1365
|
-
function
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
case 'OTEL_PROPAGATORS':
|
|
1373
|
-
case 'OTEL_RESOURCE_ATTRIBUTES':
|
|
1374
|
-
case 'OTEL_SERVICE_NAME':
|
|
1375
|
-
return typeof value !== 'string'
|
|
1376
|
-
case 'OTEL_TRACES_SAMPLER':
|
|
1377
|
-
return getFromOtelSamplerMap(value, getEnv('OTEL_TRACES_SAMPLER_ARG')) === undefined
|
|
1378
|
-
case 'OTEL_TRACES_SAMPLER_ARG':
|
|
1379
|
-
return Number.isNaN(Number.parseFloat(value))
|
|
1380
|
-
case 'OTEL_SDK_DISABLED':
|
|
1381
|
-
return value.toLowerCase() !== 'true' && value.toLowerCase() !== 'false'
|
|
1382
|
-
case 'OTEL_TRACES_EXPORTER':
|
|
1383
|
-
case 'OTEL_METRICS_EXPORTER':
|
|
1384
|
-
case 'OTEL_LOGS_EXPORTER':
|
|
1385
|
-
return value.toLowerCase() !== 'none'
|
|
1386
|
-
default:
|
|
1387
|
-
return true
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
|
|
1391
|
-
function checkIfBothOtelAndDdEnvVarSet () {
|
|
1392
|
-
for (const [otelEnvVar, ddEnvVar] of OTEL_DD_ENV_MAPPING) {
|
|
1393
|
-
const otelValue = getEnv(otelEnvVar)
|
|
1394
|
-
|
|
1395
|
-
if (ddEnvVar && getEnv(ddEnvVar) && otelValue) {
|
|
1396
|
-
log.warn('both %s and %s environment variables are set', ddEnvVar, otelEnvVar)
|
|
1397
|
-
getCounter('otel.env.hiding', ddEnvVar, otelEnvVar).inc()
|
|
673
|
+
function deactivateIfEnabledAndWarnOnWindows (config, envVar) {
|
|
674
|
+
if (config[envVar]) {
|
|
675
|
+
const source = trackedConfigOrigins.get(envVar)
|
|
676
|
+
setAndTrack(config, envVar, false)
|
|
677
|
+
// TODO: Should we log even for default values?
|
|
678
|
+
if (source) {
|
|
679
|
+
log.warn('%s is not supported on Windows. Deactivating. (source: %s)', envVar, source)
|
|
1398
680
|
}
|
|
1399
|
-
|
|
1400
|
-
if (isInvalidOtelEnvironmentVariable(otelEnvVar, otelValue)) {
|
|
1401
|
-
log.warn('unexpected value %s for %s environment variable', otelValue, otelEnvVar)
|
|
1402
|
-
getCounter('otel.env.invalid', ddEnvVar, otelEnvVar).inc()
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
function maybeFile (filepath) {
|
|
1408
|
-
if (!filepath) return
|
|
1409
|
-
try {
|
|
1410
|
-
return fs.readFileSync(filepath, 'utf8')
|
|
1411
|
-
} catch (e) {
|
|
1412
|
-
log.error('Error reading file %s', filepath, e)
|
|
1413
|
-
}
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
|
-
function maybeJsonFile (filepath) {
|
|
1417
|
-
const file = maybeFile(filepath)
|
|
1418
|
-
if (!file) return
|
|
1419
|
-
try {
|
|
1420
|
-
return JSON.parse(file)
|
|
1421
|
-
} catch (e) {
|
|
1422
|
-
log.error('Error parsing JSON file %s', filepath, e)
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
|
-
|
|
1426
|
-
function safeJsonParse (input) {
|
|
1427
|
-
try {
|
|
1428
|
-
return JSON.parse(input)
|
|
1429
|
-
} catch {}
|
|
1430
|
-
}
|
|
1431
|
-
|
|
1432
|
-
function validateNamingVersion (versionString) {
|
|
1433
|
-
if (!versionString) {
|
|
1434
|
-
return DEFAULT_NAMING_VERSION
|
|
1435
|
-
}
|
|
1436
|
-
if (!NAMING_VERSIONS.has(versionString)) {
|
|
1437
|
-
log.warn('Unexpected input for config.spanAttributeSchema, picked default', DEFAULT_NAMING_VERSION)
|
|
1438
|
-
return DEFAULT_NAMING_VERSION
|
|
1439
681
|
}
|
|
1440
|
-
return versionString
|
|
1441
682
|
}
|
|
1442
683
|
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
*
|
|
1448
|
-
* @param {string | string[]} input
|
|
1449
|
-
*/
|
|
1450
|
-
function splitJSONPathRules (input) {
|
|
1451
|
-
if (!input || input === '$') return
|
|
1452
|
-
if (Array.isArray(input)) return input
|
|
1453
|
-
if (input === 'all') return []
|
|
1454
|
-
return input.split(',')
|
|
1455
|
-
}
|
|
1456
|
-
|
|
1457
|
-
// Shallow clone with property name remapping
|
|
1458
|
-
function remapify (input, mappings) {
|
|
1459
|
-
if (!input) return
|
|
1460
|
-
const output = {}
|
|
1461
|
-
for (const [key, value] of Object.entries(input)) {
|
|
1462
|
-
output[key in mappings ? mappings[key] : key] = value
|
|
1463
|
-
}
|
|
1464
|
-
return output
|
|
1465
|
-
}
|
|
1466
|
-
|
|
1467
|
-
/**
|
|
1468
|
-
* Normalizes propagation style values to a lowercase array.
|
|
1469
|
-
* Handles both string (comma-separated) and array inputs.
|
|
1470
|
-
*/
|
|
1471
|
-
function normalizePropagationStyle (value) {
|
|
1472
|
-
if (Array.isArray(value)) {
|
|
1473
|
-
return value.map(v => v.toLowerCase())
|
|
1474
|
-
}
|
|
1475
|
-
if (typeof value === 'string') {
|
|
1476
|
-
return value.split(',')
|
|
1477
|
-
.filter(v => v !== '')
|
|
1478
|
-
.map(v => v.trim().toLowerCase())
|
|
1479
|
-
}
|
|
1480
|
-
if (value !== undefined) {
|
|
1481
|
-
log.warn('Unexpected input for config.tracePropagationStyle')
|
|
684
|
+
function increaseCounter (event, ddVar, otelVar) {
|
|
685
|
+
const tags = []
|
|
686
|
+
if (ddVar) {
|
|
687
|
+
tags.push(`config_datadog:${ddVar.toLowerCase()}`)
|
|
1482
688
|
}
|
|
689
|
+
tags.push(`config_opentelemetry:${otelVar.toLowerCase()}`)
|
|
690
|
+
tracerMetrics.count(event, tags).inc()
|
|
1483
691
|
}
|
|
1484
692
|
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
// eslint-disable-next-line @stylistic/max-len
|
|
1492
|
-
'Use either the DD_TRACE_PROPAGATION_STYLE environment variable or separate DD_TRACE_PROPAGATION_STYLE_INJECT and DD_TRACE_PROPAGATION_STYLE_EXTRACT environment variables'
|
|
1493
|
-
)
|
|
693
|
+
function getFromOtelSamplerMap (otelTracesSampler, otelTracesSamplerArg) {
|
|
694
|
+
const OTEL_TRACES_SAMPLER_MAPPING = {
|
|
695
|
+
always_on: 1,
|
|
696
|
+
always_off: 0,
|
|
697
|
+
parentbased_always_on: 1,
|
|
698
|
+
parentbased_always_off: 0,
|
|
1494
699
|
}
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
|
-
function reformatSpanSamplingRules (rules) {
|
|
1498
|
-
if (!rules) return rules
|
|
1499
|
-
return rules.map(rule => {
|
|
1500
|
-
return remapify(rule, {
|
|
1501
|
-
sample_rate: 'sampleRate',
|
|
1502
|
-
max_per_second: 'maxPerSecond',
|
|
1503
|
-
})
|
|
1504
|
-
})
|
|
1505
|
-
}
|
|
1506
700
|
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
getEnv('DD_TRACE_EXPERIMENTAL_B3_ENABLED')
|
|
1511
|
-
const defaultPropagationStyle = ['datadog', 'tracecontext']
|
|
1512
|
-
if (isTrue(DD_TRACE_B3_ENABLED)) {
|
|
1513
|
-
defaultPropagationStyle.push('b3', 'b3 single header')
|
|
701
|
+
const result = OTEL_TRACES_SAMPLER_MAPPING[otelTracesSampler] ?? otelTracesSamplerArg
|
|
702
|
+
if (result === undefined) {
|
|
703
|
+
increaseCounter('otel.env.invalid', 'DD_TRACE_SAMPLE_RATE', 'OTEL_TRACES_SAMPLER')
|
|
1514
704
|
}
|
|
1515
|
-
return
|
|
705
|
+
return result
|
|
1516
706
|
}
|
|
1517
707
|
|
|
1518
|
-
function
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
708
|
+
function warnWrongOtelSettings () {
|
|
709
|
+
// This mostly works for non-aliased environment variables only.
|
|
710
|
+
// TODO: Adjust this to work across all sources.
|
|
711
|
+
for (const [otelEnvVar, ddEnvVar, key] of [
|
|
712
|
+
// eslint-disable-next-line eslint-rules/eslint-env-aliases
|
|
713
|
+
['OTEL_LOG_LEVEL', 'DD_TRACE_LOG_LEVEL', 'logLevel'],
|
|
714
|
+
// eslint-disable-next-line eslint-rules/eslint-env-aliases
|
|
715
|
+
['OTEL_PROPAGATORS', 'DD_TRACE_PROPAGATION_STYLE'],
|
|
716
|
+
// eslint-disable-next-line eslint-rules/eslint-env-aliases
|
|
717
|
+
['OTEL_SERVICE_NAME', 'DD_SERVICE', 'service'],
|
|
718
|
+
['OTEL_TRACES_SAMPLER', 'DD_TRACE_SAMPLE_RATE'],
|
|
719
|
+
['OTEL_TRACES_SAMPLER_ARG', 'DD_TRACE_SAMPLE_RATE'],
|
|
720
|
+
['OTEL_TRACES_EXPORTER', 'DD_TRACE_ENABLED'],
|
|
721
|
+
['OTEL_METRICS_EXPORTER', 'DD_RUNTIME_METRICS_ENABLED'],
|
|
722
|
+
['OTEL_RESOURCE_ATTRIBUTES', 'DD_TAGS'],
|
|
723
|
+
['OTEL_SDK_DISABLED', 'DD_TRACE_OTEL_ENABLED'],
|
|
724
|
+
['OTEL_LOGS_EXPORTER'],
|
|
725
|
+
]) {
|
|
726
|
+
// eslint-disable-next-line eslint-rules/eslint-process-env
|
|
727
|
+
const envs = process.env
|
|
728
|
+
const otelSource = trackedConfigOrigins.get(/** @type {ConfigPath} */ (key ?? otelEnvVar))
|
|
729
|
+
const otelEnvValue = envs[otelEnvVar]
|
|
730
|
+
if (otelEnvValue) {
|
|
731
|
+
if (envs[ddEnvVar]) {
|
|
732
|
+
log.warn('Conflicting %s and %s environment variables are set for %s', ddEnvVar, otelEnvVar, otelSource)
|
|
733
|
+
increaseCounter('otel.env.hiding', ddEnvVar, otelEnvVar)
|
|
1528
734
|
}
|
|
1529
|
-
rule.tags = reformattedTags
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
return samplingRules
|
|
1533
|
-
}
|
|
1534
|
-
|
|
1535
|
-
function setBoolean (obj, name, value) {
|
|
1536
|
-
if (value === undefined || value === null) {
|
|
1537
|
-
obj[name] = value
|
|
1538
|
-
} else if (isTrue(value)) {
|
|
1539
|
-
obj[name] = true
|
|
1540
|
-
} else if (isFalse(value)) {
|
|
1541
|
-
obj[name] = false
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
|
|
1545
|
-
function setUnit (obj, name, value) {
|
|
1546
|
-
if (value === null || value === undefined) {
|
|
1547
|
-
obj[name] = value
|
|
1548
|
-
return
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
value = Number.parseFloat(value)
|
|
1552
|
-
|
|
1553
|
-
if (!Number.isNaN(value)) {
|
|
1554
|
-
// TODO: Ignore out of range values instead of normalizing them.
|
|
1555
|
-
obj[name] = Math.min(Math.max(value, 0), 1)
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
|
|
1559
|
-
function setArray (obj, name, value) {
|
|
1560
|
-
if (value == null) {
|
|
1561
|
-
obj[name] = null
|
|
1562
|
-
return
|
|
1563
|
-
}
|
|
1564
|
-
|
|
1565
|
-
if (typeof value === 'string') {
|
|
1566
|
-
value = value.split(',').map(item => {
|
|
1567
|
-
// Trim each item and remove whitespace around the colon
|
|
1568
|
-
const [key, val] = item.split(':').map(part => part.trim())
|
|
1569
|
-
return val === undefined ? key : `${key}:${val}`
|
|
1570
|
-
})
|
|
1571
|
-
}
|
|
1572
735
|
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
obj[name] = null
|
|
1581
|
-
return
|
|
1582
|
-
}
|
|
1583
|
-
value = value.split(',')
|
|
1584
|
-
const result = []
|
|
1585
|
-
|
|
1586
|
-
for (const val of value) {
|
|
1587
|
-
if (val.includes('-')) {
|
|
1588
|
-
const [start, end] = val.split('-').map(Number)
|
|
1589
|
-
for (let i = start; i <= end; i++) {
|
|
1590
|
-
result.push(i)
|
|
736
|
+
// eslint-disable-next-line eslint-rules/eslint-env-aliases
|
|
737
|
+
const invalidOtelValue = otelEnvVar === 'OTEL_PROPAGATORS'
|
|
738
|
+
? trackedConfigOrigins.get(/** @type {ConfigPath} */ ('tracePropagationStyle.inject')) !== otelSource &&
|
|
739
|
+
!envs[ddEnvVar]
|
|
740
|
+
: !otelSource
|
|
741
|
+
if (invalidOtelValue) {
|
|
742
|
+
increaseCounter('otel.env.invalid', ddEnvVar, otelEnvVar)
|
|
1591
743
|
}
|
|
1592
|
-
} else {
|
|
1593
|
-
result.push(Number(val))
|
|
1594
744
|
}
|
|
1595
745
|
}
|
|
1596
|
-
obj[name] = result
|
|
1597
|
-
}
|
|
1598
|
-
|
|
1599
|
-
function setSamplingRule (obj, name, value) {
|
|
1600
|
-
if (value == null) {
|
|
1601
|
-
obj[name] = null
|
|
1602
|
-
return
|
|
1603
|
-
}
|
|
1604
|
-
|
|
1605
|
-
if (typeof value === 'string') {
|
|
1606
|
-
value = value.split(',')
|
|
1607
|
-
}
|
|
1608
|
-
|
|
1609
|
-
if (Array.isArray(value)) {
|
|
1610
|
-
value = value.map(rule => {
|
|
1611
|
-
return remapify(rule, {
|
|
1612
|
-
sample_rate: 'sampleRate',
|
|
1613
|
-
})
|
|
1614
|
-
})
|
|
1615
|
-
obj[name] = value
|
|
1616
|
-
}
|
|
1617
|
-
}
|
|
1618
|
-
|
|
1619
|
-
function setString (obj, name, value) {
|
|
1620
|
-
obj[name] = value ? String(value) : undefined // unset for empty strings
|
|
1621
|
-
}
|
|
1622
|
-
|
|
1623
|
-
function setTags (obj, name, value) {
|
|
1624
|
-
if (!value || Object.keys(value).length === 0) {
|
|
1625
|
-
obj[name] = null
|
|
1626
|
-
return
|
|
1627
|
-
}
|
|
1628
|
-
|
|
1629
|
-
obj[name] = value
|
|
1630
|
-
}
|
|
1631
|
-
|
|
1632
|
-
function handleOtel (tagString) {
|
|
1633
|
-
return tagString
|
|
1634
|
-
?.replace(/(^|,)deployment\.environment=/, '$1env:')
|
|
1635
|
-
.replace(/(^|,)service\.name=/, '$1service:')
|
|
1636
|
-
.replace(/(^|,)service\.version=/, '$1version:')
|
|
1637
|
-
.replaceAll('=', ':')
|
|
1638
|
-
}
|
|
1639
|
-
|
|
1640
|
-
function parseSpaceSeparatedTags (tagString) {
|
|
1641
|
-
if (tagString && !tagString.includes(',')) {
|
|
1642
|
-
tagString = tagString.replaceAll(/\s+/g, ',')
|
|
1643
|
-
}
|
|
1644
|
-
return tagString
|
|
1645
|
-
}
|
|
1646
|
-
|
|
1647
|
-
function maybeInt (number) {
|
|
1648
|
-
const parsed = Number.parseInt(number)
|
|
1649
|
-
return Number.isNaN(parsed) ? undefined : parsed
|
|
1650
|
-
}
|
|
1651
|
-
|
|
1652
|
-
function maybeFloat (number) {
|
|
1653
|
-
const parsed = Number.parseFloat(number)
|
|
1654
|
-
return Number.isNaN(parsed) ? undefined : parsed
|
|
1655
|
-
}
|
|
1656
|
-
|
|
1657
|
-
function nonNegInt (value, envVarName, allowZero = true) {
|
|
1658
|
-
if (value === undefined) return
|
|
1659
|
-
const parsed = Number.parseInt(value)
|
|
1660
|
-
if (Number.isNaN(parsed) || parsed < 0 || (parsed === 0 && !allowZero)) {
|
|
1661
|
-
log.warn('Invalid value %d for %s. Using default value.', parsed, envVarName)
|
|
1662
|
-
return
|
|
1663
|
-
}
|
|
1664
|
-
return parsed
|
|
1665
|
-
}
|
|
1666
|
-
|
|
1667
|
-
function getAgentUrl (url, options) {
|
|
1668
|
-
if (url) return new URL(url)
|
|
1669
|
-
|
|
1670
|
-
if (os.type() === 'Windows_NT') return
|
|
1671
|
-
|
|
1672
|
-
if (
|
|
1673
|
-
!options.hostname &&
|
|
1674
|
-
!options.port &&
|
|
1675
|
-
!getEnv('DD_AGENT_HOST') &&
|
|
1676
|
-
!getEnv('DD_TRACE_AGENT_PORT') &&
|
|
1677
|
-
!isTrue(getEnv('DD_CIVISIBILITY_AGENTLESS_ENABLED')) &&
|
|
1678
|
-
fs.existsSync('/var/run/datadog/apm.socket')
|
|
1679
|
-
) {
|
|
1680
|
-
return new URL('unix:///var/run/datadog/apm.socket')
|
|
1681
|
-
}
|
|
1682
746
|
}
|
|
1683
747
|
|
|
748
|
+
/**
|
|
749
|
+
* @param {TracerOptions} [options]
|
|
750
|
+
*/
|
|
1684
751
|
function getConfig (options) {
|
|
1685
752
|
if (!configInstance) {
|
|
1686
753
|
configInstance = new Config(options)
|