dd-trace 5.20.0 → 5.22.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 (108) hide show
  1. package/index.d.ts +2 -1
  2. package/package.json +6 -6
  3. package/packages/datadog-instrumentations/src/aerospike.js +1 -1
  4. package/packages/datadog-instrumentations/src/apollo-server.js +1 -1
  5. package/packages/datadog-instrumentations/src/aws-sdk.js +4 -4
  6. package/packages/datadog-instrumentations/src/body-parser.js +17 -5
  7. package/packages/datadog-instrumentations/src/cassandra-driver.js +2 -2
  8. package/packages/datadog-instrumentations/src/child_process.js +2 -2
  9. package/packages/datadog-instrumentations/src/connect.js +4 -4
  10. package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
  11. package/packages/datadog-instrumentations/src/couchbase.js +12 -12
  12. package/packages/datadog-instrumentations/src/cucumber.js +16 -5
  13. package/packages/datadog-instrumentations/src/dns.js +10 -10
  14. package/packages/datadog-instrumentations/src/elasticsearch.js +4 -4
  15. package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +3 -3
  16. package/packages/datadog-instrumentations/src/express.js +4 -4
  17. package/packages/datadog-instrumentations/src/fastify.js +6 -6
  18. package/packages/datadog-instrumentations/src/fetch.js +1 -1
  19. package/packages/datadog-instrumentations/src/find-my-way.js +2 -2
  20. package/packages/datadog-instrumentations/src/fs.js +2 -2
  21. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +2 -2
  22. package/packages/datadog-instrumentations/src/grpc/client.js +4 -6
  23. package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
  24. package/packages/datadog-instrumentations/src/hapi.js +10 -13
  25. package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -2
  26. package/packages/datadog-instrumentations/src/helpers/register.js +9 -2
  27. package/packages/datadog-instrumentations/src/http/client.js +3 -3
  28. package/packages/datadog-instrumentations/src/jest.js +5 -4
  29. package/packages/datadog-instrumentations/src/knex.js +2 -2
  30. package/packages/datadog-instrumentations/src/koa.js +5 -5
  31. package/packages/datadog-instrumentations/src/ldapjs.js +1 -1
  32. package/packages/datadog-instrumentations/src/mariadb.js +8 -8
  33. package/packages/datadog-instrumentations/src/memcached.js +2 -2
  34. package/packages/datadog-instrumentations/src/microgateway-core.js +4 -4
  35. package/packages/datadog-instrumentations/src/mocha/common.js +1 -1
  36. package/packages/datadog-instrumentations/src/mocha/main.js +91 -70
  37. package/packages/datadog-instrumentations/src/mocha/utils.js +2 -3
  38. package/packages/datadog-instrumentations/src/mocha.js +4 -0
  39. package/packages/datadog-instrumentations/src/moleculer/server.js +2 -2
  40. package/packages/datadog-instrumentations/src/mongodb-core.js +7 -7
  41. package/packages/datadog-instrumentations/src/mongoose.js +5 -6
  42. package/packages/datadog-instrumentations/src/mysql.js +3 -3
  43. package/packages/datadog-instrumentations/src/mysql2.js +6 -6
  44. package/packages/datadog-instrumentations/src/net.js +2 -2
  45. package/packages/datadog-instrumentations/src/next.js +5 -5
  46. package/packages/datadog-instrumentations/src/nyc.js +23 -0
  47. package/packages/datadog-instrumentations/src/openai.js +58 -69
  48. package/packages/datadog-instrumentations/src/oracledb.js +8 -8
  49. package/packages/datadog-instrumentations/src/passport-http.js +1 -1
  50. package/packages/datadog-instrumentations/src/passport-local.js +1 -1
  51. package/packages/datadog-instrumentations/src/passport-utils.js +1 -1
  52. package/packages/datadog-instrumentations/src/pg.js +1 -1
  53. package/packages/datadog-instrumentations/src/pino.js +4 -4
  54. package/packages/datadog-instrumentations/src/playwright.js +6 -4
  55. package/packages/datadog-instrumentations/src/redis.js +2 -2
  56. package/packages/datadog-instrumentations/src/restify.js +4 -4
  57. package/packages/datadog-instrumentations/src/rhea.js +4 -4
  58. package/packages/datadog-instrumentations/src/router.js +5 -5
  59. package/packages/datadog-instrumentations/src/sharedb.js +2 -2
  60. package/packages/datadog-instrumentations/src/vitest.js +22 -5
  61. package/packages/datadog-instrumentations/src/winston.js +2 -3
  62. package/packages/datadog-plugin-cucumber/src/index.js +12 -2
  63. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +21 -10
  64. package/packages/datadog-plugin-hapi/src/index.js +2 -2
  65. package/packages/datadog-plugin-jest/src/index.js +18 -4
  66. package/packages/datadog-plugin-mocha/src/index.js +25 -6
  67. package/packages/datadog-plugin-nyc/src/index.js +35 -0
  68. package/packages/datadog-plugin-openai/src/index.js +58 -47
  69. package/packages/datadog-plugin-playwright/src/index.js +9 -4
  70. package/packages/datadog-plugin-vitest/src/index.js +30 -4
  71. package/packages/datadog-shimmer/src/shimmer.js +144 -10
  72. package/packages/dd-trace/src/appsec/blocking.js +23 -17
  73. package/packages/dd-trace/src/appsec/graphql.js +3 -1
  74. package/packages/dd-trace/src/appsec/iast/iast-log.js +2 -1
  75. package/packages/dd-trace/src/appsec/remote_config/manager.js +4 -1
  76. package/packages/dd-trace/src/appsec/rule_manager.js +8 -0
  77. package/packages/dd-trace/src/appsec/telemetry.js +3 -3
  78. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +40 -1
  79. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -4
  80. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -4
  81. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +2 -1
  82. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +8 -7
  83. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -4
  84. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -4
  85. package/packages/dd-trace/src/ci-visibility/telemetry.js +29 -2
  86. package/packages/dd-trace/src/config.js +157 -142
  87. package/packages/dd-trace/src/lambda/handler.js +1 -0
  88. package/packages/dd-trace/src/lambda/index.js +12 -1
  89. package/packages/dd-trace/src/opentelemetry/context_manager.js +22 -39
  90. package/packages/dd-trace/src/opentelemetry/span_context.js +2 -2
  91. package/packages/dd-trace/src/opentelemetry/tracer.js +23 -14
  92. package/packages/dd-trace/src/opentelemetry/tracer_provider.js +9 -1
  93. package/packages/dd-trace/src/opentracing/propagation/log.js +1 -1
  94. package/packages/dd-trace/src/opentracing/propagation/text_map.js +61 -6
  95. package/packages/dd-trace/src/opentracing/span_context.js +1 -0
  96. package/packages/dd-trace/src/plugins/ci_plugin.js +2 -2
  97. package/packages/dd-trace/src/plugins/index.js +1 -0
  98. package/packages/dd-trace/src/plugins/util/git.js +14 -1
  99. package/packages/dd-trace/src/plugins/util/test.js +1 -5
  100. package/packages/dd-trace/src/profiler.js +15 -5
  101. package/packages/dd-trace/src/profiling/config.js +2 -4
  102. package/packages/dd-trace/src/profiling/exporter_cli.js +13 -1
  103. package/packages/dd-trace/src/profiling/exporters/agent.js +7 -1
  104. package/packages/dd-trace/src/profiling/profiler.js +0 -9
  105. package/packages/dd-trace/src/profiling/ssi-heuristics.js +49 -58
  106. package/packages/dd-trace/src/proxy.js +21 -21
  107. package/packages/dd-trace/src/telemetry/index.js +24 -7
  108. package/packages/dd-trace/src/telemetry/logs/index.js +20 -0
