rollday 0.1.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad34763ae84ecaefbd8febab644f790d10a0cd18fe0cd425004e8c8b6464c10b
4
- data.tar.gz: 64474e52fb56a31a4cff7e4b11736d75163783b543bea30a6ca64b8054a5b366
3
+ metadata.gz: 02476ca50a8cb131cd458cffe10428026cee831d1c6ec555cc605541ebc20d9c
4
+ data.tar.gz: e4e0c9c14d3f02ea831fe77efe9a4142291c995d955200dd00085a136e6deba6
5
5
  SHA512:
6
- metadata.gz: fbb72f7c5446af3d674925b453bc92c978fc9db212a5ee36e905bc8775da81df6d91a477128f0cc0c0b0033f0a150ed58e017e5dd49b2af099502381d80bc57c
7
- data.tar.gz: 53b16030723f41849ec4271d55d5073b7dea6cb36b3e178b28dd24e8247abb5feb64f71385dce67b4b0d099d3fb7a3097f9d8cdbbc77722bd186509d1d2d65cd
6
+ metadata.gz: 9fc90d8d766d8687322349b6fae4bf8dc12fa7f0f1b40b81476b90a15c1980737879f92947b431d064c6e24f9da3a0cfae91c08340dbeefff4ceddda0463075a
7
+ data.tar.gz: 443ca20fde67b2447dc734c9bd3fba8b37f6373b35149cc52d5e824fc4432a59c2964cd0bd8d18e74171be934b875a85aa9a86033843404c14fd1499230508f5
data/CHANGELOG.md CHANGED
@@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ## [0.1.0] - YYYY-MM-DD
10
+ ## [0.2.0] - 2022-06-18
11
11
 
12
12
  ### Added
13
13
  - New feature 1
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rollday (0.1.0)
4
+ rollday (0.5.0)
5
+ class_composer
5
6
  faraday
6
7
  rollbar
7
8
 
@@ -9,6 +10,7 @@ GEM
9
10
  remote: https://rubygems.org/
10
11
  specs:
11
12
  byebug (11.1.3)
13
+ class_composer (1.0.0)
12
14
  coderay (1.1.3)
13
15
  concurrent-ruby (1.1.10)
14
16
  diff-lcs (1.5.0)
data/README.md CHANGED
@@ -1,11 +1,9 @@
1
1
  # Rollday
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be
4
- able to package up your Ruby library into a gem. Put your Ruby code in the file
5
- `lib/rollday`. To experiment with that code, run
6
- `bin/console` for an interactive prompt.
3
+ Rollday is a a gem to integrate with Faraday requests. It adds a default middleware for your projecrts Faraday client to send a rollbar for configurable response status codes.
4
+
5
+ It can be configured once for th eentire project, or customized per Faraday request
7
6
 
8
- TODO: Delete this and the text above, and describe your gem
9
7
 
10
8
  ## Installation
11
9
 
@@ -15,17 +13,95 @@ Add this line to your application's Gemfile:
15
13
  gem 'rollday'
16
14
  ```
17
15
 
18
- And then execute:
16
+ ## Usage
19
17
 
20
- $ bundle install
18
+ ### Initialization
21
19
 
22
- Or install it yourself as:
20
+ Intialization should happen in `app/initializers/rollday.rb`. All options below are the current defaults unless stated
21
+ ```ruby
22
+ Rollday.configure do |config|
23
+ config.use_default_middleware! # [Not default option] set middleware for all Faraday requests (Faraday.get(...)). Caution when used with Default Client Middleware
23
24
 
24
- $ gem install rollday
25
+ config.use_default_client_middleware! # [Not default option] set middleware for all Faraday instances. Caution when used with Default Middleware
25
26
 
