datadog 2.8.0 → 2.9.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -1
- data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +64 -54
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
- data/ext/datadog_profiling_native_extension/collectors_stack.c +7 -7
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +219 -122
- data/ext/datadog_profiling_native_extension/heap_recorder.h +1 -1
- data/ext/datadog_profiling_native_extension/http_transport.c +4 -4
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +3 -0
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +3 -1
- data/ext/datadog_profiling_native_extension/profiling.c +10 -8
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +8 -8
- data/ext/datadog_profiling_native_extension/stack_recorder.c +54 -54
- data/ext/datadog_profiling_native_extension/stack_recorder.h +1 -1
- data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
- data/ext/libdatadog_api/crashtracker.c +3 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +355 -157
- data/lib/datadog/appsec/assets/waf_rules/strict.json +62 -32
- data/lib/datadog/appsec/context.rb +54 -0
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +7 -7
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +6 -6
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +4 -4
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +19 -28
- data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +5 -5
- data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +64 -96
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +10 -10
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +5 -5
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +6 -6
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +43 -49
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +21 -32
- data/lib/datadog/appsec/contrib/rails/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +6 -6
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +41 -63
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +2 -2
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +5 -5
- data/lib/datadog/appsec/event.rb +6 -6
- data/lib/datadog/appsec/ext.rb +3 -1
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +22 -32
- data/lib/datadog/appsec/monitor/reactive/set_user.rb +5 -5
- data/lib/datadog/appsec/processor/rule_loader.rb +0 -3
- data/lib/datadog/appsec.rb +3 -3
- data/lib/datadog/auto_instrument.rb +3 -0
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +39 -11
- data/lib/datadog/core/configuration/components.rb +4 -2
- data/lib/datadog/core/configuration.rb +1 -1
- data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
- data/lib/datadog/core/crashtracking/component.rb +1 -3
- data/lib/datadog/core/telemetry/event.rb +87 -3
- data/lib/datadog/core/telemetry/logging.rb +2 -2
- data/lib/datadog/core/telemetry/metric.rb +22 -0
- data/lib/datadog/core/telemetry/worker.rb +33 -0
- data/lib/datadog/di/base.rb +115 -0
- data/lib/datadog/di/code_tracker.rb +7 -4
- data/lib/datadog/di/component.rb +17 -11
- data/lib/datadog/di/configuration/settings.rb +11 -1
- data/lib/datadog/di/contrib/railtie.rb +15 -0
- data/lib/datadog/di/contrib.rb +26 -0
- data/lib/datadog/di/error.rb +5 -0
- data/lib/datadog/di/instrumenter.rb +39 -18
- data/lib/datadog/di/{init.rb → preload.rb} +2 -4
- data/lib/datadog/di/probe_manager.rb +4 -4
- data/lib/datadog/di/probe_notification_builder.rb +16 -2
- data/lib/datadog/di/probe_notifier_worker.rb +5 -6
- data/lib/datadog/di/remote.rb +4 -4
- data/lib/datadog/di/transport.rb +2 -4
- data/lib/datadog/di.rb +5 -108
- data/lib/datadog/kit/appsec/events.rb +3 -3
- data/lib/datadog/kit/identity.rb +4 -4
- data/lib/datadog/profiling/component.rb +55 -53
- data/lib/datadog/profiling/http_transport.rb +1 -26
- data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
- data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_record/integration.rb +6 -2
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +3 -1
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +3 -1
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
- data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
- data/lib/datadog/tracing/span.rb +12 -4
- data/lib/datadog/tracing/span_event.rb +123 -3
- data/lib/datadog/tracing/span_operation.rb +6 -0
- data/lib/datadog/tracing/transport/serializable_trace.rb +24 -6
- data/lib/datadog/version.rb +1 -1
- metadata +19 -10
- data/lib/datadog/appsec/reactive/operation.rb +0 -68
- data/lib/datadog/appsec/scope.rb +0 -58
- data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
    
        data/lib/datadog/di/remote.rb
    CHANGED
    
    | @@ -51,7 +51,7 @@ module Datadog | |
| 51 51 | 
             
                                probe = ProbeBuilder.build_from_remote_config(probe_spec)
         | 
| 52 52 | 
             
                                payload = component.probe_notification_builder.build_received(probe)
         | 
| 53 53 | 
             
                                component.probe_notifier_worker.add_status(payload)
         | 
| 54 | 
            -
                                component.logger. | 
| 54 | 
            +
                                component.logger.debug { "di: received probe from RC: #{probe.type} #{probe.location}" }
         | 
| 55 55 |  | 
| 56 56 | 
             
                                begin
         | 
| 57 57 | 
             
                                  # TODO test exception capture
         | 
| @@ -60,7 +60,7 @@ module Datadog | |
| 60 60 | 
             
                                rescue => exc
         | 
| 61 61 | 
             
                                  raise if component.settings.dynamic_instrumentation.internal.propagate_all_exceptions
         | 
| 62 62 |  | 
| 63 | 
            -
                                  component.logger. | 
| 63 | 
            +
                                  component.logger.debug { "di: unhandled exception adding probe in DI remote receiver: #{exc.class}: #{exc}" }
         | 
| 64 64 | 
             
                                  component.telemetry&.report(exc, description: "Unhandled exception adding probe in DI remote receiver")
         | 
| 65 65 |  | 
| 66 66 | 
             
                                  # If a probe fails to install, we will mark the content
         | 
| @@ -81,7 +81,7 @@ module Datadog | |
| 81 81 | 
             
                              rescue => exc
         | 
| 82 82 | 
             
                                raise if component.settings.dynamic_instrumentation.internal.propagate_all_exceptions
         | 
| 83 83 |  | 
| 84 | 
            -
                                component.logger. | 
| 84 | 
            +
                                component.logger.debug { "di: unhandled exception handling probe in DI remote receiver: #{exc.class}: #{exc}" }
         | 
| 85 85 | 
             
                                component.telemetry&.report(exc, description: "Unhandled exception handling probe in DI remote receiver")
         | 
| 86 86 |  | 
| 87 87 | 
             
                                content.errored("Error applying dynamic instrumentation configuration: #{exc.class.name} #{exc.message}: #{Array(exc.backtrace).join("\n")}")
         | 
| @@ -95,7 +95,7 @@ module Datadog | |
| 95 95 | 
             
                          rescue => exc
         | 
| 96 96 | 
             
                            raise if component.settings.dynamic_instrumentation.internal.propagate_all_exceptions
         | 
