rack-mini-profiler 0.1.31 → 0.9.3

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.

Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +149 -0
  3. data/README.md +285 -0
  4. data/{Ruby/lib → lib}/html/includes.css +15 -4
  5. data/{Ruby/lib → lib}/html/includes.js +95 -59
  6. data/{Ruby/lib → lib}/html/includes.less +21 -5
  7. data/{Ruby/lib → lib}/html/includes.tmpl +50 -50
  8. data/{Ruby/lib → lib}/html/jquery.1.7.1.js +0 -0
  9. data/{Ruby/lib → lib}/html/jquery.tmpl.js +0 -0
  10. data/{Ruby/lib → lib}/html/list.css +2 -2
  11. data/{Ruby/lib → lib}/html/list.js +1 -1
  12. data/lib/html/list.tmpl +34 -0
  13. data/lib/html/profile_handler.js +1 -0
  14. data/{Ruby/lib → lib}/html/share.html +2 -2
  15. data/lib/mini_profiler/asset_version.rb +5 -0
  16. data/{Ruby/lib → lib}/mini_profiler/client_settings.rb +3 -3
  17. data/lib/mini_profiler/config.rb +65 -0
  18. data/{Ruby/lib → lib}/mini_profiler/context.rb +0 -0
  19. data/lib/mini_profiler/gc_profiler.rb +181 -0
  20. data/{Ruby/lib → lib}/mini_profiler/profiler.rb +120 -96
  21. data/{Ruby/lib → lib}/mini_profiler/profiling_methods.rb +15 -17
  22. data/{Ruby/lib → lib}/mini_profiler/storage/abstract_store.rb +0 -0
  23. data/{Ruby/lib → lib}/mini_profiler/storage/file_store.rb +30 -8
  24. data/{Ruby/lib → lib}/mini_profiler/storage/memcache_store.rb +5 -7
  25. data/lib/mini_profiler/storage/memory_store.rb +115 -0
  26. data/{Ruby/lib → lib}/mini_profiler/storage/redis_store.rb +19 -11
  27. data/lib/mini_profiler/timer_struct/base.rb +33 -0
  28. data/lib/mini_profiler/timer_struct/client.rb +89 -0
  29. data/lib/mini_profiler/timer_struct/custom.rb +22 -0
  30. data/lib/mini_profiler/timer_struct/page.rb +62 -0
  31. data/lib/mini_profiler/timer_struct/request.rb +126 -0
  32. data/lib/mini_profiler/timer_struct/sql.rb +59 -0
  33. data/lib/mini_profiler/version.rb +5 -0
  34. data/{Ruby/lib → lib}/mini_profiler_rails/railtie.rb +23 -6
  35. data/lib/patches/db/activerecord.rb +42 -0
  36. data/lib/patches/db/moped.rb +12 -0
  37. data/lib/patches/db/mysql2.rb +30 -0
  38. data/lib/patches/db/pg.rb +104 -0
  39. data/lib/patches/db/plucky.rb +47 -0
  40. data/lib/patches/db/rsolr.rb +24 -0
  41. data/lib/patches/db/sequel.rb +10 -0
  42. data/{Ruby/lib → lib}/patches/net_patches.rb +0 -0
  43. data/lib/patches/sql_patches.rb +46 -0
  44. data/lib/rack-mini-profiler.rb +35 -0
  45. data/rack-mini-profiler.gemspec +28 -16
  46. metadata +171 -52
  47. data/Ruby/CHANGELOG +0 -161
  48. data/Ruby/README.md +0 -172
  49. data/Ruby/lib/html/list.tmpl +0 -34
  50. data/Ruby/lib/html/profile_handler.js +0 -1
  51. data/Ruby/lib/mini_profiler/client_timer_struct.rb +0 -78
  52. data/Ruby/lib/mini_profiler/config.rb +0 -58
  53. data/Ruby/lib/mini_profiler/custom_timer_struct.rb +0 -22
  54. data/Ruby/lib/mini_profiler/gc_profiler.rb +0 -107
  55. data/Ruby/lib/mini_profiler/gc_profiler_ruby_head.rb +0 -40
  56. data/Ruby/lib/mini_profiler/page_timer_struct.rb +0 -58
  57. data/Ruby/lib/mini_profiler/request_timer_struct.rb +0 -115
  58. data/Ruby/lib/mini_profiler/sql_timer_struct.rb +0 -58
  59. data/Ruby/lib/mini_profiler/storage/memory_store.rb +0 -65
  60. data/Ruby/lib/mini_profiler/timer_struct.rb +0 -33
  61. data/Ruby/lib/mini_profiler/version.rb +0 -5
  62. data/Ruby/lib/patches/sql_patches.rb +0 -277
  63. data/Ruby/lib/rack-mini-profiler.rb +0 -7
