rack-profiler 0.0.5 → 1.0.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 +4 -4
- data/README.md +48 -9
- data/lib/rack/profiler.rb +21 -11
- data/lib/rack/profiler/version.rb +1 -1
- data/public/rack-profiler.html +1 -1
- data/spec/rack/profiler_spec.rb +41 -19
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ada3784e0444ea4df49d755fac6dc82e3ae30ee2
|
4
|
+
data.tar.gz: 7611769984c985b48d7a49cfb36750a92c000da3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3d87464a4fdf2c46f2f236ff9633b042535ffdf5184fe03453d11706e77b2b2b27a9de0dfc76dfcf87308458a5d1e5aa9f11be2fc1e4ef19adf21fe721eda89
|
7
|
+
data.tar.gz: 62c9a482614f8be5ddde9917ac96c0f36eb278b5d7e62d479682f574b5c677a90c4f704c4ca5414e4eec802574951f3ccd2d5bfe589fd28fb03016ede66e9b61
|
data/README.md
CHANGED
@@ -55,27 +55,33 @@ require 'rack/profiler'
|
|
55
55
|
use Rack::Profiler
|
56
56
|
```
|
57
57
|
|
58
|
+
NOTE: you should not expose the profiler publicly in the production environment,
|
59
|
+
as it may contain sensitive information. Refer to the [`authorization
|
60
|
+
section`](#authorization) on how to protect it.
|
61
|
+
|
58
62
|
### Rails
|
59
63
|
|
60
64
|
You can add the `Rack::Profiler` middleware at the beginning of your `config.ru`
|
61
65
|
like in the Rack/Sinatra installation or insert it in the middlewares stack configuration
|
62
|
-
in
|
66
|
+
in your `config/environments/<env>.rb` files:
|
63
67
|
|
64
68
|
```ruby
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
# ...
|
69
|
-
|
70
|
-
config.middleware.insert_before Rack::Runtime, Rack::Profiler
|
69
|
+
YourApp.configure do |config|
|
70
|
+
# ...
|
71
71
|
|
72
|
-
|
72
|
+
config.middleware.insert 0, Rack::Profiler
|
73
73
|
end
|
74
74
|
```
|
75
75
|
|
76
|
+
NOTE: you should not expose the profiler publicly in the production environment,
|
77
|
+
as it may contain sensitive information. Refer to the [`authorization
|
78
|
+
section`](#authorization) for on to protect it.
|
79
|
+
|
76
80
|
## Configuration
|
77
81
|
|
78
|
-
You can configure `Rack::Profiler` passing a block to `use
|
82
|
+
You can configure `Rack::Profiler` passing a block to `use` (or
|
83
|
+
`middleware.insert` in Rails configuration). In the block you can subscribe to
|
84
|
+
more notifications and change some defaults:
|
79
85
|
|
80
86
|
```ruby
|
81
87
|
use Rack::Profiler do |profiler|
|
@@ -88,6 +94,39 @@ use Rack::Profiler do |profiler|
|
|
88
94
|
end
|
89
95
|
```
|
90
96
|
|
97
|
+
## Authorization
|
98
|
+
|
99
|
+
You typically *do not want to expose profiling publicly*, as it may contain
|
100
|
+
sensible information about your data and app. To protect your data, the easiest
|
101
|
+
option is to only enable the profiler in the development environment:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
if ENV['RACK_ENV'] == 'development'
|
105
|
+
require 'rack/profiler'
|
106
|
+
use Rack::Profiler
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
Sometimes though, you might want to run the profiler in the production
|
111
|
+
environment, in order to get results in a real setting (including caching and
|
112
|
+
optimizations). In this case, you can configure your custom authorization logic,
|
113
|
+
which can rely on the Rack env:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
use Rack::Profiler do |profiler|
|
117
|
+
profiler.authorize do |env|
|
118
|
+
# env is the Rack environment of the request. This block should return a
|
119
|
+
# truthy value when the request is allowed to be profiled, falsy otherwise.
|
120
|
+
env['rack-profiler-enabled'] == true
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# ...then in your app:
|
125
|
+
before do
|
126
|
+
env['rack-profiler-enabled'] = true if current_user.admin?
|
127
|
+
end
|
128
|
+
```
|
129
|
+
|
91
130
|
## Usage
|
92
131
|
|
93
132
|
### Custom steps
|
data/lib/rack/profiler.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require "rack"
|
2
2
|
require "rack/request"
|
3
|
+
require "rack/auth/basic"
|
3
4
|
require "rack/profiler/version"
|
4
5
|
require "active_support/notifications"
|
5
6
|
|
6
7
|
module Rack
|
7
8
|
class Profiler
|
8
9
|
|
9
|
-
attr_reader :events, :backtrace_filter, :subscriptions
|
10
|
+
attr_reader :events, :backtrace_filter, :subscriptions, :authorizator
|
10
11
|
attr_accessor :dashboard_path
|
11
12
|
|
12
13
|
DEFAULT_SUBSCRIPTIONS = ['sql.active_record',
|
@@ -36,6 +37,7 @@ module Rack
|
|
36
37
|
def call(env)
|
37
38
|
@events = []
|
38
39
|
req = Rack::Request.new(env)
|
40
|
+
env['rack-profiler'] = self
|
39
41
|
|
40
42
|
if req.path == dashboard_path
|
41
43
|
render_dashboard
|
@@ -69,6 +71,10 @@ module Rack
|
|
69
71
|
@backtrace_filter = block
|
70
72
|
end
|
71
73
|
|
74
|
+
def authorize(&block)
|
75
|
+
@authorizator = block
|
76
|
+
end
|
77
|
+
|
72
78
|
private
|
73
79
|
|
74
80
|
def render_profiler_results(env)
|
@@ -76,16 +82,16 @@ module Rack
|
|
76
82
|
ActiveSupport::Notifications.instrument('rack-profiler.total_time') do
|
77
83
|
status, headers, body = @app.call(env)
|
78
84
|
end
|
79
|
-
[
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
]
|
85
|
+
return [status, headers, body] unless authorized?(env)
|
86
|
+
results = {
|
87
|
+
events: events.sort_by { |event| event[:start] },
|
88
|
+
response: {
|
89
|
+
status: status,
|
90
|
+
headers: headers,
|
91
|
+
body: stringify_body(body)
|
92
|
+
}
|
93
|
+
}
|
94
|
+
[200, { 'Content-Type' => 'application/json' }, [results.to_json]]
|
89
95
|
end
|
90
96
|
|
91
97
|
def render_dashboard
|
@@ -115,5 +121,9 @@ module Rack
|
|
115
121
|
body.each { |part| str << part }
|
116
122
|
str
|
117
123
|
end
|
124
|
+
|
125
|
+
def authorized?(env)
|
126
|
+
@authorizator.nil? || @authorizator.call(env)
|
127
|
+
end
|
118
128
|
end
|
119
129
|
end
|
data/public/rack-profiler.html
CHANGED
data/spec/rack/profiler_spec.rb
CHANGED
@@ -34,6 +34,7 @@ describe Rack::Profiler do
|
|
34
34
|
it "sets the correct defaults" do
|
35
35
|
expect(profiler.dashboard_path).to eq('/rack-profiler')
|
36
36
|
expect(profiler.backtrace_filter).to be_nil
|
37
|
+
expect(profiler.authorizator).to be_nil
|
37
38
|
expect(profiler.subscriptions).to include(
|
38
39
|
*Rack::Profiler::DEFAULT_SUBSCRIPTIONS
|
39
40
|
)
|
@@ -118,25 +119,25 @@ describe Rack::Profiler do
|
|
118
119
|
|
119
120
|
let(:env) do
|
120
121
|
{
|
121
|
-
"PATH_INFO"
|
122
|
-
"QUERY_STRING"
|
123
|
-
"REMOTE_HOST"
|
124
|
-
"REQUEST_METHOD"
|
125
|
-
"REQUEST_URI"
|
126
|
-
"SCRIPT_NAME"
|
127
|
-
"SERVER_NAME"
|
128
|
-
"SERVER_PORT"
|
129
|
-
"SERVER_PROTOCOL"
|
130
|
-
"HTTP_HOST"
|
131
|
-
"rack.version"
|
132
|
-
"rack.input"
|
133
|
-
"rack.errors"
|
134
|
-
"rack.multithread"
|
122
|
+
"PATH_INFO" => "/",
|
123
|
+
"QUERY_STRING" => "",
|
124
|
+
"REMOTE_HOST" => "localhost",
|
125
|
+
"REQUEST_METHOD" => "GET",
|
126
|
+
"REQUEST_URI" => "http://localhost:3000/",
|
127
|
+
"SCRIPT_NAME" => "",
|
128
|
+
"SERVER_NAME" => "localhost",
|
129
|
+
"SERVER_PORT" => "3000",
|
130
|
+
"SERVER_PROTOCOL" => "HTTP/1.1",
|
131
|
+
"HTTP_HOST" => "localhost:3000",
|
132
|
+
"rack.version" => [1, 2],
|
133
|
+
"rack.input" => StringIO.new,
|
134
|
+
"rack.errors" => StringIO.new,
|
135
|
+
"rack.multithread" => true,
|
135
136
|
"rack.multiprocess" => false,
|
136
|
-
"rack.run_once"
|
137
|
-
"rack.url_scheme"
|
138
|
-
"HTTP_VERSION"
|
139
|
-
"REQUEST_PATH"
|
137
|
+
"rack.run_once" => false,
|
138
|
+
"rack.url_scheme" => "http",
|
139
|
+
"HTTP_VERSION" => "HTTP/1.1",
|
140
|
+
"REQUEST_PATH" => "/"
|
140
141
|
}
|
141
142
|
end
|
142
143
|
|
@@ -146,7 +147,7 @@ describe Rack::Profiler do
|
|
146
147
|
expect(profiler.events).not_to include('xxx')
|
147
148
|
end
|
148
149
|
|
149
|
-
context "when the path is
|
150
|
+
context "when the path is dashboard_path" do
|
150
151
|
it "renders dashboard" do
|
151
152
|
path = ::File.expand_path('../../public/rack-profiler.html',
|
152
153
|
::File.dirname( __FILE__ ) )
|
@@ -193,6 +194,27 @@ describe Rack::Profiler do
|
|
193
194
|
parsed_body['events'].map { |e| e['name'] }
|
194
195
|
).to include('rack-profiler.total_time', 'rack-profiler.step')
|
195
196
|
end
|
197
|
+
|
198
|
+
context "when authorization is configured" do
|
199
|
+
before do
|
200
|
+
profiler.authorize { |env| env['rack-profiler-allowed'] }
|
201
|
+
end
|
202
|
+
|
203
|
+
it "returns the original response if the request is not authorized" do
|
204
|
+
response = profiler.call(env_with_param)
|
205
|
+
expect(response).to eq(
|
206
|
+
[200, { 'X-My-Header' => 'foo' }, ['hello hello']]
|
207
|
+
)
|
208
|
+
end
|
209
|
+
|
210
|
+
it "returns the profiler results if the request is authorized" do
|
211
|
+
status, headers, body = profiler.call(
|
212
|
+
env_with_param.merge('rack-profiler-allowed' => true)
|
213
|
+
)
|
214
|
+
parsed_body = JSON.parse(body.join)
|
215
|
+
expect(parsed_body).to have_key('events')
|
216
|
+
end
|
217
|
+
end
|
196
218
|
end
|
197
219
|
end
|
198
220
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-profiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Ongaro
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-01-
|
12
|
+
date: 2015-01-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|