| 97 97 |  | 
| 98 | 
            -
                            component.logger. | 
| 98 | 
            +
                            component.logger.debug { "di: unhandled exception removing probes in DI remote receiver: #{exc.class}: #{exc}" }
         | 
| 99 99 | 
             
                            component.telemetry&.report(exc, description: "Unhandled exception removing probes in DI remote receiver")
         | 
| 100 100 | 
             
                          end
         | 
| 101 101 | 
             
                        end
         | 
    
        data/lib/datadog/di/transport.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require 'ostruct'
         | 
| 4 3 | 
             
            require_relative 'error'
         | 
| 4 | 
            +
            require_relative '../core/transport/http/adapters/net'
         | 
| 5 5 |  | 
| 6 6 | 
             
            module Datadog
         | 
| 7 7 | 
             
              module DI
         | 
| @@ -60,9 +60,7 @@ module Datadog | |
| 60 60 | 
             
                  attr_reader :client
         | 
| 61 61 |  | 
| 62 62 | 
             
                  def send_request(desc, **options)
         | 
| 63 | 
            -
                     | 
| 64 | 
            -
                    env = OpenStruct.new(**options)
         | 
| 65 | 
            -
                    # steep:ignore:end
         | 
| 63 | 
            +
                    env = Core::Transport::HTTP::Env.new(nil, options)
         | 
| 66 64 | 
             
                    response = client.post(env)
         | 
| 67 65 | 
             
                    unless response.ok?
         | 
| 68 66 | 
             
                      raise Error::AgentCommunicationError, "#{desc} failed: #{response.code}: #{response.payload}"
         | 
    
        data/lib/datadog/di.rb
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require_relative 'di/base'
         | 
| 3 4 | 
             
            require_relative 'di/error'
         | 
| 4 5 | 
             
            require_relative 'di/code_tracker'
         | 
| 5 6 | 
             
            require_relative 'di/component'
         | 
| @@ -17,21 +18,6 @@ require_relative 'di/serializer' | |
| 17 18 | 
             
            require_relative 'di/transport'
         | 
| 18 19 | 
             
            require_relative 'di/utils'
         | 
| 19 20 |  | 
| 20 | 
            -
            if defined?(ActiveRecord::Base)
         | 
| 21 | 
            -
              # The third-party library integrations need to be loaded after the
         | 
| 22 | 
            -
              # third-party libraries are loaded. Tracing and appsec use Railtie
         | 
| 23 | 
            -
              # to delay integrations until all of the application's dependencies
         | 
| 24 | 
            -
              # are loaded, when running under Rails. We should do the same here in
         | 
| 25 | 
            -
              # principle, however DI currently only has an ActiveRecord integration
         | 
| 26 | 
            -
              # and AR should be loaded before any application code is loaded, being
         | 
| 27 | 
            -
              # part of Rails, therefore for now we should be OK to just require the
         | 
| 28 | 
            -
              # AR integration from here.
         | 
| 29 | 
            -
              #
         | 
| 30 | 
            -
              # TODO this require might need to be delayed via Rails post-initialization
         | 
| 31 | 
            -
              # logic?
         | 
| 32 | 
            -
              require_relative 'di/contrib/active_record'
         | 
| 33 | 
            -
            end
         | 
| 34 | 
            -
             | 
| 35 21 | 
             
            module Datadog
         | 
| 36 22 | 
             
              # Namespace for Datadog dynamic instrumentation.
         | 
| 37 23 | 
             
              #
         | 
| @@ -46,67 +32,7 @@ module Datadog | |
| 46 32 | 
             
                # Expose DI to global shared objects
         | 
| 47 33 | 
             
                Extensions.activate!
         | 
| 48 34 |  | 
| 49 | 
            -
                LOCK = Mutex.new
         | 
| 50 | 
            -
             | 
| 51 35 | 
             
                class << self
         | 
| 52 | 
            -
                  attr_reader :code_tracker
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                  # Activates code tracking. Normally this method should be called
         | 
| 55 | 
            -
                  # when the application starts. If instrumenting third-party code,
         | 
| 56 | 
            -
                  # code tracking needs to be enabled before the third-party libraries
         | 
| 57 | 
            -
                  # are loaded. If you definitely will not be instrumenting
         | 
| 58 | 
            -
                  # third-party libraries, activating tracking after third-party libraries
         | 
| 59 | 
            -
                  # have been loaded may improve lookup performance.
         | 
| 60 | 
            -
                  #
         | 
| 61 | 
            -
                  # TODO test that activating tracker multiple times preserves
         | 
| 62 | 
            -
                  # existing mappings in the registry
         | 
| 63 | 
            -
                  def activate_tracking!
         | 
| 64 | 
            -
                    (@code_tracker ||= CodeTracker.new).start
         | 
| 65 | 
            -
                  end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
                  # Activates code tracking if possible.
         | 
| 68 | 
            -
                  #
         | 
| 69 | 
            -
                  # This method does nothing if invoked in an environment that does not
         | 
| 70 | 
            -
                  # implement required trace points for code tracking (MRI Ruby < 2.6,
         | 
| 71 | 
            -
                  # JRuby) and rescues any exceptions that may be raised by downstream
         | 
| 72 | 
            -
                  # DI code.
         | 
| 73 | 
            -
                  def activate_tracking
         | 
| 74 | 
            -
                    # :script_compiled trace point was added in Ruby 2.6.
         | 
| 75 | 
            -
                    return unless RUBY_VERSION >= '2.6'
         | 
| 76 | 
            -
             | 
| 77 | 
            -
                    begin
         | 
| 78 | 
            -
                      # Activate code tracking by default because line trace points will not work
         | 
| 79 | 
            -
                      # without it.
         | 
| 80 | 
            -
                      Datadog::DI.activate_tracking!
         | 
| 81 | 
            -
                    rescue => exc
         | 
| 82 | 
            -
                      if defined?(Datadog.logger)
         | 
| 83 | 
            -
                        Datadog.logger.warn("Failed to activate code tracking for DI: #{exc.class}: #{exc}")
         | 
| 84 | 
            -
                      else
         | 
| 85 | 
            -
                        # We do not have Datadog logger potentially because DI code tracker is
         | 
| 86 | 
            -
                        # being loaded early in application boot process and the rest of datadog
         | 
| 87 | 
            -
                        # wasn't loaded yet. Output to standard error.
         | 
| 88 | 
            -
                        warn("Failed to activate code tracking for DI: #{exc.class}: #{exc}")
         | 
| 89 | 
            -
                      end
         | 
