rack-mini-profiler 0.1.16 → 0.1.21
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 +99 -78
- data/README.md +1 -1
- data/lib/mini_profiler/gc_profiler.rb +84 -0
- data/lib/mini_profiler/profiler.rb +10 -6
- data/lib/mini_profiler/profiling_methods.rb +26 -2
- data/lib/mini_profiler/storage/memcache_store.rb +51 -0
- data/lib/mini_profiler_rails/railtie.rb +2 -1
- data/lib/rack-mini-profiler.rb +1 -1
- data/rack-mini-profiler.gemspec +3 -3
- metadata +9 -7
data/CHANGELOG
CHANGED
@@ -1,78 +1,99 @@
|
|
1
|
-
28-June-2012 - Sam
|
2
|
-
|
3
|
-
* Started change log
|
4
|
-
* Corrected profiler so it properly captures POST requests (was supressing non 200s)
|
5
|
-
* Amended Rack.MiniProfiler.config[:user_provider] to use ip addres for identity
|
6
|
-
* Fixed bug where unviewed missing ids never got cleared
|
7
|
-
* Supress all '/assets/' in the rails tie (makes debugging easier)
|
8
|
-
* record_sql was mega buggy
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
*
|
17
|
-
*
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
*
|
24
|
-
*
|
25
|
-
*
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
*
|
31
|
-
*
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
*
|
37
|
-
* Fixed
|
38
|
-
*
|
39
|
-
*
|
40
|
-
*
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
*
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
*
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
*
|
60
|
-
*
|
61
|
-
* added setting config.
|
62
|
-
*
|
63
|
-
*
|
64
|
-
*
|
65
|
-
*
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
*
|
71
|
-
* fixed
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
*
|
77
|
-
* fixed
|
78
|
-
*
|
1
|
+
28-June-2012 - Sam
|
2
|
+
|
3
|
+
* Started change log
|
4
|
+
* Corrected profiler so it properly captures POST requests (was supressing non 200s)
|
5
|
+
* Amended Rack.MiniProfiler.config[:user_provider] to use ip addres for identity
|
6
|
+
* Fixed bug where unviewed missing ids never got cleared
|
7
|
+
* Supress all '/assets/' in the rails tie (makes debugging easier)
|
8
|
+
* record_sql was mega buggy
|
9
|
+
* added MemcacheStore
|
10
|
+
|
11
|
+
9-July-2012 - Sam
|
12
|
+
|
13
|
+
* Cleaned up mechanism for profiling in production, all you need to do now
|
14
|
+
is call Rack::MiniProfiler.authorize_request to get profiling working in
|
15
|
+
production
|
16
|
+
* Added option to display full backtraces pp=full-backtrace
|
17
|
+
* Cleaned up railties, got rid of the post authorize callback
|
18
|
+
* Version 0.1.3
|
19
|
+
|
20
|
+
12-July-2012 - Sam
|
21
|
+
|
22
|
+
* Fixed incorrect profiling steps (was not indenting or measuring start time right
|
23
|
+
* Implemented native PG and MySql2 interceptors, this gives way more accurate times
|
24
|
+
* Refactored context so its a proper class and not a hash
|
25
|
+
* Added some more client probing built in to rails
|
26
|
+
* More tests
|
27
|
+
|
28
|
+
18-July-2012 - Sam
|
29
|
+
|
30
|
+
* Added First Paint time for chrome
|
31
|
+
* Bug fix to ensure non Rails installs have mini profiler
|
32
|
+
* Version 0.1.7
|
33
|
+
|
34
|
+
30-July-2012 - Sam
|
35
|
+
|
36
|
+
* Made compliant with ancient versions of Rack (including Rack used by Rails2)
|
37
|
+
* Fixed broken share link
|
38
|
+
* Fixed crashes on startup (in MemoryStore and FileStore)
|
39
|
+
* Version 0.1.8
|
40
|
+
* Unicode fix
|
41
|
+
* Version 0.1.9
|
42
|
+
|
43
|
+
7-August-2012 - Sam
|
44
|
+
|
45
|
+
* Added option to disable profiler for the current session (pp=disable / pp=enable)
|
46
|
+
* yajl compatability contributed by Sven Riedel
|
47
|
+
|
48
|
+
10-August-2012 - Sam
|
49
|
+
|
50
|
+
* Added basic prepared statement profiling for postgres
|
51
|
+
|
52
|
+
20-August-2012 - Sam
|
53
|
+
|
54
|
+
* 1.12.pre
|
55
|
+
* Cap X-MiniProfiler-Ids at 10, otherwise the header can get killed
|
56
|
+
|
57
|
+
3-September-2012 - Sam
|
58
|
+
|
59
|
+
* 1.13.pre
|
60
|
+
* pg gem prepared statements were not being logged correctly
|
61
|
+
* added setting config.backtrace_ignores = [] - an array of regexes that match on caller lines that get ignored
|
62
|
+
* added setting config.backtrace_includes = [] - an array of regexes that get included in the trace by default
|
63
|
+
* cleaned up the way client settings are stored
|
64
|
+
* made pp=full-backtrace "sticky"
|
65
|
+
* added pp=normal-backtrace to clear the "sticky" state
|
66
|
+
* change "pp=sample" to work with "caller" no need for stack trace gem
|
67
|
+
|
68
|
+
4-September-2012 - Sam
|
69
|
+
|
70
|
+
* 1.15.pre
|
71
|
+
* fixed annoying bug where client settings were not sticking
|
72
|
+
* fixed long standing issue with Rack::ConditionalGet stopping MiniProfiler from working properly
|
73
|
+
|
74
|
+
5-September-2012 - Sam
|
75
|
+
|
76
|
+
* 1.16
|
77
|
+
* fixed long standing problem specs (issue with memory store)
|
78
|
+
* fixed issue where profiler would be dumped when you got a 404 in production (and any time rails is bypassed)
|
79
|
+
* implemented stacktrace properly
|
80
|
+
|
81
|
+
9-September-2012 - Sam
|
82
|
+
|
83
|
+
* 1.17
|
84
|
+
* pp=sample was bust unless stacktrace was installed
|
85
|
+
|
86
|
+
10-September-2012 - Sam
|
87
|
+
|
88
|
+
* 1.19
|
89
|
+
* fix compat issue with 1.8.7
|
90
|
+
|
91
|
+
12-September-2012 - Sam
|
92
|
+
|
93
|
+
* 1.20
|
94
|
+
* Added pp=profile-gc , it allows you to profile the GC in Ruby 1.9.3
|
95
|
+
|
96
|
+
17-September-2012
|
97
|
+
* 1.21
|
98
|
+
* New MemchacedStore
|
99
|
+
* Rails 4 support
|
data/README.md
CHANGED
@@ -56,7 +56,7 @@ By default, rack-mini-profiler stores its results in a memory store:
|
|
56
56
|
Rack::MiniProfiler.config.storage = Rack::MiniProfiler::MemoryStore
|
57
57
|
```
|
58
58
|
|
59
|
-
There are 2 other available storage engines, `RedisStore` and `FileStore`.
|
59
|
+
There are 2 other available storage engines, `RedisStore`, `MemcacheStore`, and `FileStore`.
|
60
60
|
|
61
61
|
MemoryStore is stores results in a processes heap - something that does not work well in a multi process environment.
|
62
62
|
FileStore stores results in the file system - something that may not work well in a multi machine environment.
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class Rack::MiniProfiler::GCProfiler
|
2
|
+
|
3
|
+
def object_space_stats
|
4
|
+
stats = {}
|
5
|
+
ids = Set.new
|
6
|
+
ObjectSpace.each_object { |o|
|
7
|
+
stats[o.class] ||= 1
|
8
|
+
stats[o.class] += 1
|
9
|
+
ids << o.object_id
|
10
|
+
}
|
11
|
+
{:stats => stats, :ids => ids}
|
12
|
+
end
|
13
|
+
|
14
|
+
def diff_object_stats(before,after)
|
15
|
+
diff = {}
|
16
|
+
after.each do |k,v|
|
17
|
+
diff[k] = v - (before[k] || 0)
|
18
|
+
end
|
19
|
+
before.each do |k,v|
|
20
|
+
diff[k] = 0 - v unless after[k]
|
21
|
+
end
|
22
|
+
|
23
|
+
diff
|
24
|
+
end
|
25
|
+
|
26
|
+
def analyze_strings(ids_before,ids_after)
|
27
|
+
result = {}
|
28
|
+
ids_after.each do |id|
|
29
|
+
obj = ObjectSpace._id2ref(id)
|
30
|
+
if String === obj && !ids_before.include?(obj.object_id)
|
31
|
+
result[obj] ||= 0
|
32
|
+
result[obj] += 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
def profile_gc(app,env)
|
39
|
+
|
40
|
+
body = [];
|
41
|
+
|
42
|
+
stat_after = nil
|
43
|
+
stat_before = object_space_stats
|
44
|
+
begin
|
45
|
+
GC::Profiler.clear
|
46
|
+
GC::Profiler.enable
|
47
|
+
b = app.call(env)[2]
|
48
|
+
b.close if b.respond_to? :close
|
49
|
+
stat_after = object_space_stats
|
50
|
+
body << GC::Profiler.result
|
51
|
+
ensure
|
52
|
+
GC::Profiler.disable
|
53
|
+
end
|
54
|
+
|
55
|
+
diff = diff_object_stats(stat_before[:stats],stat_after[:stats])
|
56
|
+
|
57
|
+
body << "
|
58
|
+
ObjectSpace delta caused by request:
|
59
|
+
--------------------------------------------\n"
|
60
|
+
diff.to_a.reject{|k,v| v == 0}.sort{|x,y| y[1] <=> x[1]}.each do |k,v|
|
61
|
+
body << "#{k} : #{v}\n" if v != 0
|
62
|
+
end
|
63
|
+
|
64
|
+
body << "\n
|
65
|
+
ObjectSpace stats:
|
66
|
+
-----------------\n"
|
67
|
+
|
68
|
+
stat_after[:stats].to_a.sort{|x,y| y[1] <=> x[1]}.each do |k,v|
|
69
|
+
body << "#{k} : #{v}\n"
|
70
|
+
end
|
71
|
+
|
72
|
+
r = analyze_strings(stat_before[:ids], stat_after[:ids])
|
73
|
+
|
74
|
+
body << "\n
|
75
|
+
String stats:
|
76
|
+
------------\n"
|
77
|
+
|
78
|
+
r.to_a.sort{|x,y| y[1] <=> x[1] }.take(1000).each do |string,count|
|
79
|
+
body << "#{count} : #{string}\n"
|
80
|
+
end
|
81
|
+
|
82
|
+
return [200, {'Content-Type' => 'text/plain'}, body]
|
83
|
+
end
|
84
|
+
end
|
@@ -7,6 +7,7 @@ require 'mini_profiler/sql_timer_struct'
|
|
7
7
|
require 'mini_profiler/client_timer_struct'
|
8
8
|
require 'mini_profiler/request_timer_struct'
|
9
9
|
require 'mini_profiler/storage/abstract_store'
|
10
|
+
require 'mini_profiler/storage/memcache_store'
|
10
11
|
require 'mini_profiler/storage/memory_store'
|
11
12
|
require 'mini_profiler/storage/redis_store'
|
12
13
|
require 'mini_profiler/storage/file_store'
|
@@ -14,6 +15,7 @@ require 'mini_profiler/config'
|
|
14
15
|
require 'mini_profiler/profiling_methods'
|
15
16
|
require 'mini_profiler/context'
|
16
17
|
require 'mini_profiler/client_settings'
|
18
|
+
require 'mini_profiler/gc_profiler'
|
17
19
|
|
18
20
|
module Rack
|
19
21
|
|
@@ -208,6 +210,10 @@ module Rack
|
|
208
210
|
return [status,headers,body]
|
209
211
|
end
|
210
212
|
|
213
|
+
if query_string =~ /pp=profile-gc/
|
214
|
+
return Rack::MiniProfiler::GCProfiler.new.profile_gc(@app, env)
|
215
|
+
end
|
216
|
+
|
211
217
|
MiniProfiler.create_current(env, @config)
|
212
218
|
MiniProfiler.deauthorize_request if @config.authorization_mode == :whitelist
|
213
219
|
if query_string =~ /pp=normal-backtrace/
|
@@ -234,7 +240,7 @@ module Rack
|
|
234
240
|
begin
|
235
241
|
require 'stacktrace'
|
236
242
|
skip_frames = stacktrace.length
|
237
|
-
rescue
|
243
|
+
rescue LoadError
|
238
244
|
stacktrace_installed = false
|
239
245
|
end
|
240
246
|
|
@@ -295,7 +301,7 @@ module Rack
|
|
295
301
|
|
296
302
|
if query_string =~ /pp=help/
|
297
303
|
body.close if body.respond_to? :close
|
298
|
-
return help(
|
304
|
+
return help(client_settings)
|
299
305
|
end
|
300
306
|
|
301
307
|
page_struct = current.page_struct
|
@@ -372,7 +378,7 @@ module Rack
|
|
372
378
|
[200, headers, [body]]
|
373
379
|
end
|
374
380
|
|
375
|
-
def help(
|
381
|
+
def help(client_settings)
|
376
382
|
headers = {'Content-Type' => 'text/plain'}
|
377
383
|
body = "Append the following to your query string:
|
378
384
|
|
@@ -385,10 +391,8 @@ module Rack
|
|
385
391
|
pp=sample : sample stack traces and return a report isolating heavy usage (experimental works best with the stacktrace gem)
|
386
392
|
pp=disable : disable profiling for this session
|
387
393
|
pp=enable : enable profiling for this session (if previously disabled)
|
394
|
+
pp=profile-gc: perform gc profiling on this request (ruby 1.9.3 only)
|
388
395
|
"
|
389
|
-
if (category == :stacktrace)
|
390
|
-
body = "pp=stacktrace requires the stacktrace gem - add gem 'stacktrace' to your Gemfile"
|
391
|
-
end
|
392
396
|
|
393
397
|
client_settings.write!(headers)
|
394
398
|
[200, headers, [body]]
|
@@ -8,6 +8,22 @@ module Rack
|
|
8
8
|
c.current_timer.add_sql(query, elapsed_ms, c.page_struct, c.skip_backtrace, c.full_backtrace) if (c && c.current_timer)
|
9
9
|
end
|
10
10
|
|
11
|
+
def start_step(name)
|
12
|
+
if current
|
13
|
+
parent_timer = current.current_timer
|
14
|
+
current.current_timer = current_timer = current.current_timer.add_child(name)
|
15
|
+
[current_timer,parent_timer]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def finish_step(obj)
|
20
|
+
if obj && current
|
21
|
+
current_timer, parent_timer = obj
|
22
|
+
current_timer.record_time
|
23
|
+
current.current_timer = parent_timer
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
11
27
|
# perform a profiling step on given block
|
12
28
|
def step(name, opts = nil)
|
13
29
|
if current
|
@@ -55,8 +71,16 @@ module Rack
|
|
55
71
|
return self.send without_profiling, *args, &orig unless Rack::MiniProfiler.current
|
56
72
|
|
57
73
|
name = default_name
|
58
|
-
|
59
|
-
|
74
|
+
if blk
|
75
|
+
name =
|
76
|
+
if respond_to?(:instance_exec)
|
77
|
+
instance_exec(*args, &blk)
|
78
|
+
else
|
79
|
+
# deprecated in Rails 4.x
|
80
|
+
blk.bind(self).call(*args)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
60
84
|
parent_timer = Rack::MiniProfiler.current.current_timer
|
61
85
|
page_struct = Rack::MiniProfiler.current.page_struct
|
62
86
|
result = nil
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Rack
|
2
|
+
class MiniProfiler
|
3
|
+
class MemcacheStore < AbstractStore
|
4
|
+
|
5
|
+
EXPIRE_SECONDS = 60*60*24
|
6
|
+
MAX_RETRIES = 10
|
7
|
+
|
8
|
+
def initialize(client = nil, prefix = "MPMemcacheStore")
|
9
|
+
require 'dalli' unless defined? Dalli
|
10
|
+
@prefix = prefix
|
11
|
+
@client = client || Dalli::Client.new(['localhost:11211'])
|
12
|
+
end
|
13
|
+
|
14
|
+
def save(page_struct)
|
15
|
+
@client.set("#{@prefix}#{page_struct['Id']}", Marshal::dump(page_struct), EXPIRE_SECONDS)
|
16
|
+
end
|
17
|
+
|
18
|
+
def load(id)
|
19
|
+
raw = @client.get("#{@prefix}#{id}")
|
20
|
+
if raw
|
21
|
+
Marshal::load raw
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_unviewed(user, id)
|
26
|
+
@client.add("#{@prefix}-#{user}-v", [], EXPIRE_SECONDS)
|
27
|
+
MAX_RETRIES.times do
|
28
|
+
break if @client.cas("#{@prefix}-#{user}-v", EXPIRE_SECONDS) do |ids|
|
29
|
+
ids << id unless ids.include?(id)
|
30
|
+
ids
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_viewed(user, id)
|
36
|
+
@client.add("#{@prefix}-#{user}-v", [], EXPIRE_SECONDS)
|
37
|
+
MAX_RETRIES.times do
|
38
|
+
break if @client.cas("#{@prefix}-#{user}-v", EXPIRE_SECONDS) do |ids|
|
39
|
+
ids.delete id
|
40
|
+
ids
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_unviewed_ids(user)
|
46
|
+
@client.get("#{@prefix}-#{user}-v") || []
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/rack-mini-profiler.rb
CHANGED
data/rack-mini-profiler.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rack-mini-profiler"
|
3
|
-
s.version = "0.1.
|
3
|
+
s.version = "0.1.21"
|
4
4
|
s.summary = "Profiles loading speed for rack applications."
|
5
|
-
s.authors = ["
|
6
|
-
s.description = "
|
5
|
+
s.authors = ["Sam Saffron", "Robin Ward","Aleks Totic"]
|
6
|
+
s.description = "Profiling toolkit for Rack applications with Rails integration. Client Side profiling, DB profiling and Server profiling."
|
7
7
|
s.email = "sam.saffron@gmail.com"
|
8
8
|
s.homepage = "http://miniprofiler.com"
|
9
9
|
s.files = [
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
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.21
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
|
-
- Aleks Totic
|
9
8
|
- Sam Saffron
|
10
9
|
- Robin Ward
|
10
|
+
- Aleks Totic
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-09-
|
14
|
+
date: 2012-09-16 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rack
|
@@ -77,8 +77,8 @@ dependencies:
|
|
77
77
|
- - ~>
|
78
78
|
- !ruby/object:Gem::Version
|
79
79
|
version: '3.0'
|
80
|
-
description:
|
81
|
-
|
80
|
+
description: Profiling toolkit for Rack applications with Rails integration. Client
|
81
|
+
Side profiling, DB profiling and Server profiling.
|
82
82
|
email: sam.saffron@gmail.com
|
83
83
|
executables: []
|
84
84
|
extensions: []
|
@@ -95,12 +95,14 @@ files:
|
|
95
95
|
- lib/mini_profiler/context.rb
|
96
96
|
- lib/mini_profiler/config.rb
|
97
97
|
- lib/mini_profiler/profiling_methods.rb
|
98
|
+
- lib/mini_profiler/gc_profiler.rb
|
98
99
|
- lib/mini_profiler/client_timer_struct.rb
|
99
100
|
- lib/mini_profiler/profiler.rb
|
100
101
|
- lib/mini_profiler/storage/memory_store.rb
|
101
102
|
- lib/mini_profiler/storage/file_store.rb
|
102
103
|
- lib/mini_profiler/storage/redis_store.rb
|
103
104
|
- lib/mini_profiler/storage/abstract_store.rb
|
105
|
+
- lib/mini_profiler/storage/memcache_store.rb
|
104
106
|
- lib/rack-mini-profiler.rb
|
105
107
|
- lib/html/jquery.1.7.1.js
|
106
108
|
- lib/html/includes.tmpl
|
@@ -131,7 +133,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
133
|
version: '0'
|
132
134
|
segments:
|
133
135
|
- 0
|
134
|
-
hash:
|
136
|
+
hash: -668836557
|
135
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
138
|
none: false
|
137
139
|
requirements:
|
@@ -140,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
142
|
version: '0'
|
141
143
|
segments:
|
142
144
|
- 0
|
143
|
-
hash:
|
145
|
+
hash: -668836557
|
144
146
|
requirements: []
|
145
147
|
rubyforge_project:
|
146
148
|
rubygems_version: 1.8.24
|