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
| @@ -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_view, auto_patch: false
         | 
| 21 | 
            +
                      def self.gem_name
         | 
| 22 | 
            +
                        'actionview'
         | 
| 23 | 
            +
                      end
         | 
| 21 24 |  | 
| 22 25 | 
             
                      def self.version
         | 
| 23 26 | 
             
                        # ActionView is its own gem in Rails 4.1+
         | 
| @@ -41,7 +44,7 @@ module Datadog | |
| 41 44 | 
             
                      # enabled by rails integration so should only auto instrument
         | 
| 42 45 | 
             
                      # if detected that it is being used without rails
         | 
| 43 46 | 
             
                      def auto_instrument?
         | 
| 44 | 
            -
                        !Contrib::Rails::Utils.railtie_supported?
         | 
| 47 | 
            +
                        !Core::Contrib::Rails::Utils.railtie_supported?
         | 
| 45 48 | 
             
                      end
         | 
| 46 49 |  | 
| 47 50 | 
             
                      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
         | 
| @@ -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 :active_job, auto_patch: false
         | 
| 20 | 
            +
                      def self.gem_name
         | 
| 21 | 
            +
                        'activejob'
         | 
| 22 | 
            +
                      end
         | 
| 20 23 |  | 
| 21 24 | 
             
                      def self.version
         | 
| 22 25 | 
             
                        Gem.loaded_specs['activejob'] && Gem.loaded_specs['activejob'].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
         | 
| @@ -7,7 +7,7 @@ require_relative 'patcher' | |
| 7 7 | 
             
            require_relative '../component'
         | 
| 8 8 | 
             
            require_relative '../integration'
         | 
| 9 9 | 
             
            require_relative '../rails/ext'
         | 
| 10 | 
            -
            require_relative ' | 
| 10 | 
            +
            require_relative '../../../core/contrib/rails/utils'
         | 
| 11 11 |  | 
| 12 12 | 
             
            module Datadog
         | 
| 13 13 | 
             
              module Tracing
         | 
| @@ -22,6 +22,10 @@ module Datadog | |
| 22 22 | 
             
                      # @public_api Changing the integration name or integration options can cause breaking changes
         | 
| 23 23 | 
             
                      register_as :active_record, auto_patch: false
         | 
| 24 24 |  | 
| 25 | 
            +
                      def self.gem_name
         | 
| 26 | 
            +
                        'activerecord'
         | 
| 27 | 
            +
                      end
         | 
| 28 | 
            +
             | 
| 25 29 | 
             
                      def self.version
         | 
| 26 30 | 
             
                        Gem.loaded_specs['activerecord'] && Gem.loaded_specs['activerecord'].version
         | 
| 27 31 | 
             
                      end
         | 
| @@ -37,7 +41,7 @@ module Datadog | |
| 37 41 | 
             
                      # enabled by rails integration so should only auto instrument
         | 
| 38 42 | 
             
                      # if detected that it is being used without rails
         | 
| 39 43 | 
             
                      def auto_instrument?
         | 
| 40 | 
            -
                        !Contrib::Rails::Utils.railtie_supported?
         | 
| 44 | 
            +
                        !Core::Contrib::Rails::Utils.railtie_supported?
         | 
| 41 45 | 
             
                      end
         | 
| 42 46 |  | 
| 43 47 | 
             
                      def new_configuration
         | 
| @@ -81,7 +81,9 @@ module Datadog | |
| 81 81 |  | 
| 82 82 | 
             
                            span.set_tag('EVENT', event)
         | 
| 83 83 |  | 
| 84 | 
            -
                             | 
| 84 | 
            +
                            if Datadog.configuration.tracing[:active_support][:cache_key].enabled
         | 
| 85 | 
            +
                              set_cache_key(span, key, mapping[:multi_key])
         | 
| 86 | 
            +
                            end
         | 
| 85 87 | 
             
                          rescue StandardError => e
         | 
| 86 88 | 
             
                            Datadog.logger.error(e.message)
         | 
| 87 89 | 
             
                            Datadog::Core::Telemetry::Logger.report(e)
         | 
| @@ -3,6 +3,7 @@ | |
| 3 3 | 
             
            require_relative '../../../../core/utils'
         | 
| 4 4 | 
             
            require_relative '../../../metadata/ext'
         | 
| 5 5 | 
             
            require_relative '../ext'
         | 
| 6 | 
            +
            require_relative 'event'
         | 
