dd-trace 5.24.0 → 5.26.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 (138) hide show
  1. package/LICENSE-3rdparty.csv +3 -0
  2. package/index.d.ts +345 -8
  3. package/init.js +60 -47
  4. package/package.json +16 -7
  5. package/packages/datadog-code-origin/index.js +4 -4
  6. package/packages/datadog-core/index.js +1 -3
  7. package/packages/datadog-core/src/storage.js +21 -0
  8. package/packages/datadog-core/src/utils/src/parse-tags.js +33 -0
  9. package/packages/datadog-esbuild/index.js +4 -2
  10. package/packages/datadog-instrumentations/src/amqplib.js +65 -5
  11. package/packages/datadog-instrumentations/src/child_process.js +135 -27
  12. package/packages/datadog-instrumentations/src/express.js +1 -1
  13. package/packages/datadog-instrumentations/src/handlebars.js +40 -0
  14. package/packages/datadog-instrumentations/src/helpers/hooks.js +5 -0
  15. package/packages/datadog-instrumentations/src/helpers/register.js +9 -0
  16. package/packages/datadog-instrumentations/src/jest.js +6 -2
  17. package/packages/datadog-instrumentations/src/kafkajs.js +123 -63
  18. package/packages/datadog-instrumentations/src/mocha/utils.js +2 -2
  19. package/packages/datadog-instrumentations/src/multer.js +37 -0
  20. package/packages/datadog-instrumentations/src/openai.js +2 -2
  21. package/packages/datadog-instrumentations/src/pug.js +23 -0
  22. package/packages/datadog-instrumentations/src/router.js +2 -3
  23. package/packages/datadog-instrumentations/src/url.js +84 -0
  24. package/packages/datadog-instrumentations/src/utils/src/extract-package-and-module-path.js +7 -4
  25. package/packages/datadog-plugin-amqplib/src/consumer.js +6 -5
  26. package/packages/datadog-plugin-aws-sdk/src/base.js +5 -0
  27. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -0
  28. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +10 -7
  29. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +35 -0
  30. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +11 -9
  31. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +59 -45
  32. package/packages/datadog-plugin-cypress/src/support.js +1 -0
  33. package/packages/datadog-plugin-fastify/src/code_origin.js +2 -2
  34. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +10 -2
  35. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +8 -0
  36. package/packages/datadog-plugin-grpc/src/client.js +3 -0
  37. package/packages/datadog-plugin-grpc/src/server.js +5 -1
  38. package/packages/datadog-plugin-http/src/client.js +42 -1
  39. package/packages/datadog-plugin-http2/src/client.js +26 -1
  40. package/packages/datadog-plugin-jest/src/index.js +2 -1
  41. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +6 -3
  42. package/packages/datadog-plugin-kafkajs/src/consumer.js +10 -5
  43. package/packages/datadog-plugin-kafkajs/src/producer.js +10 -4
  44. package/packages/datadog-plugin-mocha/src/index.js +5 -2
  45. package/packages/datadog-plugin-moleculer/src/server.js +2 -2
  46. package/packages/datadog-plugin-openai/src/index.js +9 -1015
  47. package/packages/datadog-plugin-openai/src/tracing.js +1023 -0
  48. package/packages/datadog-plugin-rhea/src/consumer.js +2 -1
  49. package/packages/datadog-plugin-vitest/src/index.js +2 -1
  50. package/packages/dd-trace/src/appsec/addresses.js +2 -0
  51. package/packages/dd-trace/src/appsec/api_security_sampler.js +50 -27
  52. package/packages/dd-trace/src/appsec/channels.js +3 -1
  53. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
  54. package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +33 -16
  55. package/packages/dd-trace/src/appsec/iast/analyzers/template-injection-analyzer.js +18 -0
  56. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +55 -7
  57. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +3 -2
  58. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
  59. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +4 -2
  60. package/packages/dd-trace/src/appsec/index.js +9 -6
  61. package/packages/dd-trace/src/appsec/rasp/command_injection.js +49 -0
  62. package/packages/dd-trace/src/appsec/rasp/index.js +3 -0
  63. package/packages/dd-trace/src/appsec/rasp/ssrf.js +4 -3
  64. package/packages/dd-trace/src/appsec/rasp/utils.js +3 -2
  65. package/packages/dd-trace/src/appsec/recommended.json +354 -158
  66. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
  67. package/packages/dd-trace/src/appsec/remote_config/index.js +2 -7
  68. package/packages/dd-trace/src/appsec/reporter.js +6 -4
  69. package/packages/dd-trace/src/appsec/sdk/track_event.js +5 -3
  70. package/packages/dd-trace/src/appsec/waf/waf_manager.js +4 -0
  71. package/packages/dd-trace/src/azure_metadata.js +120 -0
  72. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +97 -0
  73. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +90 -0
  74. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +19 -1
  75. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +53 -0
  76. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +8 -1
  77. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +43 -0
  78. package/packages/dd-trace/src/config.js +88 -10
  79. package/packages/dd-trace/src/constants.js +8 -1
  80. package/packages/dd-trace/src/crashtracking/crashtracker.js +98 -0
  81. package/packages/dd-trace/src/crashtracking/index.js +15 -0
  82. package/packages/dd-trace/src/crashtracking/noop.js +8 -0
  83. package/packages/dd-trace/src/datastreams/pathway.js +1 -0
  84. package/packages/dd-trace/src/debugger/devtools_client/index.js +9 -13
  85. package/packages/dd-trace/src/debugger/devtools_client/send.js +15 -1
  86. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +57 -23
  87. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +12 -2
  88. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +31 -20
  89. package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +6 -0
  90. package/packages/dd-trace/src/debugger/devtools_client/state.js +11 -2
  91. package/packages/dd-trace/src/debugger/index.js +10 -3
  92. package/packages/dd-trace/src/llmobs/constants/tags.js +34 -0
  93. package/packages/dd-trace/src/llmobs/constants/text.js +6 -0
  94. package/packages/dd-trace/src/llmobs/constants/writers.js +13 -0
  95. package/packages/dd-trace/src/llmobs/index.js +103 -0
  96. package/packages/dd-trace/src/llmobs/noop.js +82 -0
  97. package/packages/dd-trace/src/llmobs/plugins/base.js +65 -0
  98. package/packages/dd-trace/src/llmobs/plugins/openai.js +205 -0
  99. package/packages/dd-trace/src/llmobs/sdk.js +377 -0
  100. package/packages/dd-trace/src/llmobs/span_processor.js +195 -0
  101. package/packages/dd-trace/src/llmobs/storage.js +7 -0
  102. package/packages/dd-trace/src/llmobs/tagger.js +322 -0
  103. package/packages/dd-trace/src/llmobs/util.js +176 -0
  104. package/packages/dd-trace/src/llmobs/writers/base.js +111 -0
  105. package/packages/dd-trace/src/llmobs/writers/evaluations.js +29 -0
  106. package/packages/dd-trace/src/llmobs/writers/spans/agentProxy.js +23 -0
  107. package/packages/dd-trace/src/llmobs/writers/spans/agentless.js +17 -0
  108. package/packages/dd-trace/src/llmobs/writers/spans/base.js +52 -0
  109. package/packages/dd-trace/src/log/index.js +10 -13
  110. package/packages/dd-trace/src/log/log.js +52 -0
  111. package/packages/dd-trace/src/log/writer.js +50 -19
  112. package/packages/dd-trace/src/noop/proxy.js +3 -0
  113. package/packages/dd-trace/src/noop/span.js +4 -0
  114. package/packages/dd-trace/src/opentelemetry/span.js +16 -1
  115. package/packages/dd-trace/src/opentelemetry/tracer.js +1 -0
  116. package/packages/dd-trace/src/opentracing/propagation/text_map.js +106 -32
  117. package/packages/dd-trace/src/opentracing/span.js +26 -0
  118. package/packages/dd-trace/src/opentracing/span_context.js +1 -0
  119. package/packages/dd-trace/src/opentracing/tracer.js +8 -1
  120. package/packages/dd-trace/src/payload-tagging/config/aws.json +71 -3
  121. package/packages/dd-trace/src/plugins/outbound.js +9 -0
  122. package/packages/dd-trace/src/plugins/tracing.js +3 -3
  123. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +121 -0
  124. package/packages/dd-trace/src/plugins/util/ip_extractor.js +0 -1
  125. package/packages/dd-trace/src/plugins/util/web.js +39 -11
  126. package/packages/dd-trace/src/priority_sampler.js +16 -0
  127. package/packages/dd-trace/src/profiling/config.js +3 -1
  128. package/packages/dd-trace/src/profiling/exporters/agent.js +7 -5
  129. package/packages/dd-trace/src/profiling/profilers/wall.js +2 -1
  130. package/packages/dd-trace/src/proxy.js +13 -1
  131. package/packages/dd-trace/src/span_processor.js +5 -0
  132. package/packages/dd-trace/src/telemetry/index.js +11 -1
  133. package/packages/dd-trace/src/telemetry/logs/index.js +16 -11
  134. package/packages/dd-trace/src/telemetry/logs/log-collector.js +3 -8
  135. package/packages/dd-trace/src/telemetry/metrics.js +6 -1
  136. package/packages/dd-trace/src/util.js +16 -1
  137. package/version.js +4 -2
  138. /package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/{code-injection-sensitive-analyzer.js → tainted-range-based-sensitive-analyzer.js} +0 -0
