rest-client-jogger 0.3.5 → 1.0.0
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 +4 -4
- data/.travis.yml +1 -0
- data/README.md +14 -0
- data/lib/rest_client/core_ext/logged_request.rb +19 -37
- data/lib/rest_client/jogger/action.rb +59 -0
- data/lib/rest_client/jogger/configuration.rb +34 -0
- data/lib/rest_client/jogger/event_subscriber.rb +8 -4
- data/lib/rest_client/jogger/filters/base.rb +7 -4
- data/lib/rest_client/jogger/request.rb +9 -0
- data/lib/rest_client/jogger/response.rb +9 -0
- data/lib/rest_client/jogger/version.rb +1 -1
- data/lib/rest_client/jogger.rb +34 -11
- data/lib/rest_client/templates/request_logging_template.json.jbuilder +14 -0
- data/lib/rest_client/templates/response_logging_template.json.jbuilder +18 -0
- data/rest-client-jogger-0.3.4.gem +0 -0
- data/rest-client-jogger.gemspec +3 -0
- metadata +52 -4
- data/lib/rest_client/jogger/request_complete.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b29dc3193cd558f466136f495d7ea42a94d0953
|
4
|
+
data.tar.gz: 43728ec66a9b0793099dd2bbd62929be94f9f477
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91ebfb31dd64d8a640cc74411d5b80034ab923b21bc5de164df4c0d75a9c3556f4dc241b8b1c115e3eb1171b9fde1226acff6cf016bdd58b9e92ec8ccc7ea357
|
7
|
+
data.tar.gz: 3058eb900be88211bd950a75bf91fec49bd22af6cf3fa815a370601fc90293f0a633191e765149e84fa4228d31e9d94955dfa658129396d98a732bf1c317a1ff
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -35,6 +35,20 @@ RestClient::Jogger::EventSubscriber.new.subscribe
|
|
35
35
|
|
36
36
|
This will log all requests made with the `logged_request` method to a logfile in `log/rest_client.log`.
|
37
37
|
|
38
|
+
## Configuration
|
39
|
+
|
40
|
+
Some of the parameters used in this gem can be configured in the host application:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
# in an initializer somewhere
|
44
|
+
RestClient::Jogger.configure do |config|
|
45
|
+
config.request_pattern = 'my.request' # optional
|
46
|
+
config.response_pattern = 'my.response' # optional
|
47
|
+
config.default_content_type = 'application/json' # optional
|
48
|
+
config.default_filter_replacement = '[SECRET]' # optional
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
38
52
|
## Development
|
39
53
|
|
40
54
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -1,60 +1,42 @@
|
|
1
1
|
module LoggedRequest
|
2
|
-
PATTERN = 'rest_client.request'.freeze
|
3
|
-
DEFAULT_CONTENT_TYPE = 'application/json'.freeze
|
4
|
-
|
5
2
|
def logged_request(opts = {}, &block)
|
6
3
|
# We intend on using the following variables in this method's
|
7
4
|
# ensure block. This means that we must take care to ensure
|
8
5
|
# that we check for nil against these variables whenever they
|
9
6
|
# are accessed.
|
10
|
-
response, exception = nil, nil
|
11
7
|
started = Time.now
|
8
|
+
log_request(opts, started)
|
9
|
+
response, exception = nil, nil
|
12
10
|
response = execute(opts, &block)
|
13
11
|
rescue StandardError => ex
|
14
12
|
exception = ex.class.to_s
|
15
|
-
response = ex.respond_to?(:response)
|
13
|
+
response = ex.respond_to?(:response) ? ex.response : nil
|
16
14
|
raise ex # Re-raise the exception, we just wanted to capture it
|
17
15
|
ensure
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
ActiveSupport::Notifications.instrument PATTERN,
|
24
|
-
log_data(params, response, exception, time)
|
16
|
+
logged_response = opts.merge(exception: exception, response: response)
|
17
|
+
ActiveSupport::Notifications.instrument(
|
18
|
+
RestClient::Jogger.response_pattern,
|
19
|
+
log_payload(logged_response, started)
|
20
|
+
)
|
25
21
|
end
|
26
22
|
|
27
23
|
private
|
28
24
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
time_elapsed: time
|
25
|
+
def log_payload(params, started)
|
26
|
+
params.merge(
|
27
|
+
headers: filtered_headers(params),
|
28
|
+
start_time: started
|
34
29
|
)
|
35
30
|
end
|
36
31
|
|
37
|
-
def
|
38
|
-
|
39
|
-
{
|
40
|
-
code: response.code,
|
41
|
-
headers: response.headers.reject { |k, _| k.to_s.casecmp('authorization').zero? },
|
42
|
-
body: response.body.to_s.force_encoding('UTF-8')
|
43
|
-
}
|
44
|
-
end
|
32
|
+
def filtered_headers(opts)
|
33
|
+
opts.fetch(:headers, {}).reject { |k, _| k.to_s.casecmp('authorization').zero? }
|
45
34
|
end
|
46
35
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
def filter(content_type)
|
54
|
-
RestClient::Jogger::Filters::Base.filter_class(content_type)
|
55
|
-
end
|
56
|
-
|
57
|
-
def content_type_from_headers(headers)
|
58
|
-
(headers && headers[:content_type]) || DEFAULT_CONTENT_TYPE
|
36
|
+
def log_request(opts, started)
|
37
|
+
ActiveSupport::Notifications.instrument(
|
38
|
+
RestClient::Jogger.request_pattern,
|
39
|
+
log_payload(opts, started)
|
40
|
+
)
|
59
41
|
end
|
60
42
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module RestClient
|
2
|
+
module Jogger
|
3
|
+
class Action
|
4
|
+
include ActiveModel::Model
|
5
|
+
attr_accessor :logger, :notifier
|
6
|
+
|
7
|
+
def initialize(args = {})
|
8
|
+
self.logger = args.fetch :logger
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def notifier
|
13
|
+
@notifier ||= ::Rollbar
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(name, start, finish, id, payload)
|
17
|
+
start_time = payload.fetch(:start_time)
|
18
|
+
render_params = {
|
19
|
+
args: payload,
|
20
|
+
payload: filter(payload),
|
21
|
+
verify_ssl: payload[:verify_ssl],
|
22
|
+
read_timeout: payload.fetch(:timeout) { payload[:read_timeout] },
|
23
|
+
open_timeout: payload.fetch(:timeout) { payload[:open_timeout] },
|
24
|
+
event_id: id,
|
25
|
+
timestamp: start,
|
26
|
+
time_elapsed: (finish - start_time).round(10),
|
27
|
+
ip_address: ip_address
|
28
|
+
}
|
29
|
+
json = template.render nil, render_params
|
30
|
+
name =~ /error/ ? logger.error(json) : logger.debug(json)
|
31
|
+
rescue StandardError => e
|
32
|
+
notifier.error e, payload: payload
|
33
|
+
end
|
34
|
+
|
35
|
+
def template
|
36
|
+
raise NotImplementedError, 'define a #template method in a subclass'
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def filter(opts = {})
|
42
|
+
filter_class(opts[:headers] || {}).new(data: opts[:payload].to_s).filter
|
43
|
+
end
|
44
|
+
|
45
|
+
def filter_class(headers = {})
|
46
|
+
content_type = headers.fetch(:content_type) { 'application/json' }
|
47
|
+
RestClient::Jogger::Filters::Base.filter_class(content_type)
|
48
|
+
end
|
49
|
+
|
50
|
+
def root
|
51
|
+
Pathname.new(ROOT_PATH).freeze
|
52
|
+
end
|
53
|
+
|
54
|
+
def ip_address
|
55
|
+
Socket.ip_address_list.select(&:ipv4_private?).first.try(:ip_address)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RestClient
|
2
|
+
module Jogger
|
3
|
+
class Configuration
|
4
|
+
include ActiveModel::Model
|
5
|
+
|
6
|
+
REQUIRED_ATTRIBUTES = %i().freeze
|
7
|
+
OPTIONAL_ATTRIBUTES = %i(
|
8
|
+
request_pattern
|
9
|
+
response_pattern
|
10
|
+
default_content_type
|
11
|
+
default_filter_replacement
|
12
|
+
).freeze
|
13
|
+
ATTRIBUTES = (REQUIRED_ATTRIBUTES | OPTIONAL_ATTRIBUTES).freeze
|
14
|
+
|
15
|
+
attr_accessor *ATTRIBUTES
|
16
|
+
|
17
|
+
def request_pattern
|
18
|
+
@request_pattern || 'rest_client.request'
|
19
|
+
end
|
20
|
+
|
21
|
+
def response_pattern
|
22
|
+
@response_pattern || 'rest_client.response'
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_content_type
|
26
|
+
@default_content_type || 'application/json'
|
27
|
+
end
|
28
|
+
|
29
|
+
def default_filter_replacement
|
30
|
+
@default_filter_replacement || '[FILTERED]'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -7,14 +7,18 @@ module RestClient
|
|
7
7
|
@logger ||= ActiveSupport::Logger.new('log/rest_client.log').tap { |l| l.level = Logger::DEBUG }
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
|
10
|
+
def request_pattern
|
11
|
+
RestClient::Jogger.request_pattern
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
|
14
|
+
def response_pattern
|
15
|
+
RestClient::Jogger.response_pattern
|
16
16
|
end
|
17
17
|
|
18
|
+
def subscribe
|
19
|
+
ActiveSupport::Notifications.subscribe request_pattern, Request.new(logger: logger)
|
20
|
+
ActiveSupport::Notifications.subscribe response_pattern, Response.new(logger: logger)
|
21
|
+
end
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
@@ -2,8 +2,6 @@ module RestClient
|
|
2
2
|
module Jogger
|
3
3
|
module Filters
|
4
4
|
class Base
|
5
|
-
DEFAULT_REPLACEMENT = '[FILTERED]'.freeze
|
6
|
-
|
7
5
|
include ActiveModel::Model
|
8
6
|
|
9
7
|
attr_accessor :data, :content_type, :filters, :filter_replacement
|
@@ -17,6 +15,11 @@ module RestClient
|
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
18
|
+
def initialize(opts = {})
|
19
|
+
super
|
20
|
+
self.data = data.dup
|
21
|
+
end
|
22
|
+
|
20
23
|
def filter
|
21
24
|
filters.each do |filter|
|
22
25
|
filter_data filter
|
@@ -29,7 +32,7 @@ module RestClient
|
|
29
32
|
end
|
30
33
|
|
31
34
|
def filter_replacement
|
32
|
-
@filter_replacement ||=
|
35
|
+
@filter_replacement ||= RestClient::Jogger.default_filter_replacement
|
33
36
|
end
|
34
37
|
|
35
38
|
def filters
|
@@ -37,7 +40,7 @@ module RestClient
|
|
37
40
|
end
|
38
41
|
|
39
42
|
def content_type
|
40
|
-
@content_type ||=
|
43
|
+
@content_type ||= RestClient::Jogger.default_content_type
|
41
44
|
end
|
42
45
|
|
43
46
|
private
|
data/lib/rest_client/jogger.rb
CHANGED
@@ -1,19 +1,42 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
1
|
+
require 'json'
|
2
|
+
require 'mime/types'
|
3
|
+
require 'active_model'
|
4
|
+
require 'active_support/all'
|
5
|
+
require 'rollbar'
|
6
|
+
require 'tilt/jbuilder'
|
7
|
+
require 'rest_client/jogger/version'
|
8
|
+
require 'rest_client/jogger/configuration'
|
9
|
+
require 'rest_client/jogger/event_subscriber'
|
10
|
+
require 'rest_client/jogger/action'
|
11
|
+
require 'rest_client/jogger/request'
|
12
|
+
require 'rest_client/jogger/response'
|
13
|
+
require 'rest_client/jogger/filters/base'
|
14
|
+
require 'rest_client/jogger/filters/json'
|
15
|
+
require 'rest_client/jogger/filters/xml'
|
16
|
+
require 'rest_client/core_ext/logged_request'
|
12
17
|
|
13
18
|
module RestClient
|
14
19
|
class Request
|
15
20
|
extend LoggedRequest
|
16
21
|
end
|
22
|
+
|
17
23
|
module Jogger
|
24
|
+
ROOT_PATH = File.expand_path(File.dirname(__FILE__)).freeze
|
25
|
+
|
26
|
+
class << self
|
27
|
+
Configuration::ATTRIBUTES.each do |attribute|
|
28
|
+
delegate attribute, to: :configuration
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_writer :configuration
|
32
|
+
|
33
|
+
def configuration
|
34
|
+
@configuration ||= Configuration.new
|
35
|
+
end
|
36
|
+
|
37
|
+
def configure
|
38
|
+
yield(configuration)
|
39
|
+
end
|
40
|
+
end
|
18
41
|
end
|
19
42
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
json.ignore_nil!
|
3
|
+
json.url args[:url]
|
4
|
+
json.method args[:method]
|
5
|
+
json.verifySsl verify_ssl
|
6
|
+
json.requestHeaders args.fetch(:headers, {})
|
7
|
+
json.requestBody payload
|
8
|
+
json.sourceIp ip_address
|
9
|
+
json.eventName RestClient::Jogger.request_pattern
|
10
|
+
json.eventId event_id
|
11
|
+
json.timeElapsed time_elapsed
|
12
|
+
json.openTimeout open_timeout
|
13
|
+
json.readTimeout read_timeout
|
14
|
+
json.timestamp timestamp.iso8601
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
json.ignore_nil!
|
3
|
+
json.exception args[:exception]
|
4
|
+
json.url args[:url]
|
5
|
+
json.method args[:method]
|
6
|
+
json.verifySsl verify_ssl
|
7
|
+
json.requestHeaders args.fetch(:headers, {})
|
8
|
+
json.responseHeaders args[:response].try(:headers)
|
9
|
+
json.requestBody payload
|
10
|
+
json.responseBody args[:response].try(:body).to_s.force_encoding('UTF-8')
|
11
|
+
json.sourceIp ip_address
|
12
|
+
json.eventName RestClient::Jogger.response_pattern
|
13
|
+
json.eventId event_id
|
14
|
+
json.timeElapsed time_elapsed
|
15
|
+
json.openTimeout open_timeout
|
16
|
+
json.readTimeout read_timeout
|
17
|
+
json.code args[:response].try(:code)
|
18
|
+
json.timestamp timestamp.iso8601
|
Binary file
|
data/rest-client-jogger.gemspec
CHANGED
@@ -30,6 +30,9 @@ Gem::Specification.new do |spec|
|
|
30
30
|
|
31
31
|
spec.add_dependency "mime-types"
|
32
32
|
spec.add_dependency "rollbar"
|
33
|
+
spec.add_dependency "jbuilder"
|
34
|
+
spec.add_dependency 'tilt'
|
35
|
+
spec.add_dependency 'tilt-jbuilder'
|
33
36
|
|
34
37
|
spec.add_development_dependency "bundler", "~> 1.12"
|
35
38
|
spec.add_development_dependency "rake", "~> 10.0"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-client-jogger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Babe
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2018-
|
13
|
+
date: 2018-10-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -68,6 +68,48 @@ dependencies:
|
|
68
68
|
- - ">="
|
69
69
|
- !ruby/object:Gem::Version
|
70
70
|
version: '0'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: jbuilder
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :runtime
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: tilt
|
87
|
+
requirement: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
type: :runtime
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: tilt-jbuilder
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
type: :runtime
|
107
|
+
prerelease: false
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
71
113
|
- !ruby/object:Gem::Dependency
|
72
114
|
name: bundler
|
73
115
|
requirement: !ruby/object:Gem::Requirement
|
@@ -217,12 +259,18 @@ files:
|
|
217
259
|
- bin/setup
|
218
260
|
- lib/rest_client/core_ext/logged_request.rb
|
219
261
|
- lib/rest_client/jogger.rb
|
262
|
+
- lib/rest_client/jogger/action.rb
|
263
|
+
- lib/rest_client/jogger/configuration.rb
|
220
264
|
- lib/rest_client/jogger/event_subscriber.rb
|
221
265
|
- lib/rest_client/jogger/filters/base.rb
|
222
266
|
- lib/rest_client/jogger/filters/json.rb
|
223
267
|
- lib/rest_client/jogger/filters/xml.rb
|
224
|
-
- lib/rest_client/jogger/
|
268
|
+
- lib/rest_client/jogger/request.rb
|
269
|
+
- lib/rest_client/jogger/response.rb
|
225
270
|
- lib/rest_client/jogger/version.rb
|
271
|
+
- lib/rest_client/templates/request_logging_template.json.jbuilder
|
272
|
+
- lib/rest_client/templates/response_logging_template.json.jbuilder
|
273
|
+
- rest-client-jogger-0.3.4.gem
|
226
274
|
- rest-client-jogger.gemspec
|
227
275
|
homepage: https://github.com/amaabca/rest-client-jogger
|
228
276
|
licenses:
|
@@ -244,7 +292,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
244
292
|
version: '0'
|
245
293
|
requirements: []
|
246
294
|
rubyforge_project:
|
247
|
-
rubygems_version: 2.5.
|
295
|
+
rubygems_version: 2.5.2.3
|
248
296
|
signing_key:
|
249
297
|
specification_version: 4
|
250
298
|
summary: Logs RestClient requests in a JSON format
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module RestClient
|
2
|
-
module Jogger
|
3
|
-
class RequestComplete
|
4
|
-
include ::ActiveModel::Model
|
5
|
-
attr_accessor :logger, :notifier
|
6
|
-
|
7
|
-
def initialize(args = {})
|
8
|
-
self.logger = args.fetch :logger
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def notifier
|
13
|
-
@notifier ||= ::Rollbar
|
14
|
-
end
|
15
|
-
|
16
|
-
def call(name, start, finish, id, payload)
|
17
|
-
message = ::JSON.dump(payload.merge(event_name: name, event_id: id, timestamp: start))
|
18
|
-
name =~ /error/ ? logger.error(message) : logger.debug(message)
|
19
|
-
rescue StandardError => e
|
20
|
-
notifier.error e, payload: payload
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|