| 6 7 |  | 
| 7 8 | 
             
            module Datadog
         | 
| 8 9 | 
             
              module Tracing
         | 
| @@ -58,7 +59,8 @@ module Datadog | |
| 58 59 | 
             
                            end
         | 
| 59 60 |  | 
| 60 61 | 
             
                            span.set_tag(Ext::TAG_CACHE_BACKEND, store) if store
         | 
| 61 | 
            -
             | 
| 62 | 
            +
             | 
| 63 | 
            +
                            set_cache_key(span, key, multi_key) if Datadog.configuration.tracing[:active_support][:cache_key].enabled
         | 
| 62 64 |  | 
| 63 65 | 
             
                            yield
         | 
| 64 66 | 
             
                          end
         | 
| @@ -39,6 +39,16 @@ module Datadog | |
| 39 39 | 
             
                            )
         | 
| 40 40 | 
             
                          end
         | 
| 41 41 | 
             
                        end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                        # grouped "cache_key.*" settings
         | 
| 44 | 
            +
                        settings :cache_key do
         | 
| 45 | 
            +
                          # enable or disabling the inclusion of the cache_key in the span
         | 
| 46 | 
            +
                          option :enabled do |o|
         | 
| 47 | 
            +
                            # cache_key.enabled
         | 
| 48 | 
            +
                            o.type :bool
         | 
| 49 | 
            +
                            o.default true
         | 
| 50 | 
            +
                          end
         | 
| 51 | 
            +
                        end
         | 
| 42 52 | 
             
                      end
         | 
| 43 53 | 
             
                    end
         | 
| 44 54 | 
             
                  end
         | 
| @@ -5,7 +5,7 @@ require_relative 'configuration/settings' | |
| 5 5 | 
             
            require_relative 'patcher'
         | 
| 6 6 | 
             
            require_relative 'cache/redis'
         | 
| 7 7 | 
             
            require_relative '../rails/ext'
         | 
| 8 | 
            -
            require_relative ' | 
| 8 | 
            +
            require_relative '../../../core/contrib/rails/utils'
         | 
| 9 9 |  | 
| 10 10 | 
             
            module Datadog
         | 
| 11 11 | 
             
              module Tracing
         | 
| @@ -19,6 +19,9 @@ module Datadog | |
| 19 19 |  | 
| 20 20 | 
             
                      # @public_api Changing the integration name or integration options can cause breaking changes
         | 
| 21 21 | 
             
                      register_as :active_support, auto_patch: false
         | 
| 22 | 
            +
                      def self.gem_name
         | 
| 23 | 
            +
                        'activesupport'
         | 
| 24 | 
            +
                      end
         | 
| 22 25 |  | 
| 23 26 | 
             
                      def self.version
         | 
| 24 27 | 
             
                        Gem.loaded_specs['activesupport'] && Gem.loaded_specs['activesupport'].version
         | 
| @@ -35,7 +38,7 @@ module Datadog | |
| 35 38 | 
             
                      # enabled by rails integration so should only auto instrument
         | 
| 36 39 | 
             
                      # if detected that it is being used without rails
         | 
| 37 40 | 
             
                      def auto_instrument?
         | 
| 38 | 
            -
                        !Contrib::Rails::Utils.railtie_supported?
         | 
| 41 | 
            +
                        !Core::Contrib::Rails::Utils.railtie_supported?
         | 
| 39 42 | 
             
                      end
         | 
| 40 43 |  | 
| 41 44 | 
             
                      def new_configuration
         | 
| @@ -9,10 +9,10 @@ module Datadog | |
| 9 9 | 
             
                module Contrib
         | 
| 10 10 | 
             
                  # Auto-activate instrumentation
         | 
| 11 11 | 
             
                  def self.auto_instrument!
         | 
| 12 | 
            -
                    require_relative 'rails/utils'
         | 
| 12 | 
            +
                    require_relative '../../core/contrib/rails/utils'
         | 
| 13 13 |  | 
| 14 14 | 
             
                    # Defer to Rails if this is a Rails application
         | 
| 15 | 
            -
                    if Datadog:: | 
| 15 | 
            +
                    if Datadog::Core::Contrib::Rails::Utils.railtie_supported?
         | 
| 16 16 | 
             
                      require_relative 'rails/auto_instrument_railtie'
         | 
| 17 17 | 
             
                    else
         | 
| 18 18 | 
             
                      AutoInstrument.patch_all!
         | 
