rest-client-jogger 1.0.1 → 1.3.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 +5 -5
- data/.github/workflows/ci.yml +31 -0
- data/.rspec +1 -2
- data/README.md +2 -0
- data/lib/rest_client/core_ext/logged_request.rb +2 -1
- data/lib/rest_client/jogger.rb +6 -1
- data/lib/rest_client/jogger/action.rb +24 -15
- data/lib/rest_client/jogger/configuration.rb +10 -0
- data/lib/rest_client/jogger/event_subscriber.rb +1 -1
- data/lib/rest_client/jogger/filters/base.rb +2 -2
- data/lib/rest_client/jogger/filters/headers.rb +32 -0
- data/lib/rest_client/jogger/filters/json.rb +2 -2
- data/lib/rest_client/jogger/filters/query_parameters.rb +30 -0
- data/lib/rest_client/jogger/filters/xml.rb +2 -2
- data/lib/rest_client/jogger/response.rb +23 -1
- data/lib/rest_client/jogger/version.rb +3 -1
- data/lib/rest_client/templates/request_logging_template.json.jbuilder +4 -3
- data/lib/rest_client/templates/response_logging_template.json.jbuilder +8 -7
- data/rest-client-jogger.gemspec +2 -2
- metadata +15 -14
- data/.travis.yml +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 47ca02af5a3db97a2fe9f198002fdaca8e8df2bda98cd8bcd1f084b70518fbf3
|
4
|
+
data.tar.gz: 3707a76bcc37703ff62aaf87f26886323015db8331246dff7fc75e924c871e63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1416bc0d1542f4d5b3ec43a22653f6904b22712004dc30b63d18d043c5f3f080711be75dfc2179a9474c025154af3809e2e4a28fafda2b721b19c4c38c5c60b1
|
7
|
+
data.tar.gz: f906820f356edc342087acba2f640bfcf27da162979b3abfe4104aea3310192f175f5a3038bbed3750d69f955a171aa0df308ead12f17727c27dbd9066c49f2f
|
@@ -0,0 +1,31 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
branches:
|
9
|
+
- master
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
build:
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
strategy:
|
15
|
+
matrix:
|
16
|
+
ruby:
|
17
|
+
- '2.5'
|
18
|
+
- '2.6'
|
19
|
+
- '2.7'
|
20
|
+
steps:
|
21
|
+
- uses: actions/checkout@v2
|
22
|
+
- name: Set up Ruby
|
23
|
+
uses: actions/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: ${{ matrix.ruby }}
|
26
|
+
- name: Build and test with Rake
|
27
|
+
run: |
|
28
|
+
gem install bundler
|
29
|
+
echo 'bundle install'
|
30
|
+
bundle install --jobs 4 --retry 3
|
31
|
+
bundle exec rake
|
data/.rspec
CHANGED
data/README.md
CHANGED
@@ -46,6 +46,8 @@ RestClient::Jogger.configure do |config|
|
|
46
46
|
config.response_pattern = 'my.response' # optional
|
47
47
|
config.default_content_type = 'application/json' # optional
|
48
48
|
config.default_filter_replacement = '[SECRET]' # optional
|
49
|
+
config.log_output = STDOUT # optional
|
50
|
+
config.filter_parameters = [:param_name] # optional
|
49
51
|
end
|
50
52
|
```
|
51
53
|
|
@@ -30,7 +30,8 @@ module LoggedRequest
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def filtered_headers(opts)
|
33
|
-
opts.fetch(:headers
|
33
|
+
headers = opts.fetch(:headers) { {} }
|
34
|
+
RestClient::Jogger::Filters::Headers.new(data: headers).filter
|
34
35
|
end
|
35
36
|
|
36
37
|
def log_request(opts, started)
|
data/lib/rest_client/jogger.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
require 'cgi'
|
1
2
|
require 'json'
|
3
|
+
require 'uri'
|
2
4
|
require 'mime/types'
|
3
5
|
require 'active_model'
|
4
6
|
require 'active_support/all'
|
@@ -11,16 +13,19 @@ require 'rest_client/jogger/action'
|
|
11
13
|
require 'rest_client/jogger/request'
|
12
14
|
require 'rest_client/jogger/response'
|
13
15
|
require 'rest_client/jogger/filters/base'
|
16
|
+
require 'rest_client/jogger/filters/headers'
|
14
17
|
require 'rest_client/jogger/filters/json'
|
15
18
|
require 'rest_client/jogger/filters/xml'
|
19
|
+
require 'rest_client/jogger/filters/query_parameters'
|
16
20
|
require 'rest_client/core_ext/logged_request'
|
17
21
|
|
18
22
|
module RestClient
|
19
23
|
class Request
|
20
24
|
extend LoggedRequest
|
21
25
|
end
|
22
|
-
|
26
|
+
|
23
27
|
module Jogger
|
28
|
+
AGENT_VERSION = "rest-client-jogger:#{VERSION}".freeze
|
24
29
|
ROOT_PATH = File.expand_path(File.dirname(__FILE__)).freeze
|
25
30
|
|
26
31
|
class << self
|
@@ -14,19 +14,8 @@ module RestClient
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def call(name, start, finish, id, payload)
|
17
|
-
|
18
|
-
|
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
|
17
|
+
params = render_params(start, finish, id, payload)
|
18
|
+
json = template.render(nil, params)
|
30
19
|
name =~ /error/ ? logger.error(json) : logger.debug(json)
|
31
20
|
rescue StandardError => e
|
32
21
|
notifier.error e, payload: payload
|
@@ -38,12 +27,32 @@ module RestClient
|
|
38
27
|
|
39
28
|
private
|
40
29
|
|
30
|
+
def render_params(start, finish, id, opts)
|
31
|
+
start_time = opts.fetch(:start_time)
|
32
|
+
url = opts.fetch(:url)
|
33
|
+
headers = opts.fetch(:headers) { {} }
|
34
|
+
{
|
35
|
+
method: opts[:method],
|
36
|
+
headers: headers,
|
37
|
+
url: RestClient::Jogger::Filters::QueryParameters.new(data: url).filter,
|
38
|
+
payload: filter(body: opts[:payload], headers: headers),
|
39
|
+
verify_ssl: opts[:verify_ssl],
|
40
|
+
read_timeout: opts.fetch(:timeout) { opts[:read_timeout] },
|
41
|
+
open_timeout: opts.fetch(:timeout) { opts[:open_timeout] },
|
42
|
+
event_id: id,
|
43
|
+
timestamp: start,
|
44
|
+
time_elapsed: (finish - start_time).round(10),
|
45
|
+
ip_address: ip_address
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
41
49
|
def filter(opts = {})
|
42
|
-
filter_class(opts
|
50
|
+
filter_class(opts.fetch(:headers)).new(data: opts[:body].to_s).filter
|
43
51
|
end
|
44
52
|
|
45
53
|
def filter_class(headers = {})
|
46
|
-
|
54
|
+
normalized_headers = headers.transform_keys { |k| k.to_s.downcase.tr('-', '_') }
|
55
|
+
content_type = normalized_headers.fetch('content_type') { 'application/json' }
|
47
56
|
RestClient::Jogger::Filters::Base.filter_class(content_type)
|
48
57
|
end
|
49
58
|
|
@@ -9,6 +9,8 @@ module RestClient
|
|
9
9
|
response_pattern
|
10
10
|
default_content_type
|
11
11
|
default_filter_replacement
|
12
|
+
log_output
|
13
|
+
filter_parameters
|
12
14
|
).freeze
|
13
15
|
ATTRIBUTES = (REQUIRED_ATTRIBUTES | OPTIONAL_ATTRIBUTES).freeze
|
14
16
|
|
@@ -29,6 +31,14 @@ module RestClient
|
|
29
31
|
def default_filter_replacement
|
30
32
|
@default_filter_replacement || '[FILTERED]'
|
31
33
|
end
|
34
|
+
|
35
|
+
def log_output
|
36
|
+
@log_output || 'log/rest_client.log'
|
37
|
+
end
|
38
|
+
|
39
|
+
def filter_parameters
|
40
|
+
@filter_parameters || []
|
41
|
+
end
|
32
42
|
end
|
33
43
|
end
|
34
44
|
end
|
@@ -4,7 +4,7 @@ module RestClient
|
|
4
4
|
attr_accessor :logger
|
5
5
|
|
6
6
|
def logger
|
7
|
-
@logger ||= ActiveSupport::Logger.new(
|
7
|
+
@logger ||= ActiveSupport::Logger.new(RestClient::Jogger.log_output).tap { |l| l.level = Logger::DEBUG }
|
8
8
|
end
|
9
9
|
|
10
10
|
def request_pattern
|
@@ -43,10 +43,10 @@ module RestClient
|
|
43
43
|
@content_type ||= RestClient::Jogger.default_content_type
|
44
44
|
end
|
45
45
|
|
46
|
-
|
46
|
+
private
|
47
47
|
|
48
48
|
def filter_parameters
|
49
|
-
defined?(Rails) ? Rails.configuration.filter_parameters :
|
49
|
+
defined?(Rails) ? Rails.configuration.filter_parameters : RestClient::Jogger.filter_parameters
|
50
50
|
end
|
51
51
|
|
52
52
|
def filter_data(filter)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module RestClient
|
2
|
+
module Jogger
|
3
|
+
module Filters
|
4
|
+
class Headers < Base
|
5
|
+
DEFAULT_FILTERS = %w[authorization].freeze
|
6
|
+
|
7
|
+
def filter
|
8
|
+
filtered_keys = string_filters
|
9
|
+
data.each_with_object({}) do |(key, value), memo|
|
10
|
+
if filtered_keys.include?(key.to_s.downcase)
|
11
|
+
memo[key] = filter_replacement
|
12
|
+
else
|
13
|
+
memo[key] = value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def string_filters
|
21
|
+
DEFAULT_FILTERS | normalized_filters
|
22
|
+
end
|
23
|
+
|
24
|
+
def normalized_filters
|
25
|
+
filters
|
26
|
+
.select { |e| e.is_a?(Symbol) || e.is_a?(String) }
|
27
|
+
.map { |e| e.to_s.downcase }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RestClient
|
2
|
+
module Jogger
|
3
|
+
module Filters
|
4
|
+
class QueryParameters < Base
|
5
|
+
def filter
|
6
|
+
return uri.to_s if uri.query.blank?
|
7
|
+
uri.dup.tap { |u| u.query = parameters }.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def parameters
|
13
|
+
CGI.parse(uri.query.to_s).each_with_object([]) do |(key, values), memo|
|
14
|
+
values.each do |value|
|
15
|
+
memo << "#{key}=#{filtered_value(key, value)}"
|
16
|
+
end
|
17
|
+
end.join('&')
|
18
|
+
end
|
19
|
+
|
20
|
+
def filtered_value(key, value)
|
21
|
+
filters.include?(key.to_sym) ? filter_replacement : value
|
22
|
+
end
|
23
|
+
|
24
|
+
def uri
|
25
|
+
@uri ||= URI.parse(data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module RestClient
|
2
2
|
module Jogger
|
3
3
|
module Filters
|
4
|
-
class Xml <
|
4
|
+
class Xml < Base
|
5
5
|
|
6
|
-
|
6
|
+
private
|
7
7
|
|
8
8
|
def filter_data(filter)
|
9
9
|
data.gsub! /<#{filter}>(.*)<\/#{filter}>/, %{<#{filter}>#{filter_replacement}</#{filter}>}
|
@@ -2,7 +2,29 @@ module RestClient
|
|
2
2
|
module Jogger
|
3
3
|
class Response < Action
|
4
4
|
def template
|
5
|
-
Tilt::JbuilderTemplate.new
|
5
|
+
Tilt::JbuilderTemplate.new(root.join('templates', 'response_logging_template.json.jbuilder'))
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def render_params(start, finish, id, opts)
|
11
|
+
params = response_params(opts)
|
12
|
+
super.merge(params)
|
13
|
+
end
|
14
|
+
|
15
|
+
def response_params(opts = {})
|
16
|
+
response_headers = opts[:response].try(:headers) || {}
|
17
|
+
response_body = opts[:response].try(:body).to_s.dup.force_encoding('UTF-8')
|
18
|
+
{
|
19
|
+
exception: opts[:exception],
|
20
|
+
response_headers: filtered_headers(response_headers),
|
21
|
+
response_body: filter(body: response_body, headers: response_headers),
|
22
|
+
code: opts[:response].try(:code)
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def filtered_headers(headers = {})
|
27
|
+
Filters::Headers.new(data: headers).filter
|
6
28
|
end
|
7
29
|
end
|
8
30
|
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
json.ignore_nil!
|
3
|
-
json.url
|
4
|
-
json.method
|
3
|
+
json.url url
|
4
|
+
json.method method
|
5
5
|
json.verifySsl verify_ssl
|
6
|
-
json.requestHeaders
|
6
|
+
json.requestHeaders headers
|
7
7
|
json.requestBody payload
|
8
8
|
json.sourceIp ip_address
|
9
9
|
json.eventName RestClient::Jogger.request_pattern
|
10
10
|
json.eventId event_id
|
11
|
+
json.eventAgent RestClient::Jogger::AGENT_VERSION
|
11
12
|
json.timeElapsed time_elapsed
|
12
13
|
json.openTimeout open_timeout
|
13
14
|
json.readTimeout read_timeout
|
@@ -1,18 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
json.ignore_nil!
|
3
|
-
json.
|
4
|
-
json.
|
5
|
-
json.method
|
3
|
+
json.url url
|
4
|
+
json.exception exception
|
5
|
+
json.method method
|
6
6
|
json.verifySsl verify_ssl
|
7
|
-
json.requestHeaders
|
8
|
-
json.responseHeaders
|
7
|
+
json.requestHeaders headers
|
8
|
+
json.responseHeaders response_headers
|
9
9
|
json.requestBody payload
|
10
|
-
json.responseBody
|
10
|
+
json.responseBody response_body
|
11
11
|
json.sourceIp ip_address
|
12
12
|
json.eventName RestClient::Jogger.response_pattern
|
13
13
|
json.eventId event_id
|
14
|
+
json.eventAgent RestClient::Jogger::AGENT_VERSION
|
14
15
|
json.timeElapsed time_elapsed
|
15
16
|
json.openTimeout open_timeout
|
16
17
|
json.readTimeout read_timeout
|
17
|
-
json.code
|
18
|
+
json.code code
|
18
19
|
json.timestamp timestamp.iso8601
|
data/rest-client-jogger.gemspec
CHANGED
@@ -34,8 +34,8 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_dependency 'tilt'
|
35
35
|
spec.add_dependency 'tilt-jbuilder'
|
36
36
|
|
37
|
-
spec.add_development_dependency "bundler"
|
38
|
-
spec.add_development_dependency "rake", "~>
|
37
|
+
spec.add_development_dependency "bundler"
|
38
|
+
spec.add_development_dependency "rake", "~> 12.2"
|
39
39
|
spec.add_development_dependency "rspec", "~> 3.0"
|
40
40
|
spec.add_development_dependency "rspec-json_expectations"
|
41
41
|
spec.add_development_dependency "rest-client", "~> 2.0.0"
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-client-jogger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Babe
|
8
8
|
- Jesse Doyle
|
9
9
|
- Michael van den Beuken
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2021-03-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -114,30 +114,30 @@ dependencies:
|
|
114
114
|
name: bundler
|
115
115
|
requirement: !ruby/object:Gem::Requirement
|
116
116
|
requirements:
|
117
|
-
- - "
|
117
|
+
- - ">="
|
118
118
|
- !ruby/object:Gem::Version
|
119
|
-
version: '
|
119
|
+
version: '0'
|
120
120
|
type: :development
|
121
121
|
prerelease: false
|
122
122
|
version_requirements: !ruby/object:Gem::Requirement
|
123
123
|
requirements:
|
124
|
-
- - "
|
124
|
+
- - ">="
|
125
125
|
- !ruby/object:Gem::Version
|
126
|
-
version: '
|
126
|
+
version: '0'
|
127
127
|
- !ruby/object:Gem::Dependency
|
128
128
|
name: rake
|
129
129
|
requirement: !ruby/object:Gem::Requirement
|
130
130
|
requirements:
|
131
131
|
- - "~>"
|
132
132
|
- !ruby/object:Gem::Version
|
133
|
-
version: '
|
133
|
+
version: '12.2'
|
134
134
|
type: :development
|
135
135
|
prerelease: false
|
136
136
|
version_requirements: !ruby/object:Gem::Requirement
|
137
137
|
requirements:
|
138
138
|
- - "~>"
|
139
139
|
- !ruby/object:Gem::Version
|
140
|
-
version: '
|
140
|
+
version: '12.2'
|
141
141
|
- !ruby/object:Gem::Dependency
|
142
142
|
name: rspec
|
143
143
|
requirement: !ruby/object:Gem::Requirement
|
@@ -245,10 +245,10 @@ executables: []
|
|
245
245
|
extensions: []
|
246
246
|
extra_rdoc_files: []
|
247
247
|
files:
|
248
|
+
- ".github/workflows/ci.yml"
|
248
249
|
- ".gitignore"
|
249
250
|
- ".rspec"
|
250
251
|
- ".simplecov"
|
251
|
-
- ".travis.yml"
|
252
252
|
- Gemfile
|
253
253
|
- LICENSE
|
254
254
|
- README.md
|
@@ -263,7 +263,9 @@ files:
|
|
263
263
|
- lib/rest_client/jogger/configuration.rb
|
264
264
|
- lib/rest_client/jogger/event_subscriber.rb
|
265
265
|
- lib/rest_client/jogger/filters/base.rb
|
266
|
+
- lib/rest_client/jogger/filters/headers.rb
|
266
267
|
- lib/rest_client/jogger/filters/json.rb
|
268
|
+
- lib/rest_client/jogger/filters/query_parameters.rb
|
267
269
|
- lib/rest_client/jogger/filters/xml.rb
|
268
270
|
- lib/rest_client/jogger/request.rb
|
269
271
|
- lib/rest_client/jogger/response.rb
|
@@ -275,7 +277,7 @@ homepage: https://github.com/amaabca/rest-client-jogger
|
|
275
277
|
licenses:
|
276
278
|
- MIT
|
277
279
|
metadata: {}
|
278
|
-
post_install_message:
|
280
|
+
post_install_message:
|
279
281
|
rdoc_options: []
|
280
282
|
require_paths:
|
281
283
|
- lib
|
@@ -290,9 +292,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
290
292
|
- !ruby/object:Gem::Version
|
291
293
|
version: '0'
|
292
294
|
requirements: []
|
293
|
-
|
294
|
-
|
295
|
-
signing_key:
|
295
|
+
rubygems_version: 3.1.2
|
296
|
+
signing_key:
|
296
297
|
specification_version: 4
|
297
298
|
summary: Logs RestClient requests in a JSON format
|
298
299
|
test_files: []
|