grape-middleware-logger 1.4.2 → 1.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
  SHA1:
3
- metadata.gz: 8674fefb691a3aa13fc0f8aa6ec1598fe93fdd88
4
- data.tar.gz: 88e7857d7d75146f31e359fa3bbc665d1283e86b
3
+ metadata.gz: 3669f6ad5c3a84da925373a79582e997b707fd3a
4
+ data.tar.gz: 94f09b4036667d394c5f794eab4782aedf656bb6
5
5
  SHA512:
6
- metadata.gz: 88cdf493d9648813e6b2a936549f5ba7b3199aa745798624bae63b4cf6f57ccfcb64fbd2ee737053ec8096b5619583be0dba7cefd4966838caccc36cbd9ee2cf
7
- data.tar.gz: 67888e1091ac47590638f4706178b51c76184afd504e80c2ba6d3315f969855ee6bd8f6599cea405df34325f731ed6066a22fd0cac4d6b759fc03f62e9a1c0b9
6
+ metadata.gz: 80804fc3261ce716e57e458c32381f4bb83c330fd6801f901d394b22a62d68d5b0574b197e9b3bf3467f5bcc633a2e0d1754beef86a239d04cd1dbe63dd4c63a
7
+ data.tar.gz: 46d9aadf9b6ee7ea7ff9201e2dc8dd596f53d9727d2c25b6c1a8de919fa592ab7dd420ce8a9a4302f406afdf5668c9f150c470cd6d4ee10b31b90f6fba961b34
data/.travis.yml CHANGED
@@ -5,3 +5,5 @@ rvm:
5
5
  - 2.2.2
6
6
  - 2.2.3
7
7
  before_install: gem install bundler -v 1.10.5
8
+ script:
9
+ - bin/test
data/Gemfile CHANGED
@@ -6,4 +6,5 @@ gemspec
6
6
  group :test do
7
7
  gem 'rake'
8
8
  gem "factory_girl", "~> 4.0"
9
+ gem "rails", "~> 4.2"
9
10
  end
data/README.md CHANGED
@@ -23,15 +23,12 @@ end
23
23
 
24
24
  Server requests will be logged to STDOUT by default.
25
25
 
26
- #### Rails
27
- Using Grape with Rails? The `Rails.logger` will be used by default.
28
-
29
- #### Custom setup
26
+ ## Custom setup
30
27
  Customize the logging by passing the `logger` option. Example using a CustomLogger and parameter sanitization:
31
28
  ```ruby
32
29
  use Grape::Middleware::Logger, {
33
30
  logger: CustomLogger.new,
34
- filter: ActionDispatch::Http::ParameterFilter.new(Rails.application.config.filter_parameters)
31
+ filter: CustomFilter.new
35
32
  }
36
33
  ```
37
34
  The `logger` option can be any object that responds to `.info(msg)`
@@ -55,6 +52,34 @@ Processing by ReportsAPI#reports
55
52
  Completed 422 in 6.29ms