| @@ -16,6 +16,9 @@ module Datadog | |
| 16 16 |  | 
| 17 17 | 
             
                      # @public_api Changing the integration name or integration options can cause breaking changes
         | 
| 18 18 | 
             
                      register_as :concurrent_ruby
         | 
| 19 | 
            +
                      def self.gem_name
         | 
| 20 | 
            +
                        'concurrent-ruby'
         | 
| 21 | 
            +
                      end
         | 
| 19 22 |  | 
| 20 23 | 
             
                      def self.version
         | 
| 21 24 | 
             
                        Gem.loaded_specs['concurrent-ruby'] && Gem.loaded_specs['concurrent-ruby'].version
         | 
| @@ -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 :httprb
         | 
| 20 | 
            +
                      def self.gem_name
         | 
| 21 | 
            +
                        'http'
         | 
| 22 | 
            +
                      end
         | 
| 20 23 |  | 
| 21 24 | 
             
                      def self.version
         | 
| 22 25 | 
             
                        Gem.loaded_specs['http'] && Gem.loaded_specs['http'].version
         | 
| @@ -16,6 +16,9 @@ module Datadog | |
| 16 16 |  | 
| 17 17 | 
             
                      # @public_api Changing the integration name or integration options can cause breaking changes
         | 
| 18 18 | 
             
                      register_as :kafka, auto_patch: false
         | 
| 19 | 
            +
                      def self.gem_name
         | 
| 20 | 
            +
                        'ruby-kafka'
         | 
| 21 | 
            +
                      end
         | 
| 19 22 |  | 
| 20 23 | 
             
                      def self.version
         | 
| 21 24 | 
             
                        Gem.loaded_specs['ruby-kafka'] && Gem.loaded_specs['ruby-kafka'].version
         | 
| @@ -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 :mongo, auto_patch: true
         | 
| 20 | 
            +
                      def self.gem_name
         | 
| 21 | 
            +
                        'mongo'
         | 
| 22 | 
            +
                      end
         | 
| 20 23 |  | 
| 21 24 | 
             
                      def self.version
         | 
| 22 25 | 
             
                        Gem.loaded_specs['mongo'] && Gem.loaded_specs['mongo'].version
         | 
| @@ -16,6 +16,9 @@ module Datadog | |
| 16 16 |  | 
| 17 17 | 
             
                      # @public_api Changing the integration name or integration options can cause breaking changes
         | 
| 18 18 | 
             
                      register_as :opensearch, auto_patch: true
         | 
| 19 | 
            +
                      def self.gem_name
         | 
| 20 | 
            +
                        'opensearch-ruby'
         | 
| 21 | 
            +
                      end
         | 
| 19 22 |  | 
| 20 23 | 
             
                      def self.version
         | 
| 21 24 | 
             
                        Gem.loaded_specs['opensearch-ruby'] \
         | 
| @@ -16,6 +16,9 @@ module Datadog | |
| 16 16 |  | 
| 17 17 | 
             
                      # @public_api Changing the integration name or integration options can cause breaking changes
         | 
| 18 18 | 
             
                      register_as :presto
         | 
| 19 | 
            +
                      def self.gem_name
         | 
| 20 | 
            +
                        'presto-client'
         | 
| 21 | 
            +
                      end
         | 
| 19 22 |  | 
| 20 23 | 
             
                      def self.version
         | 
| 21 24 | 
             
                        Gem.loaded_specs['presto-client'] && Gem.loaded_specs['presto-client'].version
         | 
| @@ -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
         | 
| @@ -33,7 +33,7 @@ module Datadog | |
| 33 33 | 
             
                      # enabled by rails integration so should only auto instrument
         | 
| 34 34 | 
             
                      # if detected that it is being used without rails
         | 
| 35 35 | 
             
                      def auto_instrument?
         | 
| 36 | 
            -
                        !Contrib::Rails::Utils.railtie_supported?
         | 
| 36 | 
            +
                        !Core::Contrib::Rails::Utils.railtie_supported?
         | 
| 37 37 | 
             
                      end
         | 
| 38 38 |  | 
| 39 39 | 
             
                      def new_configuration
         | 
| @@ -9,7 +9,7 @@ require_relative '../active_support/integration' | |
| 9 9 | 
             
            require_relative '../grape/endpoint'
         | 
| 10 10 | 
             
            require_relative '../lograge/integration'
         | 
| 11 11 | 
             
            require_relative 'ext'
         | 
