rack-mini-profiler 0.1.7 → 0.1.8
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.
Potentially problematic release.
This version of rack-mini-profiler might be problematic. Click here for more details.
- data/CHANGELOG +6 -0
- data/README.md +18 -0
- data/lib/html/profile_handler.js +9 -9
- data/lib/html/share.html +11 -0
- data/lib/mini_profiler/client_timer_struct.rb +5 -3
- data/lib/mini_profiler/config.rb +2 -1
- data/lib/mini_profiler/page_timer_struct.rb +1 -1
- data/lib/mini_profiler/profiler.rb +36 -13
- data/lib/mini_profiler/storage/file_store.rb +8 -7
- data/lib/mini_profiler/storage/memory_store.rb +0 -4
- data/lib/mini_profiler_rails/railtie.rb +3 -1
- data/lib/rack-mini-profiler.rb +3 -3
- data/rack-mini-profiler.gemspec +3 -4
- metadata +5 -5
- data/lib/mini_profiler/body_add_proxy.rb +0 -45
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -47,6 +47,24 @@ class MyApp < Sinatra::Base
|
|
47
47
|
end
|
48
48
|
```
|
49
49
|
|
50
|
+
## Storage
|
51
|
+
|
52
|
+
By default, rack-mini-profiler stores its results in a memory store:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
# our default
|
56
|
+
Rack::MiniProfiler.config.storage = Rack::MiniProfiler::MemoryStore
|
57
|
+
```
|
58
|
+
|
59
|
+
There are 2 other available storage engines, `RedisStore` and `FileStore`.
|
60
|
+
|
61
|
+
MemoryStore is stores results in a processes heap - something that does not work well in a multi process environment.
|
62
|
+
FileStore stores results in the file system - something that may not work well in a multi machine environment.
|
63
|
+
|
64
|
+
Additionally you may implement an AbstractStore for your own provider.
|
65
|
+
|
66
|
+
Rails hooks up a FileStore for all environments.
|
67
|
+
|
50
68
|
## Running the Specs
|
51
69
|
|
52
70
|
```
|
data/lib/html/profile_handler.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
<script type="text/javascript">
|
1
|
+
<script type="text/javascript">
|
2
2
|
(function(){{
|
3
|
-
var init = function() {{
|
3
|
+
var init = function() {{
|
4
4
|
var load = function(s,f){{
|
5
5
|
var sc = document.createElement('script');
|
6
6
|
sc.async = 'async';
|
@@ -14,8 +14,8 @@
|
|
14
14
|
}};
|
15
15
|
|
16
16
|
document.getElementsByTagName('head')[0].appendChild(sc);
|
17
|
-
}};
|
18
|
-
|
17
|
+
}};
|
18
|
+
|
19
19
|
var initMp = function(){{
|
20
20
|
load('{path}includes.js?v={version}',function(){{
|
21
21
|
MiniProfiler.init({{
|
@@ -32,18 +32,18 @@
|
|
32
32
|
}});
|
33
33
|
}});
|
34
34
|
}};
|
35
|
-
if ({useExistingjQuery}) {{
|
35
|
+
if ({useExistingjQuery} && typeof(jQuery) === 'function') {{
|
36
36
|
jQueryMP = jQuery;
|
37
37
|
initMp();
|
38
38
|
}} else {{
|
39
39
|
load('{path}jquery.1.7.1.js?v={version}', initMp);
|
40
40
|
}}
|
41
|
-
|
41
|
+
|
42
42
|
}};
|
43
43
|
|
44
|
-
var w = 0;
|
44
|
+
var w = 0;
|
45
45
|
var f = false;
|
46
|
-
var deferInit = function(){{
|
46
|
+
var deferInit = function(){{
|
47
47
|
if (f) return;
|
48
48
|
if (window.performance && window.performance.timing && window.performance.timing.loadEventEnd == 0 && w < 10000){{
|
49
49
|
setTimeout(deferInit, 100);
|
@@ -59,4 +59,4 @@
|
|
59
59
|
var o = window.onload;
|
60
60
|
window.onload = function(){{if(o)o; deferInit()}};
|
61
61
|
}})();
|
62
|
-
</script>
|
62
|
+
</script>
|
data/lib/html/share.html
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>{name} ({duration} ms) - Profiling Results</title>
|
4
|
+
<script type='text/javascript' src='{path}jquery.1.7.1.js?v={version}'></script>
|
5
|
+
<script type='text/javascript'> var profiler = {json}; </script>
|
6
|
+
{includes}
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div class='profiler-result-full'></div>
|
10
|
+
</body>
|
11
|
+
</html>
|
@@ -23,7 +23,7 @@ module Rack
|
|
23
23
|
super
|
24
24
|
end
|
25
25
|
|
26
|
-
def init_from_form_data(env, page_struct)
|
26
|
+
def self.init_from_form_data(env, page_struct)
|
27
27
|
timings = []
|
28
28
|
clientTimes, clientPerf, baseTime = nil
|
29
29
|
form = env['rack.request.form_hash']
|
@@ -67,8 +67,10 @@ module Rack
|
|
67
67
|
timings.push("Name" => k, "Start" => clientTimes[k].to_i - baseTime, "Duration" => -1)
|
68
68
|
end
|
69
69
|
|
70
|
-
|
71
|
-
|
70
|
+
rval = self.new
|
71
|
+
rval['RedirectCount'] = env['rack.request.form_hash']['clientPerformance']['navigation']['redirectCount']
|
72
|
+
rval['Timings'] = timings
|
73
|
+
rval
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
data/lib/mini_profiler/config.rb
CHANGED
@@ -14,7 +14,7 @@ module Rack
|
|
14
14
|
|
15
15
|
attr_accessor :auto_inject, :base_url_path, :pre_authorize_cb, :position,
|
16
16
|
:backtrace_remove, :backtrace_filter, :skip_schema_queries,
|
17
|
-
:storage, :user_provider, :storage_instance, :storage_options, :skip_paths, :authorization_mode
|
17
|
+
:storage, :user_provider, :storage_instance, :storage_options, :skip_paths, :authorization_mode, :use_existing_jquery
|
18
18
|
|
19
19
|
def self.default
|
20
20
|
new.instance_eval {
|
@@ -30,6 +30,7 @@ module Rack
|
|
30
30
|
@storage = MiniProfiler::MemoryStore
|
31
31
|
@user_provider = Proc.new{|env| Rack::Request.new(env).ip}
|
32
32
|
@authorization_mode = :allow_all
|
33
|
+
@use_existing_jquery = false
|
33
34
|
self
|
34
35
|
}
|
35
36
|
end
|
@@ -6,7 +6,6 @@ require 'mini_profiler/page_timer_struct'
|
|
6
6
|
require 'mini_profiler/sql_timer_struct'
|
7
7
|
require 'mini_profiler/client_timer_struct'
|
8
8
|
require 'mini_profiler/request_timer_struct'
|
9
|
-
require 'mini_profiler/body_add_proxy'
|
10
9
|
require 'mini_profiler/storage/abstract_store'
|
11
10
|
require 'mini_profiler/storage/memory_store'
|
12
11
|
require 'mini_profiler/storage/redis_store'
|
@@ -101,8 +100,9 @@ module Rack
|
|
101
100
|
@app = app
|
102
101
|
@config.base_url_path << "/" unless @config.base_url_path.end_with? "/"
|
103
102
|
unless @config.storage_instance
|
104
|
-
@
|
103
|
+
@config.storage_instance = @config.storage.new(@config.storage_options)
|
105
104
|
end
|
105
|
+
@storage = @config.storage_instance
|
106
106
|
end
|
107
107
|
|
108
108
|
def user(env)
|
@@ -118,7 +118,7 @@ module Rack
|
|
118
118
|
return [404, {}, ["Request not found: #{request['id']} - user #{user(env)}"]]
|
119
119
|
end
|
120
120
|
unless page_struct['HasUserViewed']
|
121
|
-
|
121
|
+
page_struct['ClientTimings'] = ClientTimerStruct.init_from_form_data(env, page_struct)
|
122
122
|
page_struct['HasUserViewed'] = true
|
123
123
|
@storage.save(page_struct)
|
124
124
|
@storage.set_viewed(user(env), id)
|
@@ -151,8 +151,17 @@ module Rack
|
|
151
151
|
return [404, {}, ["Not found"]] unless ::File.exists? full_path
|
152
152
|
f = Rack::File.new nil
|
153
153
|
f.path = full_path
|
154
|
-
|
155
|
-
|
154
|
+
|
155
|
+
begin
|
156
|
+
f.cache_control = "max-age:86400"
|
157
|
+
f.serving env
|
158
|
+
rescue
|
159
|
+
# old versions of rack have a different api
|
160
|
+
status, headers, body = f.serving
|
161
|
+
headers.merge! 'Cache-Control' => "max-age:86400"
|
162
|
+
[status, headers, body]
|
163
|
+
end
|
164
|
+
|
156
165
|
end
|
157
166
|
|
158
167
|
|
@@ -245,7 +254,7 @@ module Rack
|
|
245
254
|
end
|
246
255
|
|
247
256
|
return [status,headers,body] if skip_it
|
248
|
-
|
257
|
+
|
249
258
|
# we must do this here, otherwise current[:discard] is not being properly treated
|
250
259
|
if env["QUERY_STRING"] =~ /pp=env/
|
251
260
|
body.close if body.respond_to? :close
|
@@ -274,6 +283,12 @@ module Rack
|
|
274
283
|
# inject headers, script
|
275
284
|
if status == 200
|
276
285
|
|
286
|
+
# mini profiler is meddling with stuff, we can not cache cause we will get incorrect data
|
287
|
+
# Rack::ETag has already inserted some nonesense in the chain
|
288
|
+
headers.delete('ETag')
|
289
|
+
headers.delete('Date')
|
290
|
+
headers['Cache-Control'] = 'must-revalidate, private, max-age=0'
|
291
|
+
|
277
292
|
# inject header
|
278
293
|
if headers.is_a? Hash
|
279
294
|
headers['X-MiniProfiler-Ids'] = ids_json(env)
|
@@ -283,21 +298,29 @@ module Rack
|
|
283
298
|
if current.inject_js \
|
284
299
|
&& headers.has_key?('Content-Type') \
|
285
300
|
&& !headers['Content-Type'].match(/text\/html/).nil? then
|
286
|
-
|
301
|
+
|
302
|
+
response = Rack::Response.new([], status, headers)
|
303
|
+
script = self.get_profile_script(env)
|
304
|
+
if String === body
|
305
|
+
response.write inject(body,script)
|
306
|
+
else
|
307
|
+
body.each { |fragment| response.write inject(fragment, script) }
|
308
|
+
end
|
309
|
+
body.close if body.respond_to? :close
|
310
|
+
return response.finish
|
287
311
|
end
|
288
312
|
end
|
289
313
|
|
290
|
-
# mini profiler is meddling with stuff, we can not cache cause we will get incorrect data
|
291
|
-
# Rack::ETag has already inserted some nonesense in the chain
|
292
|
-
headers.delete('ETag')
|
293
|
-
headers.delete('Date')
|
294
|
-
headers['Cache-Control'] = 'must-revalidate, private, max-age=0'
|
295
314
|
[status, headers, body]
|
296
315
|
ensure
|
297
316
|
# Make sure this always happens
|
298
317
|
current = nil
|
299
318
|
end
|
300
319
|
|
320
|
+
def inject(fragment, script)
|
321
|
+
fragment.sub(/<\/body>/i, script + "</body>")
|
322
|
+
end
|
323
|
+
|
301
324
|
def dump_env(env)
|
302
325
|
headers = {'Content-Type' => 'text/plain'}
|
303
326
|
body = ""
|
@@ -380,7 +403,7 @@ module Rack
|
|
380
403
|
showControls = false
|
381
404
|
currentId = current.page_struct["Id"]
|
382
405
|
authorized = true
|
383
|
-
|
406
|
+
useExistingjQuery = @config.use_existing_jquery
|
384
407
|
# TODO : cache this snippet
|
385
408
|
script = IO.read(::File.expand_path('../html/profile_handler.js', ::File.dirname(__FILE__)))
|
386
409
|
# replace the variables
|
@@ -39,9 +39,14 @@ module Rack
|
|
39
39
|
|
40
40
|
me = self
|
41
41
|
Thread.new do
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
begin
|
43
|
+
while true do
|
44
|
+
# TODO: a sane retry count before bailing
|
45
|
+
me.cleanup_cache
|
46
|
+
sleep(3600)
|
47
|
+
end
|
48
|
+
rescue
|
49
|
+
# don't crash the thread, we can clean up next time
|
45
50
|
end
|
46
51
|
end
|
47
52
|
end
|
@@ -83,10 +88,6 @@ module Rack
|
|
83
88
|
}
|
84
89
|
end
|
85
90
|
|
86
|
-
|
87
|
-
private
|
88
|
-
|
89
|
-
|
90
91
|
def cleanup_cache
|
91
92
|
files = Dir.entries(@path)
|
92
93
|
@timer_struct_lock.synchronize {
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
1
3
|
module MiniProfilerRails
|
2
4
|
|
3
5
|
class Railtie < ::Rails::Railtie
|
@@ -22,7 +24,7 @@ module MiniProfilerRails
|
|
22
24
|
|
23
25
|
# The file store is just so much less flaky
|
24
26
|
tmp = Rails.root.to_s + "/tmp/miniprofiler"
|
25
|
-
|
27
|
+
FileUtils.mkdir_p(tmp) unless File.exists?(tmp)
|
26
28
|
|
27
29
|
c.storage_options = {:path => tmp}
|
28
30
|
c.storage = Rack::MiniProfiler::FileStore
|
data/lib/rack-mini-profiler.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'mini_profiler/profiler'
|
2
|
+
require 'patches/sql_patches'
|
3
3
|
|
4
4
|
if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3
|
5
|
-
require
|
5
|
+
require 'mini_profiler_rails/railtie'
|
6
6
|
end
|
data/rack-mini-profiler.gemspec
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rack-mini-profiler"
|
3
|
-
s.version = "0.1.
|
3
|
+
s.version = "0.1.8"
|
4
4
|
s.summary = "Profiles loading speed for rack applications."
|
5
5
|
s.authors = ["Aleks Totic","Sam Saffron", "Robin Ward"]
|
6
|
-
s.date = "2012-04-02"
|
7
6
|
s.description = "Page loading speed displayed on every page. Optimize while you develop, performance is a feature."
|
8
7
|
s.email = "sam.saffron@gmail.com"
|
9
8
|
s.homepage = "http://miniprofiler.com"
|
@@ -14,9 +13,9 @@ Gem::Specification.new do |s|
|
|
14
13
|
"README.md",
|
15
14
|
"CHANGELOG"
|
16
15
|
]
|
17
|
-
s.add_runtime_dependency 'rack', '>= 1.1.3'
|
16
|
+
s.add_runtime_dependency 'rack', '>= 1.1.3'
|
18
17
|
if RUBY_VERSION < "1.9"
|
19
|
-
s.add_runtime_dependency 'json', '>= 1.6'
|
18
|
+
s.add_runtime_dependency 'json', '>= 1.6'
|
20
19
|
end
|
21
20
|
|
22
21
|
s.add_development_dependency 'rake'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-mini-profiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-07-30 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rack
|
@@ -93,7 +93,6 @@ files:
|
|
93
93
|
- lib/mini_profiler/page_timer_struct.rb
|
94
94
|
- lib/mini_profiler/context.rb
|
95
95
|
- lib/mini_profiler/config.rb
|
96
|
-
- lib/mini_profiler/body_add_proxy.rb
|
97
96
|
- lib/mini_profiler/profiling_methods.rb
|
98
97
|
- lib/mini_profiler/client_timer_struct.rb
|
99
98
|
- lib/mini_profiler/profiler.rb
|
@@ -104,6 +103,7 @@ files:
|
|
104
103
|
- lib/rack-mini-profiler.rb
|
105
104
|
- lib/html/jquery.1.7.1.js
|
106
105
|
- lib/html/includes.tmpl
|
106
|
+
- lib/html/share.html
|
107
107
|
- lib/html/includes.less
|
108
108
|
- lib/html/list.css
|
109
109
|
- lib/html/includes.js
|
@@ -130,7 +130,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
130
|
version: '0'
|
131
131
|
segments:
|
132
132
|
- 0
|
133
|
-
hash: -
|
133
|
+
hash: -902573215
|
134
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
135
|
none: false
|
136
136
|
requirements:
|
@@ -139,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
139
|
version: '0'
|
140
140
|
segments:
|
141
141
|
- 0
|
142
|
-
hash: -
|
142
|
+
hash: -902573215
|
143
143
|
requirements: []
|
144
144
|
rubyforge_project:
|
145
145
|
rubygems_version: 1.8.24
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
class MiniProfiler
|
3
|
-
|
4
|
-
# This class acts as a proxy to the Body so that we can
|
5
|
-
# safely append to the end without knowing about the internals
|
6
|
-
# of the body class.
|
7
|
-
class BodyAddProxy
|
8
|
-
def initialize(body, additional_text)
|
9
|
-
@body = body
|
10
|
-
@additional_text = additional_text
|
11
|
-
end
|
12
|
-
|
13
|
-
def respond_to?(*args)
|
14
|
-
super or @body.respond_to?(*args)
|
15
|
-
end
|
16
|
-
|
17
|
-
def method_missing(*args, &block)
|
18
|
-
@body.__send__(*args, &block)
|
19
|
-
end
|
20
|
-
|
21
|
-
# In the case of to_str we don't want to use method_missing as it might avoid
|
22
|
-
# a call to each (such as in Rack::Test)
|
23
|
-
def to_str
|
24
|
-
result = ""
|
25
|
-
each {|token| result << token}
|
26
|
-
result
|
27
|
-
end
|
28
|
-
|
29
|
-
def each(&block)
|
30
|
-
|
31
|
-
# In ruby 1.9 we don't support String#each
|
32
|
-
if @body.is_a?(String)
|
33
|
-
yield @body
|
34
|
-
else
|
35
|
-
@body.each(&block)
|
36
|
-
end
|
37
|
-
|
38
|
-
yield @additional_text
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|