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 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
- 9-July-2012 - Sam
11
-
12
- * Cleaned up mechanism for profiling in production, all you need to do now
13
- is call Rack::MiniProfiler.authorize_request to get profiling working in
14
- production
15
- * Added option to display full backtraces pp=full-backtrace
16
- * Cleaned up railties, got rid of the post authorize callback
17
- * Version 0.1.3
18
-
19
- 12-July-2012 - Sam
20
-
21
- * Fixed incorrect profiling steps (was not indenting or measuring start time right
22
- * Implemented native PG and MySql2 interceptors, this gives way more accurate times
23
- * Refactored context so its a proper class and not a hash
24
- * Added some more client probing built in to rails
25
- * More tests
26
-
27
- 18-July-2012 - Sam
28
-
29
- * Added First Paint time for chrome
30
- * Bug fix to ensure non Rails installs have mini profiler
31
- * Version 0.1.7
32
-
33
- 30-July-2012 - Sam
34
-
35
- * Made compliant with ancient versions of Rack (including Rack used by Rails2)
36
- * Fixed broken share link
37
- * Fixed crashes on startup (in MemoryStore and FileStore)
38
- * Version 0.1.8
39
- * Unicode fix
40
- * Version 0.1.9
41
-
42
- 7-August-2012 - Sam
43
-
44
- * Added option to disable profiler for the current session (pp=disable / pp=enable)
45
- * yajl compatability contributed by Sven Riedel
46
-
47
- 10-August-2012 - Sam
48
-
49
- * Added basic prepared statement profiling for postgres
50
-
51
- 20-August-2012 - Sam
52
-
53
- * 1.12.pre
54
- * Cap X-MiniProfiler-Ids at 10, otherwise the header can get killed
55
-
56
- 3-September-2012 - Sam
57
-
58
- * 1.13.pre
59
- * pg gem prepared statements were not being logged correctly
60
- * added setting config.backtrace_ignores = [] - an array of regexes that match on caller lines that get ignored
61
- * added setting config.backtrace_includes = [] - an array of regexes that get included in the trace by default
62
- * cleaned up the way client settings are stored
63
- * made pp=full-backtrace "sticky"
64
- * added pp=normal-backtrace to clear the "sticky" state
65
- * change "pp=sample" to work with "caller" no need for stack trace gem
66
-
67
- 4-September-2012 - Sam
68
-
69
- * 1.15.pre
70
- * fixed annoying bug where client settings were not sticking
71
- * fixed long standing issue with Rack::ConditionalGet stopping MiniProfiler from working properly
72
-
73
- 5-September-2012 - Sam
74
-
75
- * 1.16
76
- * fixed long standing problem specs (issue with memory store)
77
- * fixed issue where profiler would be dumped when you got a 404 in production (and any time rails is bypassed)
78
- * implemented stacktrace properly
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(nil, client_settings)
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(category = nil, client_settings)
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
- name = blk.bind(self).call(*args) if blk
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
@@ -12,8 +12,9 @@ module MiniProfilerRails
12
12
  Rails.env.development? || Rails.env.production?
13
13
  }
14
14
 
15
+ c.skip_paths ||= []
16
+
15
17
  if Rails.env.development?
16
- c.skip_paths ||= []
17
18
  c.skip_paths << "/assets/"
18
19
  c.skip_schema_queries = true
19
20
  end
@@ -1,6 +1,6 @@
1
1
  require 'mini_profiler/profiler'
2
2
  require 'patches/sql_patches'
3
3
 
4
- if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3
4
+ if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i >= 3
5
5
  require 'mini_profiler_rails/railtie'
6
6
  end
@@ -1,9 +1,9 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rack-mini-profiler"
3
- s.version = "0.1.16"
3
+ s.version = "0.1.21"
4
4
  s.summary = "Profiles loading speed for rack applications."
5
- s.authors = ["Aleks Totic","Sam Saffron", "Robin Ward"]
6
- s.description = "Page loading speed displayed on every page. Optimize while you develop, performance is a feature."
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.16
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-05 00:00:00.000000000 Z
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: Page loading speed displayed on every page. Optimize while you develop,
81
- performance is a feature.
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: 1044164429
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: 1044164429
145
+ hash: -668836557
144
146
  requirements: []
145
147
  rubyforge_project:
146
148
  rubygems_version: 1.8.24