26
- ## Usage
27
+ config.status_code_regex = /[45]\d\d$/ # If status code matches, will attempt to send a rollbar
28
+
29
+ config.use_person_scope = true # Assign a person scope to the rollbar scope
30
+
31
+ config.use_params_scope = true # Assign a params scope to the rollbar scope. Configured from Faraday params for request
32
+
33
+ config.params_scope_sanitizer = [] # Array of Procs to sanitize params. Can remove params or call Rollbar::Scrubbers.scrub_value(*) to assign value
34
+
35
+ config.use_query_scope = true # Assign the url queries to the scope
36
+
37
+ config.params_query_sanitizer = [] # Array of Procs to sanitize query params. Can remove params or call Rollbar::Scrubbers.scrub_value(*) to assign value
38
+
39
+ config.message = ->(status, phrase, body, path, domain) { "[#{status}]: #{domain} - #{path}" } # Message to set for the Rollbar item. Value can be a proc or a static message
40
+
41
+ config.use_message_exception = true # When set to true, Exception will be used to establish a backtrace
42
+
43
+ config.rollbar_level = ->(_status) { :warning } # Rollbar level can be configurable based on the status code
44
+ end
45
+ ```
46
+
47
+ ### Ex: Default Faraday Client
27
48
 
28
- TODO: Write usage instructions here
49
+ ```ruby
50
+ # Rollday initializer
51
+ Rollday.configure do |config|
52
+ config.use_default_middleware!
53
+ config.status_code_regex = /[2345]\d\d$/
54
+ config.message = -> (s, phrase, b, path, domain) { "[#{domain}] via #{path} returned #{status}" }
55
+ end
56
+
57
+ Farady.get("http://httpstat.us/207") # => 200 status code returned
58
+ # Will send a rollbar because Status code matches regex
59
+ ```
60
+
61
+ ### Ex: Default Faraday Instance
62
+
63
+ ```ruby
64
+ # Rollday initializer
65
+ Rollday.configure do |config|
66
+ config.use_default_client_middleware!
67
+ config.message = -> (s, phrase, b, path, domain) { "[#{domain}] via #{path} returned #{status} using default client middleware" }
68
+ end
69
+ Farady.get("http://httpstat.us/500") # => 500 status code returned
70
+ # Rollbar will not get sent because `use_default_middleware!` is not set
71
+
72
+ client = Faraday.new(url: base_url)
73
+ client.get("404") # => 404 status code returned
74
+ # Will send a rollbar because Status code matches regex
75
+ ```
76
+
77
+ ### Ex: Custom Faraday Instance
78
+
79
+ ```ruby
80
+ # Rollday initializer
81
+ Rollday.configure do |config|
82
+ config.status_code_regex = /[2]\d\d$/
83
+ config.message = -> (s, phrase, b, path, domain) { "[#{domain}] via #{path} returned #{status} using custom client middleware" }
84
+ end
85
+ Farady.get("http://httpstat.us/500") # => 500 status code returned
86
+ # Rollbar will not get sent because `use_default_middleware!` is not set
87
+
88
+ client = Faraday.new(url: base_url) do |conn|
89
+ conn.use Rollday::MIDDLEWARE_NAME
90
+ end
91
+ client.get("209") # => 209 status code returned
92
+ # Will send a rollbar because Status code matches regex
93
+ ```
94
+
95
+ ### Use Caution
96
+ ```ruby
97
+ # Rollday initializer
98
+ Rollday.configure do |config|
99
+ # Do not do this!
100
+ config.use_default_middleware!
101
+ config.use_default_client_middleware!
102
+ end
103
+ ```
104
+ Adding both the `use_default_middleware!` and the `use_default_client_middleware!` will cause double reporting of all default Faraday builders.
29
105
 
30
106
  ## Development
31
107
 
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rollday
4
+ module FaradayConnectionOptions
5
+ def new_builder(block)
6
+ super.tap do |builder|
7
+ # allow scope to remove usage of middleware for a request
8
+ # after it has been injected into the Connection
9
+ if Rollday.config.allow_client_middleware
10
+ builder.use(Rollday::MIDDLEWARE_NAME)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "class_composer"
4
+ require "rollbar"
5
+ require "rollday/errors"
6
+ require "rollday/use_middleware"
7
+
8
+ module Rollday
9
+ class Configuration
10
+ include ClassComposer::Generator
11
+
12
+ ROLLBAR_LEVELS = [
13
+ DEBUG = :debug,
14
+ INFO = :info,
15
+ WARNING = :warning,
16
+ ERROR = :error,
17
+ CRITICAL = :critical
18
+ ]
19
+ DEFAULT_ROLLBAR_LEVEL = WARNING
20
+
21
+ DEFAULT_STATUS_CODE_REGEX = /[45]\d\d$/
22
+ DEFAULT_MESSAGE_PROC = ->(status, phrase, body, path, domain) { "[#{status}]: #{domain} - #{path}" }
23
+ DEFAULT_LEVEL_PROC = ->(_status) { DEFAULT_ROLLBAR_LEVEL }
24
+ ROLLBAR_VALIDATOR = Proc.new do |value|
25
+ value.is_a?(Proc) || ROLLBAR_LEVELS.include?(value)
26
+ end
27
+
28
+ add_composer :message, allowed: [Proc, String], default: DEFAULT_MESSAGE_PROC
29
+ add_composer :params_query_sanitizer, allowed: Array, default: []
30
+ add_composer :params_scope_sanitizer, allowed: Array, default: []
31
+ add_composer :person_scope, allowed: Proc
32
+ add_composer :rollbar_level, allowed: [Proc, Symbol], default: DEFAULT_LEVEL_PROC, validator: ROLLBAR_VALIDATOR, invalid_message: -> (val) { "Value must be a Proc or one of #{ROLLBAR_LEVELS}" }
33
+ add_composer :status_code_regex, allowed: Regexp, default: DEFAULT_STATUS_CODE_REGEX
34
+ add_composer :use_message_exception, allowed: [TrueClass, FalseClass], default: true
35
+ add_composer :use_params_scope, allowed: [TrueClass, FalseClass], default: true
36
+ add_composer :use_person_scope, allowed: [TrueClass, FalseClass], default: true
37
+ add_composer :use_query_scope, allowed: [TrueClass, FalseClass], default: true
38
+ add_composer :exception_class, allowed: Class, default: Rollday::Faraday
39
+ add_composer :allow_client_middleware, allowed: [TrueClass, FalseClass], default: true
40
+
41
+ def person_scope
42
+ return -> {} unless @use_person_scope
43
+
44
+ @person_scope || Rollbar.scope.scope_object.raw[:person] || -> {}
45
+ end
46
+
47
+ def use_default_middleware!
48
+ Rollday.use_default_middleware!
49
+ end
50
+
51
+ def use_default_client_middleware!
52
+ Rollday.use_default_client_middleware!
53
+ end
54
+
55
+ def register_middleware!
56
+ Rollday.register_middleware!
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rollday
4
+ class Error < StandardError; end
5
+ class Faraday < Error; end # used to create backtrace for rollbar
6
+ class ConfigError < Error; end
7
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+ require "rollday/rollbar_helper"
5
+
6
+ module Rollday
7
+ class Middleware < ::Faraday::Middleware
8
+ include RollbarHelper
9
+
10
+ def initialize(app, **)
11
+ super(app)
12
+
13
+ @app = app
14
+ end
15
+
16
+ def call(env)
17
+ result = @app.(env)
18
+ if ship_to_rollbar?(result.status)
19
+ send_rollbar(result)
20
+ end
21
+
22
+ result
23
+ end
24
+
25
+ private
26
+
27
+ def ship_to_rollbar?(status)
28
+ status.to_s =~ Rollday.config.status_code_regex
29
+ end
30
+
31
+ def send_rollbar(result)
32
+ scope = rollbar_scope(result)
33
+ message = rollbar_message(result)
34
+ level = rollbar_level(result)
35
+ ::Rollbar.log(level, message, **scope)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rollbar'
4
+
5
+ module Rollday
6
+ module RollbarHelper
7
+
8
+ def rollbar_level(result)
9
+ level = Rollday.config.rollbar_level
10
+ level.is_a?(Proc) ? level.(result.status) : level
11
+ end
12
+
13
+ def rollbar_message(result)
14
+ message = Rollday.config.message.(result.status, result.reason_phrase, result.body, URI(result.env.url).path, URI(result.env.url).host)
15
+ return message unless Rollday.config.use_message_exception
16
+
17
+ Rollday.config.exception_class.new(message)
18
+ end
19
+
20
+ def rollbar_scope(result)
21
+ {
22
+ framework: "Faraday: #{::Faraday::VERSION}; Rollday: #{Rollday::VERSION}",
23
+ host: URI(result.env.url).host,
24
+ method: result.env.method,
25
+ params: params_scope(result),
26
+ path: URI(result.env.url).path,
27
+ body: result.body,
28
+ person: person_scope,
29
+ query: query_scope(result),
30
+ status: result.status,
31
+ status_phrase: result.reason_phrase,
32
+ }
33
+ end
34
+
35
+ private
36
+
37
+ def query_scope(result)
38
+ return {} unless Rollday.config.use_query_scope
39
+ raw_query = URI(result.env.url).query
40
+ return if raw_query.nil?
41
+
42
+ query_scope = CGI::parse(raw_query)
43
+ Rollday.config.params_scope_sanitizer.each do |sanitizer|
44
+ query_scope = sanitizer.(query_params)
45
+ end
46
+
47
+ query_scope
48
+ end
49
+
50
+ def params_scope(result)
51
+
52
+ end
53
+
54
+ def person_scope
55
+ Rollday.config.person_scope.()
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rollday
4
+ module UseMiddleware
5
+ # https://github.com/lostisland/faraday/blob/816d824bc18453e86027c9c5fcf8427020566e50/lib/faraday/rack_builder.rb#L83-L86
6
+ # https://github.com/lostisland/faraday/blob/816d824bc18453e86027c9c5fcf8427020566e50/lib/faraday/rack_builder.rb#L156-L169
7
+ # Once the default middleware is crated and the Faraday Rack app has been built,
8
+ # it can not be removed from the middleware Faraday stack
9
+ # If removal is needed, then use the middleware per request instead of defaulted
10
+ # or use the `with_scope` to modify the parameters of the rollday gem
11
+ def self.use_default_middleware!
12
+ register_middleware!
13
+
14
+ return false if @add_default_middleware
15
+
16
+ idx = ::Faraday.default_connection.builder.handlers.size - 1
17
+ ::Faraday.default_connection.builder.insert(idx, Middleware)
18
+ @add_default_middleware = true
19
+ end
20
+
21
+ # https://github.com/lostisland/faraday/issues/946#issuecomment-500607890
22
+ # Monkey patch to force this middleware into every single Faraday.new client
23
+ def self.use_default_client_middleware!
24
+ return false if @use_default_client_middleware
25
+
26
+ register_middleware!
27
+ require "rollday/client_middleware"
28
+ ::Faraday::ConnectionOptions.prepend(Rollday::FaradayConnectionOptions)
29
+
30
+ @use_default_client_middleware = true
31
+ end
32
+
33
+ def self.register_middleware!
34
+ return false if @register_middleware
35
+
36
+ ::Faraday::Middleware.register_middleware(Rollday::MIDDLEWARE_NAME => Middleware)
37
+ @register_middleware = true
38
+ end
39
+ end
40
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rollday
4
- VERSION = "0.1.0"
4
+ VERSION = "0.5.0"
5
5
  end
data/lib/rollday.rb CHANGED
@@ -1,8 +1,50 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "faraday"
4
+ require "rollday/configuration"
5
+ require "rollday/errors"
6
+ require "rollday/middleware"
3
7
  require "rollday/version"
4
8
 
5
9
  module Rollday
6
- class Error < StandardError; end
7
- # Your code goes here...
10
+ MIDDLEWARE_NAME = :rollday.freeze
11
+
12
+ def self.configure
13
+ yield configuration if block_given?
14
+ end
15
+
16
+ def self.configuration
17
+ @configuration ||= Rollday::Configuration.new
18
+ end
19
+
20
+ def self.configuration=(object)
21
+ raise ConfigError, "Expected configuration to be a Rollday::Configuration" unless object.is_a?(Rollday::Configuration)
22
+
23
+ @configuration = object
24
+ end
25
+
26
+ def self.reset_configuration!
27
+ @configuration = Rollday::Configuration.new
28
+ end
29
+
30
+ class << self
31
+ alias_method :config, :configuration
32
+ alias_method :config=, :configuration=
33
+ alias_method :reset_config!, :reset_configuration!
34
+ end
35
+
36
+ def self.use_default_middleware!
37
+ Rollday::UseMiddleware.use_default_middleware!
38
+ end
39
+
40
+ def self.use_default_client_middleware!
41
+ Rollday::UseMiddleware.use_default_client_middleware!
42
+ end
43
+
44
+ def self.register_middleware!
45
+ Rollday::UseMiddleware.register_middleware!
46
+ end
47
+
48
+ def self.with_scope()
49
+ end
8
50
  end
data/rollday.gemspec CHANGED
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ["lib"]
31
31
 
32
+ spec.add_dependency "class_composer"
32
33
  spec.add_dependency "faraday"
33
34
  spec.add_dependency "rollbar"
34
35
 
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rollday
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Taylor
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-18 00:00:00.000000000 Z
11
+ date: 2022-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: class_composer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: faraday
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -117,6 +131,12 @@ files:
117
131
  - bin/setup
118
132
  - docker-compose.yml
119
133
  - lib/rollday.rb
134
+ - lib/rollday/client_middleware.rb
135
+ - lib/rollday/configuration.rb
136
+ - lib/rollday/errors.rb
137
+ - lib/rollday/middleware.rb
138
+ - lib/rollday/rollbar_helper.rb
139
+ - lib/rollday/use_middleware.rb
120
140
  - lib/rollday/version.rb
121
141
  - rollday.gemspec
122
142
  homepage: https://github.com/matt-taylor/rollday