rest-client-jogger 1.0.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 581926693bcbbc9ff8005be026b530a8b42cded9
4
- data.tar.gz: 2ee7209470966596bdcbbcc8b8e16551ebb9f49c
2
+ SHA256:
3
+ metadata.gz: 47ca02af5a3db97a2fe9f198002fdaca8e8df2bda98cd8bcd1f084b70518fbf3
4
+ data.tar.gz: 3707a76bcc37703ff62aaf87f26886323015db8331246dff7fc75e924c871e63
5
5
  SHA512:
6
- metadata.gz: 8d58029a641c7195511401b82a2ab34865a23ef30d3cc744d89ab6e14ca64d42253807d8e40c59368a9cd193ef42b1f1958d3ef114b1aa2506738b9e51b101ab
7
- data.tar.gz: d158f8c8abfd99e4cba22f18f66923bf6b8d0f3080ee963615f5cdc40bb1c719d5ccbb487a4bf99d2effad01837f311d4c23785cc0e18deec56b592fc2b34e40
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
@@ -1,3 +1,2 @@
1
- --require spec_helper
2
- --format documentation
3
1
  --color
2
+ --require spec_helper
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, {}).reject { |k, _| k.to_s.casecmp('authorization').zero? }
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)
@@ -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
- 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
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[:headers] || {}).new(data: opts[:payload].to_s).filter
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
- content_type = headers.fetch(:content_type) { 'application/json' }
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('log/rest_client.log').tap { |l| l.level = Logger::DEBUG }
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
- private
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
@@ -1,9 +1,9 @@
1
1
  module RestClient
2
2
  module Jogger
3
3
  module Filters
4
- class Json < RestClient::Jogger::Filters::Base
4
+ class Json < Base
5
5
 
6
- private
6
+ private
7
7
 
8
8
  def filter_data(filter)
9
9
  data.gsub! /"#{filter}":\s*"[^"]*"/, %{"#{filter}": "#{filter_replacement}"}
@@ -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 < RestClient::Jogger::Filters::Base
4
+ class Xml < Base
5
5
 
6
- private
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 root.join('templates', 'response_logging_template.json.jbuilder')
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,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RestClient
2
4
  module Jogger
3
- VERSION = '1.0.1'.freeze
5
+ VERSION = '1.3.0'
4
6
  end
5
7
  end
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
  json.ignore_nil!
3
- json.url args[:url]
4
- json.method args[:method]
3
+ json.url url
4
+ json.method method
5
5
  json.verifySsl verify_ssl
6
- json.requestHeaders args.fetch(:headers, {})
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.exception args[:exception]
4
- json.url args[:url]
5
- json.method args[:method]
3
+ json.url url
4
+ json.exception exception
5
+ json.method method
6
6
  json.verifySsl verify_ssl
7
- json.requestHeaders args.fetch(:headers, {})
8
- json.responseHeaders args[:response].try(:headers)
7
+ json.requestHeaders headers
8
+ json.responseHeaders response_headers
9
9
  json.requestBody payload
10
- json.responseBody args[:response].try(:body).to_s.force_encoding('UTF-8')
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 args[:response].try(:code)
18
+ json.code code
18
19
  json.timestamp timestamp.iso8601
@@ -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", "~> 1.12"
38
- spec.add_development_dependency "rake", "~> 10.0"
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.1
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: 2018-10-09 00:00:00.000000000 Z
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: '1.12'
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: '1.12'
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: '10.0'
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: '10.0'
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
- rubyforge_project:
294
- rubygems_version: 2.5.2.3
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: []
data/.travis.yml DELETED
@@ -1,11 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.1.2
5
- - 2.2.0
6
- - 2.2.1
7
- - 2.2.2
8
- - 2.2.3
9
- - 2.3.0
10
- - 2.5.1
11
- before_install: gem install bundler -v 1.12.3