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)

    If a block is given, then the return value of the block. Otherwise the current client name.



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

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

.force_prepend?Boolean

Returns true if instrumentation should always use module prepend rather than method aliasing. The default is to use method aliasing since that is more compatible with other libraries. Prepending can be forced by setting the HTTP_INSTRUMENTATION_FORCE_PREPEND environment variable to “true”.

Returns:

  • (Boolean)


130
131
132
# File 'lib/http_instrumentation.rb', line 130

def force_prepend?
  ENV.fetch("HTTP_INSTRUMENTATION_FORCE_PREPEND", nil) == "true"
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



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

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)


82
83
84
# File 'lib/http_instrumentation.rb', line 82

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