| 90 | 
            -
                    end
         | 
| 91 | 
            -
                  end
         | 
| 92 | 
            -
             | 
| 93 | 
            -
                  # Deactivates code tracking. In normal usage of DI this method should
         | 
| 94 | 
            -
                  # never be called, however it is used by DI's test suite to reset
         | 
| 95 | 
            -
                  # state for individual tests.
         | 
| 96 | 
            -
                  #
         | 
| 97 | 
            -
                  # Note that deactivating tracking clears out the registry, losing
         | 
| 98 | 
            -
                  # the ability to look up files that have been loaded into the process
         | 
| 99 | 
            -
                  # already.
         | 
| 100 | 
            -
                  def deactivate_tracking!
         | 
| 101 | 
            -
                    code_tracker&.stop
         | 
| 102 | 
            -
                  end
         | 
| 103 | 
            -
             | 
| 104 | 
            -
                  # Returns whether code tracking is available.
         | 
| 105 | 
            -
                  # This method should be used instead of querying #code_tracker
         | 
| 106 | 
            -
                  # because the latter one may be nil.
         | 
| 107 | 
            -
                  def code_tracking_active?
         | 
| 108 | 
            -
                    code_tracker&.active? || false
         | 
| 109 | 
            -
                  end
         | 
| 110 36 |  | 
| 111 37 | 
             
                  # This method is called from DI Remote handler to issue DI operations
         | 
| 112 38 | 
             
                  # to the probe manager (add or remove probes).
         | 
| @@ -120,39 +46,6 @@ module Datadog | |
| 120 46 | 
             
                  def component
         | 
| 121 47 | 
             
                    Datadog.send(:components).dynamic_instrumentation
         | 
| 122 48 | 
             
                  end
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                  # DI code tracker is instantiated globally before the regular set of
         | 
| 125 | 
            -
                  # components is created, but the code tracker needs to call out to the
         | 
| 126 | 
            -
                  # "current" DI component to perform instrumentation when application
         | 
| 127 | 
            -
                  # code is loaded. Because this call may happen prior to Datadog
         | 
| 128 | 
            -
                  # components having been initialized, we maintain the "current component"
         | 
| 129 | 
            -
                  # which contains a reference to the most recently instantiated
         | 
| 130 | 
            -
                  # DI::Component. This way, if a DI component hasn't been instantiated,
         | 
| 131 | 
            -
                  # we do not try to reference Datadog.components.
         | 
| 132 | 
            -
                  def current_component
         | 
| 133 | 
            -
                    LOCK.synchronize do
         | 
| 134 | 
            -
                      @current_components&.last
         | 
| 135 | 
            -
                    end
         | 
| 136 | 
            -
                  end
         | 
| 137 | 
            -
             | 
| 138 | 
            -
                  # To avoid potential races with DI::Component being added and removed,
         | 
| 139 | 
            -
                  # we maintain a list of the components. Normally the list should contain
         | 
| 140 | 
            -
                  # either zero or one component depending on whether DI is enabled in
         | 
| 141 | 
            -
                  # Datadog configuration. However, if a new instance of DI::Component
         | 
| 142 | 
            -
                  # is created while the previous instance is still running, we are
         | 
| 143 | 
            -
                  # guaranteed to not end up with no component when one is running.
         | 
| 144 | 
            -
                  def add_current_component(component)
         | 
| 145 | 
            -
                    LOCK.synchronize do
         | 
| 146 | 
            -
                      @current_components ||= []
         | 
| 147 | 
            -
                      @current_components << component
         | 
| 148 | 
            -
                    end
         | 
| 149 | 
            -
                  end
         | 
| 150 | 
            -
             | 
| 151 | 
            -
                  def remove_current_component(component)
         | 
| 152 | 
            -
                    LOCK.synchronize do
         | 
| 153 | 
            -
                      @current_components&.delete(component)
         | 
| 154 | 
            -
                    end
         | 
| 155 | 
            -
                  end
         | 
| 156 49 | 
             
                end
         | 
| 157 50 | 
             
              end
         | 
| 158 51 | 
             
            end
         | 
| @@ -167,3 +60,7 @@ if %w(1 true).include?(ENV['DD_DYNAMIC_INSTRUMENTATION_ENABLED']) # steep:ignore | |
| 167 60 | 
             
              # for line probes to work) activate tracking in an initializer.
         | 
| 168 61 | 
             
              Datadog::DI.activate_tracking
         | 
| 169 62 | 
             
            end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            require_relative 'di/contrib'
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            Datadog::DI::Contrib.load_now_or_later
         | 
| @@ -136,9 +136,9 @@ module Datadog | |
| 136 136 | 
             
                      private
         | 
| 137 137 |  | 
| 138 138 | 
             
                      def set_trace_and_span_context(method, trace = nil, span = nil)
         | 