56
53
  ```
57
54
 
55
+ ## Using Rails?
56
+ `Rails.logger` and `Rails.application.config.filter_parameters` will be used automatically as the default logger and
57
+ param filterer, respectively.
58
+
59
+ You may want to disable Rails logging for API endpoints, so that the logging doesn't double-up. You can achieve this
60
+ by switching around some middleware. For example:
61
+
62
+ ```ruby
63
+ # config/application.rb
64
+ config.middleware.delete 'Rails::Rack::Logger'
65
+ config.middleware.insert_after 'ActionDispatch::RequestId', 'SelectiveLogger'
66
+
67
+ # config/initializers/selective_logger.rb
68
+ class SelectiveLogger
69
+ def initialize(app)
70
+ @app = app
71
+ end
72
+
73
+ def call(env)
74
+ if env['PATH_INFO'] =~ %r{^/api}
75
+ @app.call(env)
76
+ else
77
+ Rails::Rack::Logger.new(@app).call(env)
78
+ end
79
+ end
80
+ end
81
+ ```
82
+
58
83
  ## Rack
59
84
 
60
85
  If you're using the `rackup` command to run your server in development, pass the `-q` flag to silence the default rack logger.
data/bin/test ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+ set -ev
3
+ bundle exec rspec spec/lib && bundle exec rspec spec/integration && bundle exec rspec spec/integration_rails
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'grape-middleware-logger'
5
- spec.version = '1.4.2'
5
+ spec.version = '1.5.0'
6
6
  spec.platform = Gem::Platform::RUBY
7
7
  spec.authors = ['Ryan Buckley']
8
8
  spec.email = ['arebuckley@gmail.com']
@@ -3,22 +3,30 @@ require 'grape'
3
3
 
4
4
  class Grape::Middleware::Logger < Grape::Middleware::Globals
5
5
  BACKSLASH = '/'.freeze
6
- BLANK_SPACE = ''.freeze
7
6
 
8
7
  attr_reader :logger
9
8
 
9
+ class << self
10
+ attr_accessor :logger, :filter
11
+
12
+ def default_logger
13
+ default = Logger.new(STDOUT)
14
+ default.formatter = ->(*args) { args.last.to_s << "\n".freeze }
15
+ default
16
+ end
17
+ end
18
+
10
19
  def initialize(_, options = {})
11
20
  super
12
- @logger = options[:logger]
13
- @logger ||= Rails.logger if defined?(Rails) && Rails.logger.present?
14
- @logger ||= default_logger
21
+ @options[:filter] ||= self.class.filter
22
+ @logger = options[:logger] || self.class.logger || self.class.default_logger
15
23
  end
16
24
 
17
25
  def before
18
26
  start_time
19
27
  # sets env['grape.*']
20
28
  super
21
- logger.info BLANK_SPACE
29
+ logger.info ''
22
30
  logger.info %Q(Started %s "%s" at %s) % [
23
31
  env[Grape::Env::GRAPE_REQUEST].request_method,
24
32
  env[Grape::Env::GRAPE_REQUEST].path,
@@ -60,7 +68,7 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
60
68
 
61
69
  def after(status)
62
70
  logger.info "Completed #{status} in #{((Time.now - start_time) * 1000).round(2)}ms"
63
- logger.info BLANK_SPACE
71
+ logger.info ''
64
72
  end
65
73
 
66
74
  #
@@ -93,14 +101,8 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
93
101
 
94
102
  def processed_by
95
103
  endpoint = env[Grape::Env::API_ENDPOINT]
96
- parts = endpoint.options[:for].to_s
97
- parts << endpoint.namespace if endpoint.namespace != BACKSLASH
98
- parts << '#'.freeze << endpoint.options[:path].map { |path| path.to_s.sub(BACKSLASH, BLANK_SPACE) }.join(BACKSLASH)
99
- end
100
-
101
- def default_logger
102
- default = Logger.new(STDOUT)
103
- default.formatter = ->(*args) { args.last.to_s << "\n".freeze }
104
- default
104
+ endpoint.options[:for].to_s << '#'.freeze << endpoint.options[:path].map { |path| path.to_s.sub(BACKSLASH, '') }.join(BACKSLASH)
105
105
  end
106
106
  end
107
+
108
+ require_relative 'logger/railtie' if defined?(Rails)
@@ -0,0 +1,6 @@
1
+ class Grape::Middleware::Logger::Railtie < Rails::Railtie
2
+ initializer 'grape.middleware.logger', after: :load_config_initializers do
3
+ Grape::Middleware::Logger.logger = Rails.application.config.logger || Rails.logger.presence
4
+ Grape::Middleware::Logger.filter = ActionDispatch::Http::ParameterFilter.new Rails.application.config.filter_parameters
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ class RailsApp < Rails::Application
2
+ RailsLogger = Class.new Logger
3
+ config.logger = RailsLogger.new(Tempfile.new '')
4
+ config.filter_parameters += [:password]
5
+ config.eager_load = false
6
+ end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'grape/middleware/logger'
3
2
 
4
3
  describe Grape::Middleware::Logger, type: :integration do
5
4
  let(:app) { build :app }
@@ -17,7 +16,7 @@ describe Grape::Middleware::Logger, type: :integration do
17
16
  expect(subject.logger).to receive(:info).with %Q(Started POST "/api/1.0/users" at #{subject.start_time})
18
17
  expect(subject.logger).to receive(:info).with %Q(Processing by TestAPI#users)
19
18
  expect(subject.logger).to receive(:info).with %Q( Parameters: {"id"=>"101001", "name"=>"foo", "password"=>"[FILTERED]"})
20
- expect(subject.logger).to receive(:info).with /Completed 200 in \d.\d+ms/
19
+ expect(subject.logger).to receive(:info).with /Completed 200 in \d+.\d+ms/
21
20
  expect(subject.logger).to receive(:info).with ''
22
21
  subject.call!(env)
23
22
  end
@@ -28,15 +27,15 @@ describe Grape::Middleware::Logger, type: :integration do
28
27
  context 'namespacing' do
29
28
  let(:grape_endpoint) { build(:namespaced_endpoint) }
30
29
 
31
- it 'designates the namespace with a slash' do
32
- expect(subject.processed_by).to eq 'TestAPI/admin#users'
30
+ it 'ignores the namespacing' do
31
+ expect(subject.processed_by).to eq 'TestAPI#users'
33
32
  end
34
33
 
35
34
  context 'with more complex route' do
36
35
  let(:grape_endpoint) { build(:namespaced_endpoint, :complex) }
37
36
 
38
37
  it 'only escapes the first slash and leaves the rest of the untouched' do
39
- expect(subject.processed_by).to eq 'TestAPI/admin#users/:name/profile'
38
+ expect(subject.processed_by).to eq 'TestAPI#users/:name/profile'
40
39
  end
41
40
  end
42
41
  end
@@ -49,4 +48,5 @@ describe Grape::Middleware::Logger, type: :integration do
49
48
  end
50
49
  end
51
50
  end
51
+
52
52
  end
@@ -0,0 +1,82 @@
1
+ require 'rails_helper'
2
+
3
+ describe Grape::Middleware::Logger, type: :rails_integration do
4
+ let(:app) { build :app }
5
+ let(:options) { {} }
6
+
7
+ subject { described_class.new(app, options) }
8
+
9
+ let(:app_response) { build :app_response }
10
+ let(:grape_request) { build :grape_request }
11
+ let(:grape_endpoint) { build(:grape_endpoint) }
12
+ let(:env) { build(:expected_env, grape_endpoint: grape_endpoint) }
13
+
14
+ describe '#logger' do
15
+ context 'when @options[:logger] is nil' do
16
+ context 'when Rails.application.config.logger is defined' do
17
+ it 'uses the Rails logger' do
18
+ expect(subject.logger).to be_present
19
+ expect(subject.logger).to be Rails.application.config.logger
20
+ expect(subject.logger.formatter).to be_nil
21
+ end
22
+ end
23
+
24
+ context 'when the class logger is nil' do
25
+ before { described_class.logger = nil }
26
+
27
+ it 'uses the default logger' do
28
+ expect(subject.logger).to be_present
29
+ expect(subject.logger).to_not be Rails.application.config.logger
30
+ expect(subject.logger).to be_a(Logger)
31
+ expect(subject.logger.formatter.call('foo')).to eq "foo\n"
32
+ end
33
+ end
34
+ end
35
+
36
+ context 'when @options[:logger] is set' do
37
+ let(:options) { { logger: Object.new } }
38
+
39
+ it 'returns the logger object' do
40
+ expect(subject.logger).to eq options[:logger]
41
+ end
42
+ end
43
+ end
44
+
45
+ it 'logs all parts of the request' do
46
+ expect(subject.logger).to receive(:info).with ''
47
+ expect(subject.logger).to receive(:info).with %Q(Started POST "/api/1.0/users" at #{subject.start_time})
48
+ expect(subject.logger).to receive(:info).with %Q(Processing by TestAPI#users)
49
+ expect(subject.logger).to receive(:info).with %Q( Parameters: {"id"=>"101001", "name"=>"foo", "password"=>"[FILTERED]"})
50
+ expect(subject.logger).to receive(:info).with /Completed 200 in \d+.\d+ms/
51
+ expect(subject.logger).to receive(:info).with ''
52
+ subject.call!(env)
53
+ end
54
+
55
+ describe 'the "processing by" section' do
56
+ before { subject.call!(env) }
57
+
58
+ context 'namespacing' do
59
+ let(:grape_endpoint) { build(:namespaced_endpoint) }
60
+
61
+ it 'ignores the namespacing' do
62
+ expect(subject.processed_by).to eq 'TestAPI#users'
63
+ end
64
+
65
+ context 'with more complex route' do
66
+ let(:grape_endpoint) { build(:namespaced_endpoint, :complex) }
67
+
68
+ it 'only escapes the first slash and leaves the rest of the untouched' do
69
+ expect(subject.processed_by).to eq 'TestAPI#users/:name/profile'
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'with more complex route' do
75
+ let(:grape_endpoint) { build(:grape_endpoint, :complex) }
76
+
77
+ it 'only escapes the first slash and leaves the rest of the untouched' do
78
+ expect(subject.processed_by).to eq 'TestAPI#users/:name/profile'
79
+ end
80
+ end
81
+ end
82
+ end
@@ -99,52 +99,4 @@ describe Grape::Middleware::Logger do
99
99
  end
100
100
  end
101
101
  end
102
-
103
- describe '#logger' do
104
- context 'when @options[:logger] is nil' do
105
- let(:options) { {} }
106
-
107
- context 'when Rails is defined' do
108
- before do
109
- module Rails
110
- class << self
111
- attr_accessor :logger
112
- end
113
- end
114
- end
115
-
116
- it 'defaults to the the standard Logger' do
117
- expect(subject.logger).to be_a(Logger)
118
- end
119
-
120
- it 'logs each message in the correct format' do
121
- expect(subject.logger.formatter.call('foo')).to eq "foo\n"
122
- end
123
-
124
- context 'when Rails.logger is defined' do
125
- before do
126
- Rails.logger = double('rails_logger')
127
- end
128
-
129
- it 'sets @logger to Rails.logger' do
130
- expect(subject.logger).to be Rails.logger
131
- end
132
-
133
- after do
134
- Rails.logger = nil
135
- end
136
- end
137
-
138
- after do
139
- Object.send :remove_const, :Rails
140
- end
141
- end
142
- end
143
-
144
- context 'when @options[:logger] is set' do
145
- it 'returns the logger object' do
146
- expect(subject.logger).to eq options[:logger]
147
- end
148
- end
149
- end
150
102
  end
@@ -0,0 +1,4 @@
1
+ require 'rails'
2
+ require_relative 'fixtures/rails_app'
3
+ require 'spec_helper'
4
+ RailsApp.initialize!
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-middleware-logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.2
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Buckley
@@ -81,7 +81,8 @@ dependencies:
81
81
  description: Logging middleware for the Grape framework, similar to what Rails offers
82
82
  email:
83
83
  - arebuckley@gmail.com
84
- executables: []
84
+ executables:
85
+ - test
85
86
  extensions: []
86
87
  extra_rdoc_files: []
87
88
  files:
@@ -91,11 +92,16 @@ files:
91
92
  - LICENSE.txt
92
93
  - README.md
93
94
  - Rakefile
95
+ - bin/test
94
96
  - grape-middleware-logger.gemspec
95
97
  - lib/grape/middleware/logger.rb
98
+ - lib/grape/middleware/logger/railtie.rb
96
99
  - spec/factories.rb
100
+ - spec/fixtures/rails_app.rb
97
101
  - spec/integration/lib/grape/middleware/logger_spec.rb
102
+ - spec/integration_rails/lib/grape/middleware/logger_spec.rb
98
103
  - spec/lib/grape/middleware/logger_spec.rb
104
+ - spec/rails_helper.rb
99
105
  - spec/spec_helper.rb
100
106
  homepage: https://github.com/ridiculous/grape-middleware-logger
101
107
  licenses:
@@ -123,6 +129,9 @@ specification_version: 4
123
129
  summary: A logger for the Grape framework
124
130
  test_files:
125
131
  - spec/factories.rb
132
+ - spec/fixtures/rails_app.rb
126
133
  - spec/integration/lib/grape/middleware/logger_spec.rb
134
+ - spec/integration_rails/lib/grape/middleware/logger_spec.rb
127
135
  - spec/lib/grape/middleware/logger_spec.rb
136
+ - spec/rails_helper.rb
128
137
  - spec/spec_helper.rb