@@ -17,7 +17,7 @@ const { getGitMetadataFromGitProperties, removeUserSensitiveInfo } = require('./
17
17
  const { updateConfig } = require('./telemetry')
18
18
  const telemetryMetrics = require('./telemetry/metrics')
19
19
  const { getIsGCPFunction, getIsAzureFunction } = require('./serverless')
20
- const { ORIGIN_KEY } = require('./constants')
20
+ const { ORIGIN_KEY, GRPC_CLIENT_ERROR_STATUSES, GRPC_SERVER_ERROR_STATUSES } = require('./constants')
21
21
  const { appendRules } = require('./payload-tagging/config')
22
22
 
23
23
  const tracerMetrics = telemetryMetrics.manager.namespace('tracers')
@@ -444,7 +444,7 @@ class Config {
444
444
  const defaults = setHiddenProperty(this, '_defaults', {})
445
445
 
446
446
  this._setValue(defaults, 'appsec.apiSecurity.enabled', true)
447
- this._setValue(defaults, 'appsec.apiSecurity.requestSampling', 0.1)
447
+ this._setValue(defaults, 'appsec.apiSecurity.sampleDelay', 30)
448
448
  this._setValue(defaults, 'appsec.blockedTemplateGraphql', undefined)
449
449
  this._setValue(defaults, 'appsec.blockedTemplateHtml', undefined)
450
450
  this._setValue(defaults, 'appsec.blockedTemplateJson', undefined)
@@ -462,8 +462,12 @@ class Config {
462
462
  this._setValue(defaults, 'appsec.stackTrace.maxDepth', 32)
463
463
  this._setValue(defaults, 'appsec.stackTrace.maxStackTraces', 2)
464
464
  this._setValue(defaults, 'appsec.wafTimeout', 5e3) // µs
465
+ this._setValue(defaults, 'baggageMaxBytes', 8192)
466
+ this._setValue(defaults, 'baggageMaxItems', 64)
467
+ this._setValue(defaults, 'ciVisibilityTestSessionName', '')
465
468
  this._setValue(defaults, 'clientIpEnabled', false)
466
469
  this._setValue(defaults, 'clientIpHeader', null)
470
+ this._setValue(defaults, 'crashtracking.enabled', false)
467
471
  this._setValue(defaults, 'codeOriginForSpans.enabled', false)
468
472
  this._setValue(defaults, 'dbmPropagationMode', 'disabled')
469
473
  this._setValue(defaults, 'dogstatsd.hostname', '127.0.0.1')
@@ -477,6 +481,8 @@ class Config {
477
481
  this._setValue(defaults, 'flushInterval', 2000)
478
482
  this._setValue(defaults, 'flushMinSpans', 1000)
479
483
  this._setValue(defaults, 'gitMetadataEnabled', true)
484
+ this._setValue(defaults, 'grpc.client.error.statuses', GRPC_CLIENT_ERROR_STATUSES)
485
+ this._setValue(defaults, 'grpc.server.error.statuses', GRPC_SERVER_ERROR_STATUSES)
480
486
  this._setValue(defaults, 'headerTags', [])
481
487
  this._setValue(defaults, 'hostname', '127.0.0.1')
482
488
  this._setValue(defaults, 'iast.cookieFilterPattern', '.{32,}')
@@ -499,10 +505,16 @@ class Config {
499
505
  this._setValue(defaults, 'isGitUploadEnabled', false)
500
506
  this._setValue(defaults, 'isIntelligentTestRunnerEnabled', false)
501
507
  this._setValue(defaults, 'isManualApiEnabled', false)
508
+ this._setValue(defaults, 'llmobs.agentlessEnabled', false)
509
+ this._setValue(defaults, 'llmobs.enabled', false)
510
+ this._setValue(defaults, 'llmobs.mlApp', undefined)
502
511
  this._setValue(defaults, 'ciVisibilityTestSessionName', '')
503
512
  this._setValue(defaults, 'ciVisAgentlessLogSubmissionEnabled', false)
513
+ this._setValue(defaults, 'legacyBaggageEnabled', true)
514
+ this._setValue(defaults, 'isTestDynamicInstrumentationEnabled', false)
504
515
  this._setValue(defaults, 'logInjection', false)
505
516
  this._setValue(defaults, 'lookup', undefined)
517
+ this._setValue(defaults, 'inferredProxyServicesEnabled', false)
506
518
  this._setValue(defaults, 'memcachedCommandEnabled', false)
507
519
  this._setValue(defaults, 'openAiLogsEnabled', false)
508
520
  this._setValue(defaults, 'openaiSpanCharLimit', 128)
@@ -520,7 +532,7 @@ class Config {
520
532
  this._setValue(defaults, 'reportHostname', false)
521
533
  this._setValue(defaults, 'runtimeMetrics', false)
522
534
  this._setValue(defaults, 'sampleRate', undefined)
523
- this._setValue(defaults, 'sampler.rateLimit', undefined)
535
+ this._setValue(defaults, 'sampler.rateLimit', 100)
524
536
  this._setValue(defaults, 'sampler.rules', [])
525
537
  this._setValue(defaults, 'sampler.spanSamplingRules', [])
526
538
  this._setValue(defaults, 'scope', undefined)
@@ -541,11 +553,12 @@ class Config {
541
553
  this._setValue(defaults, 'telemetry.heartbeatInterval', 60000)
542
554
  this._setValue(defaults, 'telemetry.logCollection', false)
543
555
  this._setValue(defaults, 'telemetry.metrics', true)
556
+ this._setValue(defaults, 'traceEnabled', true)
544
557
  this._setValue(defaults, 'traceId128BitGenerationEnabled', true)
545
558
  this._setValue(defaults, 'traceId128BitLoggingEnabled', false)
546
559
  this._setValue(defaults, 'tracePropagationExtractFirst', false)
547
- this._setValue(defaults, 'tracePropagationStyle.inject', ['datadog', 'tracecontext'])
548
- this._setValue(defaults, 'tracePropagationStyle.extract', ['datadog', 'tracecontext'])
560
+ this._setValue(defaults, 'tracePropagationStyle.inject', ['datadog', 'tracecontext', 'baggage'])
561
+ this._setValue(defaults, 'tracePropagationStyle.extract', ['datadog', 'tracecontext', 'baggage'])
549
562
  this._setValue(defaults, 'tracePropagationStyle.otelPropagators', false)
550
563
  this._setValue(defaults, 'tracing', true)
551
564
  this._setValue(defaults, 'url', undefined)
@@ -558,7 +571,7 @@ class Config {
558
571
  AWS_LAMBDA_FUNCTION_NAME,
559
572
  DD_AGENT_HOST,
560
573
  DD_API_SECURITY_ENABLED,
561
- DD_API_SECURITY_REQUEST_SAMPLE_RATE,
574
+ DD_API_SECURITY_SAMPLE_DELAY,
562
575
  DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING,
563
576
  DD_APPSEC_ENABLED,
564
577
  DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON,
@@ -574,6 +587,7 @@ class Config {
574
587
  DD_APPSEC_RASP_ENABLED,
575
588
  DD_APPSEC_TRACE_RATE_LIMIT,
576
589
  DD_APPSEC_WAF_TIMEOUT,
590
+ DD_CRASHTRACKING_ENABLED,
577
591
  DD_CODE_ORIGIN_FOR_SPANS_ENABLED,
578
592
  DD_DATA_STREAMS_ENABLED,
579
593
  DD_DBM_PROPAGATION_MODE,
@@ -584,6 +598,8 @@ class Config {
584
598
  DD_EXPERIMENTAL_API_SECURITY_ENABLED,
585
599
  DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED,
586
600
  DD_EXPERIMENTAL_PROFILING_ENABLED,
601
+ DD_GRPC_CLIENT_ERROR_STATUSES,
602
+ DD_GRPC_SERVER_ERROR_STATUSES,
587
603
  JEST_WORKER_ID,
588
604
  DD_IAST_COOKIE_FILTER_PATTERN,
589
605
  DD_IAST_DEDUPLICATION_ENABLED,
@@ -599,6 +615,9 @@ class Config {
599
615
  DD_INSTRUMENTATION_TELEMETRY_ENABLED,
600
616
  DD_INSTRUMENTATION_CONFIG_ID,
601
617
  DD_LOGS_INJECTION,
618
+ DD_LLMOBS_AGENTLESS_ENABLED,
619
+ DD_LLMOBS_ENABLED,
620
+ DD_LLMOBS_ML_APP,
602
621
  DD_OPENAI_LOGS_ENABLED,
603
622
  DD_OPENAI_SPAN_CHAR_LIMIT,
604
623
  DD_PROFILING_ENABLED,
@@ -625,14 +644,18 @@ class Config {
625
644
  DD_TRACE_AGENT_HOSTNAME,
626
645
  DD_TRACE_AGENT_PORT,
627
646
  DD_TRACE_AGENT_PROTOCOL_VERSION,
647
+ DD_TRACE_BAGGAGE_MAX_BYTES,
648
+ DD_TRACE_BAGGAGE_MAX_ITEMS,
628
649
  DD_TRACE_CLIENT_IP_ENABLED,
629
650
  DD_TRACE_CLIENT_IP_HEADER,
651
+ DD_TRACE_ENABLED,
630
652
  DD_TRACE_EXPERIMENTAL_EXPORTER,
631
653
  DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
632
654
  DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED,
633
655
  DD_TRACE_GIT_METADATA_ENABLED,
634
656
  DD_TRACE_GLOBAL_TAGS,
635
657
  DD_TRACE_HEADER_TAGS,
658
+ DD_TRACE_LEGACY_BAGGAGE_ENABLED,
636
659
  DD_TRACE_MEMCACHED_COMMAND_ENABLED,
637
660
  DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
638
661
  DD_TRACE_PARTIAL_FLUSH_MIN_SPANS,
@@ -655,6 +678,7 @@ class Config {
655
678
  DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
656
679
  DD_TRACING_ENABLED,
657
680
  DD_VERSION,
681
+ DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED,
658
682
  OTEL_METRICS_EXPORTER,
659
683
  OTEL_PROPAGATORS,
660
684
  OTEL_RESOURCE_ATTRIBUTES,
@@ -676,7 +700,7 @@ class Config {
676
700
  DD_API_SECURITY_ENABLED && isTrue(DD_API_SECURITY_ENABLED),
677
701
  DD_EXPERIMENTAL_API_SECURITY_ENABLED && isTrue(DD_EXPERIMENTAL_API_SECURITY_ENABLED)
678
702
  ))
679
- this._setUnit(env, 'appsec.apiSecurity.requestSampling', DD_API_SECURITY_REQUEST_SAMPLE_RATE)
703
+ this._setValue(env, 'appsec.apiSecurity.sampleDelay', maybeFloat(DD_API_SECURITY_SAMPLE_DELAY))
680
704
  this._setValue(env, 'appsec.blockedTemplateGraphql', maybeFile(DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON))
681
705
  this._setValue(env, 'appsec.blockedTemplateHtml', maybeFile(DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML))
682
706
  this._envUnprocessed['appsec.blockedTemplateHtml'] = DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML
@@ -704,8 +728,11 @@ class Config {
704
728
  this._envUnprocessed['appsec.stackTrace.maxStackTraces'] = DD_APPSEC_MAX_STACK_TRACES
705
729
  this._setValue(env, 'appsec.wafTimeout', maybeInt(DD_APPSEC_WAF_TIMEOUT))
706
730
  this._envUnprocessed['appsec.wafTimeout'] = DD_APPSEC_WAF_TIMEOUT
731
+ this._setValue(env, 'baggageMaxBytes', DD_TRACE_BAGGAGE_MAX_BYTES)
732
+ this._setValue(env, 'baggageMaxItems', DD_TRACE_BAGGAGE_MAX_ITEMS)
707
733
  this._setBoolean(env, 'clientIpEnabled', DD_TRACE_CLIENT_IP_ENABLED)
708
734
  this._setString(env, 'clientIpHeader', DD_TRACE_CLIENT_IP_HEADER)
735
+ this._setBoolean(env, 'crashtracking.enabled', DD_CRASHTRACKING_ENABLED)
709
736
  this._setBoolean(env, 'codeOriginForSpans.enabled', DD_CODE_ORIGIN_FOR_SPANS_ENABLED)
710
737
  this._setString(env, 'dbmPropagationMode', DD_DBM_PROPAGATION_MODE)
711
738
  this._setString(env, 'dogstatsd.hostname', DD_DOGSTATSD_HOSTNAME)
@@ -713,6 +740,7 @@ class Config {
713
740
  this._setBoolean(env, 'dsmEnabled', DD_DATA_STREAMS_ENABLED)
714
741
  this._setBoolean(env, 'dynamicInstrumentationEnabled', DD_DYNAMIC_INSTRUMENTATION_ENABLED)
715
742
  this._setString(env, 'env', DD_ENV || tags.env)
743
+ this._setBoolean(env, 'traceEnabled', DD_TRACE_ENABLED)
716
744
  this._setBoolean(env, 'experimental.enableGetRumData', DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED)
717
745
  this._setString(env, 'experimental.exporter', DD_TRACE_EXPERIMENTAL_EXPORTER)
718
746
  this._setBoolean(env, 'experimental.runtimeId', DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED)
@@ -720,6 +748,8 @@ class Config {
720
748
  this._setValue(env, 'flushMinSpans', maybeInt(DD_TRACE_PARTIAL_FLUSH_MIN_SPANS))
721
749
  this._envUnprocessed.flushMinSpans = DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
722
750
  this._setBoolean(env, 'gitMetadataEnabled', DD_TRACE_GIT_METADATA_ENABLED)
751
+ this._setIntegerRangeSet(env, 'grpc.client.error.statuses', DD_GRPC_CLIENT_ERROR_STATUSES)
752
+ this._setIntegerRangeSet(env, 'grpc.server.error.statuses', DD_GRPC_SERVER_ERROR_STATUSES)
723
753
  this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
724
754
  this._setString(env, 'hostname', coalesce(DD_AGENT_HOST, DD_TRACE_AGENT_HOSTNAME))
725
755
  this._setString(env, 'iast.cookieFilterPattern', DD_IAST_COOKIE_FILTER_PATTERN)
@@ -741,6 +771,10 @@ class Config {
741
771
  this._setArray(env, 'injectionEnabled', DD_INJECTION_ENABLED)
742
772
  this._setBoolean(env, 'isAzureFunction', getIsAzureFunction())
743
773
  this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())
774
+ this._setBoolean(env, 'legacyBaggageEnabled', DD_TRACE_LEGACY_BAGGAGE_ENABLED)
775
+ this._setBoolean(env, 'llmobs.agentlessEnabled', DD_LLMOBS_AGENTLESS_ENABLED)
776
+ this._setBoolean(env, 'llmobs.enabled', DD_LLMOBS_ENABLED)
777
+ this._setString(env, 'llmobs.mlApp', DD_LLMOBS_ML_APP)
744
778
  this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
745
779
  // Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
746
780
  this._setBoolean(env, 'memcachedCommandEnabled', DD_TRACE_MEMCACHED_COMMAND_ENABLED)
@@ -833,6 +867,7 @@ class Config {
833
867
  : !!OTEL_PROPAGATORS)
834
868
  this._setBoolean(env, 'tracing', DD_TRACING_ENABLED)
835
869
  this._setString(env, 'version', DD_VERSION || tags.version)
870
+ this._setBoolean(env, 'inferredProxyServicesEnabled', DD_TRACE_INFERRED_PROXY_SERVICES_ENABLED)
836
871
  }
837
872
 
838
873
  _applyOptions (options) {
@@ -845,7 +880,6 @@ class Config {
845
880
  tagger.add(tags, options.tags)
846
881
 
847
882
  this._setBoolean(opts, 'appsec.apiSecurity.enabled', options.appsec.apiSecurity?.enabled)
848
- this._setUnit(opts, 'appsec.apiSecurity.requestSampling', options.appsec.apiSecurity?.requestSampling)
849
883
  this._setValue(opts, 'appsec.blockedTemplateGraphql', maybeFile(options.appsec.blockedTemplateGraphql))
850
884
  this._setValue(opts, 'appsec.blockedTemplateHtml', maybeFile(options.appsec.blockedTemplateHtml))
851
885
  this._optsUnprocessed['appsec.blockedTemplateHtml'] = options.appsec.blockedTemplateHtml
@@ -874,6 +908,8 @@ class Config {
874
908
  this._optsUnprocessed['appsec.wafTimeout'] = options.appsec.wafTimeout
875
909
  this._setBoolean(opts, 'clientIpEnabled', options.clientIpEnabled)
876
910
  this._setString(opts, 'clientIpHeader', options.clientIpHeader)
911
+ this._setValue(opts, 'baggageMaxBytes', options.baggageMaxBytes)
912
+ this._setValue(opts, 'baggageMaxItems', options.baggageMaxItems)
877
913
  this._setBoolean(opts, 'codeOriginForSpans.enabled', options.codeOriginForSpans?.enabled)
878
914
  this._setString(opts, 'dbmPropagationMode', options.dbmPropagationMode)
879
915
  if (options.dogstatsd) {
@@ -911,6 +947,9 @@ class Config {
911
947
  }
912
948
  this._setString(opts, 'iast.telemetryVerbosity', options.iast && options.iast.telemetryVerbosity)
913
949
  this._setBoolean(opts, 'isCiVisibility', options.isCiVisibility)
950
+ this._setBoolean(opts, 'legacyBaggageEnabled', options.legacyBaggageEnabled)
951
+ this._setBoolean(opts, 'llmobs.agentlessEnabled', options.llmobs?.agentlessEnabled)
952
+ this._setString(opts, 'llmobs.mlApp', options.llmobs?.mlApp)
914
953
  this._setBoolean(opts, 'logInjection', options.logInjection)
915
954
  this._setString(opts, 'lookup', options.lookup)
916
955
  this._setBoolean(opts, 'openAiLogsEnabled', options.openAiLogsEnabled)
@@ -946,6 +985,16 @@ class Config {
946
985
  this._setBoolean(opts, 'traceId128BitGenerationEnabled', options.traceId128BitGenerationEnabled)
947
986
  this._setBoolean(opts, 'traceId128BitLoggingEnabled', options.traceId128BitLoggingEnabled)
948
987
  this._setString(opts, 'version', options.version || tags.version)
988
+ this._setBoolean(opts, 'inferredProxyServicesEnabled', options.inferredProxyServicesEnabled)
989
+
990
+ // For LLMObs, we want the environment variable to take precedence over the options.
991
+ // This is reliant on environment config being set before options.
992
+ // This is to make sure the origins of each value are tracked appropriately for telemetry.
993
+ // We'll only set `llmobs.enabled` on the opts when it's not set on the environment, and options.llmobs is provided.
994
+ const llmobsEnabledEnv = this._env['llmobs.enabled']
995
+ if (llmobsEnabledEnv == null && options.llmobs) {
996
+ this._setBoolean(opts, 'llmobs.enabled', !!options.llmobs)
997
+ }
949
998
  }
950
999
 
951
1000
  _isCiVisibility () {
@@ -1045,7 +1094,8 @@ class Config {
1045
1094
  DD_CIVISIBILITY_FLAKY_RETRY_ENABLED,
1046
1095
  DD_CIVISIBILITY_FLAKY_RETRY_COUNT,
1047
1096
  DD_TEST_SESSION_NAME,
1048
- DD_AGENTLESS_LOG_SUBMISSION_ENABLED
1097
+ DD_AGENTLESS_LOG_SUBMISSION_ENABLED,
1098
+ DD_TEST_DYNAMIC_INSTRUMENTATION_ENABLED
1049
1099
  } = process.env
1050
1100
 
1051
1101
  if (DD_CIVISIBILITY_AGENTLESS_URL) {
@@ -1063,6 +1113,7 @@ class Config {
1063
1113
  this._setBoolean(calc, 'isManualApiEnabled', !isFalse(this._isCiVisibilityManualApiEnabled()))
1064
1114
  this._setString(calc, 'ciVisibilityTestSessionName', DD_TEST_SESSION_NAME)
1065
1115
  this._setBoolean(calc, 'ciVisAgentlessLogSubmissionEnabled', isTrue(DD_AGENTLESS_LOG_SUBMISSION_ENABLED))
1116
+ this._setBoolean(calc, 'isTestDynamicInstrumentationEnabled', isTrue(DD_TEST_DYNAMIC_INSTRUMENTATION_ENABLED))
1066
1117
  }
1067
1118
  this._setString(calc, 'dogstatsd.hostname', this._getHostname())
1068
1119
  this._setBoolean(calc, 'isGitUploadEnabled',
@@ -1089,6 +1140,9 @@ class Config {
1089
1140
  if (iastEnabled || ['auto', 'true'].includes(profilingEnabled) || injectionIncludesProfiler) {
1090
1141
  this._setBoolean(calc, 'telemetry.logCollection', true)
1091
1142
  }
1143
+ if (this._env.injectionEnabled?.length > 0) {
1144
+ this._setBoolean(calc, 'crashtracking.enabled', true)
1145
+ }
1092
1146
  }
1093
1147
 
1094
1148
  _applyRemote (options) {
@@ -1155,7 +1209,11 @@ class Config {
1155
1209
  }
1156
1210
 
1157
1211
  if (typeof value === 'string') {
1158
- value = value.split(',')
1212
+ value = value.split(',').map(item => {
1213
+ // Trim each item and remove whitespace around the colon
1214
+ const [key, val] = item.split(':').map(part => part.trim())
1215
+ return val !== undefined ? `${key}:${val}` : key
1216
+ })
1159
1217
  }
1160
1218
 
1161
1219
  if (Array.isArray(value)) {
@@ -1163,6 +1221,26 @@ class Config {
1163
1221
  }
1164
1222
  }
1165
1223
 
1224
+ _setIntegerRangeSet (obj, name, value) {
1225
+ if (value == null) {
1226
+ return this._setValue(obj, name, null)
1227
+ }
1228
+ value = value.split(',')
1229
+ const result = []
1230
+
1231
+ value.forEach(val => {
1232
+ if (val.includes('-')) {
1233
+ const [start, end] = val.split('-').map(Number)
1234
+ for (let i = start; i <= end; i++) {
1235
+ result.push(i)
1236
+ }
1237
+ } else {
1238
+ result.push(Number(val))
1239
+ }
1240
+ })
1241
+ this._setValue(obj, name, result)
1242
+ }
1243
+
1166
1244
  _setSamplingRule (obj, name, value) {
1167
1245
  if (value == null) {
1168
1246
  return this._setValue(obj, name, null)
@@ -44,5 +44,12 @@ module.exports = {
44
44
  SCHEMA_ID: 'schema.id',
45
45
  SCHEMA_TOPIC: 'schema.topic',
46
46
  SCHEMA_OPERATION: 'schema.operation',
47
- SCHEMA_NAME: 'schema.name'
47
+ SCHEMA_NAME: 'schema.name',
48
+ GRPC_CLIENT_ERROR_STATUSES: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
49
+ GRPC_SERVER_ERROR_STATUSES: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
50
+ S3_PTR_KIND: 'aws.s3.object',
51
+ SPAN_POINTER_DIRECTION: Object.freeze({
52
+ UPSTREAM: 'u',
53
+ DOWNSTREAM: 'd'
54
+ })
48
55
  }
@@ -0,0 +1,98 @@
1
+ 'use strict'
2
+
3
+ // Load binding first to not import other modules if it throws
4
+ const libdatadog = require('@datadog/libdatadog')
5
+ const binding = libdatadog.load('crashtracker')
6
+
7
+ const log = require('../log')
8
+ const { URL } = require('url')
9
+ const pkg = require('../../../../package.json')
10
+
11
+ class Crashtracker {
12
+ constructor () {
13
+ this._started = false
14
+ }
15
+
16
+ configure (config) {
17
+ if (!this._started) return
18
+
19
+ try {
20
+ binding.updateConfig(this._getConfig(config))
21
+ binding.updateMetadata(this._getMetadata(config))
22
+ } catch (e) {
23
+ log.error(e)
24
+ }
25
+ }
26
+
27
+ start (config) {
28
+ if (this._started) return this.configure(config)
29
+
30
+ this._started = true
31
+
32
+ try {
33
+ binding.init(
34
+ this._getConfig(config),
35
+ this._getReceiverConfig(config),
36
+ this._getMetadata(config)
37
+ )
38
+ } catch (e) {
39
+ log.error(e)
40
+ }
41
+ }
42
+
43
+ // TODO: Send only configured values when defaults are fixed.
44
+ _getConfig (config) {
45
+ const { hostname = '127.0.0.1', port = 8126 } = config
46
+ const url = config.url || new URL(`http://${hostname}:${port}`)
47
+
48
+ return {
49
+ additional_files: [],
50
+ create_alt_stack: true,
51
+ use_alt_stack: true,
52
+ endpoint: {
53
+ // TODO: Use the string directly when deserialization is fixed.
54
+ url: {
55
+ scheme: url.protocol.slice(0, -1),
56
+ authority: url.protocol === 'unix'
57
+ ? Buffer.from(url.pathname).toString('hex')
58
+ : url.host,
59
+ path_and_query: ''
60
+ },
61
+ timeout_ms: 3000
62
+ },
63
+ timeout_ms: 0,
64
+ // TODO: Use `EnabledWithSymbolsInReceiver` instead for Linux when fixed.
65
+ resolve_frames: 'EnabledWithInprocessSymbols'
66
+ }
67
+ }
68
+
69
+ _getMetadata (config) {
70
+ const tags = Object.keys(config.tags).map(key => `${key}:${config.tags[key]}`)
71
+
72
+ return {
73
+ library_name: pkg.name,
74
+ library_version: pkg.version,
75
+ family: 'nodejs',
76
+ tags: [
77
+ ...tags,
78
+ 'is_crash:true',
79
+ 'language:javascript',
80
+ `library_version:${pkg.version}`,
81
+ 'runtime:nodejs',
82
+ 'severity:crash'
83
+ ]
84
+ }
85
+ }
86
+
87
+ _getReceiverConfig () {
88
+ return {
89
+ args: [],
90
+ env: [],
91
+ path_to_receiver_binary: libdatadog.find('crashtracker-receiver', true),
92
+ stderr_filename: null,
93
+ stdout_filename: null
94
+ }
95
+ }
96
+ }
97
+
98
+ module.exports = new Crashtracker()
@@ -0,0 +1,15 @@
1
+ 'use strict'
2
+
3
+ const { isMainThread } = require('worker_threads')
4
+ const log = require('../log')
5
+
6
+ if (isMainThread) {
7
+ try {
8
+ module.exports = require('./crashtracker')
9
+ } catch (e) {
10
+ log.warn(e.message)
11
+ module.exports = require('./noop')
12
+ }
13
+ } else {
14
+ module.exports = require('./noop')
15
+ }
@@ -0,0 +1,8 @@
1
+ 'use strict'
2
+
3
+ class NoopCrashtracker {
4
+ configure () {}
5
+ start () {}
6
+ }
7
+
8
+ module.exports = new NoopCrashtracker()
@@ -21,6 +21,7 @@ function shaHash (checkpointString) {
21
21
  }
22
22
 
23
23
  function computeHash (service, env, edgeTags, parentHash) {
24
+ edgeTags.sort()
24
25
  const hashableEdgeTags = edgeTags.filter(item => item !== 'manual_checkpoint:true')
25
26
 
26
27
  const key = `${service}${env}` + hashableEdgeTags.join('') + parentHash.toString()
@@ -5,7 +5,7 @@ const { breakpoints } = require('./state')
5
5
  const session = require('./session')
6
6
  const { getLocalStateForCallFrame } = require('./snapshot')
7
7
  const send = require('./send')
8
- const { getScriptUrlFromId } = require('./state')
8
+ const { getStackFromCallFrames } = require('./state')
9
9
  const { ackEmitting, ackError } = require('./status')
10
10
  const { parentThreadId } = require('./config')
11
11
  const log = require('../../log')
@@ -23,12 +23,14 @@ session.on('Debugger.paused', async ({ params }) => {
23
23
  const timestamp = Date.now()
24
24
 
25
25
  let captureSnapshotForProbe = null
26
- let maxReferenceDepth, maxLength
26
+ let maxReferenceDepth, maxCollectionSize, maxFieldCount, maxLength
27
27
  const probes = params.hitBreakpoints.map((id) => {
28
28
  const probe = breakpoints.get(id)
29
29
  if (probe.captureSnapshot) {
30
30
  captureSnapshotForProbe = probe
31
31
  maxReferenceDepth = highestOrUndefined(probe.capture.maxReferenceDepth, maxReferenceDepth)
32
+ maxCollectionSize = highestOrUndefined(probe.capture.maxCollectionSize, maxCollectionSize)
33
+ maxFieldCount = highestOrUndefined(probe.capture.maxFieldCount, maxFieldCount)
32
34
  maxLength = highestOrUndefined(probe.capture.maxLength, maxLength)
33
35
  }
34
36
  return probe
@@ -38,7 +40,10 @@ session.on('Debugger.paused', async ({ params }) => {
38
40
  if (captureSnapshotForProbe !== null) {
39
41
  try {
40
42
  // TODO: Create unique states for each affected probe based on that probes unique `capture` settings (DEBUG-2863)
41
- processLocalState = await getLocalStateForCallFrame(params.callFrames[0], { maxReferenceDepth, maxLength })
43
+ processLocalState = await getLocalStateForCallFrame(
44
+ params.callFrames[0],
45
+ { maxReferenceDepth, maxCollectionSize, maxFieldCount, maxLength }
46
+ )
42
47
  } catch (err) {
43
48
  // TODO: This error is not tied to a specific probe, but to all probes with `captureSnapshot: true`.
44
49
  // However, in 99,99% of cases, there will be just a single probe, so I guess this simplification is ok?
@@ -61,16 +66,7 @@ session.on('Debugger.paused', async ({ params }) => {
61
66
  thread_name: threadName
62
67
  }
63
68
 
64
- const stack = params.callFrames.map((frame) => {
65
- let fileName = getScriptUrlFromId(frame.location.scriptId)
66
- if (fileName.startsWith('file://')) fileName = fileName.substr(7) // TODO: This might not be required
67
- return {
68
- fileName,
69
- function: frame.functionName,
70
- lineNumber: frame.location.lineNumber + 1, // Beware! lineNumber is zero-indexed
71
- columnNumber: frame.location.columnNumber + 1 // Beware! columnNumber is zero-indexed
72
- }
73
- })
69
+ const stack = getStackFromCallFrames(params.callFrames)
74
70
 
75
71
  // TODO: Send multiple probes in one HTTP request as an array (DEBUG-2848)
76
72
  for (const probe of probes) {
@@ -9,6 +9,8 @@ const { GIT_COMMIT_SHA, GIT_REPOSITORY_URL } = require('../../plugins/util/tags'
9
9
 
10
10
  module.exports = send
11
11
 
12
+ const MAX_PAYLOAD_SIZE = 1024 * 1024 // 1MB
13
+
12
14
  const ddsource = 'dd_debugger'
13
15
  const hostname = getHostname()
14
16
  const service = config.service
@@ -37,5 +39,17 @@ function send (message, logger, snapshot, cb) {
37
39
  'debugger.snapshot': snapshot
38
40
  }
39
41
 
40
- request(JSON.stringify(payload), opts, cb)
42
+ let json = JSON.stringify(payload)
43
+
44
+ if (Buffer.byteLength(json) > MAX_PAYLOAD_SIZE) {
45
+ // TODO: This is a very crude way to handle large payloads. Proper pruning will be implemented later (DEBUG-2624)
46
+ const line = Object.values(payload['debugger.snapshot'].captures.lines)[0]
47
+ line.locals = {
48
+ notCapturedReason: 'Snapshot was too large',
49
+ size: Object.keys(line.locals).length
50
+ }
51
+ json = JSON.stringify(payload)
52
+ }
53
+
54
+ request(json, opts, cb)
41
55
  }