Module: Datadog::Contrib::HTTP::Patcher

Defined in:
lib/ddtrace/contrib/http/patcher.rb

Overview

Patcher enables patching of ‘net/http’ module. This is used in monkey.rb to automatically apply patches

Class Method Summary collapse

Class Method Details

.patchObject

patch applies our patch if needed



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ddtrace/contrib/http/patcher.rb', line 48

def patch
  unless @patched
    begin
      require 'uri'
      require 'ddtrace/pin'
      require 'ddtrace/monkey'
      require 'ddtrace/ext/app_types'
      require 'ddtrace/ext/http'
      require 'ddtrace/ext/net'

      patch_http()

      @patched = true
    rescue StandardError => e
      Datadog::Tracer.log.error("Unable to apply net/http integration: #{e}")
    end
  end
  @patched
end

.patch_httpObject

rubocop:disable Metrics/MethodLength



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/ddtrace/contrib/http/patcher.rb', line 74

def patch_http
  ::Net::HTTP.class_eval do
    alias_method :initialize_without_datadog, :initialize
    Datadog::Monkey.without_warnings do
      remove_method :initialize
    end

    def initialize(*args)
      pin = Datadog::Pin.new(SERVICE, app: APP, app_type: Datadog::Ext::AppTypes::WEB)
      pin.onto(self)
      initialize_without_datadog(*args)
    end

    alias_method :request_without_datadog, :request
    remove_method :request
    def request(req, body = nil, &block) # :yield: +response+
      pin = Datadog::Pin.get_from(self)
      return request_without_datadog(req, body, &block) unless pin && pin.tracer

      transport = pin.tracer.writer.transport
      return request_without_datadog(req, body, &block) if
        Datadog::Contrib::HTTP.should_skip_tracing?(req, @address, @port, transport, pin)

      pin.tracer.trace(NAME) do |span|
        span.service = pin.service
        span.span_type = Datadog::Ext::HTTP::TYPE

        span.resource = req.path
        # *NOT* filling Datadog::Ext::HTTP::URL as it's already in resource.
        # The agent can then decide to quantize the URL and store the original,
        # untouched data in http.url but the client should not send redundant fields.
        span.set_tag(Datadog::Ext::HTTP::METHOD, req.method)
        response = request_without_datadog(req, body, &block)
        span.set_tag(Datadog::Ext::HTTP::STATUS_CODE, response.code)
        if req.uri
          span.set_tag(Datadog::Ext::NET::TARGET_HOST, req.uri.host)
          span.set_tag(Datadog::Ext::NET::TARGET_PORT, req.uri.port.to_s)
        else
          span.set_tag(Datadog::Ext::NET::TARGET_HOST, @address)
          span.set_tag(Datadog::Ext::NET::TARGET_PORT, @port.to_s)
        end

        case response.code.to_i / 100
        when 4
          span.set_error(response)
        when 5
          span.set_error(response)
        end

        response
      end
    end
  end
end

.patched?Boolean

patched? tells wether patch has been successfully applied

Returns:



69
70
71
# File 'lib/ddtrace/contrib/http/patcher.rb', line 69

def patched?
  @patched
end