grape-middleware-logger 1.5.1 → 1.6.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 +6 -6
- data/README.md +18 -17
- data/Rakefile +14 -2
- data/grape-middleware-logger.gemspec +2 -1
- data/lib/grape/middleware/logger.rb +24 -4
- data/spec/factories.rb +12 -6
- data/spec/integration/lib/grape/middleware/logger_spec.rb +5 -5
- data/spec/integration_rails/lib/grape/middleware/logger_spec.rb +5 -5
- data/spec/lib/grape/middleware/logger_spec.rb +4 -4
- metadata +17 -5
- data/bin/test +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34d9661cdf4110b925306cef1ca08daa1de0984b
|
4
|
+
data.tar.gz: 30a697f95684f81f84a1ab8d99b91d90730dd3ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0efea695b1be2caaf8bc63b104abc6a57240b7504d2a05bf5d15449b925feb96a5c2bcb02764979889e320391de53336af8ecfd5f107ded7663e3efccd1203ff
|
7
|
+
data.tar.gz: c2ab1a0ee0cb763d903b4a7b54a8f9368e8b2ab0b326a68a8d905cdfc873b9aced8239487b9abbcf2c697d7cb6289927ce33b8ac255d41570b2a9ef9fad27d67
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
-
# Grape
|
1
|
+
# A logger for Grape apps
|
2
2
|
[![Code Climate](https://codeclimate.com/github/ridiculous/grape-middleware-logger/badges/gpa.svg)](https://codeclimate.com/github/ridiculous/grape-middleware-logger) [![Gem Version](https://badge.fury.io/rb/grape-middleware-logger.svg)](http://badge.fury.io/rb/grape-middleware-logger)
|
3
3
|
[![Build Status](https://travis-ci.org/ridiculous/grape-middleware-logger.svg)](https://travis-ci.org/ridiculous/grape-middleware-logger)
|
4
4
|
|
5
|
-
|
5
|
+
Logs:
|
6
|
+
* Request path
|
7
|
+
* Parameters
|
8
|
+
* Endpoint class name and handler
|
9
|
+
* Response status
|
10
|
+
* Duration of the request
|
11
|
+
* Exceptions
|
12
|
+
* Error responses from `error!`
|
6
13
|
|
7
14
|
## Installation
|
8
15
|
|
@@ -23,35 +30,30 @@ end
|
|
23
30
|
|
24
31
|
Server requests will be logged to STDOUT by default.
|
25
32
|
|
26
|
-
## Custom setup
|
27
|
-
Customize the logging by passing the `logger` option. Example using a CustomLogger and parameter sanitization:
|
28
|
-
```ruby
|
29
|
-
use Grape::Middleware::Logger, {
|
30
|
-
logger: CustomLogger.new,
|
31
|
-
filter: CustomFilter.new
|
32
|
-
}
|
33
|
-
```
|
34
|
-
The `logger` option can be any object that responds to `.info(msg)`
|
35
|
-
|
36
|
-
The `filter` option can be any object that responds to `.filter(params_hash)`
|
37
|
-
|
38
33
|
## Example output
|
39
34
|
Get
|
40
35
|
```
|
41
36
|
Started GET "/v1/reports/101" at 2015-12-11 15:40:51 -0800
|
42
|
-
Processing by ReportsAPI
|
37
|
+
Processing by ReportsAPI/reports/:id
|
43
38
|
Parameters: {"id"=>"101"}
|
44
39
|
Completed 200 in 6.29ms
|
45
40
|
```
|
46
41
|
Error
|
47
42
|
```
|
48
43
|
Started POST "/v1/reports" at 2015-12-11 15:42:33 -0800
|
49
|
-
Processing by ReportsAPI
|
44
|
+
Processing by ReportsAPI/reports
|
50
45
|
Parameters: {"name"=>"foo", "password"=>"[FILTERED]"}
|
51
46
|
Error: {:error=>"undefined something something bad", :detail=>"Whoops"}
|
52
47
|
Completed 422 in 6.29ms
|
53
48
|
```
|
54
49
|
|
50
|
+
## Customization
|
51
|
+
|
52
|
+
The middleware logger can be customized with the following options:
|
53
|
+
|
54
|
+
* The `:logger` option can be any object that responds to `.info(String)`
|
55
|
+
* The `:filter` option can be any object that responds to `.filter(Hash)` and returns a hash.
|
56
|
+
|
55
57
|
## Using Rails?
|
56
58
|
`Rails.logger` and `Rails.application.config.filter_parameters` will be used automatically as the default logger and
|
57
59
|
param filterer, respectively.
|
@@ -93,7 +95,6 @@ and would love to see these two consolidated at some point.
|
|
93
95
|
## Contributing
|
94
96
|
|
95
97
|
1. Fork it ( https://github.com/ridiculous/grape-middleware-logger/fork )
|
96
|
-
1. Run the test suite with `bin/test`
|
97
98
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
98
99
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
99
100
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/Rakefile
CHANGED
@@ -1,3 +1,15 @@
|
|
1
1
|
require 'rspec/core/rake_task'
|
2
|
-
|
3
|
-
|
2
|
+
|
3
|
+
RSpec::Core::RakeTask.new(:spec) do |config|
|
4
|
+
config.pattern = 'spec/lib/**/*_spec.rb'
|
5
|
+
end
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:integration) do |config|
|
8
|
+
config.pattern = 'spec/integration/**/*_spec.rb'
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec::Core::RakeTask.new(:integration_rails) do |config|
|
12
|
+
config.pattern = 'spec/integration_rails/**/*_spec.rb'
|
13
|
+
end
|
14
|
+
|
15
|
+
task default: [:spec, :integration, :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.
|
5
|
+
spec.version = '1.6.0'
|
6
6
|
spec.platform = Gem::Platform::RUBY
|
7
7
|
spec.authors = ['Ryan Buckley']
|
8
8
|
spec.email = ['arebuckley@gmail.com']
|
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.add_dependency 'grape', '>= 0.14', '< 1'
|
20
20
|
|
21
21
|
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
|
+
spec.add_development_dependency 'mime-types', '~> 2'
|
22
23
|
spec.add_development_dependency 'rake', '~> 10.0'
|
23
24
|
spec.add_development_dependency 'rspec', '>= 3.2', '< 4'
|
24
25
|
end
|
@@ -7,7 +7,7 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
|
|
7
7
|
attr_reader :logger
|
8
8
|
|
9
9
|
class << self
|
10
|
-
attr_accessor :logger, :filter
|
10
|
+
attr_accessor :logger, :filter, :on_parameters
|
11
11
|
|
12
12
|
def default_logger
|
13
13
|
default = Logger.new(STDOUT)
|
@@ -82,7 +82,12 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
|
|
82
82
|
|
83
83
|
def parameters
|
84
84
|
request_params = env[Grape::Env::GRAPE_REQUEST_PARAMS].to_hash
|
85
|
-
|
85
|
+
formatter = Grape::Middleware::Formatter.new(app)
|
86
|
+
formatter.instance_variable_set :@env, env
|
87
|
+
# @note parses and assigns params to @env[Grape::Env::RACK_REQUEST_FORM_HASH]
|
88
|
+
formatter.before
|
89
|
+
request_params.merge! env[Grape::Env::RACK_REQUEST_FORM_HASH] if env[Grape::Env::RACK_REQUEST_FORM_HASH]
|
90
|
+
request_params.merge! env['action_dispatch.request.request_parameters'] if env['action_dispatch.request.request_parameters']
|
86
91
|
if @options[:filter]
|
87
92
|
@options[:filter].filter(request_params)
|
88
93
|
else
|
@@ -96,8 +101,23 @@ class Grape::Middleware::Logger < Grape::Middleware::Globals
|
|
96
101
|
|
97
102
|
def processed_by
|
98
103
|
endpoint = env[Grape::Env::API_ENDPOINT]
|
99
|
-
|
104
|
+
result = []
|
105
|
+
if endpoint.namespace == BACKSLASH
|
106
|
+
result << ''
|
107
|
+
else
|
108
|
+
result << endpoint.namespace
|
109
|
+
end
|
110
|
+
result.concat endpoint.options[:path].map { |path| path.to_s.sub(BACKSLASH, '') }
|
111
|
+
endpoint.options[:for].to_s << result.join(BACKSLASH)
|
100
112
|
end
|
101
113
|
end
|
102
114
|
|
103
|
-
|
115
|
+
# @description Override formatter #before so we don't read and parse the env['rack.input'] value twice
|
116
|
+
Grape::Middleware::Formatter.send :define_method, :before do
|
117
|
+
negotiate_content_type
|
118
|
+
read_body_input unless env.key? Grape::Env::RACK_REQUEST_FORM_HASH
|
119
|
+
end
|
120
|
+
|
121
|
+
if defined?(Rails)
|
122
|
+
require_relative 'logger/railtie'
|
123
|
+
end
|
data/spec/factories.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
FactoryGirl.define do
|
2
2
|
class ExpectedEnv < Hash
|
3
|
-
attr_accessor :grape_request, :params, :post_params, :grape_endpoint
|
3
|
+
attr_accessor :grape_request, :params, :post_params, :rails_post_params, :grape_endpoint
|
4
4
|
end
|
5
5
|
|
6
6
|
class ParamFilter
|
7
|
+
attr_accessor :list
|
8
|
+
|
7
9
|
def filter(opts)
|
8
|
-
opts.each_pair { |key, val| val[0..-1] = '[FILTERED]' if key
|
10
|
+
opts.each_pair { |key, val| val[0..-1] = '[FILTERED]' if list.include?(key) }
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
@@ -20,23 +22,27 @@ FactoryGirl.define do
|
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
|
-
factory :param_filter
|
25
|
+
factory :param_filter do
|
26
|
+
list %w[password secret]
|
27
|
+
end
|
24
28
|
|
25
29
|
require 'rack/rewindable_input'
|
26
30
|
|
27
31
|
factory :expected_env do
|
28
32
|
grape_request { build :grape_request }
|
29
|
-
params { grape_request.params }
|
30
|
-
post_params { { 'name' => 'foo', 'password' => 'access' } }
|
31
33
|
grape_endpoint { build(:grape_endpoint) }
|
34
|
+
params { grape_request.params }
|
35
|
+
post_params { { 'secret' => 'key', 'customer' => [] } }
|
36
|
+
rails_post_params { { 'name' => 'foo', 'password' => 'access' } }
|
32
37
|
|
33
38
|
initialize_with do
|
34
39
|
new.merge(
|
35
40
|
'REQUEST_METHOD' => 'POST',
|
36
41
|
'PATH_INFO' => '/api/1.0/users',
|
37
|
-
'action_dispatch.request.request_parameters' =>
|
42
|
+
'action_dispatch.request.request_parameters' => rails_post_params,
|
38
43
|
Grape::Env::GRAPE_REQUEST => grape_request,
|
39
44
|
Grape::Env::GRAPE_REQUEST_PARAMS => params,
|
45
|
+
Grape::Env::RACK_REQUEST_FORM_HASH => post_params,
|
40
46
|
Grape::Env::API_ENDPOINT => grape_endpoint
|
41
47
|
)
|
42
48
|
end
|
@@ -14,8 +14,8 @@ describe Grape::Middleware::Logger, type: :integration do
|
|
14
14
|
it 'logs all parts of the request' do
|
15
15
|
expect(subject.logger).to receive(:info).with ''
|
16
16
|
expect(subject.logger).to receive(:info).with %Q(Started POST "/api/1.0/users" at #{subject.start_time})
|
17
|
-
expect(subject.logger).to receive(:info).with %Q(Processing by TestAPI
|
18
|
-
expect(subject.logger).to receive(:info).with %Q( Parameters: {"id"=>"101001", "name"=>"foo", "password"=>"[FILTERED]"})
|
17
|
+
expect(subject.logger).to receive(:info).with %Q(Processing by TestAPI/users)
|
18
|
+
expect(subject.logger).to receive(:info).with %Q( Parameters: {"id"=>"101001", "secret"=>"[FILTERED]", "customer"=>[], "name"=>"foo", "password"=>"[FILTERED]"})
|
19
19
|
expect(subject.logger).to receive(:info).with /Completed 200 in \d+.\d+ms/
|
20
20
|
expect(subject.logger).to receive(:info).with ''
|
21
21
|
subject.call!(env)
|
@@ -28,14 +28,14 @@ describe Grape::Middleware::Logger, type: :integration do
|
|
28
28
|
let(:grape_endpoint) { build(:namespaced_endpoint) }
|
29
29
|
|
30
30
|
it 'ignores the namespacing' do
|
31
|
-
expect(subject.processed_by).to eq 'TestAPI
|
31
|
+
expect(subject.processed_by).to eq 'TestAPI/admin/users'
|
32
32
|
end
|
33
33
|
|
34
34
|
context 'with more complex route' do
|
35
35
|
let(:grape_endpoint) { build(:namespaced_endpoint, :complex) }
|
36
36
|
|
37
37
|
it 'only escapes the first slash and leaves the rest of the untouched' do
|
38
|
-
expect(subject.processed_by).to eq 'TestAPI
|
38
|
+
expect(subject.processed_by).to eq 'TestAPI/admin/users/:name/profile'
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -44,7 +44,7 @@ describe Grape::Middleware::Logger, type: :integration do
|
|
44
44
|
let(:grape_endpoint) { build(:grape_endpoint, :complex) }
|
45
45
|
|
46
46
|
it 'only escapes the first slash and leaves the rest of the untouched' do
|
47
|
-
expect(subject.processed_by).to eq 'TestAPI
|
47
|
+
expect(subject.processed_by).to eq 'TestAPI/users/:name/profile'
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -45,8 +45,8 @@ describe Grape::Middleware::Logger, type: :rails_integration do
|
|
45
45
|
it 'logs all parts of the request' do
|
46
46
|
expect(subject.logger).to receive(:info).with ''
|
47
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
|
49
|
-
expect(subject.logger).to receive(:info).with %Q( Parameters: {"id"=>"101001", "name"=>"foo", "password"=>"[FILTERED]"})
|
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", "secret"=>"key", "customer"=>[], "name"=>"foo", "password"=>"[FILTERED]"})
|
50
50
|
expect(subject.logger).to receive(:info).with /Completed 200 in \d+.\d+ms/
|
51
51
|
expect(subject.logger).to receive(:info).with ''
|
52
52
|
subject.call!(env)
|
@@ -59,14 +59,14 @@ describe Grape::Middleware::Logger, type: :rails_integration do
|
|
59
59
|
let(:grape_endpoint) { build(:namespaced_endpoint) }
|
60
60
|
|
61
61
|
it 'ignores the namespacing' do
|
62
|
-
expect(subject.processed_by).to eq 'TestAPI
|
62
|
+
expect(subject.processed_by).to eq 'TestAPI/admin/users'
|
63
63
|
end
|
64
64
|
|
65
65
|
context 'with more complex route' do
|
66
66
|
let(:grape_endpoint) { build(:namespaced_endpoint, :complex) }
|
67
67
|
|
68
68
|
it 'only escapes the first slash and leaves the rest of the untouched' do
|
69
|
-
expect(subject.processed_by).to eq 'TestAPI
|
69
|
+
expect(subject.processed_by).to eq 'TestAPI/admin/users/:name/profile'
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -75,7 +75,7 @@ describe Grape::Middleware::Logger, type: :rails_integration do
|
|
75
75
|
let(:grape_endpoint) { build(:grape_endpoint, :complex) }
|
76
76
|
|
77
77
|
it 'only escapes the first slash and leaves the rest of the untouched' do
|
78
|
-
expect(subject.processed_by).to eq 'TestAPI
|
78
|
+
expect(subject.processed_by).to eq 'TestAPI/users/:name/profile'
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
@@ -8,7 +8,7 @@ describe Grape::Middleware::Logger do
|
|
8
8
|
|
9
9
|
let(:app_response) { build :app_response }
|
10
10
|
let(:grape_request) { build :grape_request }
|
11
|
-
let(:env) { build
|
11
|
+
let(:env) { build :expected_env }
|
12
12
|
|
13
13
|
describe '#call!' do
|
14
14
|
context 'when calling the app results in an error response' do
|
@@ -82,12 +82,12 @@ describe Grape::Middleware::Logger do
|
|
82
82
|
|
83
83
|
context 'when @options[:filter] is set' do
|
84
84
|
it 'calls +filter+ with the raw parameters' do
|
85
|
-
expect(subject.options[:filter]).to receive(:filter).with({ "id" => '101001', "
|
85
|
+
expect(subject.options[:filter]).to receive(:filter).with({ "id" => '101001', "secret" => "key", "customer" => [], "name"=>"foo", "password"=>"access" })
|
86
86
|
subject.parameters
|
87
87
|
end
|
88
88
|
|
89
89
|
it 'returns the filtered results' do
|
90
|
-
expect(subject.parameters).to eq({ "id" => '101001', "
|
90
|
+
expect(subject.parameters).to eq({ "id" => '101001', "secret" => "[FILTERED]", "customer" => [], "name"=>"foo", "password"=>"[FILTERED]" })
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
@@ -95,7 +95,7 @@ describe Grape::Middleware::Logger do
|
|
95
95
|
let(:options) { {} }
|
96
96
|
|
97
97
|
it 'returns the params extracted out of @env' do
|
98
|
-
expect(subject.parameters).to eq({ "id" => '101001', "
|
98
|
+
expect(subject.parameters).to eq({ "id" => '101001', "secret" => "key", "customer" => [], "name"=>"foo", "password"=>"access" })
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Buckley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grape
|
@@ -44,6 +44,20 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '1.7'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: mime-types
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '2'
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
62
|
name: rake
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,8 +95,7 @@ dependencies:
|
|
81
95
|
description: Logging middleware for the Grape framework, similar to what Rails offers
|
82
96
|
email:
|
83
97
|
- arebuckley@gmail.com
|
84
|
-
executables:
|
85
|
-
- test
|
98
|
+
executables: []
|
86
99
|
extensions: []
|
87
100
|
extra_rdoc_files: []
|
88
101
|
files:
|
@@ -92,7 +105,6 @@ files:
|
|
92
105
|
- LICENSE.txt
|
93
106
|
- README.md
|
94
107
|
- Rakefile
|
95
|
-
- bin/test
|
96
108
|
- grape-middleware-logger.gemspec
|
97
109
|
- lib/grape/middleware/logger.rb
|
98
110
|
- lib/grape/middleware/logger/railtie.rb
|
data/bin/test
DELETED