dd-trace 4.29.0 → 4.30.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.
Files changed (52) hide show
  1. package/README.md +7 -0
  2. package/ci/cypress/after-spec.js +1 -0
  3. package/index.d.ts +1499 -1486
  4. package/package.json +3 -3
  5. package/packages/datadog-core/src/utils/src/get.js +11 -0
  6. package/packages/datadog-core/src/utils/src/has.js +14 -0
  7. package/packages/datadog-core/src/utils/src/set.js +16 -0
  8. package/packages/datadog-instrumentations/src/amqplib.js +1 -1
  9. package/packages/datadog-instrumentations/src/cucumber.js +2 -1
  10. package/packages/datadog-instrumentations/src/grpc/server.js +3 -1
  11. package/packages/datadog-instrumentations/src/jest.js +11 -5
  12. package/packages/datadog-instrumentations/src/mocha.js +4 -1
  13. package/packages/datadog-instrumentations/src/mongodb-core.js +34 -3
  14. package/packages/datadog-instrumentations/src/playwright.js +78 -16
  15. package/packages/datadog-plugin-amqplib/src/consumer.js +5 -4
  16. package/packages/datadog-plugin-amqplib/src/producer.js +3 -4
  17. package/packages/datadog-plugin-aws-sdk/src/base.js +3 -2
  18. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -11
  19. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +3 -6
  20. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +5 -7
  21. package/packages/datadog-plugin-cypress/src/after-spec.js +3 -0
  22. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +123 -58
  23. package/packages/datadog-plugin-cypress/src/support.js +50 -3
  24. package/packages/datadog-plugin-graphql/src/index.js +1 -1
  25. package/packages/datadog-plugin-graphql/src/resolve.js +10 -8
  26. package/packages/datadog-plugin-grpc/src/util.js +1 -1
  27. package/packages/datadog-plugin-jest/src/index.js +11 -2
  28. package/packages/datadog-plugin-kafkajs/src/consumer.js +4 -3
  29. package/packages/datadog-plugin-kafkajs/src/producer.js +3 -5
  30. package/packages/datadog-plugin-playwright/src/index.js +34 -3
  31. package/packages/datadog-plugin-rhea/src/consumer.js +5 -3
  32. package/packages/datadog-plugin-rhea/src/producer.js +3 -4
  33. package/packages/dd-trace/src/appsec/iast/index.js +10 -0
  34. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +18 -5
  35. package/packages/dd-trace/src/appsec/recommended.json +67 -27
  36. package/packages/dd-trace/src/appsec/remote_config/index.js +1 -1
  37. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -3
  38. package/packages/dd-trace/src/config.js +451 -460
  39. package/packages/dd-trace/src/data_streams_context.js +1 -1
  40. package/packages/dd-trace/src/datastreams/pathway.js +58 -1
  41. package/packages/dd-trace/src/datastreams/processor.js +3 -5
  42. package/packages/dd-trace/src/format.js +0 -1
  43. package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -1
  44. package/packages/dd-trace/src/plugins/util/test.js +2 -0
  45. package/packages/dd-trace/src/plugins/util/web.js +1 -1
  46. package/packages/dd-trace/src/profiling/exporters/agent.js +38 -2
  47. package/packages/dd-trace/src/telemetry/index.js +22 -34
  48. package/packages/dd-trace/src/tracer.js +3 -3
  49. package/register.js +4 -0
  50. /package/packages/{utils → datadog-core/src/utils}/src/kebabcase.js +0 -0
  51. /package/packages/{utils → datadog-core/src/utils}/src/pick.js +0 -0
  52. /package/packages/{utils → datadog-core/src/utils}/src/uniq.js +0 -0
@@ -8,6 +8,9 @@ const log = require('./log')
8
8
  const pkg = require('./pkg')
9
9
  const coalesce = require('koalas')
10
10
  const tagger = require('./tagger')
11
+ const get = require('../../datadog-core/src/utils/src/get')
12
+ const has = require('../../datadog-core/src/utils/src/has')
13
+ const set = require('../../datadog-core/src/utils/src/set')
11
14
  const { isTrue, isFalse } = require('./util')
12
15
  const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('./plugins/util/tags')
13
16
  const { getGitMetadataFromGitProperties, removeUserSensitiveInfo } = require('./git_properties')
