rack-mini-profiler 0.1 → 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.
- data/CHANGELOG +99 -0
- data/README.md +72 -24
- data/lib/html/includes.css +75 -1
- data/lib/html/includes.js +42 -11
- data/lib/html/includes.less +2 -2
- data/lib/html/includes.tmpl +2 -2
- data/lib/html/profile_handler.js +9 -9
- data/lib/mini_profiler/client_settings.rb +65 -0
- data/lib/mini_profiler/client_timer_struct.rb +38 -3
- data/lib/mini_profiler/config.rb +52 -0
- data/lib/mini_profiler/context.rb +10 -0
- data/lib/mini_profiler/gc_profiler.rb +84 -0
- data/lib/mini_profiler/page_timer_struct.rb +7 -3
- data/lib/mini_profiler/profiler.rb +312 -142
- data/lib/mini_profiler/profiling_methods.rb +108 -0
- data/lib/mini_profiler/request_timer_struct.rb +40 -9
- data/lib/mini_profiler/sql_timer_struct.rb +26 -5
- data/lib/mini_profiler/storage/abstract_store.rb +0 -0
- data/lib/mini_profiler/storage/file_store.rb +8 -7
- data/lib/mini_profiler/storage/memcache_store.rb +51 -0
- data/lib/mini_profiler/storage/memory_store.rb +1 -6
- data/lib/mini_profiler/storage/redis_store.rb +2 -1
- data/lib/mini_profiler/timer_struct.rb +3 -1
- data/lib/mini_profiler_rails/railtie.rb +66 -11
- data/lib/patches/sql_patches.rb +198 -39
- data/lib/rack-mini-profiler.rb +4 -4
- data/rack-mini-profiler.gemspec +8 -8
- metadata +16 -10
- data/lib/html/MiniProfilerHandler.cs +0 -419
- data/lib/mini_profiler/body_add_proxy.rb +0 -45
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Rack
|
|
2
|
+
class MiniProfiler
|
|
3
|
+
class Config
|
|
4
|
+
|
|
5
|
+
def self.attr_accessor(*vars)
|
|
6
|
+
@attributes ||= []
|
|
7
|
+
@attributes.concat vars
|
|
8
|
+
super(*vars)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.attributes
|
|
12
|
+
@attributes
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attr_accessor :auto_inject, :base_url_path, :pre_authorize_cb, :position,
|
|
16
|
+
:backtrace_remove, :backtrace_includes, :backtrace_ignores, :skip_schema_queries,
|
|
17
|
+
:storage, :user_provider, :storage_instance, :storage_options, :skip_paths, :authorization_mode, :use_existing_jquery
|
|
18
|
+
|
|
19
|
+
def self.default
|
|
20
|
+
new.instance_eval {
|
|
21
|
+
@auto_inject = true # automatically inject on every html page
|
|
22
|
+
@base_url_path = "/mini-profiler-resources/"
|
|
23
|
+
|
|
24
|
+
# called prior to rack chain, to ensure we are allowed to profile
|
|
25
|
+
@pre_authorize_cb = lambda {|env| true}
|
|
26
|
+
|
|
27
|
+
# called after rack chain, to ensure we are REALLY allowed to profile
|
|
28
|
+
@position = 'left' # Where it is displayed
|
|
29
|
+
@skip_schema_queries = false
|
|
30
|
+
@storage = MiniProfiler::MemoryStore
|
|
31
|
+
@user_provider = Proc.new{|env| Rack::Request.new(env).ip}
|
|
32
|
+
@authorization_mode = :allow_all
|
|
33
|
+
@use_existing_jquery = false
|
|
34
|
+
self
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def merge!(config)
|
|
39
|
+
return unless config
|
|
40
|
+
if Hash === config
|
|
41
|
+
config.each{|k,v| instance_variable_set "@#{k}",v}
|
|
42
|
+
else
|
|
43
|
+
self.class.attributes.each{ |k|
|
|
44
|
+
v = config.send k
|
|
45
|
+
instance_variable_set "@#{k}", v if v
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -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
|
|
@@ -16,7 +16,7 @@ module Rack
|
|
|
16
16
|
"Level" => 0,
|
|
17
17
|
"User" => "unknown user",
|
|
18
18
|
"HasUserViewed" => false,
|
|
19
|
-
"ClientTimings" =>
|
|
19
|
+
"ClientTimings" => nil,
|
|
20
20
|
"DurationMilliseconds" => 0,
|
|
21
21
|
"HasTrivialTimings" => true,
|
|
22
22
|
"HasAllTrivialTimigs" => false,
|
|
@@ -35,15 +35,19 @@ module Rack
|
|
|
35
35
|
def duration_ms
|
|
36
36
|
@attributes['Root']['DurationMilliseconds']
|
|
37
37
|
end
|
|
38
|
+
|
|
39
|
+
def root
|
|
40
|
+
@attributes['Root']
|
|
41
|
+
end
|
|
38
42
|
|
|
39
43
|
def to_json(*a)
|
|
40
44
|
attribs = @attributes.merge(
|
|
41
45
|
"Started" => '/Date(%d)/' % @attributes['Started'],
|
|
42
46
|
"DurationMilliseconds" => @attributes['Root']['DurationMilliseconds']
|
|
43
47
|
)
|
|
44
|
-
::JSON.generate(attribs,
|
|
48
|
+
::JSON.generate(attribs, :max_nesting => 100)
|
|
45
49
|
end
|
|
46
50
|
end
|
|
47
51
|
|
|
48
52
|
end
|
|
49
|
-
end
|
|
53
|
+
end
|