rack-mini-profiler 0.1.23 → 0.1.28

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.

@@ -1,108 +1,131 @@
1
- module Rack
2
- class MiniProfiler
3
- module ProfilingMethods
4
-
5
- def record_sql(query, elapsed_ms)
6
- c = current
7
- return unless c
8
- c.current_timer.add_sql(query, elapsed_ms, c.page_struct, c.skip_backtrace, c.full_backtrace) if (c && c.current_timer)
9
- end
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
-
27
- # perform a profiling step on given block
28
- def step(name, opts = nil)
29
- if current
30
- parent_timer = current.current_timer
31
- result = nil
32
- current.current_timer = current_timer = current.current_timer.add_child(name)
33
- begin
34
- result = yield if block_given?
35
- ensure
36
- current_timer.record_time
37
- current.current_timer = parent_timer
38
- end
39
- else
40
- yield if block_given?
41
- end
42
- end
43
-
44
- def unprofile_method(klass, method)
45
-
46
- clean = clean_method_name(method)
47
-
48
- with_profiling = ("#{clean}_with_mini_profiler").intern
49
- without_profiling = ("#{clean}_without_mini_profiler").intern
50
-
51
- if klass.send :method_defined?, with_profiling
52
- klass.send :alias_method, method, without_profiling
53
- klass.send :remove_method, with_profiling
54
- klass.send :remove_method, without_profiling
55
- end
56
- end
57
-
58
- def profile_method(klass, method, &blk)
59
- default_name = klass.to_s + " " + method.to_s
60
- clean = clean_method_name(method)
61
-
62
- with_profiling = ("#{clean}_with_mini_profiler").intern
63
- without_profiling = ("#{clean}_without_mini_profiler").intern
64
-
65
- if klass.send :method_defined?, with_profiling
66
- return # dont double profile
67
- end
68
-
69
- klass.send :alias_method, without_profiling, method
70
- klass.send :define_method, with_profiling do |*args, &orig|
71
- return self.send without_profiling, *args, &orig unless Rack::MiniProfiler.current
72
-
73
- name = default_name
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
-
84
- parent_timer = Rack::MiniProfiler.current.current_timer
85
- page_struct = Rack::MiniProfiler.current.page_struct
86
- result = nil
87
-
88
- Rack::MiniProfiler.current.current_timer = current_timer = parent_timer.add_child(name)
89
- begin
90
- result = self.send without_profiling, *args, &orig
91
- ensure
92
- current_timer.record_time
93
- Rack::MiniProfiler.current.current_timer = parent_timer
94
- end
95
- result
96
- end
97
- klass.send :alias_method, method, with_profiling
98
- end
99
-
100
- private
101
-
102
- def clean_method_name(method)
103
- method.to_s.gsub(/[\?\!]/, "")
104
- end
105
-
106
- end
107
- end
108
- end
1
+ module Rack
2
+ class MiniProfiler
3
+ module ProfilingMethods
4
+
5
+ def record_sql(query, elapsed_ms)
6
+ c = current
7
+ return unless c
8
+ c.current_timer.add_sql(query, elapsed_ms, c.page_struct, c.skip_backtrace, c.full_backtrace) if (c && c.current_timer)
9
+ end
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
+
27
+ # perform a profiling step on given block
28
+ def step(name, opts = nil)
29
+ if current
30
+ parent_timer = current.current_timer
31
+ result = nil
32
+ current.current_timer = current_timer = current.current_timer.add_child(name)
33
+ begin
34
+ result = yield if block_given?
35
+ ensure
36
+ current_timer.record_time
37
+ current.current_timer = parent_timer
38
+ end
39
+ else
40
+ yield if block_given?
41
+ end
42
+ end
43
+
44
+ def unprofile_method(klass, method)
45
+
46
+ clean = clean_method_name(method)
47
+
48
+ with_profiling = ("#{clean}_with_mini_profiler").intern
49
+ without_profiling = ("#{clean}_without_mini_profiler").intern
50
+
51
+ if klass.send :method_defined?, with_profiling
52
+ klass.send :alias_method, method, without_profiling
53
+ klass.send :remove_method, with_profiling
54
+ klass.send :remove_method, without_profiling
55
+ end
56
+ end
57
+
58
+ def profile_method(klass, method, &blk)
59
+ default_name = klass.to_s + " " + method.to_s
60
+ clean = clean_method_name(method)
61
+
62
+ with_profiling = ("#{clean}_with_mini_profiler").intern
63
+ without_profiling = ("#{clean}_without_mini_profiler").intern
64
+
65
+ if klass.send :method_defined?, with_profiling
66
+ return # dont double profile
67
+ end
68
+
69
+ klass.send :alias_method, without_profiling, method
70
+ klass.send :define_method, with_profiling do |*args, &orig|
71
+ return self.send without_profiling, *args, &orig unless Rack::MiniProfiler.current
72
+
73
+ name = default_name
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
+
84
+ parent_timer = Rack::MiniProfiler.current.current_timer
85
+ page_struct = Rack::MiniProfiler.current.page_struct
86
+ result = nil
87
+
88
+ Rack::MiniProfiler.current.current_timer = current_timer = parent_timer.add_child(name)
89
+ begin
90
+ result = self.send without_profiling, *args, &orig
91
+ ensure
92
+ current_timer.record_time
93
+ Rack::MiniProfiler.current.current_timer = parent_timer
94
+ end
95
+ result
96
+ end
97
+ klass.send :alias_method, method, with_profiling
98
+ end
99
+
100
+ # Add a custom timing. These are displayed similar to SQL/query time in
101
+ # columns expanding to the right.
102
+ #
103
+ # type - String counter type. Each distinct type gets its own column.
104
+ # duration_ms - Duration of the call in ms. Either this or a block must be
105
+ # given but not both.
106
+ #
107
+ # When a block is given, calculate the duration by yielding to the block
108
+ # and keeping a record of its run time.
109
+ #
110
+ # Returns the result of the block, or nil when no block is given.
111
+ def counter(type, duration_ms=nil)
112
+ result = nil
113
+ if block_given?
114
+ start = Time.now
115
+ result = yield
116
+ duration_ms = (Time.now - start).to_f * 1000
117
+ end
118
+ return result if current.nil? || !request_authorized?
119
+ current.current_timer.add_custom(type, duration_ms, current.page_struct)
120
+ result
121
+ end
122
+
123
+ private
124
+
125
+ def clean_method_name(method)
126
+ method.to_s.gsub(/[\?\!]/, "")
127
+ end
128
+
129
+ end
130
+ end
131
+ end
@@ -8,7 +8,7 @@ module Rack
8
8
  def initialize(query, duration_ms, page, parent, skip_backtrace = false, full_backtrace = false)