@@ -20,6 +23,13 @@ const fromEntries = Object.fromEntries || (entries =>
20
23
 
21
24
  // eslint-disable-next-line max-len
22
25
  const qsRegex = '(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:(?:\\s|%20)*(?:=|%3D)[^&]+|(?:"|%22)(?:\\s|%20)*(?::|%3A)(?:\\s|%20)*(?:"|%22)(?:%2[^2]|%[^2]|[^"%])+(?:"|%22))|bearer(?:\\s|%20)+[a-z0-9\\._\\-]+|token(?::|%3A)[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L](?:[\\w=-]|%3D)+\\.ey[I-L](?:[\\w=-]|%3D)+(?:\\.(?:[\\w.+\\/=-]|%3D|%2F|%2B)+)?|[\\-]{5}BEGIN(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY[\\-]{5}[^\\-]+[\\-]{5}END(?:[a-z\\s]|%20)+PRIVATE(?:\\s|%20)KEY|ssh-rsa(?:\\s|%20)*(?:[a-z0-9\\/\\.+]|%2F|%5C|%2B){100,}'
26
+ const defaultWafObfuscatorKeyRegex = `(?i)(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?\
27
+ |public_?)key)|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)|bearer|authorization`
28
+ const defaultWafObfuscatorValueRegex =
29
+ `(?i)(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|to\
30
+ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:\\s*=[^;]|"\\s*:\\s*"[^"]+")|bearer\
31
+ \\s+[a-z0-9\\._\\-]+|token:[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L][\\w=-]+\\.ey[I-L][\\w=-]+(?:\\.[\\w.+\\/=-]+)?\
32
+ |[\\-]{5}BEGIN[a-z\\s]+PRIVATE\\sKEY[\\-]{5}[^\\-]+[\\-]{5}END[a-z\\s]+PRIVATE\\sKEY|ssh-rsa\\s*[a-z0-9\\/\\.+]{100,}`
23
33
 
24
34
  function maybeFile (filepath) {
25
35
  if (!filepath) return
@@ -94,6 +104,11 @@ function propagationStyle (key, option, defaultValue) {
94
104
  class Config {
95
105
  constructor (options) {
96
106
  options = options || {}
107
+ options = this.options = {
108
+ ...options,
109
+ appsec: options.appsec != null ? options.appsec : options.experimental?.appsec,
110
+ iastOptions: options.experimental?.iast
111
+ }
97
112
 
98
113
  // Configure the logger first so it can be used to warn about other configs
99
114
  this.debug = isTrue(coalesce(
@@ -110,70 +125,6 @@ class Config {
110
125
  log.use(this.logger)
111
126
  log.toggle(this.debug, this.logLevel, this)
112
127
 
113
- const DD_PROFILING_ENABLED = coalesce(
114
- options.profiling, // TODO: remove when enabled by default
115
- process.env.DD_EXPERIMENTAL_PROFILING_ENABLED,
116
- process.env.DD_PROFILING_ENABLED,
117
- false
118
- )
119
- const DD_PROFILING_EXPORTERS = coalesce(
120
- process.env.DD_PROFILING_EXPORTERS,
121
- 'agent'
122
- )
123
- const DD_PROFILING_SOURCE_MAP = process.env.DD_PROFILING_SOURCE_MAP
124
- const DD_RUNTIME_METRICS_ENABLED = coalesce(
125
- options.runtimeMetrics, // TODO: remove when enabled by default
126
- process.env.DD_RUNTIME_METRICS_ENABLED,
127
- false
128
- )
129
- const DD_DBM_PROPAGATION_MODE = coalesce(
130
- options.dbmPropagationMode,
131
- process.env.DD_DBM_PROPAGATION_MODE,
132
- 'disabled'
133
- )
134
- const DD_DATA_STREAMS_ENABLED = coalesce(
135
- options.dsmEnabled,
136
- process.env.DD_DATA_STREAMS_ENABLED,
137
- false
138
- )
139
- const DD_AGENT_HOST = coalesce(
140
- options.hostname,
141
- process.env.DD_AGENT_HOST,
142
- process.env.DD_TRACE_AGENT_HOSTNAME,
143
- '127.0.0.1'
144
- )
145
- const DD_TRACE_AGENT_PORT = coalesce(
146
- options.port,
147
- process.env.DD_TRACE_AGENT_PORT,
148
- '8126'
149
- )
150
- const DD_TRACE_AGENT_URL = coalesce(
151
- options.url,
152
- process.env.DD_TRACE_AGENT_URL,
153
- process.env.DD_TRACE_URL,
154
- null
155
- )
156
- const DD_IS_CIVISIBILITY = coalesce(
157
- options.isCiVisibility,
158
- false
159
- )
160
- const DD_CIVISIBILITY_AGENTLESS_URL = process.env.DD_CIVISIBILITY_AGENTLESS_URL
161
-
162
- const DD_CIVISIBILITY_ITR_ENABLED = coalesce(
163
- process.env.DD_CIVISIBILITY_ITR_ENABLED,
164
- true
165
- )
166
-
167
- const DD_CIVISIBILITY_MANUAL_API_ENABLED = coalesce(
168
- process.env.DD_CIVISIBILITY_MANUAL_API_ENABLED,
169
- false
170
- )
171
-
172
- const DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED = coalesce(
173
- process.env.DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED,
174
- true
175
- )
176
-
177
128
  const DD_TRACE_MEMCACHED_COMMAND_ENABLED = coalesce(
178
129
  process.env.DD_TRACE_MEMCACHED_COMMAND_ENABLED,
179
130
  false
@@ -185,75 +136,12 @@ class Config {
185
136
  process.env.DD_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
186
137
  ) : {}
187
138
  )
188
- const DD_TRACE_STARTUP_LOGS = coalesce(
189
- options.startupLogs,
190
- process.env.DD_TRACE_STARTUP_LOGS,
191
- false
192
- )
193
-
194
- const DD_OPENAI_LOGS_ENABLED = coalesce(
195
- options.openAiLogsEnabled,
196
- process.env.DD_OPENAI_LOGS_ENABLED,
197
- false
198
- )
199
139
 
200
140
  const DD_API_KEY = coalesce(
201
141
  process.env.DATADOG_API_KEY,
202
142
  process.env.DD_API_KEY
203
143
  )
204
144
 
205
- const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
206
-
207
- const isGCPFunction = getIsGCPFunction()
208
- const isAzureFunctionConsumptionPlan = getIsAzureFunctionConsumptionPlan()
209
-
210
- const inServerlessEnvironment = inAWSLambda || isGCPFunction || isAzureFunctionConsumptionPlan
211
-
212
- const isJestWorker = !!process.env.JEST_WORKER_ID
213
-
214
- const DD_INSTRUMENTATION_TELEMETRY_ENABLED = coalesce(
215
- process.env.DD_TRACE_TELEMETRY_ENABLED, // for backward compatibility
216
- process.env.DD_INSTRUMENTATION_TELEMETRY_ENABLED, // to comply with instrumentation telemetry specs
217
- !(inServerlessEnvironment || isJestWorker)
218
- )
219
- const DD_TELEMETRY_HEARTBEAT_INTERVAL = process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL
220
- ? Math.floor(parseFloat(process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL) * 1000)
221
- : 60000
222
- const DD_OPENAI_SPAN_CHAR_LIMIT = process.env.DD_OPENAI_SPAN_CHAR_LIMIT
223
- ? parseInt(process.env.DD_OPENAI_SPAN_CHAR_LIMIT)
224
- : 128
225
- const DD_TELEMETRY_DEBUG = coalesce(
226
- process.env.DD_TELEMETRY_DEBUG,
227
- false
228
- )
229
- const DD_TELEMETRY_METRICS_ENABLED = coalesce(
230
- process.env.DD_TELEMETRY_METRICS_ENABLED,
231
- true
232
- )
233
- const DD_TRACE_AGENT_PROTOCOL_VERSION = coalesce(
234
- options.protocolVersion,
235
- process.env.DD_TRACE_AGENT_PROTOCOL_VERSION,
236
- '0.4'
237
- )
238
- const DD_TRACE_PARTIAL_FLUSH_MIN_SPANS = coalesce(
239
- parseInt(options.flushMinSpans),
240
- parseInt(process.env.DD_TRACE_PARTIAL_FLUSH_MIN_SPANS),
241
- 1000
242
- )
243
- const DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP = coalesce(
244
- process.env.DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
245
- qsRegex
246
- )
247
- const DD_TRACE_CLIENT_IP_ENABLED = coalesce(
248
- options.clientIpEnabled,
249
- process.env.DD_TRACE_CLIENT_IP_ENABLED && isTrue(process.env.DD_TRACE_CLIENT_IP_ENABLED),
250
- false
251
- )
252
- const DD_TRACE_CLIENT_IP_HEADER = coalesce(
253
- options.clientIpHeader,
254
- process.env.DD_TRACE_CLIENT_IP_HEADER,
255
- null
256
- )
257
145
  // TODO: Remove the experimental env vars as a major?
258
146
  const DD_TRACE_B3_ENABLED = coalesce(
259
147
  options.experimental && options.experimental.b3,
@@ -289,238 +177,36 @@ class Config {
289
177
  process.env.DD_TRACE_PROPAGATION_EXTRACT_FIRST,
290
178
  false
291
179
  )
292
- const DD_TRACE_RUNTIME_ID_ENABLED = coalesce(
293
- options.experimental && options.experimental.runtimeId,
294
- process.env.DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED,
295
- false
296
- )
297
- const DD_TRACE_EXPORTER = coalesce(
298
- options.experimental && options.experimental.exporter,
299
- process.env.DD_TRACE_EXPERIMENTAL_EXPORTER
300
- )
301
- const DD_TRACE_GET_RUM_DATA_ENABLED = coalesce(
302
- options.experimental && options.experimental.enableGetRumData,
303
- process.env.DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
304
- false
305
- )
306
- const DD_TRACE_SPAN_ATTRIBUTE_SCHEMA = validateNamingVersion(
307
- coalesce(
308
- options.spanAttributeSchema,
309
- process.env.DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
310
- )
311
- )
312
- const DD_TRACE_PEER_SERVICE_MAPPING = coalesce(
313
- options.peerServiceMapping,
314
- process.env.DD_TRACE_PEER_SERVICE_MAPPING ? fromEntries(
315
- process.env.DD_TRACE_PEER_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
316
- ) : {}
317
- )
318
-
319
- const peerServiceSet = (
320
- options.hasOwnProperty('spanComputePeerService') ||
321
- process.env.hasOwnProperty('DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED')
322
- )
323
- const peerServiceValue = coalesce(
324
- options.spanComputePeerService,
325
- process.env.DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED
326
- )
327
-
328
- const DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED = (
329
- DD_TRACE_SPAN_ATTRIBUTE_SCHEMA === 'v0'
330
- // In v0, peer service is computed only if it is explicitly set to true
331
- ? peerServiceSet && isTrue(peerServiceValue)
332
- // In >v0, peer service is false only if it is explicitly set to false
333
- : (peerServiceSet ? !isFalse(peerServiceValue) : true)
334
- )
335
-
336
- const DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED = coalesce(
337
- options.spanRemoveIntegrationFromService,
338
- isTrue(process.env.DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED)
339
- )
340
- const DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH = coalesce(
341
- process.env.DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
342
- '512'
343
- )
344
-
345
- const DD_TRACE_STATS_COMPUTATION_ENABLED = coalesce(
346
- options.stats,
347
- process.env.DD_TRACE_STATS_COMPUTATION_ENABLED,
348
- isGCPFunction || isAzureFunctionConsumptionPlan
349
- )
350
-
351
- // the tracer generates 128 bit IDs by default as of v5
352
- const DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED = coalesce(
353
- options.traceId128BitGenerationEnabled,
354
- process.env.DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED,
355
- true
356
- )
357
-
358
- const DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED = coalesce(
359
- options.traceId128BitLoggingEnabled,
360
- process.env.DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED,
361
- false
362
- )
363
180
 
364
- let appsec = options.appsec != null ? options.appsec : options.experimental && options.experimental.appsec
365
-
366
- if (typeof appsec === 'boolean') {
367
- appsec = {
368
- enabled: appsec
181
+ if (typeof options.appsec === 'boolean') {
182
+ options.appsec = {
183
+ enabled: options.appsec
369
184
  }
370
- } else if (appsec == null) {
371
- appsec = {}
185
+ } else if (options.appsec == null) {
186
+ options.appsec = {}
372
187
  }
373
188
 
374
- const DD_APPSEC_ENABLED = coalesce(
375
- appsec.enabled,
376
- process.env.DD_APPSEC_ENABLED && isTrue(process.env.DD_APPSEC_ENABLED)
377
- )
378
- const DD_APPSEC_RULES = coalesce(
379
- appsec.rules,
380
- process.env.DD_APPSEC_RULES
381
- )
382
- const DD_APPSEC_TRACE_RATE_LIMIT = coalesce(
383
- parseInt(appsec.rateLimit),
384
- parseInt(process.env.DD_APPSEC_TRACE_RATE_LIMIT),
385
- 100
386
- )
387
- const DD_APPSEC_WAF_TIMEOUT = coalesce(
388
- parseInt(appsec.wafTimeout),
389
- parseInt(process.env.DD_APPSEC_WAF_TIMEOUT),
390
- 5e3 // µs
391
- )
392
- const DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP = coalesce(
393
- appsec.obfuscatorKeyRegex,
394
- process.env.DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP,
395
- `(?i)(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?)key)|token|consumer_?(?:id|key|se\
396
- cret)|sign(?:ed|ature)|bearer|authorization`
397
- )
398
- const DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP = coalesce(
399
- appsec.obfuscatorValueRegex,
400
- process.env.DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP,
401
- `(?i)(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|to\
402
- ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)(?:\\s*=[^;]|"\\s*:\\s*"[^"]+")|bearer\
403
- \\s+[a-z0-9\\._\\-]+|token:[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L][\\w=-]+\\.ey[I-L][\\w=-]+(?:\\.[\\w.+\\/=-]+)?\
404
- |[\\-]{5}BEGIN[a-z\\s]+PRIVATE\\sKEY[\\-]{5}[^\\-]+[\\-]{5}END[a-z\\s]+PRIVATE\\sKEY|ssh-rsa\\s*[a-z0-9\\/\\.+]{100,}`
405
- )
406
- const DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML = coalesce(
407
- maybeFile(appsec.blockedTemplateHtml),
408
- maybeFile(process.env.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML)
409
- )
410
- const DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON = coalesce(
411
- maybeFile(appsec.blockedTemplateJson),
412
- maybeFile(process.env.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON)
413
- )
414
189
  const DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON = coalesce(
415
- maybeFile(appsec.blockedTemplateGraphql),
190
+ maybeFile(options.appsec.blockedTemplateGraphql),
416
191
  maybeFile(process.env.DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON)
417
192
  )
418
193
  const DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING = coalesce(
419
- appsec.eventTracking && appsec.eventTracking.mode,
194
+ options.appsec.eventTracking && options.appsec.eventTracking.mode,
420
195
  process.env.DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING,
421
196
  'safe'
422
197
  ).toLowerCase()
423
198
  const DD_API_SECURITY_ENABLED = coalesce(
424
- appsec?.apiSecurity?.enabled,
199
+ options.appsec?.apiSecurity?.enabled,
425
200
  process.env.DD_API_SECURITY_ENABLED && isTrue(process.env.DD_API_SECURITY_ENABLED),
426
201
  process.env.DD_EXPERIMENTAL_API_SECURITY_ENABLED && isTrue(process.env.DD_EXPERIMENTAL_API_SECURITY_ENABLED),
427
202
  true
428
203
  )
429
204
  const DD_API_SECURITY_REQUEST_SAMPLE_RATE = coalesce(
430
- appsec?.apiSecurity?.requestSampling,
205
+ options.appsec?.apiSecurity?.requestSampling,
431
206
  parseFloat(process.env.DD_API_SECURITY_REQUEST_SAMPLE_RATE),
432
207
  0.1
433
208
  )
434
209
 
435
- const remoteConfigOptions = options.remoteConfig || {}
436
- const DD_REMOTE_CONFIGURATION_ENABLED = coalesce(
437
- process.env.DD_REMOTE_CONFIGURATION_ENABLED && isTrue(process.env.DD_REMOTE_CONFIGURATION_ENABLED),
438
- !inServerlessEnvironment
439
- )
440
- const DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS = coalesce(
441
- parseFloat(remoteConfigOptions.pollInterval),
442
- parseFloat(process.env.DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS),
443
- 5 // seconds
444
- )
445
-
446
- const iastOptions = options?.experimental?.iast
447
- const DD_IAST_ENABLED = coalesce(
448
- iastOptions &&
449
- (iastOptions === true || iastOptions.enabled === true),
450
- process.env.DD_IAST_ENABLED,
451
- false
452
- )
453
- const DD_TELEMETRY_LOG_COLLECTION_ENABLED = coalesce(
454
- process.env.DD_TELEMETRY_LOG_COLLECTION_ENABLED,
455
- DD_IAST_ENABLED
456
- )
457
-
458
- const DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED = coalesce(
459
- process.env.DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED,
460
- true
461
- )
462
-
463
- const defaultIastRequestSampling = 30
464
- const iastRequestSampling = coalesce(
465
- parseInt(iastOptions?.requestSampling),
466
- parseInt(process.env.DD_IAST_REQUEST_SAMPLING),
467
- defaultIastRequestSampling
468
- )
469
- const DD_IAST_REQUEST_SAMPLING = iastRequestSampling < 0 ||
470
- iastRequestSampling > 100 ? defaultIastRequestSampling : iastRequestSampling
471
-
472
- const DD_IAST_MAX_CONCURRENT_REQUESTS = coalesce(
473
- parseInt(iastOptions?.maxConcurrentRequests),
474
- parseInt(process.env.DD_IAST_MAX_CONCURRENT_REQUESTS),
475
- 2
476
- )
477
-
478
- const DD_IAST_MAX_CONTEXT_OPERATIONS = coalesce(
479
- parseInt(iastOptions?.maxContextOperations),
480
- parseInt(process.env.DD_IAST_MAX_CONTEXT_OPERATIONS),
481
- 2
482
- )
483
-
484
- const DD_IAST_DEDUPLICATION_ENABLED = coalesce(
485
- iastOptions?.deduplicationEnabled,
486
- process.env.DD_IAST_DEDUPLICATION_ENABLED && isTrue(process.env.DD_IAST_DEDUPLICATION_ENABLED),
487
- true
488
- )
489
-
490
- const DD_IAST_REDACTION_ENABLED = coalesce(
491
- iastOptions?.redactionEnabled,
492
- !isFalse(process.env.DD_IAST_REDACTION_ENABLED),
493
- true
494
- )
495
-
496
- const DD_IAST_REDACTION_NAME_PATTERN = coalesce(
497
- iastOptions?.redactionNamePattern,
498
- process.env.DD_IAST_REDACTION_NAME_PATTERN,
499
- null
500
- )
501
-
502
- const DD_IAST_REDACTION_VALUE_PATTERN = coalesce(
503
- iastOptions?.redactionValuePattern,
504
- process.env.DD_IAST_REDACTION_VALUE_PATTERN,
505
- null
506
- )
507
-
508
- const DD_IAST_TELEMETRY_VERBOSITY = coalesce(
509
- iastOptions?.telemetryVerbosity,
510
- process.env.DD_IAST_TELEMETRY_VERBOSITY,
511
- 'INFORMATION'
512
- )
513
-
514
- const DD_CIVISIBILITY_GIT_UPLOAD_ENABLED = coalesce(
515
- process.env.DD_CIVISIBILITY_GIT_UPLOAD_ENABLED,
516
- true
517
- )
518
-
519
- const DD_TRACE_GIT_METADATA_ENABLED = coalesce(
520
- process.env.DD_TRACE_GIT_METADATA_ENABLED,
521
- true
522
- )
523
-
524
210
  // 0: disabled, 1: logging, 2: garbage collection + logging
525
211
  const DD_TRACE_SPAN_LEAK_DEBUG = coalesce(
526
212
  process.env.DD_TRACE_SPAN_LEAK_DEBUG,
@@ -540,10 +226,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
540
226
  null
541
227
  )
542
228
 
543
- const ingestion = options.ingestion || {}
544
- const dogstatsd = coalesce(options.dogstatsd, {})
545
229
  const sampler = {
546
- rateLimit: coalesce(options.rateLimit, process.env.DD_TRACE_RATE_LIMIT, ingestion.rateLimit),
547
230
  rules: coalesce(
548
231
  options.samplingRules,
549
232
  safeJsonParse(process.env.DD_TRACE_SAMPLING_RULES),
@@ -566,73 +249,16 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
566
249
  })
567
250
  }
568
251
 
569
- const defaultFlushInterval = inAWSLambda ? 0 : 2000
570
-
571
- this.dbmPropagationMode = DD_DBM_PROPAGATION_MODE
572
- this.dsmEnabled = isTrue(DD_DATA_STREAMS_ENABLED)
573
- this.openAiLogsEnabled = DD_OPENAI_LOGS_ENABLED
252
+ // TODO: refactor
574
253
  this.apiKey = DD_API_KEY
575
- this.url = DD_CIVISIBILITY_AGENTLESS_URL ? new URL(DD_CIVISIBILITY_AGENTLESS_URL)
576
- : getAgentUrl(DD_TRACE_AGENT_URL, options)
577
- this.site = coalesce(options.site, process.env.DD_SITE, 'datadoghq.com')
578
- this.hostname = DD_AGENT_HOST || (this.url && this.url.hostname)
579
- this.port = String(DD_TRACE_AGENT_PORT || (this.url && this.url.port))
580
- this.flushInterval = coalesce(parseInt(options.flushInterval, 10), defaultFlushInterval)
581
- this.flushMinSpans = DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
582
- this.queryStringObfuscation = DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP
583
- this.clientIpEnabled = DD_TRACE_CLIENT_IP_ENABLED
584
- this.clientIpHeader = DD_TRACE_CLIENT_IP_HEADER
585
- this.plugins = !!coalesce(options.plugins, true)
586
254
  this.serviceMapping = DD_SERVICE_MAPPING
587
- this.dogstatsd = {
588
- hostname: coalesce(dogstatsd.hostname, process.env.DD_DOGSTATSD_HOSTNAME, this.hostname),
589
- port: String(coalesce(dogstatsd.port, process.env.DD_DOGSTATSD_PORT, 8125))
590
- }
591
- this.runtimeMetrics = isTrue(DD_RUNTIME_METRICS_ENABLED)
592
255
  this.tracePropagationStyle = {
593
256
  inject: DD_TRACE_PROPAGATION_STYLE_INJECT,
594
257
  extract: DD_TRACE_PROPAGATION_STYLE_EXTRACT
595
258
  }
596
259
  this.tracePropagationExtractFirst = isTrue(DD_TRACE_PROPAGATION_EXTRACT_FIRST)
597
- this.experimental = {
598
- runtimeId: isTrue(DD_TRACE_RUNTIME_ID_ENABLED),
599
- exporter: DD_TRACE_EXPORTER,
600
- enableGetRumData: isTrue(DD_TRACE_GET_RUM_DATA_ENABLED)
601
- }
602
260
  this.sampler = sampler
603
- this.reportHostname = isTrue(coalesce(options.reportHostname, process.env.DD_TRACE_REPORT_HOSTNAME, false))
604
- this.scope = process.env.DD_TRACE_SCOPE
605
- this.profiling = {
606
- enabled: isTrue(DD_PROFILING_ENABLED),
607
- sourceMap: !isFalse(DD_PROFILING_SOURCE_MAP),
608
- exporters: DD_PROFILING_EXPORTERS
609
- }
610
- this.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
611
- this.spanComputePeerService = DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED
612
- this.spanRemoveIntegrationFromService = DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED
613
- this.peerServiceMapping = DD_TRACE_PEER_SERVICE_MAPPING
614
- this.lookup = options.lookup
615
- this.startupLogs = isTrue(DD_TRACE_STARTUP_LOGS)
616
- this.telemetry = {
617
- enabled: isTrue(DD_INSTRUMENTATION_TELEMETRY_ENABLED),
618
- heartbeatInterval: DD_TELEMETRY_HEARTBEAT_INTERVAL,
619
- debug: isTrue(DD_TELEMETRY_DEBUG),
620
- logCollection: isTrue(DD_TELEMETRY_LOG_COLLECTION_ENABLED),
621
- metrics: isTrue(DD_TELEMETRY_METRICS_ENABLED),
622
- dependencyCollection: DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED
623
- }
624
- this.protocolVersion = DD_TRACE_AGENT_PROTOCOL_VERSION
625
- this.tagsHeaderMaxLength = parseInt(DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH)
626
261
  this.appsec = {
627
- enabled: DD_APPSEC_ENABLED,
628
- rules: DD_APPSEC_RULES,
629
- customRulesProvided: !!DD_APPSEC_RULES,
630
- rateLimit: DD_APPSEC_TRACE_RATE_LIMIT,
631
- wafTimeout: DD_APPSEC_WAF_TIMEOUT,
632
- obfuscatorKeyRegex: DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP,
633
- obfuscatorValueRegex: DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP,
634
- blockedTemplateHtml: DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML,
635
- blockedTemplateJson: DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON,
636
262
  blockedTemplateGraphql: DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON,
637
263
  eventTracking: {
638
264
  enabled: ['extended', 'safe'].includes(DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING),
@@ -645,49 +271,10 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
645
271
  }
646
272
  }
647
273
 
648
- this.remoteConfig = {
649
- enabled: DD_REMOTE_CONFIGURATION_ENABLED,
650
- pollInterval: DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS
651
- }
652
- this.iast = {
653
- enabled: isTrue(DD_IAST_ENABLED),
654
- requestSampling: DD_IAST_REQUEST_SAMPLING,
655
- maxConcurrentRequests: DD_IAST_MAX_CONCURRENT_REQUESTS,
656
- maxContextOperations: DD_IAST_MAX_CONTEXT_OPERATIONS,
657
- deduplicationEnabled: DD_IAST_DEDUPLICATION_ENABLED,
658
- redactionEnabled: DD_IAST_REDACTION_ENABLED,
659
- redactionNamePattern: DD_IAST_REDACTION_NAME_PATTERN,
660
- redactionValuePattern: DD_IAST_REDACTION_VALUE_PATTERN,
661
- telemetryVerbosity: DD_IAST_TELEMETRY_VERBOSITY
662
- }
663
-
664
- this.isCiVisibility = isTrue(DD_IS_CIVISIBILITY)
665
-
666
- this.isIntelligentTestRunnerEnabled = this.isCiVisibility && isTrue(DD_CIVISIBILITY_ITR_ENABLED)
667
- this.isGitUploadEnabled = this.isCiVisibility &&
668
- (this.isIntelligentTestRunnerEnabled && !isFalse(DD_CIVISIBILITY_GIT_UPLOAD_ENABLED))
669
-
670
- this.gitMetadataEnabled = isTrue(DD_TRACE_GIT_METADATA_ENABLED)
671
- this.isManualApiEnabled = this.isCiVisibility && isTrue(DD_CIVISIBILITY_MANUAL_API_ENABLED)
672
- this.isEarlyFlakeDetectionEnabled = this.isCiVisibility && isTrue(DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED)
673
-
674
- this.openaiSpanCharLimit = DD_OPENAI_SPAN_CHAR_LIMIT
675
-
676
274
  // Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
677
275
  this.memcachedCommandEnabled = isTrue(DD_TRACE_MEMCACHED_COMMAND_ENABLED)
678
-
679
- this.stats = {
680
- enabled: isTrue(DD_TRACE_STATS_COMPUTATION_ENABLED)
681
- }
682
-
683
- this.traceId128BitGenerationEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
684
- this.traceId128BitLoggingEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
685
-
686
- this.isGCPFunction = isGCPFunction
687
- this.isAzureFunctionConsumptionPlan = isAzureFunctionConsumptionPlan
688
-
276
+ this.isAzureFunctionConsumptionPlan = getIsAzureFunctionConsumptionPlan()
689
277
  this.spanLeakDebug = Number(DD_TRACE_SPAN_LEAK_DEBUG)
690
-
691
278
  this.installSignature = {
692
279
  id: DD_INSTRUMENTATION_INSTALL_ID,
693
280
  time: DD_INSTRUMENTATION_INSTALL_TIME,
@@ -697,6 +284,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
697
284
  this._applyDefaults()
698
285
  this._applyEnvironment()
699
286
  this._applyOptions(options)
287
+ this._applyCalculated()
700
288
  this._applyRemote({})
701
289
  this._merge()
702
290
 
@@ -755,9 +343,19 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
755
343
  this._applyOptions(options)
756
344
  }
757
345
 
346
+ // TODO: test
347
+ this._applyCalculated()
758
348
  this._merge()
759
349
  }
760
350
 
351
+ _isInServerlessEnvironment () {
352
+ const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
353
+ const isGCPFunction = getIsGCPFunction()
354
+ const isAzureFunctionConsumptionPlan = getIsAzureFunctionConsumptionPlan()
355
+ return inAWSLambda || isGCPFunction || isAzureFunctionConsumptionPlan
356
+ }
357
+
358
+ // for _merge to work, every config value must have a default value
761
359
  _applyDefaults () {
762
360
  const {
763
361
  AWS_LAMBDA_FUNCTION_NAME,
@@ -775,27 +373,158 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
775
373
 
776
374
  const defaults = this._defaults = {}
777
375
 
778
- this._setValue(defaults, 'service', service)
376
+ this._setValue(defaults, 'appsec.blockedTemplateHtml', undefined)
377
+ this._setValue(defaults, 'appsec.blockedTemplateJson', undefined)
378
+ this._setValue(defaults, 'appsec.enabled', undefined)
379
+ this._setValue(defaults, 'appsec.obfuscatorKeyRegex', defaultWafObfuscatorKeyRegex)
380
+ this._setValue(defaults, 'appsec.obfuscatorValueRegex', defaultWafObfuscatorValueRegex)
381
+ this._setValue(defaults, 'appsec.rateLimit', 100)
382
+ this._setValue(defaults, 'appsec.rules', undefined)
383
+ this._setValue(defaults, 'appsec.wafTimeout', 5e3) // µs
384
+ this._setValue(defaults, 'clientIpEnabled', false)
385
+ this._setValue(defaults, 'clientIpHeader', null)
386
+ this._setValue(defaults, 'dbmPropagationMode', 'disabled')
387
+ this._setValue(defaults, 'dogstatsd.hostname', '127.0.0.1')
388
+ this._setValue(defaults, 'dogstatsd.port', '8125')
389
+ this._setValue(defaults, 'dsmEnabled', false)
779
390
  this._setValue(defaults, 'env', undefined)
780
- this._setValue(defaults, 'version', pkg.version)
781
- this._setUnit(defaults, 'sampleRate', undefined)
782
- this._setBoolean(defaults, 'logInjection', false)
783
- this._setArray(defaults, 'headerTags', [])
391
+ this._setValue(defaults, 'experimental.enableGetRumData', false)
392
+ this._setValue(defaults, 'experimental.exporter', undefined)
393
+ this._setValue(defaults, 'experimental.runtimeId', false)
394
+ this._setValue(defaults, 'flushInterval', 2000)
395
+ this._setValue(defaults, 'flushMinSpans', 1000)
396
+ this._setValue(defaults, 'gitMetadataEnabled', true)
397
+ this._setValue(defaults, 'headerTags', [])
398
+ this._setValue(defaults, 'hostname', '127.0.0.1')
399
+ this._setValue(defaults, 'iast.deduplicationEnabled', true)
400
+ this._setValue(defaults, 'iast.enabled', false)
401
+ this._setValue(defaults, 'iast.maxConcurrentRequests', 2)
402
+ this._setValue(defaults, 'iast.maxContextOperations', 2)
403
+ this._setValue(defaults, 'iast.redactionEnabled', true)
404
+ this._setValue(defaults, 'iast.redactionNamePattern', null)
405
+ this._setValue(defaults, 'iast.redactionValuePattern', null)
406
+ this._setValue(defaults, 'iast.requestSampling', 30)
407
+ this._setValue(defaults, 'iast.telemetryVerbosity', 'INFORMATION')
408
+ this._setValue(defaults, 'isCiVisibility', false)
409
+ this._setValue(defaults, 'isEarlyFlakeDetectionEnabled', false)
410
+ this._setValue(defaults, 'isGCPFunction', false)
411
+ this._setValue(defaults, 'isGitUploadEnabled', false)
412
+ this._setValue(defaults, 'isIntelligentTestRunnerEnabled', false)
413
+ this._setValue(defaults, 'isManualApiEnabled', false)
414
+ this._setValue(defaults, 'logInjection', false)
415
+ this._setValue(defaults, 'lookup', undefined)
416
+ this._setValue(defaults, 'openAiLogsEnabled', false)
417
+ this._setValue(defaults, 'openaiSpanCharLimit', 128)
418
+ this._setValue(defaults, 'peerServiceMapping', {})
419
+ this._setValue(defaults, 'plugins', true)
420
+ this._setValue(defaults, 'port', '8126')
421
+ this._setValue(defaults, 'profiling.enabled', false)
422
+ this._setValue(defaults, 'profiling.exporters', 'agent')
423
+ this._setValue(defaults, 'profiling.sourceMap', true)
424
+ this._setValue(defaults, 'protocolVersion', '0.4')
425
+ this._setValue(defaults, 'queryStringObfuscation', qsRegex)
426
+ this._setValue(defaults, 'remoteConfig.enabled', true)
427
+ this._setValue(defaults, 'remoteConfig.pollInterval', 5) // seconds
428
+ this._setValue(defaults, 'reportHostname', false)
429
+ this._setValue(defaults, 'runtimeMetrics', false)
430
+ this._setValue(defaults, 'sampleRate', undefined)
431
+ this._setValue(defaults, 'sampler.rateLimit', undefined)
432
+ this._setValue(defaults, 'scope', undefined)
433
+ this._setValue(defaults, 'service', service)
434
+ this._setValue(defaults, 'site', 'datadoghq.com')
435
+ this._setValue(defaults, 'spanAttributeSchema', 'v0')
436
+ this._setValue(defaults, 'spanComputePeerService', false)
437
+ this._setValue(defaults, 'spanRemoveIntegrationFromService', false)
438
+ this._setValue(defaults, 'startupLogs', false)
439
+ this._setValue(defaults, 'stats.enabled', false)
784
440
  this._setValue(defaults, 'tags', {})
785
- this._setBoolean(defaults, 'tracing', true)
441
+ this._setValue(defaults, 'tagsHeaderMaxLength', 512)
442
+ this._setValue(defaults, 'telemetry.debug', false)
443
+ this._setValue(defaults, 'telemetry.dependencyCollection', true)
444
+ this._setValue(defaults, 'telemetry.enabled', true)
445
+ this._setValue(defaults, 'telemetry.heartbeatInterval', 60000)
446
+ this._setValue(defaults, 'telemetry.logCollection', false)
447
+ this._setValue(defaults, 'telemetry.metrics', true)
448
+ this._setValue(defaults, 'traceId128BitGenerationEnabled', true)
449
+ this._setValue(defaults, 'traceId128BitLoggingEnabled', false)
450
+ this._setValue(defaults, 'tracing', true)
451
+ this._setValue(defaults, 'url', undefined)
452
+ this._setValue(defaults, 'version', pkg.version)
786
453
  }
787
454
 
788
455
  _applyEnvironment () {
789
456
  const {
457
+ AWS_LAMBDA_FUNCTION_NAME,
458
+ DD_AGENT_HOST,
459
+ DD_APPSEC_ENABLED,
460
+ DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML,
461
+ DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON,
462
+ DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP,
463
+ DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP,
464
+ DD_APPSEC_RULES,
465
+ DD_APPSEC_TRACE_RATE_LIMIT,
466
+ DD_APPSEC_WAF_TIMEOUT,
467
+ DD_DATA_STREAMS_ENABLED,
468
+ DD_DBM_PROPAGATION_MODE,
469
+ DD_DOGSTATSD_HOSTNAME,
470
+ DD_DOGSTATSD_PORT,
790
471
  DD_ENV,
472
+ DD_EXPERIMENTAL_PROFILING_ENABLED,
473
+ JEST_WORKER_ID,
474
+ DD_IAST_DEDUPLICATION_ENABLED,
475
+ DD_IAST_ENABLED,
476
+ DD_IAST_MAX_CONCURRENT_REQUESTS,
477
+ DD_IAST_MAX_CONTEXT_OPERATIONS,
478
+ DD_IAST_REDACTION_ENABLED,
479
+ DD_IAST_REDACTION_NAME_PATTERN,
480
+ DD_IAST_REDACTION_VALUE_PATTERN,
481
+ DD_IAST_REQUEST_SAMPLING,
482
+ DD_IAST_TELEMETRY_VERBOSITY,
483
+ DD_INSTRUMENTATION_TELEMETRY_ENABLED,
791
484
  DD_LOGS_INJECTION,
485
+ DD_OPENAI_LOGS_ENABLED,
486
+ DD_OPENAI_SPAN_CHAR_LIMIT,
487
+ DD_PROFILING_ENABLED,
488
+ DD_PROFILING_EXPORTERS,
489
+ DD_PROFILING_SOURCE_MAP,
490
+ DD_REMOTE_CONFIGURATION_ENABLED,
491
+ DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS,
492
+ DD_RUNTIME_METRICS_ENABLED,
792
493
  DD_SERVICE,
793
494
  DD_SERVICE_NAME,
495
+ DD_SITE,
794
496
  DD_TAGS,
497
+ DD_TELEMETRY_DEBUG,
498
+ DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED,
499
+ DD_TELEMETRY_HEARTBEAT_INTERVAL,
500
+ DD_TELEMETRY_LOG_COLLECTION_ENABLED,
501
+ DD_TELEMETRY_METRICS_ENABLED,
502
+ DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED,
503
+ DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED,
504
+ DD_TRACE_AGENT_HOSTNAME,
505
+ DD_TRACE_AGENT_PORT,
506
+ DD_TRACE_AGENT_PROTOCOL_VERSION,
507
+ DD_TRACE_CLIENT_IP_ENABLED,
508
+ DD_TRACE_CLIENT_IP_HEADER,
509
+ DD_TRACE_EXPERIMENTAL_EXPORTER,
510
+ DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
511
+ DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED,
512
+ DD_TRACE_GIT_METADATA_ENABLED,
795
513
  DD_TRACE_GLOBAL_TAGS,
796
514
  DD_TRACE_HEADER_TAGS,
515
+ DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
516
+ DD_TRACE_PARTIAL_FLUSH_MIN_SPANS,
517
+ DD_TRACE_PEER_SERVICE_MAPPING,
518
+ DD_TRACE_RATE_LIMIT,
519
+ DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED,
520
+ DD_TRACE_REPORT_HOSTNAME,
797
521
  DD_TRACE_SAMPLE_RATE,
522
+ DD_TRACE_SCOPE,
523
+ DD_TRACE_SPAN_ATTRIBUTE_SCHEMA,
524
+ DD_TRACE_STARTUP_LOGS,
798
525
  DD_TRACE_TAGS,
526
+ DD_TRACE_TELEMETRY_ENABLED,
527
+ DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
799
528
  DD_TRACING_ENABLED,
800
529
  DD_VERSION
801
530
  } = process.env
@@ -807,31 +536,281 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
807
536
  tagger.add(tags, DD_TRACE_TAGS)
808
537
  tagger.add(tags, DD_TRACE_GLOBAL_TAGS)
809
538
 
810
- this._setString(env, 'service', DD_SERVICE || DD_SERVICE_NAME || tags.service)
539
+ this._setValue(env, 'appsec.blockedTemplateHtml', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML))
540
+ this._setValue(env, 'appsec.blockedTemplateJson', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON))
541
+ this._setBoolean(env, 'appsec.enabled', DD_APPSEC_ENABLED)
542
+ this._setString(env, 'appsec.obfuscatorKeyRegex', DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP)
543
+ this._setString(env, 'appsec.obfuscatorValueRegex', DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP)
544
+ this._setValue(env, 'appsec.rateLimit', maybeInt(DD_APPSEC_TRACE_RATE_LIMIT))
545
+ this._setString(env, 'appsec.rules', DD_APPSEC_RULES)
546
+ this._setValue(env, 'appsec.wafTimeout', maybeInt(DD_APPSEC_WAF_TIMEOUT))
547
+ this._setBoolean(env, 'clientIpEnabled', DD_TRACE_CLIENT_IP_ENABLED)
548
+ this._setString(env, 'clientIpHeader', DD_TRACE_CLIENT_IP_HEADER)
549
+ this._setString(env, 'dbmPropagationMode', DD_DBM_PROPAGATION_MODE)
550
+ this._setString(env, 'dogstatsd.hostname', DD_DOGSTATSD_HOSTNAME)
551
+ this._setString(env, 'dogstatsd.port', DD_DOGSTATSD_PORT)
552
+ this._setBoolean(env, 'dsmEnabled', DD_DATA_STREAMS_ENABLED)
811
553
  this._setString(env, 'env', DD_ENV || tags.env)
812
- this._setString(env, 'version', DD_VERSION || tags.version)
813
- this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE)
814
- this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
554
+ this._setBoolean(env, 'experimental.enableGetRumData', DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED)
555
+ this._setString(env, 'experimental.exporter', DD_TRACE_EXPERIMENTAL_EXPORTER)
556
+ this._setBoolean(env, 'experimental.runtimeId', DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED)
557
+ if (AWS_LAMBDA_FUNCTION_NAME) this._setValue(env, 'flushInterval', 0)
558
+ this._setValue(env, 'flushMinSpans', maybeInt(DD_TRACE_PARTIAL_FLUSH_MIN_SPANS))
559
+ this._setBoolean(env, 'gitMetadataEnabled', DD_TRACE_GIT_METADATA_ENABLED)
815
560
  this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
561
+ this._setString(env, 'hostname', coalesce(DD_AGENT_HOST, DD_TRACE_AGENT_HOSTNAME))
562
+ this._setBoolean(env, 'iast.deduplicationEnabled', DD_IAST_DEDUPLICATION_ENABLED)
563
+ this._setBoolean(env, 'iast.enabled', DD_IAST_ENABLED)
564
+ this._setValue(env, 'iast.maxConcurrentRequests', maybeInt(DD_IAST_MAX_CONCURRENT_REQUESTS))
565
+ this._setValue(env, 'iast.maxContextOperations', maybeInt(DD_IAST_MAX_CONTEXT_OPERATIONS))
566
+ this._setBoolean(env, 'iast.redactionEnabled', DD_IAST_REDACTION_ENABLED && !isFalse(DD_IAST_REDACTION_ENABLED))
567
+ this._setString(env, 'iast.redactionNamePattern', DD_IAST_REDACTION_NAME_PATTERN)
568
+ this._setString(env, 'iast.redactionValuePattern', DD_IAST_REDACTION_VALUE_PATTERN)
569
+ const iastRequestSampling = maybeInt(DD_IAST_REQUEST_SAMPLING)
570
+ if (iastRequestSampling > -1 && iastRequestSampling < 101) {
571
+ this._setValue(env, 'iast.requestSampling', iastRequestSampling)
572
+ }
573
+ this._setString(env, 'iast.telemetryVerbosity', DD_IAST_TELEMETRY_VERBOSITY)
574
+ this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())
575
+ this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
576
+ this._setBoolean(env, 'openAiLogsEnabled', DD_OPENAI_LOGS_ENABLED)
577
+ this._setValue(env, 'openaiSpanCharLimit', maybeInt(DD_OPENAI_SPAN_CHAR_LIMIT))
578
+ if (DD_TRACE_PEER_SERVICE_MAPPING) {
579
+ this._setValue(env, 'peerServiceMapping', fromEntries(
580
+ process.env.DD_TRACE_PEER_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
581
+ ))
582
+ }
583
+ this._setString(env, 'port', DD_TRACE_AGENT_PORT)
584
+ this._setBoolean(env, 'profiling.enabled', coalesce(DD_EXPERIMENTAL_PROFILING_ENABLED, DD_PROFILING_ENABLED))
585
+ this._setString(env, 'profiling.exporters', DD_PROFILING_EXPORTERS)
586
+ this._setBoolean(env, 'profiling.sourceMap', DD_PROFILING_SOURCE_MAP && !isFalse(DD_PROFILING_SOURCE_MAP))
587
+ this._setString(env, 'protocolVersion', DD_TRACE_AGENT_PROTOCOL_VERSION)
588
+ this._setString(env, 'queryStringObfuscation', DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP)
589
+ this._setBoolean(env, 'remoteConfig.enabled', coalesce(
590
+ DD_REMOTE_CONFIGURATION_ENABLED,
591
+ !this._isInServerlessEnvironment()
592
+ ))
593
+ this._setValue(env, 'remoteConfig.pollInterval', maybeFloat(DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS))
594
+ this._setBoolean(env, 'reportHostname', DD_TRACE_REPORT_HOSTNAME)
595
+ this._setBoolean(env, 'runtimeMetrics', DD_RUNTIME_METRICS_ENABLED)
596
+ this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE)
597
+ this._setValue(env, 'sampler.rateLimit', DD_TRACE_RATE_LIMIT)
598
+ this._setString(env, 'scope', DD_TRACE_SCOPE)
599
+ this._setString(env, 'service', DD_SERVICE || DD_SERVICE_NAME || tags.service)
600
+ this._setString(env, 'site', DD_SITE)
601
+ if (DD_TRACE_SPAN_ATTRIBUTE_SCHEMA) {
602
+ this._setString(env, 'spanAttributeSchema', validateNamingVersion(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA))
603
+ }
604
+ this._setBoolean(env, 'spanRemoveIntegrationFromService', DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED)
605
+ this._setBoolean(env, 'startupLogs', DD_TRACE_STARTUP_LOGS)
816
606
  this._setTags(env, 'tags', tags)
607
+ this._setValue(env, 'tagsHeaderMaxLength', DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH)
608
+ this._setBoolean(env, 'telemetry.enabled', coalesce(
609
+ DD_TRACE_TELEMETRY_ENABLED, // for backward compatibility
610
+ DD_INSTRUMENTATION_TELEMETRY_ENABLED, // to comply with instrumentation telemetry specs
611
+ !(this._isInServerlessEnvironment() || JEST_WORKER_ID)
612
+ ))
613
+ this._setBoolean(env, 'telemetry.debug', DD_TELEMETRY_DEBUG)
614
+ this._setBoolean(env, 'telemetry.dependencyCollection', DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED)
615
+ this._setValue(env, 'telemetry.heartbeatInterval', maybeInt(Math.floor(DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000)))
616
+ this._setBoolean(env, 'telemetry.logCollection', coalesce(DD_TELEMETRY_LOG_COLLECTION_ENABLED, DD_IAST_ENABLED))
617
+ this._setBoolean(env, 'telemetry.metrics', DD_TELEMETRY_METRICS_ENABLED)
618
+ this._setBoolean(env, 'traceId128BitGenerationEnabled', DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
619
+ this._setBoolean(env, 'traceId128BitLoggingEnabled', DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
817
620
  this._setBoolean(env, 'tracing', DD_TRACING_ENABLED)
621
+ this._setString(env, 'version', DD_VERSION || tags.version)
818
622
  }
819
623
 
820
624
  _applyOptions (options) {
821
625
  const opts = this._options = this._options || {}
822
626
  const tags = {}
823
627
 
824
- options = Object.assign({ ingestion: {} }, options, opts)
628
+ options = this.options = Object.assign({ ingestion: {} }, options, opts)
825
629
 
826
630
  tagger.add(tags, options.tags)
827
631
 
828
- this._setString(opts, 'service', options.service || tags.service)
632
+ this._setValue(opts, 'appsec.blockedTemplateHtml', maybeFile(options.appsec.blockedTemplateHtml))
633
+ this._setValue(opts, 'appsec.blockedTemplateJson', maybeFile(options.appsec.blockedTemplateJson))
634
+ this._setBoolean(opts, 'appsec.enabled', options.appsec.enabled)
635
+ this._setString(opts, 'appsec.obfuscatorKeyRegex', options.appsec.obfuscatorKeyRegex)
636
+ this._setString(opts, 'appsec.obfuscatorValueRegex', options.appsec.obfuscatorValueRegex)
637
+ this._setValue(opts, 'appsec.rateLimit', maybeInt(options.appsec.rateLimit))
638
+ this._setString(opts, 'appsec.rules', options.appsec.rules)
639
+ this._setValue(opts, 'appsec.wafTimeout', maybeInt(options.appsec.wafTimeout))
640
+ this._setBoolean(opts, 'clientIpEnabled', options.clientIpEnabled)
641
+ this._setString(opts, 'clientIpHeader', options.clientIpHeader)
642
+ this._setString(opts, 'dbmPropagationMode', options.dbmPropagationMode)
643
+ if (options.dogstatsd) {
644
+ this._setString(opts, 'dogstatsd.hostname', options.dogstatsd.hostname)
645
+ this._setString(opts, 'dogstatsd.port', options.dogstatsd.port)
646
+ }
647
+ this._setBoolean(opts, 'dsmEnabled', options.dsmEnabled)
829
648
  this._setString(opts, 'env', options.env || tags.env)
830
- this._setString(opts, 'version', options.version || tags.version)
831
- this._setUnit(opts, 'sampleRate', coalesce(options.sampleRate, options.ingestion.sampleRate))
832
- this._setBoolean(opts, 'logInjection', options.logInjection)
649
+ this._setBoolean(opts, 'experimental.enableGetRumData',
650
+ options.experimental && options.experimental.enableGetRumData)
651
+ this._setString(opts, 'experimental.exporter', options.experimental && options.experimental.exporter)
652
+ this._setBoolean(opts, 'experimental.runtimeId', options.experimental && options.experimental.runtimeId)
653
+ this._setValue(opts, 'flushInterval', maybeInt(options.flushInterval))
654
+ this._setValue(opts, 'flushMinSpans', maybeInt(options.flushMinSpans))
833
655
  this._setArray(opts, 'headerTags', options.headerTags)
656
+ this._setString(opts, 'hostname', options.hostname)
657
+ this._setBoolean(opts, 'iast.deduplicationEnabled', options.iastOptions && options.iastOptions.deduplicationEnabled)
658
+ this._setBoolean(opts, 'iast.enabled',
659
+ options.iastOptions && (options.iastOptions === true || options.iastOptions.enabled === true))
660
+ const iastRequestSampling = maybeInt(options.iastOptions?.requestSampling)
661
+ this._setValue(opts, 'iast.maxConcurrentRequests',
662
+ maybeInt(options.iastOptions?.maxConcurrentRequests))
663
+ this._setValue(opts, 'iast.maxContextOperations',
664
+ maybeInt(options.iastOptions && options.iastOptions.maxContextOperations))
665
+ this._setBoolean(opts, 'iast.redactionEnabled', options.iastOptions && options.iastOptions.redactionEnabled)
666
+ this._setString(opts, 'iast.redactionNamePattern', options.iastOptions?.redactionNamePattern)
667
+ this._setString(opts, 'iast.redactionValuePattern', options.iastOptions?.redactionValuePattern)
668
+ if (iastRequestSampling > -1 && iastRequestSampling < 101) {
669
+ this._setValue(opts, 'iast.requestSampling', iastRequestSampling)
670
+ }
671
+ this._setString(opts, 'iast.telemetryVerbosity', options.iastOptions && options.iastOptions.telemetryVerbosity)
672
+ this._setBoolean(opts, 'isCiVisibility', options.isCiVisibility)
673
+ this._setBoolean(opts, 'logInjection', options.logInjection)
674
+ this._setString(opts, 'lookup', options.lookup)
675
+ this._setBoolean(opts, 'openAiLogsEnabled', options.openAiLogsEnabled)
676
+ this._setValue(opts, 'peerServiceMapping', options.peerServiceMapping)
677
+ this._setBoolean(opts, 'plugins', options.plugins)
678
+ this._setString(opts, 'port', options.port)
679
+ this._setBoolean(opts, 'profiling.enabled', options.profiling)
680
+ this._setString(opts, 'protocolVersion', options.protocolVersion)
681
+ if (options.remoteConfig) {
682
+ this._setValue(opts, 'remoteConfig.pollInterval', maybeFloat(options.remoteConfig.pollInterval))
683
+ }
684
+ this._setBoolean(opts, 'reportHostname', options.reportHostname)
685
+ this._setBoolean(opts, 'runtimeMetrics', options.runtimeMetrics)
686
+ this._setUnit(opts, 'sampleRate', coalesce(options.sampleRate, options.ingestion.sampleRate))
687
+ const ingestion = options.ingestion || {}
688
+ this._setValue(opts, 'sampler.rateLimit', coalesce(options.rateLimit, ingestion.rateLimit))
689
+ this._setString(opts, 'service', options.service || tags.service)
690
+ this._setString(opts, 'site', options.site)
691
+ if (options.spanAttributeSchema) {
692
+ this._setString(opts, 'spanAttributeSchema', validateNamingVersion(options.spanAttributeSchema))
693
+ }
694
+ this._setBoolean(opts, 'spanRemoveIntegrationFromService', options.spanRemoveIntegrationFromService)
695
+ this._setBoolean(opts, 'startupLogs', options.startupLogs)
834
696
  this._setTags(opts, 'tags', tags)
697
+ this._setBoolean(opts, 'telemetry.logCollection', options.iastOptions &&
698
+ (options.iastOptions === true || options.iastOptions.enabled === true))
699
+ this._setBoolean(opts, 'traceId128BitGenerationEnabled', options.traceId128BitGenerationEnabled)
700
+ this._setBoolean(opts, 'traceId128BitLoggingEnabled', options.traceId128BitLoggingEnabled)
701
+ this._setString(opts, 'version', options.version || tags.version)
702
+ }
703
+
704
+ _isCiVisibility () {
705
+ return coalesce(
706
+ this.options.isCiVisibility,
707
+ this._defaults['isCiVisibility']
708
+ )
709
+ }
710
+
711
+ _isCiVisibilityItrEnabled () {
712
+ return coalesce(
713
+ process.env.DD_CIVISIBILITY_ITR_ENABLED,
714
+ true
715
+ )
716
+ }
717
+
718
+ _getHostname () {
719
+ const DD_CIVISIBILITY_AGENTLESS_URL = process.env.DD_CIVISIBILITY_AGENTLESS_URL
720
+ const url = DD_CIVISIBILITY_AGENTLESS_URL ? new URL(DD_CIVISIBILITY_AGENTLESS_URL)
721
+ : getAgentUrl(this._getTraceAgentUrl(), this.options)
722
+ const DD_AGENT_HOST = coalesce(
723
+ this.options.hostname,
724
+ process.env.DD_AGENT_HOST,
725
+ process.env.DD_TRACE_AGENT_HOSTNAME,
726
+ '127.0.0.1'
727
+ )
728
+ return DD_AGENT_HOST || (url && url.hostname)
729
+ }
730
+
731
+ _getSpanComputePeerService () {
732
+ const DD_TRACE_SPAN_ATTRIBUTE_SCHEMA = validateNamingVersion(
733
+ coalesce(
734
+ this.options.spanAttributeSchema,
735
+ process.env.DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
736
+ )
737
+ )
738
+
739
+ const peerServiceSet = (
740
+ this.options.hasOwnProperty('spanComputePeerService') ||
741
+ process.env.hasOwnProperty('DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED')
742
+ )
743
+ const peerServiceValue = coalesce(
744
+ this.options.spanComputePeerService,
745
+ process.env.DD_TRACE_PEER_SERVICE_DEFAULTS_ENABLED
746
+ )
747
+
748
+ const spanComputePeerService = (
749
+ DD_TRACE_SPAN_ATTRIBUTE_SCHEMA === 'v0'
750
+ // In v0, peer service is computed only if it is explicitly set to true
751
+ ? peerServiceSet && isTrue(peerServiceValue)
752
+ // In >v0, peer service is false only if it is explicitly set to false
753
+ : (peerServiceSet ? !isFalse(peerServiceValue) : true)
754
+ )
755
+
756
+ return spanComputePeerService
757
+ }
758
+
759
+ _isCiVisibilityGitUploadEnabled () {
760
+ return coalesce(
761
+ process.env.DD_CIVISIBILITY_GIT_UPLOAD_ENABLED,
762
+ true
763
+ )
764
+ }
765
+
766
+ _isCiVisibilityManualApiEnabled () {
767
+ return isTrue(coalesce(
768
+ process.env.DD_CIVISIBILITY_MANUAL_API_ENABLED,
769
+ false
770
+ ))
771
+ }
772
+
773
+ _isTraceStatsComputationEnabled () {
774
+ return coalesce(
775
+ this.options.stats,
776
+ process.env.DD_TRACE_STATS_COMPUTATION_ENABLED,
777
+ getIsGCPFunction() || getIsAzureFunctionConsumptionPlan()
778
+ )
779
+ }
780
+
781
+ _getTraceAgentUrl () {
782
+ return coalesce(
783
+ this.options.url,
784
+ process.env.DD_TRACE_AGENT_URL,
785
+ process.env.DD_TRACE_URL,
786
+ null
787
+ )
788
+ }
789
+
790
+ // handles values calculated from a mixture of options and env vars
791
+ _applyCalculated () {
792
+ const calc = this._calculated = {}
793
+
794
+ const {
795
+ DD_CIVISIBILITY_AGENTLESS_URL
796
+ } = process.env
797
+
798
+ if (DD_CIVISIBILITY_AGENTLESS_URL) {
799
+ this._setValue(calc, 'url', new URL(DD_CIVISIBILITY_AGENTLESS_URL))
800
+ } else {
801
+ this._setValue(calc, 'url', getAgentUrl(this._getTraceAgentUrl(), this.options))
802
+ }
803
+ if (this._isCiVisibility()) {
804
+ this._setBoolean(calc, 'isEarlyFlakeDetectionEnabled',
805
+ coalesce(process.env.DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED, true))
806
+ this._setBoolean(calc, 'isIntelligentTestRunnerEnabled', isTrue(this._isCiVisibilityItrEnabled()))
807
+ this._setBoolean(calc, 'isManualApiEnabled', this._isCiVisibilityManualApiEnabled())
808
+ }
809
+ this._setString(calc, 'dogstatsd.hostname', this._getHostname())
810
+ this._setBoolean(calc, 'isGitUploadEnabled',
811
+ calc['isIntelligentTestRunnerEnabled'] && !isFalse(this._isCiVisibilityGitUploadEnabled()))
812
+ this._setBoolean(calc, 'spanComputePeerService', this._getSpanComputePeerService())
813
+ this._setBoolean(calc, 'stats.enabled', this._isTraceStatsComputationEnabled())
835
814
  }
836
815
 
837
816
  _applyRemote (options) {
@@ -890,7 +869,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
890
869
  }
891
870
 
892
871
  _setString (obj, name, value) {
893
- obj[name] = value || undefined // unset for empty strings
872
+ obj[name] = value ? String(value) : undefined // unset for empty strings
894
873
  }
895
874
 
896
875
  _setTags (obj, name, value) {
@@ -908,9 +887,12 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
908
887
  // TODO: Report origin changes and errors to telemetry.
909
888
  // TODO: Deeply merge configurations.
910
889
  // TODO: Move change tracking to telemetry.
890
+ // for telemetry reporting, `name`s in `containers` need to be keys from:
891
+ // eslint-disable-next-line max-len
892
+ // https://github.com/DataDog/dd-go/blob/prod/trace/apps/tracer-telemetry-intake/telemetry-payload/static/config_norm_rules.json
911
893
  _merge () {
912
- const containers = [this._remote, this._options, this._env, this._defaults]
913
- const origins = ['remote_config', 'code', 'env_var', 'default']
894
+ const containers = [this._remote, this._options, this._env, this._calculated, this._defaults]
895
+ const origins = ['remote_config', 'code', 'env_var', 'calculated', 'default']
914
896
  const changes = []
915
897
 
916
898
  for (const name in this._defaults) {
@@ -919,9 +901,10 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
919
901
  const origin = origins[i]
920
902
 
921
903
  if ((container[name] !== null && container[name] !== undefined) || container === this._defaults) {
922
- if (this[name] === container[name] && this.hasOwnProperty(name)) break
904
+ if (get(this, name) === container[name] && has(this, name)) break
923
905
 
924
- const value = this[name] = container[name]
906
+ const value = container[name]
907
+ set(this, name, value)
925
908
 
926
909
  changes.push({ name, value, origin })
927
910
 
@@ -931,11 +914,19 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
931
914
  }
932
915
 
933
916
  this.sampler.sampleRate = this.sampleRate
934
-
935
917
  updateConfig(changes, this)
936
918
  }
937
919
  }
938
920
 
921
+ function maybeInt (number) {
922
+ const parsed = parseInt(number)
923
+ return isNaN(parsed) ? undefined : parsed
924
+ }
925
+ function maybeFloat (number) {
926
+ const parsed = parseFloat(number)
927
+ return isNaN(parsed) ? undefined : parsed
928
+ }
929
+
939
930
  function getAgentUrl (url, options) {
940
931
  if (url) return new URL(url)
941
932