@@ -1,58 +0,0 @@
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,
18
- :toggle_shortcut, :start_hidden, :backtrace_threshold_ms
19
-
20
- # Deprecated options
21
- attr_accessor :use_existing_jquery
22
-
23
- def self.default
24
- new.instance_eval {
25
- @auto_inject = true # automatically inject on every html page
26
- @base_url_path = "/mini-profiler-resources/"
27
-
28
- # called prior to rack chain, to ensure we are allowed to profile
29
- @pre_authorize_cb = lambda {|env| true}
30
-
31
- # called after rack chain, to ensure we are REALLY allowed to profile
32
- @position = 'left' # Where it is displayed
33
- @skip_schema_queries = false
34
- @storage = MiniProfiler::MemoryStore
35
- @user_provider = Proc.new{|env| Rack::Request.new(env).ip}
36
- @authorization_mode = :allow_all
37
- @toggle_shortcut = 'Alt+P'
38
- @start_hidden = false
39
- @backtrace_threshold_ms = 0
40
- self
41
- }
42
- end
43
-
44
- def merge!(config)
45
- return unless config
46
- if Hash === config
47
- config.each{|k,v| instance_variable_set "@#{k}",v}
48
- else
49
- self.class.attributes.each{ |k|
50
- v = config.send k
51
- instance_variable_set "@#{k}", v if v
52
- }
53
- end
54
- end
55
-
56
- end
57
- end
58
- end
@@ -1,22 +0,0 @@
1
- require 'mini_profiler/timer_struct'
2
-
3
- module Rack
4
- class MiniProfiler
5
-
6
- # Timing system for a custom timers such as cache, redis, RPC, external API
7
- # calls, etc.
8
- class CustomTimerStruct < TimerStruct
9
- def initialize(type, duration_ms, page, parent)
10
- @parent = parent
11
- @page = page
12
- @type = type
13
-
14
- super("Type" => type,
15
- "StartMilliseconds" => ((Time.now.to_f * 1000).to_i - page['Started']) - duration_ms,
16
- "DurationMilliseconds" => duration_ms,
17
- "ParentTimingId" => nil)
18
- end
19
- end
20
-
21
- end
22
- end
@@ -1,107 +0,0 @@
1
- class Rack::MiniProfiler::GCProfiler
2
-
3
- def object_space_stats
4
- stats = {}
5
- ids = Set.new
6
- i=0
7
- ObjectSpace.each_object { |o|
8
- begin
9
- i = stats[o.class] || 0
10
- i += 1
11
- stats[o.class] = i
12
- ids << o.object_id if Integer === o.object_id
13
- rescue NoMethodError
14
- # Redis::Future undefines .class and .object_id super weird
15
- end
16
- }
17
- {:stats => stats, :ids => ids}
18
- end
19
-
20
- def diff_object_stats(before,after)
21
- diff = {}
22
- after.each do |k,v|
23
- diff[k] = v - (before[k] || 0)
24
- end
25
- before.each do |k,v|
26
- diff[k] = 0 - v unless after[k]
27
- end
28
-
29
- diff
30
- end
31
-
32
- def analyze_strings(ids_before,ids_after)
33
- result = {}
34
- ids_after.each do |id|
35
- obj = ObjectSpace._id2ref(id)
36
- if String === obj && !ids_before.include?(obj.object_id)
37
- result[obj] ||= 0
38
- result[obj] += 1
39
- end
40
- end
41
- result
42
- end
43
-
44
- def profile_gc_time(app,env)
45
- body = []
46
-
47
- begin
48
- GC::Profiler.clear
49
- GC::Profiler.enable
50
- b = app.call(env)[2]
51
- b.close if b.respond_to? :close
52
- body << "GC Profiler ran during this request, if it fired you will see the cost below:\n\n"
53
- body << GC::Profiler.result
54
- ensure
55
- GC.enable
56
- GC::Profiler.disable
57
- end
58
-
59
- return [200, {'Content-Type' => 'text/plain'}, body]
60
- end
61
-
62
- def profile_gc(app,env)
63
-
64
- body = [];
65
-
66
- stat_before,stat_after,diff,string_analysis = nil
67
- begin
68
- GC.disable
69
- stat_before = object_space_stats
70
- b = app.call(env)[2]
71
- b.close if b.respond_to? :close
72
- stat_after = object_space_stats
73
-
74
- diff = diff_object_stats(stat_before[:stats],stat_after[:stats])
75
- string_analysis = analyze_strings(stat_before[:ids], stat_after[:ids])
76
- ensure
77
- GC.enable
78
- end
79
-
80
-
81
- body << "
82
- ObjectSpace delta caused by request:
83
- --------------------------------------------\n"
84
- diff.to_a.reject{|k,v| v == 0}.sort{|x,y| y[1] <=> x[1]}.each do |k,v|
85
- body << "#{k} : #{v}\n" if v != 0
86
- end
87
-
88
- body << "\n
89
- ObjectSpace stats:
90
- -----------------\n"
91
-
92
- stat_after[:stats].to_a.sort{|x,y| y[1] <=> x[1]}.each do |k,v|
93
- body << "#{k} : #{v}\n"
94
- end
95
-
96
-
97
- body << "\n
98
- String stats:
99
- ------------\n"
100
-
101
- string_analysis.to_a.sort{|x,y| y[1] <=> x[1] }.take(1000).each do |string,count|
102
- body << "#{count} : #{string}\n"
103
- end
104
-
105
- return [200, {'Content-Type' => 'text/plain'}, body]
106
- end
107
- end
@@ -1,40 +0,0 @@
1
- require 'objspace'
2
-
3
- class Rack::MiniProfiler::GCProfilerRubyHead
4
- def profile_rack(app,env)
5
- end
6
-
7
- def profile(&block)
8
- GC.start
9
- GC.disable
10
-
11
- items = []
12
- objs = []
13
-
14
- ObjectSpace.trace_object_allocations do
15
- block.call
16
-
17
- ObjectSpace.each_object do |o|
18
- objs << o
19
- end
20
-
21
- objs.each do |o|
22
- g = ObjectSpace.allocation_generation(o)
23
- if g
24
- l = ObjectSpace.allocation_sourceline(o)
25
- f = ObjectSpace.allocation_sourcefile(o)
26
- c = ObjectSpace.allocation_class_path(o)
27
- m = ObjectSpace.allocation_method_id(o)
28
- items << "Allocated #{c} in #{m} #{f}:#{l}"
29
- end
30
- end
31
- end
32
-
33
- items.group_by{|x| x}.sort{|a,b| b[1].length <=> a[1].length}.each do |row, group|
34
- puts "#{row} x #{group.length}"
35
- end
36
-
37
- GC.enable
38
- profile_allocations(name, &block)
39
- end
40
- end
@@ -1,58 +0,0 @@
1
- require 'mini_profiler/timer_struct'
2
-
3
- module Rack
4
- class MiniProfiler
5
-
6
- # PageTimerStruct
7
- # Root: RequestTimer
8
- # :has_many RequestTimer children
9
- # :has_many SqlTimer children
10
- # :has_many CustomTimer children
11
- class PageTimerStruct < TimerStruct
12
- def initialize(env)
13
- super("Id" => MiniProfiler.generate_id,
14
- "Name" => env['PATH_INFO'],
15
- "Started" => (Time.now.to_f * 1000).to_i,
16
- "MachineName" => env['SERVER_NAME'],
17
- "Level" => 0,
18
- "User" => "unknown user",
19
- "HasUserViewed" => false,
20
- "ClientTimings" => nil,
21
- "DurationMilliseconds" => 0,
22
- "HasTrivialTimings" => true,
23
- "HasAllTrivialTimigs" => false,
24
- "TrivialDurationThresholdMilliseconds" => 2,
25
- "Head" => nil,
26
- "DurationMillisecondsInSql" => 0,
27
- "HasSqlTimings" => true,
28
- "HasDuplicateSqlTimings" => false,
29
- "ExecutedReaders" => 0,
30
- "ExecutedScalars" => 0,
31
- "ExecutedNonQueries" => 0,
32
- "CustomTimingNames" => [],
33
- "CustomTimingStats" => {}
34
- )
35
- name = "#{env['REQUEST_METHOD']} http://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{env['SCRIPT_NAME']}#{env['PATH_INFO']}"
36
- self['Root'] = RequestTimerStruct.createRoot(name, self)
37
- end
38
-
39
- def duration_ms
40
- @attributes['Root']['DurationMilliseconds']
41
- end
42
-
43
- def root
44
- @attributes['Root']
45
- end
46
-
47
- def to_json(*a)
48
- attribs = @attributes.merge(
49
- "Started" => '/Date(%d)/' % @attributes['Started'],
50
- "DurationMilliseconds" => @attributes['Root']['DurationMilliseconds'],
51
- "CustomTimingNames" => @attributes['CustomTimingStats'].keys.sort
52
- )
53
- ::JSON.generate(attribs, :max_nesting => 100)
54
- end
55
- end
56
-
57
- end
58
- end
@@ -1,115 +0,0 @@
1
- require 'mini_profiler/timer_struct'
2
-
3
- module Rack
4
- class MiniProfiler
5
-
6
- class RequestTimerStruct < TimerStruct
7
-
8
- def self.createRoot(name, page)
9
- rt = RequestTimerStruct.new(name, page, nil)
10
- rt["IsRoot"]= true
11
- rt
12
- end
13
-
14
- attr_accessor :children_duration
15
-
16
- def initialize(name, page, parent)
17
- super("Id" => MiniProfiler.generate_id,
18
- "Name" => name,
19
- "DurationMilliseconds" => 0,
20
- "DurationWithoutChildrenMilliseconds"=> 0,
21
- "StartMilliseconds" => (Time.now.to_f * 1000).to_i - page['Started'],
22
- "ParentTimingId" => nil,
23
- "Children" => [],
24
- "HasChildren"=> false,
25
- "KeyValues" => nil,
26
- "HasSqlTimings"=> false,
27
- "HasDuplicateSqlTimings"=> false,
28
- "TrivialDurationThresholdMilliseconds" => 2,
29
- "SqlTimings" => [],
30
- "SqlTimingsDurationMilliseconds"=> 0,
31
- "IsTrivial"=> false,
32
- "IsRoot"=> false,
33
- "Depth"=> parent ? parent.depth + 1 : 0,
34
- "ExecutedReaders"=> 0,
35
- "ExecutedScalars"=> 0,
36
- "ExecutedNonQueries"=> 0,
37
- "CustomTimingStats" => {},
38
- "CustomTimings" => {})
39
- @children_duration = 0
40
- @start = Time.now
41
- @parent = parent
42
- @page = page
43
- end
44
-
45
- def duration_ms
46
- self['DurationMilliseconds']
47
- end
48
-
49
- def start_ms
50
- self['StartMilliseconds']
51
- end
52
-
53
- def start
54
- @start
55
- end
56
-
57
- def depth
58
- self['Depth']
59
- end
60
-
61
- def children
62
- self['Children']
63
- end
64
-
65
- def add_child(name)
66
- request_timer = RequestTimerStruct.new(name, @page, self)
67
- self['Children'].push(request_timer)
68
- self['HasChildren'] = true
69
- request_timer['ParentTimingId'] = self['Id']
70
- request_timer['Depth'] = self['Depth'] + 1
71
- request_timer
72
- end
73
-
74
- def add_sql(query, elapsed_ms, page, skip_backtrace = false, full_backtrace = false)
75
- timer = SqlTimerStruct.new(query, elapsed_ms, page, self , skip_backtrace, full_backtrace)
76
- timer['ParentTimingId'] = self['Id']
77
- self['SqlTimings'].push(timer)
78
- self['HasSqlTimings'] = true
79
- self['SqlTimingsDurationMilliseconds'] += elapsed_ms
80
- page['DurationMillisecondsInSql'] += elapsed_ms
81
- timer
82
- end
83
-
84
- def add_custom(type, elapsed_ms, page)
85
- timer = CustomTimerStruct.new(type, elapsed_ms, page, self)
86
- timer['ParentTimingId'] = self['Id']
87
- self['CustomTimings'][type] ||= []
88
- self['CustomTimings'][type].push(timer)
89
-
90
- self['CustomTimingStats'][type] ||= {"Count" => 0, "Duration" => 0.0}
91
- self['CustomTimingStats'][type]['Count'] += 1
92
- self['CustomTimingStats'][type]['Duration'] += elapsed_ms
93
-
94
- page['CustomTimingStats'][type] ||= {"Count" => 0, "Duration" => 0.0}
95
- page['CustomTimingStats'][type]['Count'] += 1
96
- page['CustomTimingStats'][type]['Duration'] += elapsed_ms
97
-
98
- timer
99
- end
100
-
101
- def record_time(milliseconds = nil)
102
- milliseconds ||= (Time.now - @start) * 1000
103
- self['DurationMilliseconds'] = milliseconds
104
- self['IsTrivial'] = true if milliseconds < self["TrivialDurationThresholdMilliseconds"]
105
- self['DurationWithoutChildrenMilliseconds'] = milliseconds - @children_duration
106
-
107
- if @parent
108
- @parent.children_duration += milliseconds
109
- end
110
-
111
- end
112
- end
113
- end
114
-
115
- end
@@ -1,58 +0,0 @@
1
- require 'mini_profiler/timer_struct'
2
-
3
- module Rack
4
- class MiniProfiler
5
-
6
- # Timing system for a SQL query
7
- class SqlTimerStruct < TimerStruct
8
- def initialize(query, duration_ms, page, parent, skip_backtrace = false, full_backtrace = false)
9
-
10
- stack_trace = nil
11
- unless skip_backtrace || duration_ms < Rack::MiniProfiler.config.backtrace_threshold_ms
12
- # Allow us to filter the stack trace
13
- stack_trace = ""
14
- # Clean up the stack trace if there are options to do so
15
- Kernel.caller.each do |ln|
16
- ln.gsub!(Rack::MiniProfiler.config.backtrace_remove, '') if Rack::MiniProfiler.config.backtrace_remove and !full_backtrace
17
- if full_backtrace or
18
- (
19
- (
20
- Rack::MiniProfiler.config.backtrace_includes.nil? or
21
- Rack::MiniProfiler.config.backtrace_includes.all?{|regex| ln =~ regex}
22
- ) and
23
- (
24
- Rack::MiniProfiler.config.backtrace_ignores.nil? or
25
- Rack::MiniProfiler.config.backtrace_ignores.all?{|regex| !(ln =~ regex)}
26
- )
27
- )
28
- stack_trace << ln << "\n"
29
- end
30
- end
31
- end
32
-
33
- @parent = parent
34
- @page = page
35
-
36
- super("ExecuteType" => 3, # TODO
37
- "FormattedCommandString" => query,
38
- "StackTraceSnippet" => stack_trace,
39
- "StartMilliseconds" => ((Time.now.to_f * 1000).to_i - page['Started']) - duration_ms,
40
- "DurationMilliseconds" => duration_ms,
41
- "FirstFetchDurationMilliseconds" => duration_ms,
42
- "Parameters" => nil,
43
- "ParentTimingId" => nil,
44
- "IsDuplicate" => false)
45
- end
46
-
47
- def report_reader_duration(elapsed_ms)
48
- return if @reported
49
- @reported = true
50
- self["DurationMilliseconds"] += elapsed_ms
51
- @parent["SqlTimingsDurationMilliseconds"] += elapsed_ms
52
- @page["DurationMillisecondsInSql"] += elapsed_ms
53
- end
54
-
55
- end
56
-
57
- end
58
- end