grape-middleware-logger 1.4.2 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/Gemfile +1 -0
- data/README.md +30 -5
- data/bin/test +3 -0
- data/grape-middleware-logger.gemspec +1 -1
- data/lib/grape/middleware/logger.rb +17 -15
- data/lib/grape/middleware/logger/railtie.rb +6 -0
- data/spec/fixtures/rails_app.rb +6 -0
- data/spec/integration/lib/grape/middleware/logger_spec.rb +5 -5
- data/spec/integration_rails/lib/grape/middleware/logger_spec.rb +82 -0
- data/spec/lib/grape/middleware/logger_spec.rb +0 -48
- data/spec/rails_helper.rb +4 -0
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3669f6ad5c3a84da925373a79582e997b707fd3a
|
4
|
+
data.tar.gz: 94f09b4036667d394c5f794eab4782aedf656bb6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80804fc3261ce716e57e458c32381f4bb83c330fd6801f901d394b22a62d68d5b0574b197e9b3bf3467f5bcc633a2e0d1754beef86a239d04cd1dbe63dd4c63a
|
7
|
+
data.tar.gz: 46d9aadf9b6ee7ea7ff9201e2dc8dd596f53d9727d2c25b6c1a8de919fa592ab7dd420ce8a9a4302f406afdf5668c9f150c470cd6d4ee10b31b90f6fba961b34
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
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
|
-
|
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:
|
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
@@ -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
|
-
@
|
13
|
-
@logger
|
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
|
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
|
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
|
-
|
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
|
@@ -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
|
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 '
|
32
|
-
expect(subject.processed_by).to eq 'TestAPI
|
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
|
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
|
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
|
+
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
|