| 139 | 
            -
                        if ( | 
| 140 | 
            -
                          trace =  | 
| 141 | 
            -
                          span =  | 
| 139 | 
            +
                        if (appsec_context = Datadog::AppSec.active_context)
         | 
| 140 | 
            +
                          trace = appsec_context.trace
         | 
| 141 | 
            +
                          span = appsec_context.span
         | 
| 142 142 | 
             
                        end
         | 
| 143 143 |  | 
| 144 144 | 
             
                        trace ||= Datadog::Tracing.active_trace
         | 
    
        data/lib/datadog/kit/identity.rb
    CHANGED
    
    | @@ -66,7 +66,7 @@ module Datadog | |
| 66 66 | 
             
                          active_span.set_tag("usr.#{k}", v) unless v.nil?
         | 
| 67 67 | 
             
                        end
         | 
| 68 68 |  | 
| 69 | 
            -
                        if Datadog::AppSec. | 
| 69 | 
            +
                        if Datadog::AppSec.active_context
         | 
| 70 70 | 
             
                          user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(id)
         | 
| 71 71 | 
             
                          ::Datadog::AppSec::Instrumentation.gateway.push('identity.set_user', user)
         | 
| 72 72 | 
             
                        end
         | 
| @@ -78,9 +78,9 @@ module Datadog | |
| 78 78 | 
             
                    private
         | 
| 79 79 |  | 
| 80 80 | 
             
                    def set_trace_and_span_context(method, trace = nil, span = nil)
         | 
| 81 | 
            -
                      if ( | 
| 82 | 
            -
                        trace =  | 
| 83 | 
            -
                        span =  | 
| 81 | 
            +
                      if (appsec_context = Datadog::AppSec.active_context)
         | 
| 82 | 
            +
                        trace = appsec_context.trace
         | 
| 83 | 
            +
                        span = appsec_context.span
         | 
| 84 84 | 
             
                      end
         | 
| 85 85 |  | 
| 86 86 | 
             
                      trace ||= Datadog::Tracing.active_trace
         | 
| @@ -4,10 +4,13 @@ module Datadog | |
| 4 4 | 
             
              module Profiling
         | 
| 5 5 | 
             
                # Responsible for wiring up the Profiler for execution
         | 
| 6 6 | 
             
                module Component
         | 
| 7 | 
            +
                  ALLOCATION_WITH_RACTORS_ONLY_ONCE = Datadog::Core::Utils::OnlyOnce.new
         | 
| 8 | 
            +
                  private_constant :ALLOCATION_WITH_RACTORS_ONLY_ONCE
         | 
| 9 | 
            +
             | 
| 7 10 | 
             
                  # Passing in a `nil` tracer is supported and will disable the following profiling features:
         | 
| 8 | 
            -
                  # *  | 
| 11 | 
            +
                  # * Profiling in the trace viewer, as well as scoping a profile down to a span
         | 
| 9 12 | 
             
                  # * Endpoint aggregation in the profiler UX, including normalization (resource per endpoint call)
         | 
| 10 | 
            -
                  def self.build_profiler_component(settings:, agent_settings:, optional_tracer:) # rubocop:disable Metrics/MethodLength
         | 
| 13 | 
            +
                  def self.build_profiler_component(settings:, agent_settings:, optional_tracer:, logger:) # rubocop:disable Metrics/MethodLength
         | 
| 11 14 | 
             
                    return [nil, {profiling_enabled: false}] unless settings.profiling.enabled
         | 
| 12 15 |  | 
| 13 16 | 
             
                    # Workaround for weird dependency direction: the Core::Configuration::Components class currently has a
         | 
| @@ -36,14 +39,14 @@ module Datadog | |
| 36 39 |  | 
| 37 40 | 
             
                    # NOTE: Please update the Initialization section of ProfilingDevelopment.md with any changes to this method
         | 
| 38 41 |  | 
| 39 | 
            -
                    no_signals_workaround_enabled = no_signals_workaround_enabled?(settings)
         | 
| 42 | 
            +
                    no_signals_workaround_enabled = no_signals_workaround_enabled?(settings, logger)
         | 
| 40 43 | 
             
                    timeline_enabled = settings.profiling.advanced.timeline_enabled
         | 
| 41 | 
            -
                    allocation_profiling_enabled = enable_allocation_profiling?(settings)
         | 
| 44 | 
            +
                    allocation_profiling_enabled = enable_allocation_profiling?(settings, logger)
         | 
| 42 45 | 
             
                    heap_sample_every = get_heap_sample_every(settings)
         | 
| 43 | 
            -
                    heap_profiling_enabled = enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_every)
         | 
| 44 | 
            -
                    heap_size_profiling_enabled = enable_heap_size_profiling?(settings, heap_profiling_enabled)
         | 
| 46 | 
            +
                    heap_profiling_enabled = enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_every, logger)
         | 
| 47 | 
            +
                    heap_size_profiling_enabled = enable_heap_size_profiling?(settings, heap_profiling_enabled, logger)
         | 
| 45 48 |  | 
| 46 | 
            -
                    overhead_target_percentage = valid_overhead_target(settings.profiling.advanced.overhead_target_percentage)
         | 
| 49 | 
            +
                    overhead_target_percentage = valid_overhead_target(settings.profiling.advanced.overhead_target_percentage, logger)
         | 
| 47 50 | 
             
                    upload_period_seconds = [60, settings.profiling.advanced.upload_period_seconds].max
         | 
| 48 51 |  | 
| 49 52 | 
             
                    recorder = Datadog::Profiling::StackRecorder.new(
         | 
| @@ -57,13 +60,13 @@ module Datadog | |
| 57 60 | 
             
                    )
         | 
| 58 61 | 
             
                    thread_context_collector = build_thread_context_collector(settings, recorder, optional_tracer, timeline_enabled)
         | 
| 59 62 | 
             
                    worker = Datadog::Profiling::Collectors::CpuAndWallTimeWorker.new(
         | 
| 60 | 
            -
                      gc_profiling_enabled: enable_gc_profiling?(settings),
         | 
| 63 | 
            +
                      gc_profiling_enabled: enable_gc_profiling?(settings, logger),
         | 
| 61 64 | 
             
                      no_signals_workaround_enabled: no_signals_workaround_enabled,
         | 
| 62 65 | 
             
                      thread_context_collector: thread_context_collector,
         | 
| 63 66 | 
             
                      dynamic_sampling_rate_overhead_target_percentage: overhead_target_percentage,
         | 
| 64 67 | 
             
                      allocation_profiling_enabled: allocation_profiling_enabled,
         | 
| 65 68 | 
             
                      allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
         | 
| 66 | 
            -
                      gvl_profiling_enabled: enable_gvl_profiling?(settings),
         | 
| 69 | 
            +
                      gvl_profiling_enabled: enable_gvl_profiling?(settings, logger),
         | 
| 67 70 | 
             
                    )
         | 
| 68 71 |  | 
| 69 72 | 
             
                    internal_metadata = {
         | 
| @@ -120,7 +123,7 @@ module Datadog | |
| 120 123 | 
             
                      )
         | 
| 121 124 | 
             
                  end
         | 
| 122 125 |  | 
| 123 | 
            -
                  private_class_method def self.enable_gc_profiling?(settings)
         | 
| 126 | 
            +
                  private_class_method def self.enable_gc_profiling?(settings, logger)
         | 
| 124 127 | 
             
                    return false unless settings.profiling.advanced.gc_enabled
         | 
| 125 128 |  | 
| 126 129 | 
             
                    # SEVERE - Only with Ractors
         | 
| @@ -131,14 +134,14 @@ module Datadog | |
| 131 134 | 
             
                    if RUBY_VERSION.start_with?("3.0.") ||
         | 
| 132 135 | 
             
                        (RUBY_VERSION.start_with?("3.1.") && RUBY_VERSION < "3.1.4") ||
         | 
