dd-trace 4.47.1 → 4.49.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 (156) hide show
  1. package/LICENSE-3rdparty.csv +1 -1
  2. package/ext/types.d.ts +1 -0
  3. package/ext/types.js +1 -0
  4. package/index.d.ts +361 -0
  5. package/package.json +18 -13
  6. package/packages/datadog-code-origin/index.js +38 -0
  7. package/packages/datadog-core/index.js +2 -2
  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/avsc.js +37 -0
  12. package/packages/datadog-instrumentations/src/azure-functions.js +48 -0
  13. package/packages/datadog-instrumentations/src/child_process.js +144 -27
  14. package/packages/datadog-instrumentations/src/express.js +37 -4
  15. package/packages/datadog-instrumentations/src/fastify.js +12 -1
  16. package/packages/datadog-instrumentations/src/fs.js +27 -7
  17. package/packages/datadog-instrumentations/src/helpers/hooks.js +6 -0
  18. package/packages/datadog-instrumentations/src/helpers/register.js +9 -0
  19. package/packages/datadog-instrumentations/src/jest.js +2 -1
  20. package/packages/datadog-instrumentations/src/kafkajs.js +123 -63
  21. package/packages/datadog-instrumentations/src/mocha/common.js +1 -1
  22. package/packages/datadog-instrumentations/src/mocha/utils.js +2 -2
  23. package/packages/datadog-instrumentations/src/multer.js +37 -0
  24. package/packages/datadog-instrumentations/src/mysql2.js +220 -1
  25. package/packages/datadog-instrumentations/src/openai.js +2 -2
  26. package/packages/datadog-instrumentations/src/protobufjs.js +127 -0
  27. package/packages/datadog-instrumentations/src/url.js +84 -0
  28. package/packages/datadog-instrumentations/src/utils/src/extract-package-and-module-path.js +7 -4
  29. package/packages/datadog-instrumentations/src/winston.js +22 -0
  30. package/packages/datadog-plugin-amqplib/src/consumer.js +4 -4
  31. package/packages/datadog-plugin-avsc/src/index.js +9 -0
  32. package/packages/datadog-plugin-avsc/src/schema_iterator.js +169 -0
  33. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -0
  34. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
  35. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -0
  36. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
  37. package/packages/datadog-plugin-azure-functions/src/index.js +77 -0
  38. package/packages/datadog-plugin-fastify/src/code_origin.js +31 -0
  39. package/packages/datadog-plugin-fastify/src/index.js +10 -12
  40. package/packages/datadog-plugin-fastify/src/tracing.js +19 -0
  41. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +8 -1
  42. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +8 -0
  43. package/packages/datadog-plugin-grpc/src/client.js +3 -0
  44. package/packages/datadog-plugin-grpc/src/server.js +3 -0
  45. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +6 -3
  46. package/packages/datadog-plugin-kafkajs/src/consumer.js +8 -4
  47. package/packages/datadog-plugin-kafkajs/src/producer.js +10 -4
  48. package/packages/datadog-plugin-mocha/src/index.js +4 -1
  49. package/packages/datadog-plugin-openai/src/index.js +9 -1015
  50. package/packages/datadog-plugin-openai/src/tracing.js +1023 -0
  51. package/packages/datadog-plugin-protobufjs/src/index.js +14 -0
  52. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +180 -0
  53. package/packages/dd-trace/src/appsec/addresses.js +8 -1
  54. package/packages/dd-trace/src/appsec/channels.js +7 -1
  55. package/packages/dd-trace/src/appsec/iast/analyzers/cookie-analyzer.js +13 -1
  56. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +8 -1
  57. package/packages/dd-trace/src/appsec/iast/iast-plugin.js +1 -1
  58. package/packages/dd-trace/src/appsec/iast/index.js +3 -0
  59. package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +1 -0
  60. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +55 -7
  61. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +15 -0
  62. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +4 -2
  63. package/packages/dd-trace/src/appsec/index.js +61 -43
  64. package/packages/dd-trace/src/appsec/rasp/command_injection.js +49 -0
  65. package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +99 -0
  66. package/packages/dd-trace/src/appsec/rasp/index.js +27 -10
  67. package/packages/dd-trace/src/appsec/rasp/lfi.js +112 -0
  68. package/packages/dd-trace/src/appsec/rasp/sql_injection.js +24 -4
  69. package/packages/dd-trace/src/appsec/rasp/ssrf.js +4 -3
  70. package/packages/dd-trace/src/appsec/rasp/utils.js +4 -2
  71. package/packages/dd-trace/src/appsec/recommended.json +3 -7
  72. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +6 -1
  73. package/packages/dd-trace/src/appsec/remote_config/index.js +10 -0
  74. package/packages/dd-trace/src/appsec/reporter.js +17 -9
  75. package/packages/dd-trace/src/appsec/sdk/track_event.js +10 -3
  76. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +1 -1
  77. package/packages/dd-trace/src/appsec/waf/waf_manager.js +4 -0
  78. package/packages/dd-trace/src/azure_metadata.js +120 -0
  79. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +97 -0
  80. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +90 -0
  81. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -14
  82. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +19 -1
  83. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +53 -0
  84. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +8 -1
  85. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +43 -0
  86. package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +53 -0
  87. package/packages/dd-trace/src/config.js +86 -6
  88. package/packages/dd-trace/src/constants.js +3 -1
  89. package/packages/dd-trace/src/datastreams/pathway.js +1 -0
  90. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +25 -17
  91. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
  92. package/packages/dd-trace/src/debugger/devtools_client/index.js +52 -5
  93. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +4 -4
  94. package/packages/dd-trace/src/debugger/devtools_client/send.js +29 -2
  95. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +187 -0
  96. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +40 -0
  97. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +252 -0
  98. package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +6 -0
  99. package/packages/dd-trace/src/debugger/devtools_client/state.js +19 -4
  100. package/packages/dd-trace/src/debugger/index.js +10 -3
  101. package/packages/dd-trace/src/exporters/common/request.js +8 -34
  102. package/packages/dd-trace/src/exporters/common/url-to-http-options-polyfill.js +31 -0
  103. package/packages/dd-trace/src/llmobs/constants/tags.js +34 -0
  104. package/packages/dd-trace/src/llmobs/constants/text.js +6 -0
  105. package/packages/dd-trace/src/llmobs/constants/writers.js +13 -0
  106. package/packages/dd-trace/src/llmobs/index.js +103 -0
  107. package/packages/dd-trace/src/llmobs/noop.js +82 -0
  108. package/packages/dd-trace/src/llmobs/plugins/base.js +65 -0
  109. package/packages/dd-trace/src/llmobs/plugins/openai.js +205 -0
  110. package/packages/dd-trace/src/llmobs/sdk.js +377 -0
  111. package/packages/dd-trace/src/llmobs/span_processor.js +195 -0
  112. package/packages/dd-trace/src/llmobs/storage.js +7 -0
  113. package/packages/dd-trace/src/llmobs/tagger.js +322 -0
  114. package/packages/dd-trace/src/llmobs/util.js +176 -0
  115. package/packages/dd-trace/src/llmobs/writers/base.js +111 -0
  116. package/packages/dd-trace/src/llmobs/writers/evaluations.js +29 -0
  117. package/packages/dd-trace/src/llmobs/writers/spans/agentProxy.js +23 -0
  118. package/packages/dd-trace/src/llmobs/writers/spans/agentless.js +17 -0
  119. package/packages/dd-trace/src/llmobs/writers/spans/base.js +49 -0
  120. package/packages/dd-trace/src/noop/proxy.js +3 -0
  121. package/packages/dd-trace/src/noop/span.js +3 -0
  122. package/packages/dd-trace/src/opentelemetry/span.js +1 -1
  123. package/packages/dd-trace/src/opentelemetry/tracer.js +1 -0
  124. package/packages/dd-trace/src/opentracing/propagation/text_map.js +73 -12
  125. package/packages/dd-trace/src/opentracing/span.js +12 -0
  126. package/packages/dd-trace/src/opentracing/tracer.js +8 -1
  127. package/packages/dd-trace/src/payload-tagging/config/aws.json +71 -3
  128. package/packages/dd-trace/src/payload-tagging/index.js +1 -1
  129. package/packages/dd-trace/src/payload-tagging/jsonpath-plus.js +2094 -0
  130. package/packages/dd-trace/src/plugin_manager.js +4 -2
  131. package/packages/dd-trace/src/plugins/ci_plugin.js +2 -0
  132. package/packages/dd-trace/src/plugins/index.js +3 -0
  133. package/packages/dd-trace/src/plugins/log_plugin.js +1 -1
  134. package/packages/dd-trace/src/plugins/outbound.js +9 -0
  135. package/packages/dd-trace/src/plugins/schema.js +35 -0
  136. package/packages/dd-trace/src/plugins/util/ci.js +23 -1
  137. package/packages/dd-trace/src/plugins/util/serverless.js +7 -0
  138. package/packages/dd-trace/src/plugins/util/stacktrace.js +94 -0
  139. package/packages/dd-trace/src/plugins/util/tags.js +7 -0
  140. package/packages/dd-trace/src/plugins/util/test.js +20 -22
  141. package/packages/dd-trace/src/plugins/util/web.js +6 -4
  142. package/packages/dd-trace/src/priority_sampler.js +16 -0
  143. package/packages/dd-trace/src/profiling/config.js +3 -1
  144. package/packages/dd-trace/src/profiling/exporters/agent.js +7 -5
  145. package/packages/dd-trace/src/profiling/profiler.js +24 -14
  146. package/packages/dd-trace/src/profiling/profilers/events.js +3 -3
  147. package/packages/dd-trace/src/profiling/profilers/wall.js +95 -66
  148. package/packages/dd-trace/src/proxy.js +20 -1
  149. package/packages/dd-trace/src/service-naming/schemas/v0/index.js +2 -1
  150. package/packages/dd-trace/src/service-naming/schemas/v0/serverless.js +12 -0
  151. package/packages/dd-trace/src/service-naming/schemas/v1/index.js +2 -1
  152. package/packages/dd-trace/src/service-naming/schemas/v1/serverless.js +12 -0
  153. package/packages/dd-trace/src/span_processor.js +5 -0
  154. package/packages/dd-trace/src/telemetry/index.js +11 -1
  155. package/packages/datadog-core/src/storage/async_resource.js +0 -108
  156. package/packages/datadog-core/src/storage/index.js +0 -5