9
9
 
10
10
  stack_trace = nil
11
- unless skip_backtrace
11
+ unless skip_backtrace || duration_ms < Rack::MiniProfiler.config.backtrace_threshold_ms
12
12
  # Allow us to filter the stack trace
13
13
  stack_trace = ""
14
14
  # Clean up the stack trace if there are options to do so
@@ -1,27 +1,32 @@
1
- module Rack
2
- class MiniProfiler
3
- class AbstractStore
4
-
5
- def save(page_struct)
6
- raise NotImplementedError.new("save is not implemented")
7
- end
8
-
9
- def load(id)
10
- raise NotImplementedError.new("load is not implemented")
11
- end
12
-
13
- def set_unviewed(user, id)
14
- raise NotImplementedError.new("set_unviewed is not implemented")
15
- end
16
-
17
- def set_viewed(user, id)
18
- raise NotImplementedError.new("set_viewed is not implemented")
19
- end
20
-
21
- def get_unviewed_ids(user)
22
- raise NotImplementedError.new("get_unviewed_ids is not implemented")
23
- end
24
-
25
- end
26
- end
27
- end
1
+ module Rack
2
+ class MiniProfiler
3
+ class AbstractStore
4
+
5
+ def save(page_struct)
6
+ raise NotImplementedError.new("save is not implemented")
7
+ end
8
+
9
+ def load(id)
10
+ raise NotImplementedError.new("load is not implemented")
11
+ end
12
+
13
+ def set_unviewed(user, id)
14
+ raise NotImplementedError.new("set_unviewed is not implemented")
15
+ end
16
+
17
+ def set_viewed(user, id)
18
+ raise NotImplementedError.new("set_viewed is not implemented")
19
+ end
20
+
21
+ def get_unviewed_ids(user)
22
+ raise NotImplementedError.new("get_unviewed_ids is not implemented")
23
+ end
24
+
25
+ def diagnostics(user)
26
+ # this is opt in, no need to explode if not implemented
27
+ ""
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -1,109 +1,111 @@
1
- module Rack
2
- class MiniProfiler
3
- class FileStore < AbstractStore
4
-
5
- class FileCache
6
- def initialize(path, prefix)
7
- @path = path
8
- @prefix = prefix
9
- end
10
-
11
- def [](key)
12
- begin
13
- data = ::File.open(path(key),"rb") {|f| f.read}
14
- return Marshal.load data
15
- rescue => e
16
- return nil
17
- end
18
- end
19
-
20
- def []=(key,val)
21
- ::File.open(path(key), "wb+") {|f| f.write Marshal.dump(val)}
22
- end
23
-
24
- private
25
- def path(key)
26
- @path + "/" + @prefix + "_" + key
27
- end
28
- end
29
-
30
- EXPIRE_TIMER_CACHE = 3600 * 24
31
-
32
- def initialize(args)
33
- @path = args[:path]
34
- raise ArgumentError.new :path unless @path
35
- @timer_struct_cache = FileCache.new(@path, "mp_timers")
36
- @timer_struct_lock = Mutex.new
37
- @user_view_cache = FileCache.new(@path, "mp_views")
38
- @user_view_lock = Mutex.new
39
-
40
- me = self
41
- Thread.new do
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
50
- end
51
- end
52
- end
53
-
54
- def save(page_struct)
55
- @timer_struct_lock.synchronize {
56
- @timer_struct_cache[page_struct['Id']] = page_struct
57
- }
58
- end
59
-
60
- def load(id)
61
- @timer_struct_lock.synchronize {
62
- @timer_struct_cache[id]
63
- }
64
- end
65
-
66
- def set_unviewed(user, id)
67
- @user_view_lock.synchronize {
68
- current = @user_view_cache[user]
69
- current = [] unless Array === current
70
- current << id
71
- @user_view_cache[user] = current.uniq
72
- }
73
- end
74
-
75
- def set_viewed(user, id)
76
- @user_view_lock.synchronize {
77
- @user_view_cache[user] ||= []
78
- current = @user_view_cache[user]
79
- current = [] unless Array === current
80
- current.delete(id)
81
- @user_view_cache[user] = current.uniq
82
- }
83
- end
84
-
85
- def get_unviewed_ids(user)
86
- @user_view_lock.synchronize {
87
- @user_view_cache[user]
88
- }
89
- end
90
-
91
- def cleanup_cache
92
- files = Dir.entries(@path)
93
- @timer_struct_lock.synchronize {
94
- files.each do |f|
95
- f = @path + '/' + f
96
- File.delete f if f =~ /^mp_timers/ and (Time.now - File.mtime(f)) > EXPIRE_TIMER_CACHE
97
- end
98
- }
99
- @user_view_lock.synchronize {
100
- files.each do |f|
101
- f = @path + '/' + f
102
- File.delete f if f =~ /^mp_views/ and (Time.now - File.mtime(f)) > EXPIRE_TIMER_CACHE
103
- end
104
- }
105
- end
106
-
107
- end
108
- end
109
- end
1
+ module Rack
2
+ class MiniProfiler
3
+ class FileStore < AbstractStore
4
+
5
+ class FileCache
6
+ def initialize(path, prefix)
7
+ @path = path
8
+ @prefix = prefix
9
+ end
10
+
11
+ def [](key)
12
+ begin
13
+ data = ::File.open(path(key),"rb") {|f| f.read}
14
+ return Marshal.load data
15
+ rescue => e
16
+ return nil
17
+ end
18
+ end
19
+
20
+ def []=(key,val)
21
+ ::File.open(path(key), "wb+") {|f| f.write Marshal.dump(val)}
22
+ end
23
+
24
+ private
25
+ def path(key)
26
+ @path + "/" + @prefix + "_" + key
27
+ end
28
+ end
29
+
30
+ EXPIRES_IN_SECONDS = 60 * 60 * 24
31
+
32
+ def initialize(args = nil)
33
+ args ||= {}
34
+ @path = args[:path]
35
+ @expires_in_seconds = args[:expires_in] || EXPIRES_IN_SECONDS
36
+ raise ArgumentError.new :path unless @path
37
+ @timer_struct_cache = FileCache.new(@path, "mp_timers")
38
+ @timer_struct_lock = Mutex.new
39
+ @user_view_cache = FileCache.new(@path, "mp_views")
40
+ @user_view_lock = Mutex.new
41
+
42
+ me = self
43
+ Thread.new do
44
+ begin
45
+ while true do
46
+ # TODO: a sane retry count before bailing
47
+ me.cleanup_cache
48
+ sleep(3600)
49
+ end
50
+ rescue
51
+ # don't crash the thread, we can clean up next time
52
+ end
53
+ end
54
+ end
55
+
56
+ def save(page_struct)
57
+ @timer_struct_lock.synchronize {
58
+ @timer_struct_cache[page_struct['Id']] = page_struct
59
+ }
60
+ end
61
+
62
+ def load(id)
63
+ @timer_struct_lock.synchronize {
64
+ @timer_struct_cache[id]
65
+ }
66
+ end
67
+
68
+ def set_unviewed(user, id)
69
+ @user_view_lock.synchronize {
70
+ current = @user_view_cache[user]
71
+ current = [] unless Array === current
72
+ current << id
73
+ @user_view_cache[user] = current.uniq
74
+ }
75
+ end
76
+
77
+ def set_viewed(user, id)
78
+ @user_view_lock.synchronize {
79
+ @user_view_cache[user] ||= []
80
+ current = @user_view_cache[user]
81
+ current = [] unless Array === current
82
+ current.delete(id)
83
+ @user_view_cache[user] = current.uniq
84
+ }
85
+ end
86
+
87
+ def get_unviewed_ids(user)
88
+ @user_view_lock.synchronize {
89
+ @user_view_cache[user]
90
+ }
91
+ end
92
+
93
+ def cleanup_cache
94
+ files = Dir.entries(@path)
95
+ @timer_struct_lock.synchronize {
96
+ files.each do |f|
97
+ f = @path + '/' + f
98
+ ::File.delete f if ::File.basename(f) =~ /^mp_timers/ and (Time.now - ::File.mtime(f)) > @expires_in_seconds
99
+ end
100
+ }
101
+ @user_view_lock.synchronize {
102
+ files.each do |f|
103
+ f = @path + '/' + f
104
+ ::File.delete f if ::File.basename(f) =~ /^mp_views/ and (Time.now - ::File.mtime(f)) > @expires_in_seconds
105
+ end
106
+ }
107
+ end
108
+
109
+ end
110
+ end
111
+ end