@@ -183,7 +183,7 @@ function remapify (input, mappings) {
183
183
  return output
184
184
  }
185
185
 
186
- function propagationStyle (key, option, defaultValue) {
186
+ function propagationStyle (key, option) {
187
187
  // Extract by key if in object-form value
188
188
  if (option !== null && typeof option === 'object' && !Array.isArray(option)) {
189
189
  option = option[key]
@@ -206,8 +206,16 @@ function propagationStyle (key, option, defaultValue) {
206
206
  .filter(v => v !== '')
207
207
  .map(v => v.trim().toLowerCase())
208
208
  }
209
+ }
209
210
 
210
- return defaultValue
211
+ function reformatSpanSamplingRules (rules) {
212
+ if (!rules) return rules
213
+ return rules.map(rule => {
214
+ return remapify(rule, {
215
+ sample_rate: 'sampleRate',
216
+ max_per_second: 'maxPerSecond'
217
+ })
218
+ })
211
219
  }
212
220
 
213
221
  class Config {
@@ -229,36 +237,11 @@ class Config {
229
237
 
230
238
  checkIfBothOtelAndDdEnvVarSet()
231
239
 
232
- const DD_TRACE_MEMCACHED_COMMAND_ENABLED = coalesce(
233
- process.env.DD_TRACE_MEMCACHED_COMMAND_ENABLED,
234
- false
235
- )
236
-
237
- const DD_SERVICE_MAPPING = coalesce(
238
- options.serviceMapping,
239
- process.env.DD_SERVICE_MAPPING
240
- ? fromEntries(
241
- process.env.DD_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
242
- )
243
- : {}
244
- )
245
-
246
240
  const DD_API_KEY = coalesce(
247
241
  process.env.DATADOG_API_KEY,
248
242
  process.env.DD_API_KEY
249
243
  )
250
244
 
251
- // TODO: Remove the experimental env vars as a major?
252
- const DD_TRACE_B3_ENABLED = coalesce(
253
- options.experimental && options.experimental.b3,
254
- process.env.DD_TRACE_EXPERIMENTAL_B3_ENABLED,
255
- false
256
- )
257
- const defaultPropagationStyle = ['datadog', 'tracecontext']
258
- if (isTrue(DD_TRACE_B3_ENABLED)) {
259
- defaultPropagationStyle.push('b3')
260
- defaultPropagationStyle.push('b3 single header')
261
- }
262
245
  if (process.env.DD_TRACE_PROPAGATION_STYLE && (
263
246
  process.env.DD_TRACE_PROPAGATION_STYLE_INJECT ||
264
247
  process.env.DD_TRACE_PROPAGATION_STYLE_EXTRACT
@@ -272,21 +255,11 @@ class Config {
272
255
  const PROPAGATION_STYLE_INJECT = propagationStyle(
273
256
  'inject',
274
257
  options.tracePropagationStyle,
275
- defaultPropagationStyle
276
- )
277
- const PROPAGATION_STYLE_EXTRACT = propagationStyle(
278
- 'extract',
279
- options.tracePropagationStyle,
280
- defaultPropagationStyle
258
+ this._getDefaultPropagationStyle(options)
281
259
  )
282
260
 
283
261
  validateOtelPropagators(PROPAGATION_STYLE_INJECT)
284
262
 
285
- const DD_TRACE_PROPAGATION_EXTRACT_FIRST = coalesce(
286
- process.env.DD_TRACE_PROPAGATION_EXTRACT_FIRST,
287
- false
288
- )
289
-
290
263
  if (typeof options.appsec === 'boolean') {
291
264
  options.appsec = {
292
265
  enabled: options.appsec
@@ -295,33 +268,6 @@ class Config {
295
268
  options.appsec = {}
296
269
  }
297
270
 
298
- const DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON = coalesce(
299
- maybeFile(options.appsec.blockedTemplateGraphql),
300
- maybeFile(process.env.DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON)
301
- )
302
- const DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING = coalesce(
303
- options.appsec.eventTracking && options.appsec.eventTracking.mode,
304
- process.env.DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING,
305
- 'safe'
306
- ).toLowerCase()
307
- const DD_API_SECURITY_ENABLED = coalesce(
308
- options.appsec?.apiSecurity?.enabled,
309
- process.env.DD_API_SECURITY_ENABLED && isTrue(process.env.DD_API_SECURITY_ENABLED),
310
- process.env.DD_EXPERIMENTAL_API_SECURITY_ENABLED && isTrue(process.env.DD_EXPERIMENTAL_API_SECURITY_ENABLED),
311
- true
312
- )
313
- const DD_API_SECURITY_REQUEST_SAMPLE_RATE = coalesce(
314
- options.appsec?.apiSecurity?.requestSampling,
315
- parseFloat(process.env.DD_API_SECURITY_REQUEST_SAMPLE_RATE),
316
- 0.1
317
- )
318
-
319
- // 0: disabled, 1: logging, 2: garbage collection + logging
320
- const DD_TRACE_SPAN_LEAK_DEBUG = coalesce(
321
- process.env.DD_TRACE_SPAN_LEAK_DEBUG,
322
- 0
323
- )
324
-
325
271
  const DD_INSTRUMENTATION_INSTALL_ID = coalesce(
326
272
  process.env.DD_INSTRUMENTATION_INSTALL_ID,
327
273
  null
@@ -335,51 +281,10 @@ class Config {
335
281
  null
336
282
  )
337
283
 
338
- const sampler = {
339
- spanSamplingRules: coalesce(
340
- options.spanSamplingRules,
341
- safeJsonParse(maybeFile(process.env.DD_SPAN_SAMPLING_RULES_FILE)),
342
- safeJsonParse(process.env.DD_SPAN_SAMPLING_RULES),
343
- []
344
- ).map(rule => {
345
- return remapify(rule, {
346
- sample_rate: 'sampleRate',
347
- max_per_second: 'maxPerSecond'
348
- })
349
- })
350
- }
351
-
352
284
  // TODO: refactor
353
285
  this.apiKey = DD_API_KEY
354
- this.serviceMapping = DD_SERVICE_MAPPING
355
- this.tracePropagationStyle = {
356
- inject: PROPAGATION_STYLE_INJECT,
357
- extract: PROPAGATION_STYLE_EXTRACT,
358
- otelPropagators: process.env.DD_TRACE_PROPAGATION_STYLE ||
359
- process.env.DD_TRACE_PROPAGATION_STYLE_INJECT ||
360
- process.env.DD_TRACE_PROPAGATION_STYLE_EXTRACT
361
- ? false
362
- : !!process.env.OTEL_PROPAGATORS
363
- }
364
- this.tracePropagationExtractFirst = isTrue(DD_TRACE_PROPAGATION_EXTRACT_FIRST)
365
- this.sampler = sampler
366
- this.appsec = {
367
- blockedTemplateGraphql: DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON,
368
- eventTracking: {
369
- enabled: ['extended', 'safe'].includes(DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING),
370
- mode: DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING
371
- },
372
- apiSecurity: {
373
- enabled: DD_API_SECURITY_ENABLED,
374
- // Coerce value between 0 and 1
375
- requestSampling: Math.min(1, Math.max(0, DD_API_SECURITY_REQUEST_SAMPLE_RATE))
376
- }
377
- }
378
286
 
379
- // Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
380
- this.memcachedCommandEnabled = isTrue(DD_TRACE_MEMCACHED_COMMAND_ENABLED)
381
- this.isAzureFunction = getIsAzureFunction()
382
- this.spanLeakDebug = Number(DD_TRACE_SPAN_LEAK_DEBUG)
287
+ // sent in telemetry event app-started
383
288
  this.installSignature = {
384
289
  id: DD_INSTRUMENTATION_INSTALL_ID,
385
290
  time: DD_INSTRUMENTATION_INSTALL_TIME,
@@ -453,6 +358,21 @@ class Config {
453
358
  this._merge()
454
359
  }
455
360
 
361
+ _getDefaultPropagationStyle (options) {
362
+ // TODO: Remove the experimental env vars as a major?
363
+ const DD_TRACE_B3_ENABLED = coalesce(
364
+ options.experimental && options.experimental.b3,
365
+ process.env.DD_TRACE_EXPERIMENTAL_B3_ENABLED,
366
+ false
367
+ )
368
+ const defaultPropagationStyle = ['datadog', 'tracecontext']
369
+ if (isTrue(DD_TRACE_B3_ENABLED)) {
370
+ defaultPropagationStyle.push('b3')
371
+ defaultPropagationStyle.push('b3 single header')
372
+ }
373
+ return defaultPropagationStyle
374
+ }
375
+
456
376
  _isInServerlessEnvironment () {
457
377
  const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
458
378
  const isGCPFunction = getIsGCPFunction()
@@ -478,9 +398,14 @@ class Config {
478
398
 
479
399
  const defaults = setHiddenProperty(this, '_defaults', {})
480
400
 
401
+ this._setValue(defaults, 'appsec.apiSecurity.enabled', true)
402
+ this._setValue(defaults, 'appsec.apiSecurity.requestSampling', 0.1)
403
+ this._setValue(defaults, 'appsec.blockedTemplateGraphql', undefined)
481
404
  this._setValue(defaults, 'appsec.blockedTemplateHtml', undefined)
482
405
  this._setValue(defaults, 'appsec.blockedTemplateJson', undefined)
483
406
  this._setValue(defaults, 'appsec.enabled', undefined)
407
+ this._setValue(defaults, 'appsec.eventTracking.enabled', true)
408
+ this._setValue(defaults, 'appsec.eventTracking.mode', 'safe')
484
409
  this._setValue(defaults, 'appsec.obfuscatorKeyRegex', defaultWafObfuscatorKeyRegex)
485
410
  this._setValue(defaults, 'appsec.obfuscatorValueRegex', defaultWafObfuscatorValueRegex)
486
411
  this._setValue(defaults, 'appsec.rasp.enabled', true)
@@ -516,14 +441,19 @@ class Config {
516
441
  this._setValue(defaults, 'iast.redactionValuePattern', null)
517
442
  this._setValue(defaults, 'iast.requestSampling', 30)
518
443
  this._setValue(defaults, 'iast.telemetryVerbosity', 'INFORMATION')
444
+ this._setValue(defaults, 'injectionEnabled', [])
445
+ this._setValue(defaults, 'isAzureFunction', false)
519
446
  this._setValue(defaults, 'isCiVisibility', false)
520
447
  this._setValue(defaults, 'isEarlyFlakeDetectionEnabled', false)
448
+ this._setValue(defaults, 'isFlakyTestRetriesEnabled', false)
449
+ this._setValue(defaults, 'flakyTestRetriesCount', 5)
521
450
  this._setValue(defaults, 'isGCPFunction', false)
522
451
  this._setValue(defaults, 'isGitUploadEnabled', false)
523
452
  this._setValue(defaults, 'isIntelligentTestRunnerEnabled', false)
524
453
  this._setValue(defaults, 'isManualApiEnabled', false)
525
454
  this._setValue(defaults, 'logInjection', false)
526
455
  this._setValue(defaults, 'lookup', undefined)
456
+ this._setValue(defaults, 'memcachedCommandEnabled', false)
527
457
  this._setValue(defaults, 'openAiLogsEnabled', false)
528
458
  this._setValue(defaults, 'openaiSpanCharLimit', 128)
529
459
  this._setValue(defaults, 'peerServiceMapping', {})
@@ -532,8 +462,6 @@ class Config {
532
462
  this._setValue(defaults, 'profiling.enabled', undefined)
533
463
  this._setValue(defaults, 'profiling.exporters', 'agent')
534
464
  this._setValue(defaults, 'profiling.sourceMap', true)
535
- this._setValue(defaults, 'profiling.ssi', false)
536
- this._setValue(defaults, 'profiling.heuristicsEnabled', false)
537
465
  this._setValue(defaults, 'profiling.longLivedThreshold', undefined)
538
466
  this._setValue(defaults, 'protocolVersion', '0.4')
539
467
  this._setValue(defaults, 'queryStringObfuscation', qsRegex)
@@ -544,11 +472,14 @@ class Config {
544
472
  this._setValue(defaults, 'sampleRate', undefined)
545
473
  this._setValue(defaults, 'sampler.rateLimit', undefined)
546
474
  this._setValue(defaults, 'sampler.rules', [])
475
+ this._setValue(defaults, 'sampler.spanSamplingRules', [])
547
476
  this._setValue(defaults, 'scope', undefined)
548
477
  this._setValue(defaults, 'service', service)
478
+ this._setValue(defaults, 'serviceMapping', {})
549
479
  this._setValue(defaults, 'site', 'datadoghq.com')
550
480
  this._setValue(defaults, 'spanAttributeSchema', 'v0')
551
481
  this._setValue(defaults, 'spanComputePeerService', false)
482
+ this._setValue(defaults, 'spanLeakDebug', 0)
552
483
  this._setValue(defaults, 'spanRemoveIntegrationFromService', false)
553
484
  this._setValue(defaults, 'startupLogs', false)
554
485
  this._setValue(defaults, 'stats.enabled', false)
@@ -562,6 +493,10 @@ class Config {
562
493
  this._setValue(defaults, 'telemetry.metrics', true)
563
494
  this._setValue(defaults, 'traceId128BitGenerationEnabled', true)
564
495
  this._setValue(defaults, 'traceId128BitLoggingEnabled', false)
496
+ this._setValue(defaults, 'tracePropagationExtractFirst', false)
497
+ this._setValue(defaults, 'tracePropagationStyle.inject', ['datadog', 'tracecontext'])
498
+ this._setValue(defaults, 'tracePropagationStyle.extract', ['datadog', 'tracecontext'])
499
+ this._setValue(defaults, 'tracePropagationStyle.otelPropagators', false)
565
500
  this._setValue(defaults, 'tracing', true)
566
501
  this._setValue(defaults, 'url', undefined)
567
502
  this._setValue(defaults, 'version', pkg.version)
@@ -572,7 +507,11 @@ class Config {
572
507
  const {
573
508
  AWS_LAMBDA_FUNCTION_NAME,
574
509
  DD_AGENT_HOST,
510
+ DD_API_SECURITY_ENABLED,
511
+ DD_API_SECURITY_REQUEST_SAMPLE_RATE,
512
+ DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING,
575
513
  DD_APPSEC_ENABLED,
514
+ DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON,
576
515
  DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML,
577
516
  DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON,
578
517
  DD_APPSEC_MAX_STACK_TRACES,
@@ -590,6 +529,7 @@ class Config {
590
529
  DD_DOGSTATSD_HOSTNAME,
591
530
  DD_DOGSTATSD_PORT,
592
531
  DD_ENV,
532
+ DD_EXPERIMENTAL_API_SECURITY_ENABLED,
593
533
  DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED,
594
534
  DD_EXPERIMENTAL_PROFILING_ENABLED,
595
535
  JEST_WORKER_ID,
@@ -616,8 +556,11 @@ class Config {
616
556
  DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS,
617
557
  DD_RUNTIME_METRICS_ENABLED,
618
558
  DD_SERVICE,
559
+ DD_SERVICE_MAPPING,
619
560
  DD_SERVICE_NAME,
620
561
  DD_SITE,
562
+ DD_SPAN_SAMPLING_RULES,
563
+ DD_SPAN_SAMPLING_RULES_FILE,
621
564
  DD_TAGS,
622
565
  DD_TELEMETRY_DEBUG,
623
566
  DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED,
@@ -637,9 +580,14 @@ class Config {
637
580
  DD_TRACE_GIT_METADATA_ENABLED,
638
581
  DD_TRACE_GLOBAL_TAGS,
639
582
  DD_TRACE_HEADER_TAGS,
583
+ DD_TRACE_MEMCACHED_COMMAND_ENABLED,
640
584
  DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
641
585
  DD_TRACE_PARTIAL_FLUSH_MIN_SPANS,
642
586
  DD_TRACE_PEER_SERVICE_MAPPING,
587
+ DD_TRACE_PROPAGATION_EXTRACT_FIRST,
588
+ DD_TRACE_PROPAGATION_STYLE,
589
+ DD_TRACE_PROPAGATION_STYLE_INJECT,
590
+ DD_TRACE_PROPAGATION_STYLE_EXTRACT,
643
591
  DD_TRACE_RATE_LIMIT,
644
592
  DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED,
645
593
  DD_TRACE_REPORT_HOSTNAME,
@@ -647,17 +595,19 @@ class Config {
647
595
  DD_TRACE_SAMPLING_RULES,
648
596
  DD_TRACE_SCOPE,
649
597
  DD_TRACE_SPAN_ATTRIBUTE_SCHEMA,
598
+ DD_TRACE_SPAN_LEAK_DEBUG,
650
599
  DD_TRACE_STARTUP_LOGS,
651
600
  DD_TRACE_TAGS,
652
601
  DD_TRACE_TELEMETRY_ENABLED,
653
602
  DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
654
603
  DD_TRACING_ENABLED,
655
604
  DD_VERSION,
656
- OTEL_SERVICE_NAME,
605
+ OTEL_METRICS_EXPORTER,
606
+ OTEL_PROPAGATORS,
657
607
  OTEL_RESOURCE_ATTRIBUTES,
608
+ OTEL_SERVICE_NAME,
658
609
  OTEL_TRACES_SAMPLER,
659
- OTEL_TRACES_SAMPLER_ARG,
660
- OTEL_METRICS_EXPORTER
610
+ OTEL_TRACES_SAMPLER_ARG
661
611
  } = process.env
662
612
 
663
613
  const tags = {}
@@ -669,11 +619,22 @@ class Config {
669
619
  tagger.add(tags, DD_TRACE_TAGS)
670
620
  tagger.add(tags, DD_TRACE_GLOBAL_TAGS)
671
621
 
622
+ this._setBoolean(env, 'appsec.apiSecurity.enabled', coalesce(
623
+ DD_API_SECURITY_ENABLED && isTrue(DD_API_SECURITY_ENABLED),
624
+ DD_EXPERIMENTAL_API_SECURITY_ENABLED && isTrue(DD_EXPERIMENTAL_API_SECURITY_ENABLED)
625
+ ))
626
+ this._setUnit(env, 'appsec.apiSecurity.requestSampling', DD_API_SECURITY_REQUEST_SAMPLE_RATE)
627
+ this._setValue(env, 'appsec.blockedTemplateGraphql', maybeFile(DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON))
672
628
  this._setValue(env, 'appsec.blockedTemplateHtml', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML))
673
629
  this._envUnprocessed['appsec.blockedTemplateHtml'] = DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML
674
630
  this._setValue(env, 'appsec.blockedTemplateJson', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON))
675
631
  this._envUnprocessed['appsec.blockedTemplateJson'] = DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON
676
632
  this._setBoolean(env, 'appsec.enabled', DD_APPSEC_ENABLED)
633
+ if (DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING) {
634
+ this._setValue(env, 'appsec.eventTracking.enabled',
635
+ ['extended', 'safe'].includes(DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING.toLowerCase()))
636
+ this._setValue(env, 'appsec.eventTracking.mode', DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING.toLowerCase())
637
+ }
677
638
  this._setString(env, 'appsec.obfuscatorKeyRegex', DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP)
678
639
  this._setString(env, 'appsec.obfuscatorValueRegex', DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP)
679
640
  this._setBoolean(env, 'appsec.rasp.enabled', DD_APPSEC_RASP_ENABLED)
@@ -721,8 +682,12 @@ class Config {
721
682
  }
722
683
  this._envUnprocessed['iast.requestSampling'] = DD_IAST_REQUEST_SAMPLING
723
684
  this._setString(env, 'iast.telemetryVerbosity', DD_IAST_TELEMETRY_VERBOSITY)
685
+ this._setArray(env, 'injectionEnabled', DD_INJECTION_ENABLED)
686
+ this._setBoolean(env, 'isAzureFunction', getIsAzureFunction())
724
687
  this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())
725
688
  this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
689
+ // Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
690
+ this._setBoolean(env, 'memcachedCommandEnabled', DD_TRACE_MEMCACHED_COMMAND_ENABLED)
726
691
  this._setBoolean(env, 'openAiLogsEnabled', DD_OPENAI_LOGS_ENABLED)
727
692
  this._setValue(env, 'openaiSpanCharLimit', maybeInt(DD_OPENAI_SPAN_CHAR_LIMIT))
728
693
  this._envUnprocessed.openaiSpanCharLimit = DD_OPENAI_SPAN_CHAR_LIMIT
@@ -733,18 +698,18 @@ class Config {
733
698
  this._envUnprocessed.peerServiceMapping = DD_TRACE_PEER_SERVICE_MAPPING
734
699
  }
735
700
  this._setString(env, 'port', DD_TRACE_AGENT_PORT)
736
- this._setBoolean(env, 'profiling.enabled', coalesce(DD_EXPERIMENTAL_PROFILING_ENABLED, DD_PROFILING_ENABLED))
701
+ const profilingEnabledEnv = coalesce(DD_EXPERIMENTAL_PROFILING_ENABLED, DD_PROFILING_ENABLED)
702
+ const profilingEnabled = isTrue(profilingEnabledEnv)
703
+ ? 'true'
704
+ : isFalse(profilingEnabledEnv)
705
+ ? 'false'
706
+ : profilingEnabledEnv === 'auto' ? 'auto' : undefined
707
+ this._setString(env, 'profiling.enabled', profilingEnabled)
737
708
  this._setString(env, 'profiling.exporters', DD_PROFILING_EXPORTERS)
738
709
  this._setBoolean(env, 'profiling.sourceMap', DD_PROFILING_SOURCE_MAP && !isFalse(DD_PROFILING_SOURCE_MAP))
739
- if (DD_PROFILING_ENABLED === 'auto' || DD_INJECTION_ENABLED) {
740
- this._setBoolean(env, 'profiling.ssi', true)
741
- if (DD_PROFILING_ENABLED === 'auto' || DD_INJECTION_ENABLED.split(',').includes('profiler')) {
742
- this._setBoolean(env, 'profiling.heuristicsEnabled', true)
743
- }
744
- if (DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD) {
745
- // This is only used in testing to not have to wait 30s
746
- this._setValue(env, 'profiling.longLivedThreshold', Number(DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD))
747
- }
710
+ if (DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD) {
711
+ // This is only used in testing to not have to wait 30s
712
+ this._setValue(env, 'profiling.longLivedThreshold', Number(DD_INTERNAL_PROFILING_LONG_LIVED_THRESHOLD))
748
713
  }
749
714
 
750
715
  this._setString(env, 'protocolVersion', DD_TRACE_AGENT_PROTOCOL_VERSION)
@@ -762,6 +727,10 @@ class Config {
762
727
  : undefined
763
728
  this._setBoolean(env, 'runtimeMetrics', DD_RUNTIME_METRICS_ENABLED ||
764
729
  otelSetRuntimeMetrics)
730
+ this._setArray(env, 'sampler.spanSamplingRules', reformatSpanSamplingRules(coalesce(
731
+ safeJsonParse(maybeFile(DD_SPAN_SAMPLING_RULES_FILE)),
732
+ safeJsonParse(DD_SPAN_SAMPLING_RULES)
733
+ )))
765
734
  this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE ||
766
735
  getFromOtelSamplerMap(OTEL_TRACES_SAMPLER, OTEL_TRACES_SAMPLER_ARG))
767
736
  this._setValue(env, 'sampler.rateLimit', DD_TRACE_RATE_LIMIT)
@@ -769,11 +738,18 @@ class Config {
769
738
  this._envUnprocessed['sampler.rules'] = DD_TRACE_SAMPLING_RULES
770
739
  this._setString(env, 'scope', DD_TRACE_SCOPE)
771
740
  this._setString(env, 'service', DD_SERVICE || DD_SERVICE_NAME || tags.service || OTEL_SERVICE_NAME)
741
+ if (DD_SERVICE_MAPPING) {
742
+ this._setValue(env, 'serviceMapping', fromEntries(
743
+ process.env.DD_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
744
+ ))
745
+ }
772
746
  this._setString(env, 'site', DD_SITE)
773
747
  if (DD_TRACE_SPAN_ATTRIBUTE_SCHEMA) {
774
748
  this._setString(env, 'spanAttributeSchema', validateNamingVersion(DD_TRACE_SPAN_ATTRIBUTE_SCHEMA))
775
749
  this._envUnprocessed.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
776
750
  }
751
+ // 0: disabled, 1: logging, 2: garbage collection + logging
752
+ this._setValue(env, 'spanLeakDebug', maybeInt(DD_TRACE_SPAN_LEAK_DEBUG))
777
753
  this._setBoolean(env, 'spanRemoveIntegrationFromService', DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED)
778
754
  this._setBoolean(env, 'startupLogs', DD_TRACE_STARTUP_LOGS)
779
755
  this._setTags(env, 'tags', tags)
@@ -788,15 +764,17 @@ class Config {
788
764
  this._setBoolean(env, 'telemetry.dependencyCollection', DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED)
789
765
  this._setValue(env, 'telemetry.heartbeatInterval', maybeInt(Math.floor(DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000)))
790
766
  this._envUnprocessed['telemetry.heartbeatInterval'] = DD_TELEMETRY_HEARTBEAT_INTERVAL * 1000
791
- const hasTelemetryLogsUsingFeatures =
792
- env['iast.enabled'] || env['profiling.enabled'] || env['profiling.heuristicsEnabled']
793
- ? true
794
- : undefined
795
- this._setBoolean(env, 'telemetry.logCollection', coalesce(DD_TELEMETRY_LOG_COLLECTION_ENABLED,
796
- hasTelemetryLogsUsingFeatures))
767
+ this._setBoolean(env, 'telemetry.logCollection', DD_TELEMETRY_LOG_COLLECTION_ENABLED)
797
768
  this._setBoolean(env, 'telemetry.metrics', DD_TELEMETRY_METRICS_ENABLED)
798
769
  this._setBoolean(env, 'traceId128BitGenerationEnabled', DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
799
770
  this._setBoolean(env, 'traceId128BitLoggingEnabled', DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
771
+ this._setBoolean(env, 'tracePropagationExtractFirst', DD_TRACE_PROPAGATION_EXTRACT_FIRST)
772
+ this._setBoolean(env, 'tracePropagationStyle.otelPropagators',
773
+ DD_TRACE_PROPAGATION_STYLE ||
774
+ DD_TRACE_PROPAGATION_STYLE_INJECT ||
775
+ DD_TRACE_PROPAGATION_STYLE_EXTRACT
776
+ ? false
777
+ : !!OTEL_PROPAGATORS)
800
778
  this._setBoolean(env, 'tracing', DD_TRACING_ENABLED)
801
779
  this._setString(env, 'version', DD_VERSION || tags.version)
802
780
  }
@@ -810,11 +788,20 @@ class Config {
810
788
 
811
789
  tagger.add(tags, options.tags)
812
790
 
791
+ this._setBoolean(opts, 'appsec.apiSecurity.enabled', options.appsec.apiSecurity?.enabled)
792
+ this._setUnit(opts, 'appsec.apiSecurity.requestSampling', options.appsec.apiSecurity?.requestSampling)
793
+ this._setValue(opts, 'appsec.blockedTemplateGraphql', maybeFile(options.appsec.blockedTemplateGraphql))
813
794
  this._setValue(opts, 'appsec.blockedTemplateHtml', maybeFile(options.appsec.blockedTemplateHtml))
814
795
  this._optsUnprocessed['appsec.blockedTemplateHtml'] = options.appsec.blockedTemplateHtml
815
796
  this._setValue(opts, 'appsec.blockedTemplateJson', maybeFile(options.appsec.blockedTemplateJson))
816
797
  this._optsUnprocessed['appsec.blockedTemplateJson'] = options.appsec.blockedTemplateJson
817
798
  this._setBoolean(opts, 'appsec.enabled', options.appsec.enabled)
799
+ let eventTracking = options.appsec.eventTracking?.mode
800
+ if (eventTracking) {
801
+ eventTracking = eventTracking.toLowerCase()
802
+ this._setValue(opts, 'appsec.eventTracking.enabled', ['extended', 'safe'].includes(eventTracking))
803
+ this._setValue(opts, 'appsec.eventTracking.mode', eventTracking)
804
+ }
818
805
  this._setString(opts, 'appsec.obfuscatorKeyRegex', options.appsec.obfuscatorKeyRegex)
819
806
  this._setString(opts, 'appsec.obfuscatorValueRegex', options.appsec.obfuscatorValueRegex)
820
807
  this._setBoolean(opts, 'appsec.rasp.enabled', options.appsec.rasp?.enabled)
@@ -872,7 +859,10 @@ class Config {
872
859
  this._setValue(opts, 'peerServiceMapping', options.peerServiceMapping)
873
860
  this._setBoolean(opts, 'plugins', options.plugins)
874
861
  this._setString(opts, 'port', options.port)
875
- this._setBoolean(opts, 'profiling.enabled', options.profiling)
862
+ const strProfiling = String(options.profiling)
863
+ if (['true', 'false', 'auto'].includes(strProfiling)) {
864
+ this._setString(opts, 'profiling.enabled', strProfiling)
865
+ }
876
866
  this._setString(opts, 'protocolVersion', options.protocolVersion)
877
867
  if (options.remoteConfig) {
878
868
  this._setValue(opts, 'remoteConfig.pollInterval', maybeFloat(options.remoteConfig.pollInterval))
@@ -880,11 +870,13 @@ class Config {
880
870
  }
881
871
  this._setBoolean(opts, 'reportHostname', options.reportHostname)
882
872
  this._setBoolean(opts, 'runtimeMetrics', options.runtimeMetrics)
873
+ this._setArray(opts, 'sampler.spanSamplingRules', reformatSpanSamplingRules(options.spanSamplingRules))
883
874
  this._setUnit(opts, 'sampleRate', coalesce(options.sampleRate, options.ingestion.sampleRate))
884
875
  const ingestion = options.ingestion || {}
885
876
  this._setValue(opts, 'sampler.rateLimit', coalesce(options.rateLimit, ingestion.rateLimit))
886
877
  this._setSamplingRule(opts, 'sampler.rules', options.samplingRules)
887
878
  this._setString(opts, 'service', options.service || tags.service)
879
+ this._setValue(opts, 'serviceMapping', options.serviceMapping)
888
880
  this._setString(opts, 'site', options.site)
889
881
  if (options.spanAttributeSchema) {
890
882
  this._setString(opts, 'spanAttributeSchema', validateNamingVersion(options.spanAttributeSchema))
@@ -893,10 +885,6 @@ class Config {
893
885
  this._setBoolean(opts, 'spanRemoveIntegrationFromService', options.spanRemoveIntegrationFromService)
894
886
  this._setBoolean(opts, 'startupLogs', options.startupLogs)
895
887
  this._setTags(opts, 'tags', tags)
896
- const hasTelemetryLogsUsingFeatures =
897
- (options.iast && (options.iast === true || options.iast?.enabled === true)) ||
898
- (options.profiling && options.profiling === true)
899
- this._setBoolean(opts, 'telemetry.logCollection', hasTelemetryLogsUsingFeatures)
900
888
  this._setBoolean(opts, 'traceId128BitGenerationEnabled', options.traceId128BitGenerationEnabled)
901
889
  this._setBoolean(opts, 'traceId128BitLoggingEnabled', options.traceId128BitLoggingEnabled)
902
890
  this._setString(opts, 'version', options.version || tags.version)
@@ -994,7 +982,10 @@ class Config {
994
982
  const calc = setHiddenProperty(this, '_calculated', {})
995
983
 
996
984
  const {
997
- DD_CIVISIBILITY_AGENTLESS_URL
985
+ DD_CIVISIBILITY_AGENTLESS_URL,
986
+ DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED,
987
+ DD_CIVISIBILITY_FLAKY_RETRY_ENABLED,
988
+ DD_CIVISIBILITY_FLAKY_RETRY_COUNT
998
989
  } = process.env
999
990
 
1000
991
  if (DD_CIVISIBILITY_AGENTLESS_URL) {
@@ -1004,7 +995,10 @@ class Config {
1004
995
  }
1005
996
  if (this._isCiVisibility()) {
1006
997
  this._setBoolean(calc, 'isEarlyFlakeDetectionEnabled',
1007
- coalesce(process.env.DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED, true))
998
+ coalesce(DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED, true))
999
+ this._setBoolean(calc, 'isFlakyTestRetriesEnabled',
1000
+ coalesce(DD_CIVISIBILITY_FLAKY_RETRY_ENABLED, true))
1001
+ this._setValue(calc, 'flakyTestRetriesCount', coalesce(maybeInt(DD_CIVISIBILITY_FLAKY_RETRY_COUNT), 5))
1008
1002
  this._setBoolean(calc, 'isIntelligentTestRunnerEnabled', isTrue(this._isCiVisibilityItrEnabled()))
1009
1003
  this._setBoolean(calc, 'isManualApiEnabled', this._isCiVisibilityManualApiEnabled())
1010
1004
  }
@@ -1013,6 +1007,26 @@ class Config {
1013
1007
  calc.isIntelligentTestRunnerEnabled && !isFalse(this._isCiVisibilityGitUploadEnabled()))
1014
1008
  this._setBoolean(calc, 'spanComputePeerService', this._getSpanComputePeerService())
1015
1009
  this._setBoolean(calc, 'stats.enabled', this._isTraceStatsComputationEnabled())
1010
+ const defaultPropagationStyle = this._getDefaultPropagationStyle(this._optionsArg)
1011
+ this._setValue(calc, 'tracePropagationStyle.inject', propagationStyle(
1012
+ 'inject',
1013
+ this._optionsArg.tracePropagationStyle
1014
+ ))
1015
+ this._setValue(calc, 'tracePropagationStyle.extract', propagationStyle(
1016
+ 'extract',
1017
+ this._optionsArg.tracePropagationStyle
1018
+ ))
1019
+ if (defaultPropagationStyle.length > 2) {
1020
+ calc['tracePropagationStyle.inject'] = calc['tracePropagationStyle.inject'] || defaultPropagationStyle
1021
+ calc['tracePropagationStyle.extract'] = calc['tracePropagationStyle.extract'] || defaultPropagationStyle
1022
+ }
1023
+
1024
+ const iastEnabled = coalesce(this._options['iast.enabled'], this._env['iast.enabled'])
1025
+ const profilingEnabled = coalesce(this._options['profiling.enabled'], this._env['profiling.enabled'])
1026
+ const injectionIncludesProfiler = (this._env.injectionEnabled || []).includes('profiler')
1027
+ if (iastEnabled || ['auto', 'true'].includes(profilingEnabled) || injectionIncludesProfiler) {
1028
+ this._setBoolean(calc, 'telemetry.logCollection', true)
1029
+ }
1016
1030
  }
1017
1031
 
1018
1032
  _applyRemote (options) {
@@ -1137,17 +1151,18 @@ class Config {
1137
1151
  for (const name in this._defaults) {
1138
1152
  for (let i = 0; i < containers.length; i++) {
1139
1153
  const container = containers[i]
1140
- const origin = origins[i]
1141
- const unprocessed = unprocessedValues[i]
1154
+ const value = container[name]
1142
1155
 
1143
- if ((container[name] !== null && container[name] !== undefined) || container === this._defaults) {
1144
- if (get(this, name) === container[name] && has(this, name)) break
1156
+ if ((value !== null && value !== undefined) || container === this._defaults) {
1157
+ if (get(this, name) === value && has(this, name)) break
1145
1158
 
1146
- let value = container[name]
1147
1159
  set(this, name, value)
1148
- value = unprocessed[name] || value
1149
1160
 
1150
- changes.push({ name, value, origin })
1161
+ changes.push({
1162
+ name,
1163
+ value: unprocessedValues[i][name] || value,
1164
+ origin: origins[i]
1165
+ })
1151
1166
 
1152
1167
  break
1153
1168
  }
@@ -93,6 +93,7 @@ exports.datadog = function datadog (lambdaHandler) {
93
93
  return res
94
94
  })
95
95
  }
96
+ clearTimeout(__lambdaTimeout)
96
97
  return result
97
98
  }
98
99
  }
@@ -2,4 +2,15 @@
2
2
 
3
3
  const { registerLambdaHook } = require('./runtime/ritm')
4
4
 
5
- registerLambdaHook()
5
+ /**
6
+ * It is safe to do it this way, since customers will never be expected to disable
7
+ * this specific instrumentation through the init config object.
8
+ */
9
+ const _DD_TRACE_DISABLED_INSTRUMENTATIONS = process.env.DD_TRACE_DISABLED_INSTRUMENTATIONS || ''
10
+ const _disabledInstrumentations = new Set(
11
+ _DD_TRACE_DISABLED_INSTRUMENTATIONS ? _DD_TRACE_DISABLED_INSTRUMENTATIONS.split(',') : []
12
+ )
13
+
14
+ if (!_disabledInstrumentations.has('lambda')) {
15
+ registerLambdaHook()
16
+ }