rack-mini-profiler 0.1.20 → 0.1.21
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rack-mini-profiler might be problematic. Click here for more details.
- data/CHANGELOG +99 -93
- data/README.md +1 -1
- data/lib/mini_profiler/gc_profiler.rb +84 -0
- data/lib/mini_profiler/profiler.rb +3 -58
- data/lib/mini_profiler/profiling_methods.rb +10 -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,93 +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
|
-
*
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
*
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
*
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
*
|
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
|
|
@@ -209,7 +211,7 @@ module Rack
|
|
209
211
|
end
|
210
212
|
|
211
213
|
if query_string =~ /pp=profile-gc/
|
212
|
-
return profile_gc(env)
|
214
|
+
return Rack::MiniProfiler::GCProfiler.new.profile_gc(@app, env)
|
213
215
|
end
|
214
216
|
|
215
217
|
MiniProfiler.create_current(env, @config)
|
@@ -396,63 +398,6 @@ module Rack
|
|
396
398
|
[200, headers, [body]]
|
397
399
|
end
|
398
400
|
|
399
|
-
|
400
|
-
def object_space_stats
|
401
|
-
stats = {}
|
402
|
-
ObjectSpace.each_object { |o|
|
403
|
-
stats[o.class] ||= 1
|
404
|
-
stats[o.class] += 1
|
405
|
-
}
|
406
|
-
stats
|
407
|
-
end
|
408
|
-
|
409
|
-
def diff_object_stats(before,after)
|
410
|
-
diff = {}
|
411
|
-
after.each do |k,v|
|
412
|
-
diff[k] = v - (before[k] || 0)
|
413
|
-
end
|
414
|
-
before.each do |k,v|
|
415
|
-
diff[k] = 0 - v unless after[k]
|
416
|
-
end
|
417
|
-
|
418
|
-
diff
|
419
|
-
end
|
420
|
-
|
421
|
-
def profile_gc(env)
|
422
|
-
|
423
|
-
body = "";
|
424
|
-
|
425
|
-
stat_before = object_space_stats
|
426
|
-
begin
|
427
|
-
GC::Profiler.clear
|
428
|
-
GC::Profiler.enable
|
429
|
-
@app.call(env)
|
430
|
-
body << GC::Profiler.result
|
431
|
-
ensure
|
432
|
-
GC::Profiler.disable
|
433
|
-
end
|
434
|
-
stat_after = object_space_stats
|
435
|
-
|
436
|
-
diff = diff_object_stats(stat_before,stat_after)
|
437
|
-
|
438
|
-
body << "
|
439
|
-
ObjectSpace delta caused by request:
|
440
|
-
--------------------------------------------\n"
|
441
|
-
diff.to_a.reject{|k,v| v == 0}.sort{|x,y| y[1] <=> x[1]}.each do |k,v|
|
442
|
-
body << "#{k} : #{v}\n" if v != 0
|
443
|
-
end
|
444
|
-
|
445
|
-
body << "\n
|
446
|
-
ObjectSpace stats:
|
447
|
-
-----------------\n"
|
448
|
-
|
449
|
-
stat_after.to_a.sort{|x,y| y[1] <=> x[1]}.each do |k,v|
|
450
|
-
body << "#{k} : #{v}\n"
|
451
|
-
end
|
452
|
-
|
453
|
-
return [200, {'Content-Type' => 'text/plain'}, body]
|
454
|
-
end
|
455
|
-
|
456
401
|
def analyze(traces, page_struct)
|
457
402
|
headers = {'Content-Type' => 'text/plain'}
|
458
403
|
body = "Collected: #{traces.count} stack traces. Duration(ms): #{page_struct.duration_ms}"
|
@@ -71,8 +71,16 @@ module Rack
|
|
71
71
|
return self.send without_profiling, *args, &orig unless Rack::MiniProfiler.current
|
72
72
|
|
73
73
|
name = default_name
|
74
|
-
|
75
|
-
|
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
|
+
|
76
84
|
parent_timer = Rack::MiniProfiler.current.current_timer
|
77
85
|
page_struct = Rack::MiniProfiler.current.page_struct
|
78
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
|