http_event_logger 0.1.0.rc1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/lib/http_event_logger/adapter/ethon.rb +56 -0
- data/lib/http_event_logger/adapter/excon.rb +64 -0
- data/lib/http_event_logger/adapter/httpclient.rb +60 -0
- data/lib/http_event_logger/adapter/net_http.rb +65 -0
- data/lib/http_event_logger/adapter/patron.rb +40 -0
- data/lib/http_event_logger/configuration.rb +9 -0
- data/lib/http_event_logger/event/connection.rb +21 -0
- data/lib/http_event_logger/event/headers.rb +21 -0
- data/lib/http_event_logger/event/observer.rb +13 -0
- data/lib/http_event_logger/event/request.rb +24 -0
- data/lib/http_event_logger/event/response.rb +47 -0
- data/lib/http_event_logger/logger.rb +47 -0
- data/lib/http_event_logger/version.rb +3 -0
- data/lib/http_event_logger.rb +43 -0
- data/spec/http_event_logger_integration_spec.rb +151 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/custom_logger.rb +25 -0
- data/spec/support/driver/base.rb +48 -0
- data/spec/support/driver/ethon.rb +29 -0
- data/spec/support/driver/excon.rb +21 -0
- data/spec/support/driver/faraday.rb +36 -0
- data/spec/support/driver/httparty.rb +21 -0
- data/spec/support/driver/httpclient.rb +29 -0
- data/spec/support/driver/net_http.rb +24 -0
- data/spec/support/driver/open_uri.rb +19 -0
- data/spec/support/driver/patron.rb +27 -0
- data/spec/support/driver/typhoeus.rb +34 -0
- data/spec/support/index.html +8 -0
- data/spec/support/server.rb +28 -0
- metadata +299 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d1c6e13a02bf58df078b6db91d89d34e04a3ab46
|
4
|
+
data.tar.gz: 8743f10e8bc7672991d0447cf8dad126d84d7e7f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5827ef887a7b2a13a9d9d29a684eb1b75963047ed30c7a4c9717c5346a2268ad94521dd363f8c57b84311306242e52d4e732f091f0aa9882ea0fccfeea9f169c
|
7
|
+
data.tar.gz: 27e747db5d476fbc7fc9db0adf5a759ca1ea5d750c4b70ddf8219a60956b7bf8bea9cdda18aeabbd0c0cc3bc9f1f95f3d0fd8ebc56021954dfcf966512809079
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2011 Thilo Rusche
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Ethon
|
2
|
+
|
3
|
+
class Easy
|
4
|
+
|
5
|
+
module Http
|
6
|
+
|
7
|
+
def http_request_with_logging(url, action_name, options={})
|
8
|
+
create_request_event(url, action_name, options)
|
9
|
+
http_request_without_logging(url, action_name, options)
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method_chain :http_request, :logging
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def create_request_event(url, action_name, options)
|
17
|
+
@request_event = HttpEventLogger::Event::Request.new(
|
18
|
+
method: action_name,
|
19
|
+
uri: url,
|
20
|
+
headers: options[:headers],
|
21
|
+
body: options[:body]
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
module Operations
|
28
|
+
|
29
|
+
def perform_with_logging
|
30
|
+
result = nil
|
31
|
+
time_taken_in_seconds = ::Benchmark.realtime do
|
32
|
+
result = perform_without_logging
|
33
|
+
end
|
34
|
+
create_response_event(time_taken_in_seconds)
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
alias_method_chain :perform, :logging
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def create_response_event(time_taken_in_seconds)
|
43
|
+
HttpEventLogger::Event::Response.new(
|
44
|
+
request: @request_event,
|
45
|
+
time_taken_in_seconds: time_taken_in_seconds,
|
46
|
+
status: response_code,
|
47
|
+
headers: response_headers,
|
48
|
+
body: response_body
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end if defined?(Ethon)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Excon
|
2
|
+
|
3
|
+
class Socket
|
4
|
+
|
5
|
+
def connect_with_logging
|
6
|
+
host = @data[:proxy] ? @data[:proxy][:host] : @data[:host]
|
7
|
+
port = @data[:proxy] ? @data[:proxy][:port] : @data[:port]
|
8
|
+
HttpEventLogger::Event::Connection.new(host, port)
|
9
|
+
connect_without_logging
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method_chain :connect, :logging
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
class Connection
|
17
|
+
|
18
|
+
def request_with_logging(params, &block)
|
19
|
+
request_datum = @data.merge(params)
|
20
|
+
request_datum[:headers] = @data[:headers].merge(request_datum[:headers] || {})
|
21
|
+
request_event = create_request_event(request_datum)
|
22
|
+
result = nil
|
23
|
+
time_taken_in_seconds = ::Benchmark.realtime do
|
24
|
+
result = request_without_logging(params, &block)
|
25
|
+
end
|
26
|
+
response = result.is_a?(Excon::Response) ? result : Excon::Response.new(response(result)[:response])
|
27
|
+
create_response_event(request_event, time_taken_in_seconds, response)
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method_chain :request, :logging
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def create_request_event(datum)
|
36
|
+
HttpEventLogger::Event::Request.new(
|
37
|
+
method: method_from(datum),
|
38
|
+
uri: absolute_url_from(datum),
|
39
|
+
headers: datum[:headers],
|
40
|
+
body: datum[:body]
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def method_from(datum)
|
45
|
+
datum[:method] ? datum[:method].to_s.upcase : "UNKNOWN"
|
46
|
+
end
|
47
|
+
|
48
|
+
def absolute_url_from(datum)
|
49
|
+
"#{datum[:scheme]}://#{datum[:host]}:#{datum[:port]}#{datum[:path]}#{datum[:query]}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_response_event(request_event, time_taken_in_seconds, response)
|
53
|
+
HttpEventLogger::Event::Response.new(
|
54
|
+
request: request_event,
|
55
|
+
time_taken_in_seconds: time_taken_in_seconds,
|
56
|
+
status: response.status,
|
57
|
+
headers: response.headers,
|
58
|
+
body: response.body
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end if defined?(Excon)
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class HTTPClient
|
2
|
+
|
3
|
+
private
|
4
|
+
|
5
|
+
class Session
|
6
|
+
|
7
|
+
def create_socket_with_logging(site)
|
8
|
+
HttpEventLogger::Event::Connection.new(site.host, site.port)
|
9
|
+
create_socket_without_logging(site)
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method_chain :create_socket, :logging
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
def do_get_block_with_logging(req, proxy, conn, &block)
|
17
|
+
request_event = create_request_event(req)
|
18
|
+
retryable_response_error = nil
|
19
|
+
time_taken_in_seconds = ::Benchmark.realtime do
|
20
|
+
begin
|
21
|
+
do_get_block_without_logging(req, proxy, conn, &block)
|
22
|
+
rescue RetryableResponse => exc
|
23
|
+
retryable_response_error = exc
|
24
|
+
end
|
25
|
+
end
|
26
|
+
res = conn.pop
|
27
|
+
create_response_event(request_event, res, time_taken_in_seconds)
|
28
|
+
conn.push(res)
|
29
|
+
raise retryable_response_error unless retryable_response_error.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method_chain :do_get_block, :logging
|
33
|
+
|
34
|
+
def create_request_event(req)
|
35
|
+
HttpEventLogger::Event::Request.new(
|
36
|
+
method: req.header.request_method,
|
37
|
+
uri: req.header.request_uri,
|
38
|
+
headers: req.headers,
|
39
|
+
body: req.body
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_response_event(request_event, res, time_taken_in_seconds)
|
44
|
+
HttpEventLogger::Event::Response.new(
|
45
|
+
request: request_event,
|
46
|
+
time_taken_in_seconds: time_taken_in_seconds,
|
47
|
+
status: res.status_code,
|
48
|
+
headers: response_headers_from(res),
|
49
|
+
body: res.body
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
def response_headers_from(res)
|
54
|
+
res.header.all.reduce({}) do |result, header|
|
55
|
+
result[header[0]] = header[1]
|
56
|
+
result
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end if defined?(::HTTPClient)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Net
|
2
|
+
|
3
|
+
class HTTP
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
HIDDEN_PORTS = [ 80, 443 ].freeze
|
8
|
+
|
9
|
+
public
|
10
|
+
|
11
|
+
def connect_with_logging
|
12
|
+
HttpEventLogger::Event::Connection.new(@address, @port) unless started?
|
13
|
+
connect_without_logging
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method_chain :connect, :logging
|
17
|
+
|
18
|
+
def request_with_logging(req, body = nil, &block)
|
19
|
+
create_request_event(req, body) if started?
|
20
|
+
response = nil
|
21
|
+
time_taken_in_seconds = ::Benchmark.realtime do
|
22
|
+
response = request_without_logging(req, body, &block)
|
23
|
+
end
|
24
|
+
create_response_event(time_taken_in_seconds, response) if started?
|
25
|
+
response
|
26
|
+
end
|
27
|
+
|
28
|
+
alias_method_chain :request, :logging
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def create_request_event(req, body)
|
33
|
+
@request_event = HttpEventLogger::Event::Request.new(
|
34
|
+
method: req.method,
|
35
|
+
uri: absolute_url_from(req),
|
36
|
+
headers: req.each_header.collect,
|
37
|
+
body: request_body_from(req, body)
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def absolute_url_from(req)
|
42
|
+
protocol = @use_ssl ? "https" : "http"
|
43
|
+
port_indicator = HIDDEN_PORTS.include?(@port) ? "" : ":#{@port}"
|
44
|
+
hostname = "#{@address}#{port_indicator}"
|
45
|
+
"#{protocol}://#{hostname}#{req.path}"
|
46
|
+
end
|
47
|
+
|
48
|
+
# A bit convoluted because post_form uses form_data= to assign the data, so in that case req.body will be empty
|
49
|
+
def request_body_from(req, body)
|
50
|
+
req.body.nil? || req.body.size == 0 ? body : req.body
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_response_event(time_taken_in_seconds, response)
|
54
|
+
HttpEventLogger::Event::Response.new(
|
55
|
+
request: @request_event,
|
56
|
+
time_taken_in_seconds: time_taken_in_seconds,
|
57
|
+
status: response.code,
|
58
|
+
headers: response.each_header.collect,
|
59
|
+
body: response.body
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Patron
|
2
|
+
|
3
|
+
class Session
|
4
|
+
|
5
|
+
def request_with_logging(action_name, url, headers, options={})
|
6
|
+
create_request_event(action_name, headers, options, url)
|
7
|
+
response = nil
|
8
|
+
time_taken_in_seconds = ::Benchmark.realtime do
|
9
|
+
response = request_without_logging(action_name, url, headers, options)
|
10
|
+
end
|
11
|
+
create_response_event(response, time_taken_in_seconds)
|
12
|
+
response
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method_chain :request, :logging
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def create_response_event(response, time_taken_in_seconds)
|
20
|
+
HttpEventLogger::Event::Response.new(
|
21
|
+
request: @request_event,
|
22
|
+
time_taken_in_seconds: time_taken_in_seconds,
|
23
|
+
status: response.status,
|
24
|
+
headers: response.headers,
|
25
|
+
body: response.body
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_request_event(action_name, headers, options, url)
|
30
|
+
@request_event = HttpEventLogger::Event::Request.new(
|
31
|
+
method: action_name,
|
32
|
+
uri: url,
|
33
|
+
headers: headers,
|
34
|
+
body: options[:data]
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end if defined?(Patron)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module HttpEventLogger
|
2
|
+
module Event
|
3
|
+
|
4
|
+
class Connection
|
5
|
+
|
6
|
+
attr_reader :host, :port
|
7
|
+
|
8
|
+
def initialize(host, port)
|
9
|
+
@host = host
|
10
|
+
@port = port ? port.to_s : nil
|
11
|
+
HttpEventLogger::Event::Observer.observe(:connected, self)
|
12
|
+
end
|
13
|
+
|
14
|
+
def uri
|
15
|
+
@port.present? ? "#{@host}:#{@port}" : @host
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module HttpEventLogger
|
2
|
+
module Event
|
3
|
+
|
4
|
+
class Headers
|
5
|
+
|
6
|
+
def initialize(headers)
|
7
|
+
@headers = headers || ""
|
8
|
+
end
|
9
|
+
|
10
|
+
def [](name)
|
11
|
+
@headers.is_a?(Hash) ? @headers[name] : nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
@headers.is_a?(String) ? @headers : @headers.map { |key, value| "#{key}: #{value}" }.join(", ")
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module HttpEventLogger
|
2
|
+
module Event
|
3
|
+
|
4
|
+
class Request
|
5
|
+
|
6
|
+
attr_reader :method, :uri, :headers, :body
|
7
|
+
|
8
|
+
def initialize(args)
|
9
|
+
@method = args[:method].to_s.upcase
|
10
|
+
@uri = args[:uri].to_s
|
11
|
+
@headers = HttpEventLogger::Event::Headers.new(args[:headers])
|
12
|
+
@body = args[:body]
|
13
|
+
HttpEventLogger::Event::Observer.observe(:sent, self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def base_uri
|
17
|
+
matcher = @uri.match(/\/\/([^\/\?]*)/)
|
18
|
+
matcher ? matcher[1] : ""
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module HttpEventLogger
|
2
|
+
module Event
|
3
|
+
|
4
|
+
class Response
|
5
|
+
|
6
|
+
attr_reader :request, :time_taken_in_seconds, :status, :headers
|
7
|
+
|
8
|
+
delegate :base_uri, :uri, to: :request
|
9
|
+
|
10
|
+
def initialize(args)
|
11
|
+
@request = args[:request]
|
12
|
+
@time_taken_in_seconds = args[:time_taken_in_seconds]
|
13
|
+
@status = args[:status].to_s
|
14
|
+
@headers = HttpEventLogger::Event::Headers.new(args[:headers])
|
15
|
+
@raw_body = args[:body]
|
16
|
+
HttpEventLogger::Event::Observer.observe(:received, self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def body_with_formatting
|
20
|
+
body.include?("\n") ? "\n#{body}" : body
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def body
|
26
|
+
if body_read_deferred?
|
27
|
+
"[not available]"
|
28
|
+
elsif body_gzip_encoded?
|
29
|
+
Zlib::GzipReader.new(StringIO.new(@raw_body.to_s)).read
|
30
|
+
else
|
31
|
+
@raw_body.to_s
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# open-uri wraps the response in a Net::ReadAdapter, so the response body is not available yet
|
36
|
+
def body_read_deferred?
|
37
|
+
@raw_body.is_a?(Net::ReadAdapter)
|
38
|
+
end
|
39
|
+
|
40
|
+
def body_gzip_encoded?
|
41
|
+
@headers["Content-Encoding"] =~ /gzip/
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module HttpEventLogger
|
2
|
+
|
3
|
+
class Logger
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
DEFAULT_LOGGER = ::Logger.new($stdout).freeze
|
8
|
+
DEFAULT_SEVERITY = ::Logger::Severity::DEBUG.freeze
|
9
|
+
|
10
|
+
public
|
11
|
+
|
12
|
+
def initialize(options={})
|
13
|
+
@logger = options[:logger] || DEFAULT_LOGGER
|
14
|
+
@severity = options[:severity] || DEFAULT_SEVERITY
|
15
|
+
@blacklist_pattern = options[:blacklist_pattern] || nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def logs?(uri)
|
19
|
+
@blacklist_pattern.nil? || @blacklist_pattern !~ uri
|
20
|
+
end
|
21
|
+
|
22
|
+
def connected(connection)
|
23
|
+
log "[#{connection.uri}] Connected"
|
24
|
+
end
|
25
|
+
|
26
|
+
def sent(request)
|
27
|
+
log "[#{request.base_uri}] Sent - #{request.method} #{request.uri}"
|
28
|
+
log "[#{request.base_uri}] Sent - Headers: #{request.headers}"
|
29
|
+
log "[#{request.base_uri}] Sent - Body: #{request.body}" if request.body.present?
|
30
|
+
end
|
31
|
+
|
32
|
+
def received(response)
|
33
|
+
log "[#{response.base_uri}] Benchmark: #{response.time_taken_in_seconds} seconds"
|
34
|
+
log "[#{response.base_uri}] Received - Status: #{response.status}"
|
35
|
+
log "[#{response.base_uri}] Received - Headers: #{response.headers}"
|
36
|
+
log "[#{response.base_uri}] Received - Body:#{response.body_with_formatting}"
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def log(message)
|
42
|
+
@logger.add(@severity) { message }
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'logger'
|
3
|
+
require 'benchmark'
|
4
|
+
|
5
|
+
require 'active_support/core_ext/object/blank'
|
6
|
+
require 'active_support/core_ext/module/aliasing'
|
7
|
+
require 'active_support/core_ext/module/delegation'
|
8
|
+
require 'active_support/core_ext/string/inflections'
|
9
|
+
|
10
|
+
require_relative 'http_event_logger/configuration'
|
11
|
+
require_relative 'http_event_logger/event/connection'
|
12
|
+
require_relative 'http_event_logger/event/headers'
|
13
|
+
require_relative 'http_event_logger/event/request'
|
14
|
+
require_relative 'http_event_logger/event/response'
|
15
|
+
require_relative 'http_event_logger/logger'
|
16
|
+
require_relative 'http_event_logger/event/observer'
|
17
|
+
require_relative 'http_event_logger/adapter/net_http'
|
18
|
+
require_relative 'http_event_logger/adapter/httpclient'
|
19
|
+
require_relative 'http_event_logger/adapter/excon'
|
20
|
+
require_relative 'http_event_logger/adapter/ethon'
|
21
|
+
require_relative 'http_event_logger/adapter/patron'
|
22
|
+
|
23
|
+
module HttpEventLogger
|
24
|
+
|
25
|
+
class << self
|
26
|
+
|
27
|
+
attr_reader :configuration
|
28
|
+
|
29
|
+
def configure(&block)
|
30
|
+
@configuration = HttpEventLogger::Configuration.new
|
31
|
+
block.call @configuration
|
32
|
+
end
|
33
|
+
|
34
|
+
def logger
|
35
|
+
@configuration.logger
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
# Establish default configuration
|
43
|
+
HttpEventLogger.configure { |config| config.logger = HttpEventLogger::Logger.new }
|