forked from httprb/http
/
instrumentation.rb
64 lines (56 loc) · 1.95 KB
/
instrumentation.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# frozen_string_literal: true
module HTTP
module Features
# Instrument requests and responses. Expects an
# ActiveSupport::Notifications-compatible instrumenter. Defaults to use a
# namespace of 'http' which may be overridden with a `:namespace` param.
# Emits a single event like `"request.{namespace}"`, eg `"request.http"`.
# Be sure to specify the instrumenter when enabling the feature:
#
# HTTP
# .use(instrumentation: {instrumenter: ActiveSupport::Notifications.instrumenter})
# .get("https://example.com/")
#
# Emits two events on every request:
#
# * `start_request.http` before the request is made, so you can log the reqest being started
# * `request.http` after the response is recieved, and contains `start`
# and `finish` so the duration of the request can be calculated.
#
class Instrumentation < Feature
attr_reader :instrumenter, :name
def initialize(instrumenter: NullInstrumenter.new, namespace: "http")
@instrumenter = instrumenter
@name = "request.#{namespace}"
end
def wrap_request(request)
# Emit a separate "start" event, so a logger can print the request
# being run without waiting for a response
instrumenter.instrument("start_#{name}", :request => request) {}
instrumenter.start(name, :request => request)
request
end
def wrap_response(response)
instrumenter.finish(name, :response => response)
response
end
HTTP::Options.register_feature(:instrumentation, self)
class NullInstrumenter
def instrument(name, payload = {})
start(name, payload)
begin
yield payload if block_given?
ensure
finish name, payload
end
end
def start(_name, _payload)
true
end
def finish(_name, _payload)
true
end
end
end
end
end