@@ -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')
@@ -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, 'codeOriginForSpans.enabled', false)
467
471
  this._setValue(defaults, 'dbmPropagationMode', 'disabled')
468
472
  this._setValue(defaults, 'dogstatsd.hostname', '127.0.0.1')
469
473
  this._setValue(defaults, 'dogstatsd.port', '8125')
@@ -476,8 +480,11 @@ class Config {
476
480
  this._setValue(defaults, 'flushInterval', 2000)
477
481
  this._setValue(defaults, 'flushMinSpans', 1000)
478
482
  this._setValue(defaults, 'gitMetadataEnabled', true)
483
+ this._setValue(defaults, 'grpc.client.error.statuses', GRPC_CLIENT_ERROR_STATUSES)
484
+ this._setValue(defaults, 'grpc.server.error.statuses', GRPC_SERVER_ERROR_STATUSES)
479
485
  this._setValue(defaults, 'headerTags', [])
480
486
  this._setValue(defaults, 'hostname', '127.0.0.1')
487
+ this._setValue(defaults, 'iast.cookieFilterPattern', '.{32,}')
481
488
  this._setValue(defaults, 'iast.deduplicationEnabled', true)
482
489
  this._setValue(defaults, 'iast.enabled', false)
483
490
  this._setValue(defaults, 'iast.maxConcurrentRequests', 2)
@@ -497,7 +504,13 @@ class Config {
497
504
  this._setValue(defaults, 'isGitUploadEnabled', false)
498
505
  this._setValue(defaults, 'isIntelligentTestRunnerEnabled', false)
499
506
  this._setValue(defaults, 'isManualApiEnabled', false)
507
+ this._setValue(defaults, 'llmobs.agentlessEnabled', false)
508
+ this._setValue(defaults, 'llmobs.enabled', false)
509
+ this._setValue(defaults, 'llmobs.mlApp', undefined)
500
510
  this._setValue(defaults, 'ciVisibilityTestSessionName', '')
511
+ this._setValue(defaults, 'ciVisAgentlessLogSubmissionEnabled', false)
512
+ this._setValue(defaults, 'legacyBaggageEnabled', true)
513
+ this._setValue(defaults, 'isTestDynamicInstrumentationEnabled', false)
501
514
  this._setValue(defaults, 'logInjection', false)
502
515
  this._setValue(defaults, 'lookup', undefined)
503
516
  this._setValue(defaults, 'memcachedCommandEnabled', false)
@@ -517,7 +530,7 @@ class Config {
517
530
  this._setValue(defaults, 'reportHostname', false)
518
531
  this._setValue(defaults, 'runtimeMetrics', false)
519
532
  this._setValue(defaults, 'sampleRate', undefined)
520
- this._setValue(defaults, 'sampler.rateLimit', undefined)
533
+ this._setValue(defaults, 'sampler.rateLimit', 100)
521
534
  this._setValue(defaults, 'sampler.rules', [])
522
535
  this._setValue(defaults, 'sampler.spanSamplingRules', [])
523
536
  this._setValue(defaults, 'scope', undefined)
@@ -538,11 +551,12 @@ class Config {
538
551
  this._setValue(defaults, 'telemetry.heartbeatInterval', 60000)
539
552
  this._setValue(defaults, 'telemetry.logCollection', false)
540
553
  this._setValue(defaults, 'telemetry.metrics', true)
554
+ this._setValue(defaults, 'traceEnabled', true)
541
555
  this._setValue(defaults, 'traceId128BitGenerationEnabled', true)
542
556
  this._setValue(defaults, 'traceId128BitLoggingEnabled', false)
543
557
  this._setValue(defaults, 'tracePropagationExtractFirst', false)
544
- this._setValue(defaults, 'tracePropagationStyle.inject', ['datadog', 'tracecontext'])
545
- this._setValue(defaults, 'tracePropagationStyle.extract', ['datadog', 'tracecontext'])
558
+ this._setValue(defaults, 'tracePropagationStyle.inject', ['datadog', 'tracecontext', 'baggage'])
559
+ this._setValue(defaults, 'tracePropagationStyle.extract', ['datadog', 'tracecontext', 'baggage'])
546
560
  this._setValue(defaults, 'tracePropagationStyle.otelPropagators', false)
547
561
  this._setValue(defaults, 'tracing', true)
548
562
  this._setValue(defaults, 'url', undefined)
@@ -571,6 +585,7 @@ class Config {
571
585
  DD_APPSEC_RASP_ENABLED,
572
586
  DD_APPSEC_TRACE_RATE_LIMIT,
573
587
  DD_APPSEC_WAF_TIMEOUT,
588
+ DD_CODE_ORIGIN_FOR_SPANS_ENABLED,
574
589
  DD_DATA_STREAMS_ENABLED,
575
590
  DD_DBM_PROPAGATION_MODE,
576
591
  DD_DOGSTATSD_HOSTNAME,
@@ -580,7 +595,10 @@ class Config {
580
595
  DD_EXPERIMENTAL_API_SECURITY_ENABLED,
581
596
  DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED,
582
597
  DD_EXPERIMENTAL_PROFILING_ENABLED,
598
+ DD_GRPC_CLIENT_ERROR_STATUSES,
599
+ DD_GRPC_SERVER_ERROR_STATUSES,
583
600
  JEST_WORKER_ID,
601
+ DD_IAST_COOKIE_FILTER_PATTERN,
584
602
  DD_IAST_DEDUPLICATION_ENABLED,
585
603
  DD_IAST_ENABLED,
586
604
  DD_IAST_MAX_CONCURRENT_REQUESTS,
@@ -594,6 +612,9 @@ class Config {
594
612
  DD_INSTRUMENTATION_TELEMETRY_ENABLED,
595
613
  DD_INSTRUMENTATION_CONFIG_ID,
596
614
  DD_LOGS_INJECTION,
615
+ DD_LLMOBS_AGENTLESS_ENABLED,
616
+ DD_LLMOBS_ENABLED,
617
+ DD_LLMOBS_ML_APP,
597
618
  DD_OPENAI_LOGS_ENABLED,
598
619
  DD_OPENAI_SPAN_CHAR_LIMIT,
599
620
  DD_PROFILING_ENABLED,
@@ -620,14 +641,18 @@ class Config {
620
641
  DD_TRACE_AGENT_HOSTNAME,
621
642
  DD_TRACE_AGENT_PORT,
622
643
  DD_TRACE_AGENT_PROTOCOL_VERSION,
644
+ DD_TRACE_BAGGAGE_MAX_BYTES,
645
+ DD_TRACE_BAGGAGE_MAX_ITEMS,
623
646
  DD_TRACE_CLIENT_IP_ENABLED,
624
647
  DD_TRACE_CLIENT_IP_HEADER,
648
+ DD_TRACE_ENABLED,
625
649
  DD_TRACE_EXPERIMENTAL_EXPORTER,
626
650
  DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
627
651
  DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED,
628
652
  DD_TRACE_GIT_METADATA_ENABLED,
629
653
  DD_TRACE_GLOBAL_TAGS,
630
654
  DD_TRACE_HEADER_TAGS,
655
+ DD_TRACE_LEGACY_BAGGAGE_ENABLED,
631
656
  DD_TRACE_MEMCACHED_COMMAND_ENABLED,
632
657
  DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP,
633
658
  DD_TRACE_PARTIAL_FLUSH_MIN_SPANS,
@@ -699,14 +724,18 @@ class Config {
699
724
  this._envUnprocessed['appsec.stackTrace.maxStackTraces'] = DD_APPSEC_MAX_STACK_TRACES
700
725
  this._setValue(env, 'appsec.wafTimeout', maybeInt(DD_APPSEC_WAF_TIMEOUT))
701
726
  this._envUnprocessed['appsec.wafTimeout'] = DD_APPSEC_WAF_TIMEOUT
727
+ this._setValue(env, 'baggageMaxBytes', DD_TRACE_BAGGAGE_MAX_BYTES)
728
+ this._setValue(env, 'baggageMaxItems', DD_TRACE_BAGGAGE_MAX_ITEMS)
702
729
  this._setBoolean(env, 'clientIpEnabled', DD_TRACE_CLIENT_IP_ENABLED)
703
730
  this._setString(env, 'clientIpHeader', DD_TRACE_CLIENT_IP_HEADER)
731
+ this._setBoolean(env, 'codeOriginForSpans.enabled', DD_CODE_ORIGIN_FOR_SPANS_ENABLED)
704
732
  this._setString(env, 'dbmPropagationMode', DD_DBM_PROPAGATION_MODE)
705
733
  this._setString(env, 'dogstatsd.hostname', DD_DOGSTATSD_HOSTNAME)
706
734
  this._setString(env, 'dogstatsd.port', DD_DOGSTATSD_PORT)
707
735
  this._setBoolean(env, 'dsmEnabled', DD_DATA_STREAMS_ENABLED)
708
736
  this._setBoolean(env, 'dynamicInstrumentationEnabled', DD_DYNAMIC_INSTRUMENTATION_ENABLED)
709
737
  this._setString(env, 'env', DD_ENV || tags.env)
738
+ this._setBoolean(env, 'traceEnabled', DD_TRACE_ENABLED)
710
739
  this._setBoolean(env, 'experimental.enableGetRumData', DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED)
711
740
  this._setString(env, 'experimental.exporter', DD_TRACE_EXPERIMENTAL_EXPORTER)
712
741
  this._setBoolean(env, 'experimental.runtimeId', DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED)
@@ -714,8 +743,11 @@ class Config {
714
743
  this._setValue(env, 'flushMinSpans', maybeInt(DD_TRACE_PARTIAL_FLUSH_MIN_SPANS))
715
744
  this._envUnprocessed.flushMinSpans = DD_TRACE_PARTIAL_FLUSH_MIN_SPANS
716
745
  this._setBoolean(env, 'gitMetadataEnabled', DD_TRACE_GIT_METADATA_ENABLED)
746
+ this._setIntegerRangeSet(env, 'grpc.client.error.statuses', DD_GRPC_CLIENT_ERROR_STATUSES)
747
+ this._setIntegerRangeSet(env, 'grpc.server.error.statuses', DD_GRPC_SERVER_ERROR_STATUSES)
717
748
  this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
718
749
  this._setString(env, 'hostname', coalesce(DD_AGENT_HOST, DD_TRACE_AGENT_HOSTNAME))
750
+ this._setString(env, 'iast.cookieFilterPattern', DD_IAST_COOKIE_FILTER_PATTERN)
719
751
  this._setBoolean(env, 'iast.deduplicationEnabled', DD_IAST_DEDUPLICATION_ENABLED)
720
752
  this._setBoolean(env, 'iast.enabled', DD_IAST_ENABLED)
721
753
  this._setValue(env, 'iast.maxConcurrentRequests', maybeInt(DD_IAST_MAX_CONCURRENT_REQUESTS))
@@ -734,6 +766,10 @@ class Config {
734
766
  this._setArray(env, 'injectionEnabled', DD_INJECTION_ENABLED)
735
767
  this._setBoolean(env, 'isAzureFunction', getIsAzureFunction())
736
768
  this._setBoolean(env, 'isGCPFunction', getIsGCPFunction())
769
+ this._setBoolean(env, 'legacyBaggageEnabled', DD_TRACE_LEGACY_BAGGAGE_ENABLED)
770
+ this._setBoolean(env, 'llmobs.agentlessEnabled', DD_LLMOBS_AGENTLESS_ENABLED)
771
+ this._setBoolean(env, 'llmobs.enabled', DD_LLMOBS_ENABLED)
772
+ this._setString(env, 'llmobs.mlApp', DD_LLMOBS_ML_APP)
737
773
  this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
738
774
  // Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
739
775
  this._setBoolean(env, 'memcachedCommandEnabled', DD_TRACE_MEMCACHED_COMMAND_ENABLED)
@@ -867,6 +903,9 @@ class Config {
867
903
  this._optsUnprocessed['appsec.wafTimeout'] = options.appsec.wafTimeout
868
904
  this._setBoolean(opts, 'clientIpEnabled', options.clientIpEnabled)
869
905
  this._setString(opts, 'clientIpHeader', options.clientIpHeader)
906
+ this._setValue(opts, 'baggageMaxBytes', options.baggageMaxBytes)
907
+ this._setValue(opts, 'baggageMaxItems', options.baggageMaxItems)
908
+ this._setBoolean(opts, 'codeOriginForSpans.enabled', options.codeOriginForSpans?.enabled)
870
909
  this._setString(opts, 'dbmPropagationMode', options.dbmPropagationMode)
871
910
  if (options.dogstatsd) {
872
911
  this._setString(opts, 'dogstatsd.hostname', options.dogstatsd.hostname)
@@ -884,6 +923,7 @@ class Config {
884
923
  this._optsUnprocessed.flushMinSpans = options.flushMinSpans
885
924
  this._setArray(opts, 'headerTags', options.headerTags)
886
925
  this._setString(opts, 'hostname', options.hostname)
926
+ this._setString(opts, 'iast.cookieFilterPattern', options.iast?.cookieFilterPattern)
887
927
  this._setBoolean(opts, 'iast.deduplicationEnabled', options.iast && options.iast.deduplicationEnabled)
888
928
  this._setBoolean(opts, 'iast.enabled',
889
929
  options.iast && (options.iast === true || options.iast.enabled === true))
@@ -902,6 +942,9 @@ class Config {
902
942
  }
903
943
  this._setString(opts, 'iast.telemetryVerbosity', options.iast && options.iast.telemetryVerbosity)
904
944
  this._setBoolean(opts, 'isCiVisibility', options.isCiVisibility)
945
+ this._setBoolean(opts, 'legacyBaggageEnabled', options.legacyBaggageEnabled)
946
+ this._setBoolean(opts, 'llmobs.agentlessEnabled', options.llmobs?.agentlessEnabled)
947
+ this._setString(opts, 'llmobs.mlApp', options.llmobs?.mlApp)
905
948
  this._setBoolean(opts, 'logInjection', options.logInjection)
906
949
  this._setString(opts, 'lookup', options.lookup)
907
950
  this._setBoolean(opts, 'openAiLogsEnabled', options.openAiLogsEnabled)
@@ -937,6 +980,15 @@ class Config {
937
980
  this._setBoolean(opts, 'traceId128BitGenerationEnabled', options.traceId128BitGenerationEnabled)
938
981
  this._setBoolean(opts, 'traceId128BitLoggingEnabled', options.traceId128BitLoggingEnabled)
939
982
  this._setString(opts, 'version', options.version || tags.version)
983
+
984
+ // For LLMObs, we want the environment variable to take precedence over the options.
985
+ // This is reliant on environment config being set before options.
986
+ // This is to make sure the origins of each value are tracked appropriately for telemetry.
987
+ // We'll only set `llmobs.enabled` on the opts when it's not set on the environment, and options.llmobs is provided.
988
+ const llmobsEnabledEnv = this._env['llmobs.enabled']
989
+ if (llmobsEnabledEnv == null && options.llmobs) {
990
+ this._setBoolean(opts, 'llmobs.enabled', !!options.llmobs)
991
+ }
940
992
  }
941
993
 
942
994
  _isCiVisibility () {
@@ -1035,7 +1087,9 @@ class Config {
1035
1087
  DD_CIVISIBILITY_EARLY_FLAKE_DETECTION_ENABLED,
1036
1088
  DD_CIVISIBILITY_FLAKY_RETRY_ENABLED,
1037
1089
  DD_CIVISIBILITY_FLAKY_RETRY_COUNT,
1038
- DD_TEST_SESSION_NAME
1090
+ DD_TEST_SESSION_NAME,
1091
+ DD_AGENTLESS_LOG_SUBMISSION_ENABLED,
1092
+ DD_TEST_DYNAMIC_INSTRUMENTATION_ENABLED
1039
1093
  } = process.env
1040
1094
 
1041
1095
  if (DD_CIVISIBILITY_AGENTLESS_URL) {
@@ -1052,6 +1106,8 @@ class Config {
1052
1106
  this._setBoolean(calc, 'isIntelligentTestRunnerEnabled', isTrue(this._isCiVisibilityItrEnabled()))
1053
1107
  this._setBoolean(calc, 'isManualApiEnabled', !isFalse(this._isCiVisibilityManualApiEnabled()))
1054
1108
  this._setString(calc, 'ciVisibilityTestSessionName', DD_TEST_SESSION_NAME)
1109
+ this._setBoolean(calc, 'ciVisAgentlessLogSubmissionEnabled', isTrue(DD_AGENTLESS_LOG_SUBMISSION_ENABLED))
1110
+ this._setBoolean(calc, 'isTestDynamicInstrumentationEnabled', isTrue(DD_TEST_DYNAMIC_INSTRUMENTATION_ENABLED))
1055
1111
  }
1056
1112
  this._setString(calc, 'dogstatsd.hostname', this._getHostname())
1057
1113
  this._setBoolean(calc, 'isGitUploadEnabled',
@@ -1144,7 +1200,11 @@ class Config {
1144
1200
  }
1145
1201
 
1146
1202
  if (typeof value === 'string') {
1147
- value = value.split(',')
1203
+ value = value.split(',').map(item => {
1204
+ // Trim each item and remove whitespace around the colon
1205
+ const [key, val] = item.split(':').map(part => part.trim())
1206
+ return val !== undefined ? `${key}:${val}` : key
1207
+ })
1148
1208
  }
1149
1209
 
1150
1210
  if (Array.isArray(value)) {
@@ -1152,6 +1212,26 @@ class Config {
1152
1212
  }
1153
1213
  }
1154
1214
 
1215
+ _setIntegerRangeSet (obj, name, value) {
1216
+ if (value == null) {
1217
+ return this._setValue(obj, name, null)
1218
+ }
1219
+ value = value.split(',')
1220
+ const result = []
1221
+
1222
+ value.forEach(val => {
1223
+ if (val.includes('-')) {
1224
+ const [start, end] = val.split('-').map(Number)
1225
+ for (let i = start; i <= end; i++) {
1226
+ result.push(i)
1227
+ }
1228
+ } else {
1229
+ result.push(Number(val))
1230
+ }
1231
+ })
1232
+ this._setValue(obj, name, result)
1233
+ }
1234
+
1155
1235
  _setSamplingRule (obj, name, value) {
1156
1236
  if (value == null) {
1157
1237
  return this._setValue(obj, name, null)
@@ -44,5 +44,7 @@ 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]
48
50
  }
@@ -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()
@@ -4,13 +4,36 @@ const { Schema } = require('./schema')
4
4
 
5
5
  const maxDepth = 10
6
6
  const maxProperties = 1000
7
- const CACHE = new LRUCache({ max: 32 })
7
+ const CACHE = new LRUCache({ max: 256 })
8
8
 
9
9
  class SchemaBuilder {
10
10
  constructor (iterator) {
11
11
  this.schema = new OpenApiSchema()
12
12
  this.iterator = iterator
13
- this.proerties = 0
13
+ this.properties = 0
14
+ }
15
+
16
+ static getCache () {
17
+ return CACHE
18
+ }
19
+
20
+ static getSchemaDefinition (schema) {
21
+ const noNones = convertToJsonCompatible(schema)
22
+ const definition = jsonStringify(noNones)
23
+ const id = fnv64(Buffer.from(definition, 'utf-8')).toString()
24
+ return new Schema(definition, id)
25
+ }
26
+
27
+ static getSchema (schemaName, iterator, builder) {
28
+ if (!CACHE.has(schemaName)) {
29
+ CACHE.set(schemaName, (builder ?? new SchemaBuilder(iterator)).build())
30
+ }
31
+ return CACHE.get(schemaName)
32
+ }
33
+
34
+ build () {
35
+ this.iterator.iterateOverSchema(this)
36
+ return this.schema
14
37
  }
15
38
 
16
39
  addProperty (schemaName, fieldName, isArray, type, description, ref, format, enumValues) {
@@ -26,14 +49,6 @@ class SchemaBuilder {
26
49
  return true
27
50
  }
28
51
 
29
- build () {
30
- this.iterator.iterateOverSchema(this)
31
- const noNones = convertToJsonCompatible(this.schema)
32
- const definition = jsonStringify(noNones)
33
- const id = fnv64(Buffer.from(definition, 'utf-8')).toString()
34
- return new Schema(definition, id)
35
- }
36
-
37
52
  shouldExtractSchema (schemaName, depth) {
38
53
  if (depth > maxDepth) {
39
54
  return false
@@ -44,13 +59,6 @@ class SchemaBuilder {
44
59
  this.schema.components.schemas[schemaName] = new OpenApiSchema.SCHEMA()
45
60
  return true
46
61
  }
47
-
48
- static getSchema (schemaName, iterator) {
49
- if (!CACHE.has(schemaName)) {
50
- CACHE.set(schemaName, new SchemaBuilder(iterator).build())
51
- }
52
- return CACHE.get(schemaName)
53
- }
54
62
  }
55
63
 
56
64
  class OpenApiSchema {
@@ -7,6 +7,8 @@ const log = require('../../log')
7
7
  const config = module.exports = {
8
8
  runtimeId: parentConfig.tags['runtime-id'],
9
9
  service: parentConfig.service,
10
+ commitSHA: parentConfig.commitSHA,
11
+ repositoryUrl: parentConfig.repositoryUrl,
10
12
  parentThreadId
11
13
  }
12
14
 
@@ -3,8 +3,10 @@
3
3
  const { randomUUID } = require('crypto')
4
4
  const { breakpoints } = require('./state')
5
5
  const session = require('./session')
6
+ const { getLocalStateForCallFrame } = require('./snapshot')
6
7
  const send = require('./send')
7
- const { ackEmitting } = require('./status')
8
+ const { getStackFromCallFrames } = require('./state')
9
+ const { ackEmitting, ackError } = require('./status')
8
10
  const { parentThreadId } = require('./config')
9
11
  const log = require('../../log')
10
12
  const { version } = require('../../../../../package.json')
@@ -19,9 +21,38 @@ const threadName = parentThreadId === 0 ? 'MainThread' : `WorkerThread:${parentT
19
21
  session.on('Debugger.paused', async ({ params }) => {
20
22
  const start = process.hrtime.bigint()
21
23
  const timestamp = Date.now()
22
- const probes = params.hitBreakpoints.map((id) => breakpoints.get(id))
24
+
25
+ let captureSnapshotForProbe = null
26
+ let maxReferenceDepth, maxCollectionSize, maxFieldCount, maxLength
27
+ const probes = params.hitBreakpoints.map((id) => {
28
+ const probe = breakpoints.get(id)
29
+ if (probe.captureSnapshot) {
30
+ captureSnapshotForProbe = probe
31
+ maxReferenceDepth = highestOrUndefined(probe.capture.maxReferenceDepth, maxReferenceDepth)
32
+ maxCollectionSize = highestOrUndefined(probe.capture.maxCollectionSize, maxCollectionSize)
33
+ maxFieldCount = highestOrUndefined(probe.capture.maxFieldCount, maxFieldCount)
34
+ maxLength = highestOrUndefined(probe.capture.maxLength, maxLength)
35
+ }
36
+ return probe
37
+ })
38
+
39
+ let processLocalState
40
+ if (captureSnapshotForProbe !== null) {
41
+ try {
42
+ // TODO: Create unique states for each affected probe based on that probes unique `capture` settings (DEBUG-2863)
43
+ processLocalState = await getLocalStateForCallFrame(
44
+ params.callFrames[0],
45
+ { maxReferenceDepth, maxCollectionSize, maxFieldCount, maxLength }
46
+ )
47
+ } catch (err) {
48
+ // TODO: This error is not tied to a specific probe, but to all probes with `captureSnapshot: true`.
49
+ // However, in 99,99% of cases, there will be just a single probe, so I guess this simplification is ok?
50
+ ackError(err, captureSnapshotForProbe) // TODO: Ok to continue after sending ackError?
51
+ }
52
+ }
53
+
23
54
  await session.post('Debugger.resume')
24
- const diff = process.hrtime.bigint() - start // TODO: Should this be recored as telemetry?
55
+ const diff = process.hrtime.bigint() - start // TODO: Recored as telemetry (DEBUG-2858)
25
56
 
26
57
  log.debug(`Finished processing breakpoints - main thread paused for: ${Number(diff) / 1000000} ms`)
27
58
 
@@ -35,7 +66,9 @@ session.on('Debugger.paused', async ({ params }) => {
35
66
  thread_name: threadName
36
67
  }
37
68
 
38
- // TODO: Send multiple probes in one HTTP request as an array
69
+ const stack = getStackFromCallFrames(params.callFrames)
70
+
71
+ // TODO: Send multiple probes in one HTTP request as an array (DEBUG-2848)
39
72
  for (const probe of probes) {
40
73
  const snapshot = {
41
74
  id: randomUUID(),
@@ -45,13 +78,27 @@ session.on('Debugger.paused', async ({ params }) => {
45
78
  version: probe.version,
46
79
  location: probe.location
47
80
  },
81
+ stack,
48
82
  language: 'javascript'
49
83
  }
50
84
 
51
- // TODO: Process template
85
+ if (probe.captureSnapshot) {
86
+ const state = processLocalState()
87
+ if (state) {
88
+ snapshot.captures = {
89
+ lines: { [probe.location.lines[0]]: { locals: state } }
90
+ }
91
+ }
92
+ }
93
+
94
+ // TODO: Process template (DEBUG-2628)
52
95
  send(probe.template, logger, snapshot, (err) => {
53
96
  if (err) log.error(err)
54
97
  else ackEmitting(probe)
55
98
  })
56
99
  }
57
100
  })
101
+
102
+ function highestOrUndefined (num, max) {
103
+ return num === undefined ? max : Math.max(num, max ?? 0)
104
+ }
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { workerData: { rcPort } } = require('node:worker_threads')
4
- const { getScript, probes, breakpoints } = require('./state')
4
+ const { findScriptFromPartialPath, probes, breakpoints } = require('./state')
5
5
  const session = require('./session')
6
6
  const { ackReceived, ackInstalled, ackError } = require('./status')
7
7
  const log = require('../../log')
@@ -92,7 +92,7 @@ async function processMsg (action, probe) {
92
92
  await addBreakpoint(probe)
93
93
  break
94
94
  case 'modify':
95
- // TODO: Can we modify in place?
95
+ // TODO: Modify existing probe instead of removing it (DEBUG-2817)
96
96
  await removeBreakpoint(probe)
97
97
  await addBreakpoint(probe)
98
98
  break
@@ -114,13 +114,13 @@ async function addBreakpoint (probe) {
114
114
  const line = Number(probe.where.lines[0]) // Tracer doesn't support multiple-line breakpoints
115
115
 
116
116
  // Optimize for sending data to /debugger/v1/input endpoint
117
- probe.location = { file, lines: [line] }
117
+ probe.location = { file, lines: [String(line)] }
118
118
  delete probe.where
119
119
 
120
120
  // TODO: Inbetween `await session.post('Debugger.enable')` and here, the scripts are parsed and cached.
121
121
  // Maybe there's a race condition here or maybe we're guraenteed that `await session.post('Debugger.enable')` will
122
122
  // not continue untill all scripts have been parsed?
123
- const script = getScript(file)
123
+ const script = findScriptFromPartialPath(file)
124
124
  if (!script) throw new Error(`No loaded script found for ${file} (probe: ${probe.id}, version: ${probe.version})`)
125
125
  const [path, scriptId] = script
126
126
 
@@ -1,28 +1,55 @@
1
1
  'use strict'
2
2
 
3
+ const { hostname: getHostname } = require('os')
4
+ const { stringify } = require('querystring')
5
+
3
6
  const config = require('./config')
4
7
  const request = require('../../exporters/common/request')
8
+ const { GIT_COMMIT_SHA, GIT_REPOSITORY_URL } = require('../../plugins/util/tags')
5
9
 
6
10
  module.exports = send
7
11
 
12
+ const MAX_PAYLOAD_SIZE = 1024 * 1024 // 1MB
13
+
8
14
  const ddsource = 'dd_debugger'
15
+ const hostname = getHostname()
9
16
  const service = config.service
10
17
 
18
+ const ddtags = [
19
+ [GIT_COMMIT_SHA, config.commitSHA],
20
+ [GIT_REPOSITORY_URL, config.repositoryUrl]
21
+ ].map((pair) => pair.join(':')).join(',')
22
+
23
+ const path = `/debugger/v1/input?${stringify({ ddtags })}`
24
+
11
25
  function send (message, logger, snapshot, cb) {
12
26
  const opts = {
13
27
  method: 'POST',
14
28
  url: config.url,
15
- path: '/debugger/v1/input',
29
+ path,
16
30
  headers: { 'Content-Type': 'application/json; charset=utf-8' }
17
31
  }
18
32
 
19
33
  const payload = {
20
34
  ddsource,
35
+ hostname,
21
36
  service,
22
37
  message,
23
38
  logger,
24
39
  'debugger.snapshot': snapshot
25
40
  }
26
41
 
27
- 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)
28
55
  }