| 133 136 | 
             
                        (RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3")
         | 
| 134 | 
            -
                       | 
| 137 | 
            +
                      logger.warn(
         | 
| 135 138 | 
             
                        "Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling GC profiling would cause " \
         | 
| 136 139 | 
             
                        "crashes (https://bugs.ruby-lang.org/issues/18464). GC profiling has been disabled."
         | 
| 137 140 | 
             
                      )
         | 
| 138 141 | 
             
                      return false
         | 
| 139 142 | 
             
                    elsif RUBY_VERSION.start_with?("3.")
         | 
| 140 | 
            -
                       | 
| 141 | 
            -
                        " | 
| 143 | 
            +
                      logger.debug(
         | 
| 144 | 
            +
                        "Using Ractors may result in GC profiling unexpectedly " \
         | 
| 142 145 | 
             
                        "stopping (https://bugs.ruby-lang.org/issues/19112). Note that this stop has no impact in your " \
         | 
| 143 146 | 
             
                        "application stability or performance. This does not happen if Ractors are not used."
         | 
| 144 147 | 
             
                      )
         | 
| @@ -155,7 +158,7 @@ module Datadog | |
| 155 158 | 
             
                    heap_sample_rate
         | 
| 156 159 | 
             
                  end
         | 
| 157 160 |  | 
| 158 | 
            -
                  private_class_method def self.enable_allocation_profiling?(settings)
         | 
| 161 | 
            +
                  private_class_method def self.enable_allocation_profiling?(settings, logger)
         | 
| 159 162 | 
             
                    return false unless settings.profiling.allocation_enabled
         | 
| 160 163 |  | 
| 161 164 | 
             
                    # Allocation sampling is safe and supported on Ruby 2.x, but has a few caveats on Ruby 3.x.
         | 
| @@ -165,7 +168,7 @@ module Datadog | |
| 165 168 | 
             
                    # https://github.com/ruby/ruby/pull/7464) that makes this crash in any configuration. This bug is
         | 
| 166 169 | 
             
                    # fixed on Ruby versions 3.2.3 and 3.3.0.
         | 
| 167 170 | 
             
                    if RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3"
         | 
| 168 | 
            -
                       | 
| 171 | 
            +
                      logger.warn(
         | 
| 169 172 | 
             
                        "Allocation profiling is not supported in Ruby versions 3.2.0, 3.2.1 and 3.2.2 and will be forcibly " \
         | 
| 170 173 | 
             
                        "disabled. This is due to a VM bug that can lead to crashes (https://bugs.ruby-lang.org/issues/19482). " \
         | 
| 171 174 | 
             
                        "Other Ruby versions do not suffer from this issue."
         | 
| @@ -181,7 +184,7 @@ module Datadog | |
| 181 184 | 
             
                    if RUBY_VERSION.start_with?("3.0.") ||
         | 
| 182 185 | 
             
                        (RUBY_VERSION.start_with?("3.1.") && RUBY_VERSION < "3.1.4") ||
         | 
| 183 186 | 
             
                        (RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3")
         | 
| 184 | 
            -
                       | 
| 187 | 
            +
                      logger.warn(
         | 
| 185 188 | 
             
                        "Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling allocation profiling while using " \
         | 
| 186 189 | 
             
                        "Ractors may cause unexpected issues, including crashes (https://bugs.ruby-lang.org/issues/18464). " \
         | 
| 187 190 | 
             
                        "This does not happen if Ractors are not used."
         | 
| @@ -190,25 +193,27 @@ module Datadog | |
| 190 193 | 
             
                    # On all known versions of Ruby 3.x, due to https://bugs.ruby-lang.org/issues/19112, when a ractor gets
         | 
| 191 194 | 
             
                    # garbage collected, Ruby will disable all active tracepoints, which this feature internally relies on.
         | 
| 192 195 | 
             
                    elsif RUBY_VERSION.start_with?("3.")
         | 
| 193 | 
            -
                       | 
| 194 | 
            -
                         | 
| 195 | 
            -
             | 
| 196 | 
            -
             | 
| 197 | 
            -
             | 
| 196 | 
            +
                      ALLOCATION_WITH_RACTORS_ONLY_ONCE.run do
         | 
| 197 | 
            +
                        logger.info(
         | 
| 198 | 
            +
                          "Using Ractors may result in allocation profiling " \
         | 
| 199 | 
            +
                          "stopping (https://bugs.ruby-lang.org/issues/19112). Note that this stop has no impact in your " \
         | 
| 200 | 
            +
                          "application stability or performance. This does not happen if Ractors are not used."
         | 
| 201 | 
            +
                        )
         | 
| 202 | 
            +
                      end
         | 
| 198 203 | 
             
                    end
         | 
| 199 204 |  | 
| 200 | 
            -
                     | 
| 205 | 
            +
                    logger.debug("Enabled allocation profiling")
         | 
| 201 206 |  | 
| 202 207 | 
             
                    true
         | 
| 203 208 | 
             
                  end
         | 
| 204 209 |  | 
| 205 | 
            -
                  private_class_method def self.enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_rate)
         | 
| 210 | 
            +
                  private_class_method def self.enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_rate, logger)
         | 
| 206 211 | 
             
                    heap_profiling_enabled = settings.profiling.advanced.experimental_heap_enabled
         | 
| 207 212 |  | 
| 208 213 | 
             
                    return false unless heap_profiling_enabled
         | 
| 209 214 |  | 
| 210 215 | 
             
                    if RUBY_VERSION < "3.1"
         | 
| 211 | 
            -
                       | 
| 216 | 
            +
                      logger.warn(
         | 
| 212 217 | 
             
                        "Current Ruby version (#{RUBY_VERSION}) cannot support heap profiling due to VM limitations. " \
         | 
| 213 218 | 
             
                        "Please upgrade to Ruby >= 3.1 in order to use this feature. Heap profiling has been disabled."
         | 
| 214 219 | 
             
                      )
         | 
| @@ -219,7 +224,7 @@ module Datadog | |
| 219 224 | 
             
                      raise ArgumentError, "Heap profiling requires allocation profiling to be enabled"
         | 
| 220 225 | 
             
                    end
         | 
| 221 226 |  | 
| 222 | 
            -
                     | 
| 227 | 
            +
                    logger.warn(
         | 
| 223 228 | 
             
                      "Enabled experimental heap profiling: heap_sample_rate=#{heap_sample_rate}. This is experimental, not " \
         | 
| 224 229 | 
             
                      "recommended, and will increase overhead!"
         | 
| 225 230 | 
             
                    )
         | 
| @@ -227,25 +232,23 @@ module Datadog | |
| 227 232 | 
             
                    true
         | 
| 228 233 | 
             
                  end
         | 
| 229 234 |  | 
| 230 | 
            -
                  private_class_method def self.enable_heap_size_profiling?(settings, heap_profiling_enabled)
         | 
| 235 | 
            +
                  private_class_method def self.enable_heap_size_profiling?(settings, heap_profiling_enabled, logger)
         | 
| 231 236 | 
             
                    heap_size_profiling_enabled = settings.profiling.advanced.experimental_heap_size_enabled
         | 
| 232 237 |  | 
| 233 238 | 
             
                    return false unless heap_profiling_enabled && heap_size_profiling_enabled
         | 
| 234 239 |  | 
| 235 | 
            -
                     | 
| 240 | 
            +
                    logger.warn(
         | 
| 236 241 | 
             
                      "Enabled experimental heap size profiling. This is experimental, not recommended, and will increase overhead!"
         | 
| 237 242 | 
             
                    )
         | 
| 238 243 |  | 
| 239 244 | 
             
                    true
         | 
| 240 245 | 
             
                  end
         | 
| 241 246 |  | 
| 242 | 
            -
                  private_class_method def self.no_signals_workaround_enabled?(settings) # rubocop:disable Metrics/MethodLength
         | 
| 247 | 
            +
                  private_class_method def self.no_signals_workaround_enabled?(settings, logger) # rubocop:disable Metrics/MethodLength
         | 
| 243 248 | 
             
                    setting_value = settings.profiling.advanced.no_signals_workaround_enabled
         | 
| 244 | 
            -
                    legacy_ruby_that_should_use_workaround = RUBY_VERSION.start_with?("2.5.")
         | 
| 245 249 |  | 
| 246 250 | 
             
                    unless [true, false, :auto].include?(setting_value)
         | 
| 247 | 
            -
                       | 
| 248 | 
            -
                      Datadog.logger.error(
         | 
| 251 | 
            +
                      logger.warn(
         | 
| 249 252 | 
             
                        "Ignoring invalid value for profiling no_signals_workaround_enabled setting: #{setting_value.inspect}. " \
         | 
| 250 253 | 
             
                        "Valid options are `true`, `false` or (default) `:auto`."
         | 
| 251 254 | 
             
                      )
         | 
| @@ -254,23 +257,23 @@ module Datadog | |
| 254 257 | 
             
                    end
         | 
| 255 258 |  | 
| 256 259 | 
             
                    if setting_value == false
         | 
| 257 | 
            -
                      if  | 
| 258 | 
            -
                         | 
| 259 | 
            -
                          'The profiling "no signals" workaround has been disabled via configuration on  | 
| 260 | 
            -
                          " | 
| 261 | 
            -
                          "in production environments, as due to limitations in Ruby APIs, we suspect it may lead to crashes " \
         | 
| 262 | 
            -
                          " | 
| 260 | 
            +
                      if RUBY_VERSION.start_with?("2.5.")
         | 
| 261 | 
            +
                        logger.warn(
         | 
| 262 | 
            +
                          'The profiling "no signals" workaround has been disabled via configuration on Ruby 2.5. ' \
         | 
| 263 | 
            +
                          "This is not recommended " \
         | 
| 264 | 
            +
                          "in production environments, as due to limitations in Ruby APIs, we suspect it may lead to rare crashes " \
         | 
| 265 | 
            +
                          "Please report any issues you run into to Datadog support or " \
         | 
| 263 266 | 
             
                          "via <https://github.com/datadog/dd-trace-rb/issues/new>!"
         | 
| 264 267 | 
             
                        )
         | 
| 265 268 | 
             
                      else
         | 
| 266 | 
            -
                         | 
| 269 | 
            +
                        logger.warn('Profiling "no signals" workaround disabled via configuration')
         | 
| 267 270 | 
             
                      end
         | 
| 268 271 |  | 
| 269 272 | 
             
                      return false
         | 
| 270 273 | 
             
                    end
         | 
| 271 274 |  | 
| 272 275 | 
             
                    if setting_value == true
         | 
| 273 | 
            -
                       | 
| 276 | 
            +
                      logger.warn(
         | 
| 274 277 | 
             
                        'Profiling "no signals" workaround enabled via configuration. Profiling data will have lower quality.'
         | 
| 275 278 | 
             
                      )
         | 
| 276 279 |  | 
| @@ -280,10 +283,10 @@ module Datadog | |
| 280 283 | 
             
                    # Setting is in auto mode. Let's probe to see if we should enable it:
         | 
| 281 284 |  | 
| 282 285 | 
             
                    # We don't warn users in this situation because "upgrade your Ruby" is not a great warning
         | 
| 283 | 
            -
                    return true if  | 
| 286 | 
            +
                    return true if RUBY_VERSION.start_with?("2.5.")
         | 
| 284 287 |  | 
| 285 | 
            -
                    if Gem.loaded_specs["mysql2"] && incompatible_libmysqlclient_version?(settings)
         | 
| 286 | 
            -
                       | 
| 288 | 
            +
                    if Gem.loaded_specs["mysql2"] && incompatible_libmysqlclient_version?(settings, logger)
         | 
| 289 | 
            +
                      logger.warn(
         | 
| 287 290 | 
             
                        'Enabling the profiling "no signals" workaround because an incompatible version of the mysql2 gem is ' \
         | 
| 288 291 | 
             
                        "installed. Profiling data will have lower quality. " \
         | 
| 289 292 | 
             
                        "To fix this, upgrade the libmysqlclient in your OS image to version 8.0.0 or above."
         | 
| @@ -292,7 +295,7 @@ module Datadog | |
| 292 295 | 
             
                    end
         | 
| 293 296 |  | 
| 294 297 | 
             
                    if Gem.loaded_specs["rugged"]
         | 
| 295 | 
            -
                       | 
| 298 | 
            +
                      logger.warn(
         | 
| 296 299 | 
             
                        'Enabling the profiling "no signals" workaround because the rugged gem is installed. ' \
         | 
| 297 300 | 
             
                        "This is needed because some operations on this gem are currently incompatible with the normal working mode " \
         | 
| 298 301 | 
             
                        "of the profiler, as detailed in <https://github.com/datadog/dd-trace-rb/issues/2721>. " \
         | 
| @@ -302,7 +305,7 @@ module Datadog | |
| 302 305 | 
             
                    end
         | 
| 303 306 |  | 
| 304 307 | 
             
                    if (defined?(::PhusionPassenger) || Gem.loaded_specs["passenger"]) && incompatible_passenger_version?
         | 
| 305 | 
            -
                       | 
| 308 | 
            +
                      logger.warn(
         | 
| 306 309 | 
             
                        'Enabling the profiling "no signals" workaround because an incompatible version of the passenger gem is ' \
         | 
| 307 310 | 
             
                        "installed. Profiling data will have lower quality." \
         | 
| 308 311 | 
             
                        "To fix this, upgrade the passenger gem to version 6.0.19 or above."
         | 
| @@ -322,10 +325,10 @@ module Datadog | |
| 322 325 | 
             
                  #
         | 
| 323 326 | 
             
                  # The `mysql2` gem's `info` method can be used to determine which `libmysqlclient` version is in use, and thus to
         | 
| 324 327 | 
             
                  # detect if it's safe for the profiler to use signals or if we need to employ a fallback.
         | 
| 325 | 
            -
                  private_class_method def self.incompatible_libmysqlclient_version?(settings)
         | 
| 328 | 
            +
                  private_class_method def self.incompatible_libmysqlclient_version?(settings, logger)
         | 
| 326 329 | 
             
                    return true if settings.profiling.advanced.skip_mysql2_check
         | 
| 327 330 |  | 
| 328 | 
            -
                     | 
| 331 | 
            +
                    logger.debug(
         | 
| 329 332 | 
             
                      "Requiring `mysql2` to check if the `libmysqlclient` version it uses is compatible with profiling"
         | 
| 330 333 | 
             
                    )
         | 
| 331 334 |  | 
| @@ -354,14 +357,14 @@ module Datadog | |
| 354 357 | 
             
                        libmysqlclient_version >= Gem::Version.new("8.0.0") ||
         | 
| 355 358 | 
             
                        looks_like_mariadb?(info, libmysqlclient_version)
         | 
| 356 359 |  | 
| 357 | 
            -
                       | 
| 360 | 
            +
                      logger.debug(
         | 
| 358 361 | 
             
                        "The `mysql2` gem is using #{compatible ? "a compatible" : "an incompatible"} version of " \
         | 
| 359 362 | 
             
                        "the `libmysqlclient` library (#{libmysqlclient_version})"
         | 
| 360 363 | 
             
                      )
         | 
| 361 364 |  | 
| 362 365 | 
             
                      !compatible
         | 
| 363 366 | 
             
                    rescue StandardError, LoadError => e
         | 
| 364 | 
            -
                       | 
| 367 | 
            +
                      logger.warn(
         | 
| 365 368 | 
             
                        "Failed to probe `mysql2` gem information. " \
         | 
| 366 369 | 
             
                        "Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
         | 
| 367 370 | 
             
                      )
         | 
| @@ -383,12 +386,11 @@ module Datadog | |
| 383 386 | 
             
                    end
         | 
| 384 387 | 
             
                  end
         | 
| 385 388 |  | 
| 386 | 
            -
                  private_class_method def self.valid_overhead_target(overhead_target_percentage)
         | 
| 389 | 
            +
                  private_class_method def self.valid_overhead_target(overhead_target_percentage, logger)
         | 
| 387 390 | 
             
                    if overhead_target_percentage > 0 && overhead_target_percentage <= 20
         | 
| 388 391 | 
             
                      overhead_target_percentage
         | 
| 389 392 | 
             
                    else
         | 
| 390 | 
            -
                       | 
| 391 | 
            -
                      Datadog.logger.error(
         | 
| 393 | 
            +
                      logger.warn(
         | 
| 392 394 | 
             
                        "Ignoring invalid value for profiling overhead_target_percentage setting: " \
         | 
| 393 395 | 
             
                        "#{overhead_target_percentage.inspect}. Falling back to default value."
         | 
| 394 396 | 
             
                      )
         | 
| @@ -432,10 +434,10 @@ module Datadog | |
| 432 434 | 
             
                    settings.profiling.advanced.dir_interruption_workaround_enabled
         | 
| 433 435 | 
             
                  end
         | 
| 434 436 |  | 
| 435 | 
            -
                  private_class_method def self.enable_gvl_profiling?(settings)
         | 
| 437 | 
            +
                  private_class_method def self.enable_gvl_profiling?(settings, logger)
         | 
| 436 438 | 
             
                    if RUBY_VERSION < "3.2"
         | 
| 437 439 | 
             
                      if settings.profiling.advanced.preview_gvl_enabled
         | 
| 438 | 
            -
                         | 
| 440 | 
            +
                        logger.warn("GVL profiling is currently not supported in Ruby < 3.2 and will not be enabled.")
         | 
| 439 441 | 
             
                      end
         | 
| 440 442 |  | 
| 441 443 | 
             
                      return false
         | 
| @@ -13,13 +13,11 @@ module Datadog | |
| 13 13 | 
             
                  def initialize(agent_settings:, site:, api_key:, upload_timeout_seconds:)
         | 
| 14 14 | 
             
                    @upload_timeout_milliseconds = (upload_timeout_seconds * 1_000).to_i
         | 
| 15 15 |  | 
| 16 | 
            -
                    validate_agent_settings(agent_settings)
         | 
| 17 | 
            -
             | 
| 18 16 | 
             
                    @exporter_configuration =
         | 
| 19 17 | 
             
                      if agentless?(site, api_key)
         | 
| 20 18 | 
             
                        [:agentless, site, api_key].freeze
         | 
| 21 19 | 
             
                      else
         | 
| 22 | 
            -
                        [:agent,  | 
| 20 | 
            +
                        [:agent, agent_settings.url].freeze
         | 
| 23 21 | 
             
                      end
         | 
| 24 22 |  | 
| 25 23 | 
             
                    status, result = validate_exporter(exporter_configuration)
         | 
| @@ -75,29 +73,6 @@ module Datadog | |
| 75 73 |  | 
| 76 74 | 
             
                  private
         | 
| 77 75 |  | 
| 78 | 
            -
                  def base_url_from(agent_settings)
         | 
| 79 | 
            -
                    case agent_settings.adapter
         | 
| 80 | 
            -
                    when Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
         | 
| 81 | 
            -
                      "#{agent_settings.ssl ? "https" : "http"}://#{agent_settings.hostname}:#{agent_settings.port}/"
         | 
| 82 | 
            -
                    when Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER
         | 
| 83 | 
            -
                      "unix://#{agent_settings.uds_path}"
         | 
| 84 | 
            -
                    else
         | 
| 85 | 
            -
                      raise ArgumentError, "Unexpected adapter: #{agent_settings.adapter}"
         | 
| 86 | 
            -
                    end
         | 
| 87 | 
            -
                  end
         | 
| 88 | 
            -
             | 
| 89 | 
            -
                  def validate_agent_settings(agent_settings)
         | 
| 90 | 
            -
                    supported_adapters = [
         | 
| 91 | 
            -
                      Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER,
         | 
| 92 | 
            -
                      Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
         | 
| 93 | 
            -
                    ]
         | 
| 94 | 
            -
                    unless supported_adapters.include?(agent_settings.adapter)
         | 
| 95 | 
            -
                      raise ArgumentError,
         | 
| 96 | 
            -
                        "Unsupported transport configuration for profiling: Adapter #{agent_settings.adapter} " \
         | 
| 97 | 
            -
                                    " is not supported"
         | 
| 98 | 
            -
                    end
         | 
| 99 | 
            -
                  end
         | 
| 100 | 
            -
             | 
| 101 76 | 
             
                  def agentless?(site, api_key)
         | 
| 102 77 | 
             
                    site && api_key && Core::Environment::VariableHelpers.env_to_bool(Profiling::Ext::ENV_AGENTLESS, false)
         | 
| 103 78 | 
             
                  end
         | 
| @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            require_relative '../integration'
         | 
| 4 4 | 
             
            require_relative 'configuration/settings'
         | 
| 5 5 | 
             
            require_relative 'patcher'
         | 
| 6 | 
            -
            require_relative ' | 
| 6 | 
            +
            require_relative '../../../core/contrib/rails/utils'
         | 
| 7 7 |  | 
| 8 8 | 
             
            module Datadog
         | 
| 9 9 | 
             
              module Tracing
         | 
| @@ -17,6 +17,9 @@ module Datadog | |
| 17 17 |  | 
| 18 18 | 
             
                      # @public_api Changing the integration name or integration options can cause breaking changes
         | 
| 19 19 | 
             
                      register_as :action_cable, auto_patch: false
         | 
| 20 | 
            +
                      def self.gem_name
         | 
| 21 | 
            +
                        'actioncable'
         | 
| 22 | 
            +
                      end
         | 
| 20 23 |  | 
| 21 24 | 
             
                      def self.version
         | 
| 22 25 | 
             
                        Gem.loaded_specs['actioncable'] && Gem.loaded_specs['actioncable'].version
         | 
| @@ -33,7 +36,7 @@ module Datadog | |
| 33 36 | 
             
                      # enabled by rails integration so should only auto instrument
         | 
| 34 37 | 
             
                      # if detected that it is being used without rails
         | 
| 35 38 | 
             
                      def auto_instrument?
         | 
| 36 | 
            -
                        !Contrib::Rails::Utils.railtie_supported?
         | 
| 39 | 
            +
                        !Core::Contrib::Rails::Utils.railtie_supported?
         | 
| 37 40 | 
             
                      end
         | 
| 38 41 |  | 
| 39 42 | 
             
                      def new_configuration
         | 
| @@ -3,7 +3,7 @@ | |
| 3 3 | 
             
            require_relative 'configuration/settings'
         | 
| 4 4 | 
             
            require_relative 'patcher'
         | 
| 5 5 | 
             
            require_relative '../integration'
         | 
| 6 | 
            -
            require_relative ' | 
| 6 | 
            +
            require_relative '../../../core/contrib/rails/utils'
         | 
| 7 7 |  | 
| 8 8 | 
             
            module Datadog
         | 
| 9 9 | 
             
              module Tracing
         | 
| @@ -18,6 +18,10 @@ module Datadog | |
| 18 18 | 
             
                      # @public_api Changing the integration name or integration options can cause breaking changes
         | 
| 19 19 | 
             
                      register_as :action_mailer, auto_patch: false
         | 
| 20 20 |  | 
| 21 | 
            +
                      def self.gem_name
         | 
| 22 | 
            +
                        'actionmailer'
         | 
| 23 | 
            +
                      end
         | 
| 24 | 
            +
             | 
| 21 25 | 
             
                      def self.version
         | 
| 22 26 | 
             
                        Gem.loaded_specs['actionmailer'] && Gem.loaded_specs['actionmailer'].version
         | 
| 23 27 | 
             
                      end
         | 
| @@ -33,7 +37,7 @@ module Datadog | |
| 33 37 | 
             
                      # enabled by rails integration so should only auto instrument
         | 
| 34 38 | 
             
                      # if detected that it is being used without rails
         | 
| 35 39 | 
             
                      def auto_instrument?
         | 
| 36 | 
            -
                        !Contrib::Rails::Utils.railtie_supported?
         | 
| 40 | 
            +
                        !Core::Contrib::Rails::Utils.railtie_supported?
         | 
| 37 41 | 
             
                      end
         | 
| 38 42 |  | 
| 39 43 | 
             
                      def new_configuration
         | 
| @@ -4,7 +4,7 @@ require_relative 'configuration/settings' | |
| 4 4 | 
             
            require_relative 'patcher'
         | 
| 5 5 | 
             
            require_relative '../integration'
         | 
| 6 6 | 
             
            require_relative '../rails/ext'
         | 
| 7 | 
            -
            require_relative ' | 
| 7 | 
            +
            require_relative '../../../core/contrib/rails/utils'
         | 
| 8 8 |  | 
| 9 9 | 
             
            module Datadog
         | 
| 10 10 | 
             
              module Tracing
         | 
| @@ -18,6 +18,9 @@ module Datadog | |
| 18 18 |  | 
| 19 19 | 
             
                      # @public_api Changing the integration name or integration options can cause breaking changes
         | 
| 20 20 | 
             
                      register_as :action_pack, auto_patch: false
         | 
| 21 | 
            +
                      def self.gem_name
         | 
| 22 | 
            +
                        'actionpack'
         | 
| 23 | 
            +
                      end
         | 
| 21 24 |  | 
| 22 25 | 
             
                      def self.version
         | 
| 23 26 | 
             
                        Gem.loaded_specs['actionpack'] && Gem.loaded_specs['actionpack'].version
         | 
| @@ -34,7 +37,7 @@ module Datadog | |
| 34 37 | 
             
                      # enabled by rails integration so should only auto instrument
         | 
| 35 38 | 
             
                      # if detected that it is being used without rails
         | 
| 36 39 | 
             
                      def auto_instrument?
         | 
| 37 | 
            -
                        !Contrib::Rails::Utils.railtie_supported?
         | 
| 40 | 
            +
                        !Core::Contrib::Rails::Utils.railtie_supported?
         | 
| 38 41 | 
             
                      end
         | 
| 39 42 |  | 
| 40 43 | 
             
                      def new_configuration
         |