| 12 | 
            -
            require_relative 'utils'
         | 
| 12 | 
            +
            require_relative '../../../core/contrib/rails/utils'
         | 
| 13 13 | 
             
            require_relative '../semantic_logger/integration'
         | 
| 14 14 |  | 
| 15 15 | 
             
            module Datadog
         | 
| @@ -41,7 +41,7 @@ module Datadog | |
| 41 41 | 
             
                          # being executed, but here we know better, get it from Rails config.
         | 
| 42 42 | 
             
                          # Don't set this if service has been explicitly provided by the user.
         | 
| 43 43 | 
             
                          if datadog_config.service_without_fallback.nil?
         | 
| 44 | 
            -
                            datadog_config.service = rails_config[:service_name] || Utils.app_name
         | 
| 44 | 
            +
                            datadog_config.service = rails_config[:service_name] || Core::Contrib::Rails::Utils.app_name
         | 
| 45 45 | 
             
                          end
         | 
| 46 46 |  | 
| 47 47 | 
             
                          activate_rack!(datadog_config, rails_config)
         | 
| @@ -6,7 +6,7 @@ require_relative 'framework' | |
| 6 6 | 
             
            require_relative 'log_injection'
         | 
| 7 7 | 
             
            require_relative 'middlewares'
         | 
| 8 8 | 
             
            require_relative 'runner'
         | 
| 9 | 
            -
            require_relative 'utils'
         | 
| 9 | 
            +
            require_relative '../../../core/contrib/rails/utils'
         | 
| 10 10 | 
             
            require_relative '../semantic_logger/patcher'
         | 
| 11 11 |  | 
| 12 12 | 
             
            module Datadog
         | 
| @@ -16,6 +16,9 @@ module Datadog | |
| 16 16 |  | 
| 17 17 | 
             
                      # @public_api Changing the integration name or integration options can cause breaking changes
         | 
| 18 18 | 
             
                      register_as :rest_client
         | 
| 19 | 
            +
                      def self.gem_name
         | 
| 20 | 
            +
                        'rest-client'
         | 
| 21 | 
            +
                      end
         | 
| 19 22 |  | 
| 20 23 | 
             
                      def self.version
         | 
| 21 24 | 
             
                        Gem.loaded_specs['rest-client'] && Gem.loaded_specs['rest-client'].version
         | 
    
        data/lib/datadog/tracing/span.rb
    CHANGED
    
    | @@ -112,7 +112,10 @@ module Datadog | |
| 112 112 |  | 
| 113 113 | 
             
                  def duration
         | 
| 114 114 | 
             
                    return @duration if @duration
         | 
| 115 | 
            -
             | 
| 115 | 
            +
             | 
| 116 | 
            +
                    start_time = @start_time
         | 
| 117 | 
            +
                    end_time = @end_time
         | 
| 118 | 
            +
                    end_time - start_time if start_time && end_time
         | 
| 116 119 | 
             
                  end
         | 
| 117 120 |  | 
| 118 121 | 
             
                  def set_error(e)
         | 
| @@ -135,6 +138,8 @@ module Datadog | |
| 135 138 | 
             
                  # TODO: Change this to reflect attributes when serialization
         | 
| 136 139 | 
             
                  # isn't handled by this method.
         | 
| 137 140 | 
             
                  def to_hash
         | 
| 141 | 
            +
                    @meta['events'] = @events.map(&:to_hash).to_json unless @events.empty?
         | 
| 142 | 
            +
             | 
