Module: HTTPInstrumentation

Defined in:
lib/http_instrumentation.rb,
lib/http_instrumentation/instrumentation.rb,
lib/http_instrumentation/instrumentation/curb_hook.rb,
lib/http_instrumentation/instrumentation/http_hook.rb,
lib/http_instrumentation/instrumentation/ethon_hook.rb,
lib/http_instrumentation/instrumentation/excon_hook.rb,
lib/http_instrumentation/instrumentation/httpx_hook.rb,
lib/http_instrumentation/instrumentation/patron_hook.rb,
lib/http_instrumentation/instrumentation/net_http_hook.rb,
lib/http_instrumentation/instrumentation/typhoeus_hook.rb,
lib/http_instrumentation/instrumentation/httpclient_hook.rb

Defined Under Namespace

Modules: Instrumentation

Constant Summary collapse

IMPLEMENTATIONS =
[
  :curb,
  :ethon,
  :excon,
  :http,
  :httpclient,
  :httpx,
  :net_http,
  :net_http2,
  :patron,
  :typhoeus
].freeze
EVENT =
"request.http"

Class Method Summary collapse

Class Method Details

.client(name = nil) ⇒ String, ...

If a block is given, then set the HTTP client name for the duration of the block. If no block is given, then return the current HTTP client name.

Parameters:

  • name (String, Symbol, nil) (defaults to: nil)

    The name of the client to set

Returns:

  • (String, Symbol, nil)

    The current name of the client



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/http_instrumentation.rb', line 64

def client(name = nil)
  save_val = Thread.current[:http_instrumentation_client]
  if block_given?
    begin
      Thread.current[:http_instrumentation_client] = name
      yield
    ensure
      Thread.current[:http_instrumentation_client] = save_val
    end
  end
  save_val
end

.initialize!(only: nil, except: nil) ⇒ void

This method returns an undefined value.

Add instrumentation into HTTP client libraries. By default all supported libraries are instrumented. You can pass the only or except options to limit the instrumentation to a subset of libraries.

Parameters:

  • only (Array<Symbol>) (defaults to: nil)

    List of libraries to instrument.

  • except (Array<Symbol>) (defaults to: nil)

    List of libraries to not instrument.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/http_instrumentation.rb', line 31

def initialize!(only: nil, except: nil)
  list = (only || IMPLEMENTATIONS)
  list &= Array(except) if except

  Instrumentation::CurbHook.instrument! if list.include?(:curb)
  Instrumentation::EthonHook.instrument! if list.include?(:ethon)
  Instrumentation::ExconHook.instrument! if list.include?(:excon)
  Instrumentation::HTTPHook.instrument! if list.include?(:http)
  Instrumentation::HTTPClientHook.instrument! if list.include?(:httpclient)
  Instrumentation::HTTPXHook.instrument! if list.include?(:httpx)
  Instrumentation::NetHTTPHook.instrument! if list.include?(:net_http)
  Instrumentation::PatronHook.instrument! if list.include?(:patron)
  Instrumentation::TyphoeusHook.instrument! if list.include?(:typhoeus)
end

.instrument(client, &block) ⇒ Object

Instrument the given block with the given client name. An ActiveSupport event will be fired with the following payload:

  • :client - The name of the client as a string.

  • :http_method - The HTTP method as a lowercase symbol.

  • :url - The URL as a string.

  • :uri - The URL as a URI object.

  • :status_code - The HTTP status code as an integer.

  • :count - The number of requests made as an integer.

Parameters:

  • client (String, Symbol)

    The name of the client.

Returns:

  • (Object)

    the return value of the block



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
# File 'lib/http_instrumentation.rb', line 96

def instrument(client, &block)
  payload = {client: (self.client || client).to_s}

  return yield(payload) if silenced?

  ActiveSupport::Notifications.instrument(EVENT, payload) do
    retval = silence { yield(payload) }

    payload[:http_method] = normalize_http_method(payload[:http_method]) if payload.include?(:http_method)

    if payload.include?(:url)
      uri = sanitized_uri(payload[:url])
      if uri
        payload[:url] = uri_without_query_string(uri)
        payload[:uri] = uri
      else
        payload[:url] = payload[:url]&.to_s
      end
    end

    payload[:status_code] = payload[:status_code]&.to_i if payload.include?(:status_code)

    payload[:count] = (payload.include?(:count) ? payload[:count].to_i : 1)

    retval
  end
end

.silence(&block) ⇒ Object

Silence instrumentation for the duration of the block.

Returns:

  • (Object)

    the return value of the block



49
50
51
52
53
54
55
56
57
# File 'lib/http_instrumentation.rb', line 49

def silence(&block)
  save_val = Thread.current[:http_instrumentation_silence]
  begin
    Thread.current[:http_instrumentation_silence] = true
    yield
  ensure
    Thread.current[:http_instrumentation_silence] = save_val
  end
end

.silenced?Boolean

Returns true if instrumentation is currently silenced.

Returns:

  • (Boolean)


80
81
82
# File 'lib/http_instrumentation.rb', line 80

def silenced?
  !!Thread.current[:http_instrumentation_silence]
end