| 138 143 | 
             
                    h = {
         | 
| 139 144 | 
             
                      error: @status,
         | 
| 140 145 | 
             
                      meta: @meta,
         | 
| @@ -154,8 +159,6 @@ module Datadog | |
| 154 159 | 
             
                      h[:duration] = duration_nano
         | 
| 155 160 | 
             
                    end
         | 
| 156 161 |  | 
| 157 | 
            -
                    h[:meta]['events'] = @events.map(&:to_hash).to_json unless @events.empty?
         | 
| 158 | 
            -
             | 
| 159 162 | 
             
                    h
         | 
| 160 163 | 
             
                  end
         | 
| 161 164 |  | 
| @@ -196,12 +199,17 @@ module Datadog | |
| 196 199 | 
             
                  # Used for serialization
         | 
| 197 200 | 
             
                  # @return [Integer] in nanoseconds since Epoch
         | 
| 198 201 | 
             
                  def start_time_nano
         | 
| 199 | 
            -
                     | 
| 202 | 
            +
                    return unless (start_time = @start_time)
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                    start_time.to_i * 1000000000 + start_time.nsec
         | 
| 200 205 | 
             
                  end
         | 
| 201 206 |  | 
| 202 207 | 
             
                  # Used for serialization
         | 
| 203 208 | 
             
                  # @return [Integer] in nanoseconds since Epoch
         | 
| 204 209 | 
             
                  def duration_nano
         | 
| 210 | 
            +
                    duration = self.duration
         | 
| 211 | 
            +
                    return unless duration
         | 
| 212 | 
            +
             | 
| 205 213 | 
             
                    (duration * 1e9).to_i
         | 
| 206 214 | 
             
                  end
         | 
| 207 215 |  | 
| @@ -19,23 +19,143 @@ module Datadog | |
| 19 19 | 
             
                  #   @return [Integer]
         | 
| 20 20 | 
             
                  attr_reader :time_unix_nano
         | 
| 21 21 |  | 
| 22 | 
            +
                  # TODO: Accept {Time} as the time_unix_nano parameter, possibly in addition to the current nano integer.
         | 
| 22 23 | 
             
                  def initialize(
         | 
| 23 24 | 
             
                    name,
         | 
| 24 25 | 
             
                    attributes: nil,
         | 
| 25 26 | 
             
                    time_unix_nano: nil
         | 
| 26 27 | 
             
                  )
         | 
| 27 28 | 
             
                    @name = name
         | 
| 28 | 
            -
             | 
| 29 | 
            +
             | 
| 30 | 
            +
                    @attributes = attributes.dup || {}
         | 
| 31 | 
            +
                    validate_attributes!(@attributes)
         | 
| 32 | 
            +
                    @attributes.transform_keys!(&:to_s)
         | 
| 33 | 
            +
             | 
| 29 34 | 
             
                    # OpenTelemetry SDK stores span event timestamps in nanoseconds (not seconds).
         | 
| 30 35 | 
             
                    # We will do the same here to avoid unnecessary conversions and inconsistencies.
         | 
| 31 36 | 
             
                    @time_unix_nano = time_unix_nano || (Time.now.to_r * 1_000_000_000).to_i
         | 
| 32 37 | 
             
                  end
         | 
| 33 38 |  | 
| 39 | 
            +
                  # Converts the span event into a hash to be used by with the span tag serialization
         | 
| 40 | 
            +
                  # (`span.set_tag('events) = [event.to_hash]`). This serialization format has the drawback
         | 
| 41 | 
            +
                  # of being limiting span events to the size limit of a span tag.
         | 
| 42 | 
            +
                  # All Datadog agents support this format.
         | 
| 34 43 | 
             
                  def to_hash
         | 
| 35 | 
            -
                    h = { name | 
| 36 | 
            -
                    h[ | 
| 44 | 
            +
                    h = { 'name' => @name, 'time_unix_nano' => @time_unix_nano }
         | 
| 45 | 
            +
                    h['attributes'] = @attributes unless @attributes.empty?
         | 
| 46 | 
            +
                    h
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  # Converts the span event into a hash to be used by the MessagePack serialization as a
         | 
| 50 | 
            +
                  # top-level span field (span.span_events = [event.to_native_format]).
         | 
| 51 | 
            +
                  # This serialization format removes the serialization limitations of the `span.set_tag('events)` approach,
         | 
| 52 | 
            +
                  # but is only supported by newer version of the Datadog agent.
         | 
| 53 | 
            +
                  def to_native_format
         | 
| 54 | 
            +
                    h = { 'name' => @name, 'time_unix_nano' => @time_unix_nano }
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    attr = {}
         | 
| 57 | 
            +
                    @attributes.each do |key, value|
         | 
| 58 | 
            +
                      attr[key] = if value.is_a?(Array)
         | 
| 59 | 
            +
                                    { type: ARRAY_TYPE, array_value: value.map { |v| serialize_native_attribute(v) } }
         | 
| 60 | 
            +
                                  else
         | 
| 61 | 
            +
                                    serialize_native_attribute(value)
         | 
| 62 | 
            +
                                  end
         | 
| 63 | 
            +
                    end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    h['attributes'] = attr unless @attributes.empty?
         | 
| 66 | 
            +
             | 
| 37 67 | 
             
                    h
         | 
| 38 68 | 
             
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  private
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  MIN_INT64_SIGNED = -2**63
         | 
| 73 | 
            +
                  MAX_INT64_SIGNED = 2 << 63 - 1
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  # Checks the attributes hash to ensure it only contains serializable values.
         | 
| 76 | 
            +
                  # Invalid values are removed from the hash.
         | 
| 77 | 
            +
                  def validate_attributes!(attributes)
         | 
| 78 | 
            +
                    attributes.select! do |key, value|
         | 
| 79 | 
            +
                      case value
         | 
| 80 | 
            +
                      when Array
         | 
| 81 | 
            +
                        next true if value.empty?
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                        first = value.first
         | 
| 84 | 
            +
                        case first
         | 
| 85 | 
            +
                        when String, Integer, Float
         | 
| 86 | 
            +
                          first_type = first.class
         | 
| 87 | 
            +
                          if value.all? { |v| v.is_a?(first_type) }
         | 
| 88 | 
            +
                            value.all? { |v| validate_scalar_attribute!(key, v) }
         | 
| 89 | 
            +
                          else
         | 
| 90 | 
            +
                            Datadog.logger.warn("Attribute #{key} array must be homogenous: #{value}.")
         | 
| 91 | 
            +
                            false
         | 
| 92 | 
            +
                          end
         | 
| 93 | 
            +
                        when TrueClass, FalseClass
         | 
| 94 | 
            +
                          if value.all? { |v| v.is_a?(TrueClass) || v.is_a?(FalseClass) }
         | 
| 95 | 
            +
                            value.all? { |v| validate_scalar_attribute!(key, v) }
         | 
| 96 | 
            +
                          else
         | 
| 97 | 
            +
                            Datadog.logger.warn("Attribute #{key} array must be homogenous: #{value}.")
         | 
| 98 | 
            +
                            false
         | 
| 99 | 
            +
                          end
         | 
| 100 | 
            +
                        else
         | 
| 101 | 
            +
                          Datadog.logger.warn("Attribute #{key} must be a string, number, or boolean: #{value}.")
         | 
| 102 | 
            +
                          false
         | 
| 103 | 
            +
                        end
         | 
| 104 | 
            +
                      when String, Numeric, TrueClass, FalseClass
         | 
| 105 | 
            +
                        validate_scalar_attribute!(key, value)
         | 
| 106 | 
            +
                      else
         | 
| 107 | 
            +
                        Datadog.logger.warn("Attribute #{key} must be a string, number, boolean, or array: #{value}.")
         | 
| 108 | 
            +
                        false
         | 
| 109 | 
            +
                      end
         | 
| 110 | 
            +
                    end
         | 
| 111 | 
            +
                  end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                  def validate_scalar_attribute!(key, value)
         | 
| 114 | 
            +
                    case value
         | 
| 115 | 
            +
                    when String, TrueClass, FalseClass
         | 
| 116 | 
            +
                      true
         | 
| 117 | 
            +
                    when Integer
         | 
| 118 | 
            +
                      # Cannot be larger than signed 64-bit integer
         | 
| 119 | 
            +
                      if value < MIN_INT64_SIGNED || value > MAX_INT64_SIGNED
         | 
| 120 | 
            +
                        Datadog.logger.warn("Attribute #{key} must be within the range of a signed 64-bit integer: #{value}.")
         | 
| 121 | 
            +
                        false
         | 
| 122 | 
            +
                      else
         | 
| 123 | 
            +
                        true
         | 
| 124 | 
            +
                      end
         | 
| 125 | 
            +
                    when Float
         | 
| 126 | 
            +
                      # Has to be finite
         | 
| 127 | 
            +
                      return true if value.finite?
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                      Datadog.logger.warn("Attribute #{key} must be a finite number: #{value}.")
         | 
| 130 | 
            +
                      false
         | 
| 131 | 
            +
                    else
         | 
| 132 | 
            +
                      Datadog.logger.warn("Attribute #{key} must be a string, number, or boolean: #{value}.")
         | 
| 133 | 
            +
                      false
         | 
| 134 | 
            +
                    end
         | 
| 135 | 
            +
                  end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  STRING_TYPE = 0
         | 
| 138 | 
            +
                  BOOLEAN_TYPE = 1
         | 
| 139 | 
            +
                  INTEGER_TYPE = 2
         | 
| 140 | 
            +
                  DOUBLE_TYPE = 3
         | 
| 141 | 
            +
                  ARRAY_TYPE = 4
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                  # Serializes individual scalar attributes into the native format.
         | 
| 144 | 
            +
                  def serialize_native_attribute(value)
         | 
| 145 | 
            +
                    case value
         | 
| 146 | 
            +
                    when String
         | 
| 147 | 
            +
                      { type: STRING_TYPE, string_value: value }
         | 
| 148 | 
            +
                    when TrueClass, FalseClass
         | 
| 149 | 
            +
                      { type: BOOLEAN_TYPE, bool_value: value }
         | 
| 150 | 
            +
                    when Integer
         | 
| 151 | 
            +
                      { type: INTEGER_TYPE, int_value: value }
         | 
| 152 | 
            +
                    when Float
         | 
| 153 | 
            +
                      { type: DOUBLE_TYPE, double_value: value }
         | 
| 154 | 
            +
                    else
         | 
| 155 | 
            +
                      # This is technically unreachable due to the validation in #initialize.
         | 
| 156 | 
            +
                      raise ArgumentError, "Attribute must be a string, number, or boolean: #{value}."
         | 
| 157 | 
            +
                    end
         | 
| 158 | 
            +
                  end
         | 
| 39 159 | 
             
                end
         | 
| 40 160 | 
             
              end
         | 
| 41 161 | 
             
            end
         | 
| @@ -11,6 +11,8 @@ require_relative 'event' | |
| 11 11 | 
             
            require_relative 'metadata'
         | 
| 12 12 | 
             
            require_relative 'metadata/ext'
         | 
| 13 13 | 
             
            require_relative 'span'
         | 
| 14 | 
            +
            require_relative 'span_event'
         | 
| 15 | 
            +
            require_relative 'span_link'
         | 
| 14 16 | 
             
            require_relative 'utils'
         | 
| 15 17 |  | 
| 16 18 | 
             
            module Datadog
         | 
| @@ -197,6 +199,9 @@ module Datadog | |
| 197 199 | 
             
                  end
         | 
| 198 200 |  | 
| 199 201 | 
             
                  # Mark the span stopped at the current time
         | 
| 202 | 
            +
                  #
         | 
| 203 | 
            +
                  # steep:ignore:start
         | 
| 204 | 
            +
                  # Steep issue fixed in https://github.com/soutaro/steep/pull/1467
         | 
| 200 205 | 
             
                  def stop(stop_time = nil)
         | 
| 201 206 | 
             
                    # A span should not be stopped twice. Note that this is not thread-safe,
         | 
| 202 207 | 
             
                    # stop is called from multiple threads, a given span might be stopped
         | 
| @@ -219,6 +224,7 @@ module Datadog | |
| 219 224 |  | 
| 220 225 | 
             
                    self
         | 
| 221 226 | 
             
                  end
         | 
| 227 | 
            +
                  # steep:ignore:end
         | 
| 222 228 |  | 
| 223 229 | 
             
                  # Return whether the duration is started or not
         | 
| 224 230 | 
             
                  def started?
         | 
| @@ -12,8 +12,11 @@ module Datadog | |
| 12 12 | 
             
                    attr_reader \
         | 
| 13 13 | 
             
                      :trace
         | 
| 14 14 |  | 
| 15 | 
            -
                     | 
| 15 | 
            +
                    # @param trace [Datadog::Trace] the trace to serialize
         | 
| 16 | 
            +
                    # @param native_events_supported [Boolean] whether the agent supports span events as a top-level field
         | 
| 17 | 
            +
                    def initialize(trace, native_events_supported = false)
         | 
| 16 18 | 
             
                      @trace = trace
         | 
| 19 | 
            +
                      @native_events_supported = native_events_supported
         | 
| 17 20 | 
             
                    end
         | 
| 18 21 |  | 
| 19 22 | 
             
                    # MessagePack serializer interface. Making this object
         | 
| @@ -26,13 +29,13 @@ module Datadog | |
| 26 29 | 
             
                    # @param packer [MessagePack::Packer] serialization buffer, can be +nil+ with JRuby
         | 
| 27 30 | 
             
                    def to_msgpack(packer = nil)
         | 
| 28 31 | 
             
                      # As of 1.3.3, JRuby implementation doesn't pass an existing packer
         | 
| 29 | 
            -
                      trace.spans.map { |s| SerializableSpan.new(s) }.to_msgpack(packer)
         | 
| 32 | 
            +
                      trace.spans.map { |s| SerializableSpan.new(s, @native_events_supported) }.to_msgpack(packer)
         | 
| 30 33 | 
             
                    end
         | 
| 31 34 |  | 
| 32 35 | 
             
                    # JSON serializer interface.
         | 
| 33 36 | 
             
                    # Used by older version of the transport.
         | 
| 34 37 | 
             
                    def to_json(*args)
         | 
| 35 | 
            -
                      trace.spans.map { |s| SerializableSpan.new(s).to_hash }.to_json(*args)
         | 
| 38 | 
            +
                      trace.spans.map { |s| SerializableSpan.new(s, @native_events_supported).to_hash }.to_json(*args)
         | 
| 36 39 | 
             
                    end
         | 
| 37 40 | 
             
                  end
         | 
| 38 41 |  | 
| @@ -41,9 +44,12 @@ module Datadog | |
| 41 44 | 
             
                    attr_reader \
         | 
| 42 45 | 
             
                      :span
         | 
| 43 46 |  | 
| 44 | 
            -
                     | 
| 47 | 
            +
                    # @param span [Datadog::Span] the span to serialize
         | 
| 48 | 
            +
                    # @param native_events_supported [Boolean] whether the agent supports span events as a top-level field
         | 
| 49 | 
            +
                    def initialize(span, native_events_supported)
         | 
| 45 50 | 
             
                      @span = span
         | 
| 46 51 | 
             
                      @trace_id = Tracing::Utils::TraceId.to_low_order(span.trace_id)
         | 
| 52 | 
            +
                      @native_events_supported = native_events_supported
         | 
| 47 53 | 
             
                    end
         | 
| 48 54 |  | 
| 49 55 | 
             
                    # MessagePack serializer interface. Making this object
         | 
| @@ -55,11 +61,14 @@ module Datadog | |
| 55 61 | 
             
                    #
         | 
| 56 62 | 
             
                    # @param packer [MessagePack::Packer] serialization buffer, can be +nil+ with JRuby
         | 
| 57 63 | 
             
                    # rubocop:disable Metrics/AbcSize
         | 
| 64 | 
            +
                    # rubocop:disable Metrics/MethodLength
         | 
| 58 65 | 
             
                    def to_msgpack(packer = nil)
         | 
| 59 66 | 
             
                      packer ||= MessagePack::Packer.new
         | 
| 60 67 |  | 
| 61 68 | 
             
                      number_of_elements_to_write = 11
         | 
| 62 69 |  | 
| 70 | 
            +
                      number_of_elements_to_write += 1 if span.events.any? && @native_events_supported
         | 
| 71 | 
            +
             | 
| 63 72 | 
             
                      if span.stopped?
         | 
| 64 73 | 
             
                        packer.write_map_header(number_of_elements_to_write + 2) # Set header with how many elements in the map
         | 
| 65 74 |  | 
| @@ -72,8 +81,16 @@ module Datadog | |
| 72 81 | 
             
                        packer.write_map_header(number_of_elements_to_write) # Set header with how many elements in the map
         | 
| 73 82 | 
             
                      end
         | 
| 74 83 |  | 
| 75 | 
            -
                       | 
| 76 | 
            -
             | 
| 84 | 
            +
                      if span.events.any?
         | 
| 85 | 
            +
                        if @native_events_supported
         | 
| 86 | 
            +
                          # Use top-level field for native events
         | 
| 87 | 
            +
                          packer.write('span_events')
         | 
| 88 | 
            +
                          packer.write(span.events.map(&:to_native_format))
         | 
| 89 | 
            +
                        else
         | 
| 90 | 
            +
                          # Serialize span events as meta tags
         | 
| 91 | 
            +
                          span.set_tag('events', span.events.map(&:to_hash).to_json)
         | 
| 92 | 
            +
                        end
         | 
| 93 | 
            +
                      end
         | 
| 77 94 |  | 
| 78 95 | 
             
                      # DEV: We use strings as keys here, instead of symbols, as
         | 
| 79 96 | 
             
                      # DEV: MessagePack will ultimately convert them to strings.
         | 
| @@ -103,6 +120,7 @@ module Datadog | |
| 103 120 | 
             
                      packer
         | 
| 104 121 | 
             
                    end
         | 
| 105 122 | 
             
                    # rubocop:enable Metrics/AbcSize
         | 
| 123 | 
            +
                    # rubocop:enable Metrics/MethodLength
         | 
| 106 124 |  | 
| 107 125 | 
             
                    # JSON serializer interface.
         | 
| 108 126 | 
             
                    # Used by older version of the transport.
         |