rack-insight 0.5.23 → 0.5.24

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,5 +1,13 @@
1
1
  == HEAD
2
2
 
3
+ == 0.5.24 / 2013-01-01
4
+
5
+ * Bug Fixes
6
+
7
+ * (Issue #17) Fix 20x performance hit with default log level by changing default log level from `:debug` to `:silent` (Rack::Insight::Logging::VERBOSITY[:silent])
8
+
9
+ * Changed event logging in the instrumentation from `:high` to `:debug` level.
10
+
3
11
  == 0.5.23 / 2012-09-14
4
12
 
5
13
  * New Features
@@ -217,20 +225,20 @@
217
225
  * Can use LoggerPanel on ruby stdlib Logger in non-rails app (Tim Connor)
218
226
 
219
227
  * Bug fixes
220
-
228
+
221
229
  * Fix profile, explain and select in the queries tab, fixes issue #22 (ebertech)
222
-
230
+
223
231
  * Minor fixes
224
-
232
+
225
233
  * Explicitly require 'digest/sha1' (Jérémy Lecour)
226
234
  * Eliminate unreachable code in params signature validation (Tim Connor)
227
235
 
228
236
  * Compatibilty
229
237
 
230
238
  * Make Redis panel compatible with latest redis-rb gem, without breaking older redis-rb versions (Luke Melia)
231
-
239
+
232
240
  * Other
233
-
241
+
234
242
  * Refactoring and code cleanup (Tim Connor)
235
243
  * Testing cleanup - better isolation of Rails vs. non-Rails in tests (Tim Connor)
236
244
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rack-insight (0.5.19)
4
+ rack-insight (0.5.23)
5
5
  rack
6
6
  sqlite3 (>= 1.3.3)
7
7
  uuidtools (>= 2.1.2)
@@ -9,11 +9,15 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- archive-tar-minitar (0.5.2)
13
12
  columnize (0.3.6)
13
+ debugger (1.2.0)
14
+ columnize (>= 0.3.1)
15
+ debugger-linecache (~> 1.1.1)
16
+ debugger-ruby_core_source (~> 1.1.3)
17
+ debugger-linecache (1.1.2)
18
+ debugger-ruby_core_source (>= 1.1.1)
19
+ debugger-ruby_core_source (1.1.3)
14
20
  diff-lcs (1.1.3)
15
- linecache19 (0.5.12)
16
- ruby_core_source (>= 0.1.4)
17
21
  nokogiri (1.5.4)
18
22
  rack (1.3.5)
19
23
  rack-protection (1.1.4)
@@ -39,19 +43,9 @@ GEM
39
43
  rspec-expectations (2.11.2)
40
44
  diff-lcs (~> 1.1.3)
41
45
  rspec-mocks (2.11.2)
42
- ruby-debug-base19 (0.11.25)
43
- columnize (>= 0.3.1)
44
- linecache19 (>= 0.5.11)
45
- ruby_core_source (>= 0.1.4)
46
- ruby-debug19 (0.11.6)
47
- columnize (>= 0.3.1)
48
- linecache19 (>= 0.5.11)
49
- ruby-debug-base19 (>= 0.11.19)
50
46
  ruby2ruby (1.2.5)
51
47
  ruby_parser (~> 2.0)
52
48
  sexp_processor (~> 3.0)
53
- ruby_core_source (0.1.5)
54
- archive-tar-minitar (>= 0.5.2)
55
49
  ruby_parser (2.3.1)
56
50
  sexp_processor (~> 3.0)
57
51
  sexp_processor (3.2.0)
@@ -71,12 +65,12 @@ PLATFORMS
71
65
  ruby
72
66
 
73
67
  DEPENDENCIES
68
+ debugger
74
69
  rack-insight!
75
70
  rake
76
71
  redcarpet
77
72
  reek (>= 1.2.8)
78
73
  roodi (>= 2.1.0)
79
74
  rspec (>= 2.11.0)
80
- ruby-debug19
81
75
  sinatra
82
76
  webrat
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- Rack::Insight
1
+ Rack::Insight [![Dependency Status](https://gemnasium.com/pboling/rack-insight.png)](https://gemnasium.com/pboling/rack-insight) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/pboling/rack-insight) [![Build Status](https://secure.travis-ci.org/pboling/rack-insight.png?branch=master)](https://travis-ci.org/pboling/rack-insight) [![Endorse Me](http://api.coderwall.com/pboling/endorsecount.png)](http://coderwall.com/pboling)
2
2
  =============
3
3
 
4
4
  Rack::Insight began life as an fork of Logical::Insight by LRDesign.
@@ -43,10 +43,10 @@ Features
43
43
  * SQL (Failing specs, and I don't use it, someone please pull me a fix!)
44
44
  * Active Record (Failing specs, and I don't use it, someone please pull me a fix!)
45
45
  * Other bundled panels:
46
+ * Sphinx (thanks to Oggy for updating this to the rack-insight panel API)
46
47
  * Redis
47
48
  * Speedtracer
48
- * Retired panels - if needed they could come back quickly:
49
- * Sphinx
49
+ * Panels under construction:
50
50
  * Mongo
51
51
  * The API for adding your own panels is simple and very powerful
52
52
  * Consistent interface to instrument application code
@@ -54,6 +54,13 @@ Features
54
54
  * Easy to add sub-applications for more detailed reports (c.f. SQLPanel)
55
55
  * Ask me (pboling) if you need help with this.
56
56
 
57
+ Build Status
58
+ ---------------------------
59
+
60
+ Travis-ci: [![Build Status](https://secure.travis-ci.org/pboling/rack-insight.png?branch=master)](https://travis-ci.org/pboling/rack-insight) - Please help if you have time!
61
+
62
+ CodeClimate: [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/pboling/rack-insight)
63
+
57
64
  Rails quick start
58
65
  ---------------------------
59
66
 
@@ -153,7 +160,8 @@ Specify the set of panels you want, in the order you want them to appear:
153
160
  templates_panel
154
161
  cache_panel
155
162
  log_panel
156
- memory_panel
163
+ memory_panel,
164
+ sphinx_panel
157
165
  ]
158
166
 
159
167
  By default panel files are looked up by prepending "rack/insight/panels/" and requiring them.
@@ -211,7 +219,7 @@ Restrict access using a password:
211
219
 
212
220
  #### custom file path for the request recording database ####
213
221
 
214
- Logical Rack::Insight uses SQLite to store data from requests, and outputs a database
222
+ Rack::Insight uses SQLite to store data from requests, and outputs a database
215
223
  file in the root directory. If you need the file to be created at another
216
224
  location (i.e. Heroku), you can pass a custom file path.
217
225
 
@@ -241,7 +249,7 @@ Setup the probes for the magic panel in a `before_initialize` block in your appl
241
249
  Custom Panels
242
250
  -------------
243
251
 
244
- See Magic Panels above, remove teh is_magic declaration, and add your own methods.
252
+ See Magic Panels above, remove the is_magic declaration, and add your own methods.
245
253
  Look at the panels bundled with this gem for pointers. Here are some important methods to watch for:
246
254
 
247
255
  * initialize
@@ -259,7 +267,7 @@ Authors
259
267
  Thanks
260
268
  ------
261
269
  Rack::Insight owes a lot to both LogicalInsight and Rack::Bug, as the basis projects. There's a lot of smart
262
- in there. Many thanks to Evan, Judson, and Bryan for building them.
270
+ in there. Many thanks to Judson, and Bryan for building them.
263
271
 
264
272
  Inspiration for Rack::Bug is primarily from the Django debug toolbar.
265
273
  Additional ideas from Rails footnotes, Rack's ShowException middleware, Oink,
@@ -273,6 +281,8 @@ MIT. See LICENSE in this directory.
273
281
  Notes
274
282
  -----
275
283
 
284
+ The ActiveRecord panel doesn't seem to work currently. Probably something minor, but haven't had time to look into it.
285
+
276
286
  Legacy files: would like to re-include them, but they need work
277
287
 
278
288
  lib/rack/insight/views/panels/mongo.html.erb
@@ -280,9 +290,5 @@ Legacy files: would like to re-include them, but they need work
280
290
  lib/rack/insight/panels/mongo_panel/stats.rb
281
291
  lib/rack/insight/panels/mongo_panel.rb
282
292
 
283
- lib/rack/insight/views/panels/sphinx.html.erb
284
- lib/rack/insight/panels/sphinx_panel/stats.rb
285
- lib/rack/insight/panels/sphinx_panel.rb
286
-
287
293
  This one is mostly just a curiosity
288
294
  lib/rack/insight/panels/speedtracer_panel/profiling.rb
@@ -1,7 +1,7 @@
1
1
  require 'rack'
2
2
  require "digest/sha1"
3
- require "rack/insight/config"
4
3
  require "rack/insight/logging"
4
+ require "rack/insight/config"
5
5
  require "rack/insight/filtered_backtrace"
6
6
  require "rack/insight/options"
7
7
  require 'rack/insight/magic_insight'
@@ -8,7 +8,7 @@ module Rack::Insight
8
8
  @log_file = STDOUT
9
9
  @log_level = ::Logger::DEBUG
10
10
  @logger = nil
11
- @verbosity = true
11
+ @verbosity = Rack::Insight::Logging::VERBOSITY[:silent]
12
12
  @rails_log_copy = true
13
13
  @filtered_backtrace = true
14
14
  @panel_configs = {
@@ -20,6 +20,7 @@ module Rack::Insight
20
20
  'Dalli::Client' => [:instance, :perform] } },
21
21
  :active_record => {:probes => {'ActiveRecord' => [:class, :allocate]}},
22
22
  # :log_panel => The log panel configures its probes in its initializer
23
+ :sphinx => {:probes => {'Riddle::Client' => [:instance, :request]}},
23
24
  :sql => {:probes => Hash[%w{ PostgreSQLAdapter MysqlAdapter SQLiteAdapter
24
25
  Mysql2Adapter OracleEnhancedAdapter }.map do |adapter|
25
26
  ["ActiveRecord::ConnectionAdapters::#{adapter}", [:instance, :execute]]
@@ -47,8 +48,8 @@ module Rack::Insight
47
48
  :log_level => @log_level,
48
49
  :rails_log_copy => @rails_log_copy, # Only has effect when logger is the Rack::Insight::Logger, or a logger behaving like it
49
50
  # Can set a specific verbosity: Rack::Insight::Logging::VERBOSITY[:debug]
50
- :verbosity => @verbosity, # true is equivalent to relying soley on the log level of each logged message
51
- :filtered_backtrace => @filtered_backtrace, # Full backtraces, or filtered ones?
51
+ :verbosity => @verbosity, # true is equivalent to relying solely on the log level of each logged message
52
+ :filtered_backtrace => @filtered_backtrace, # Full back-traces, or filtered ones?
52
53
  :panel_configs => @panel_configs, # Allow specific panels to have their own configurations, and make it extensible
53
54
  :silence_magic_insight_warnings => @silence_magic_insight_warnings, # Should Rack::Insight warn when the MagicInsight is used?
54
55
  :database => @database # a hash. Keys :raise_encoding_errors, and :raise_decoding_errors are self explanatory
@@ -71,7 +71,7 @@ module Rack::Insight
71
71
  end
72
72
 
73
73
  def start_event(method_call, arguments)
74
- if verbose(:high)
74
+ if verbose(:debug)
75
75
  logger.debug{ "Starting event: #{method_call.context} #{method_call.kind} #{method_call.method}" }
76
76
  end
77
77
 
@@ -82,7 +82,7 @@ module Rack::Insight
82
82
 
83
83
  def finish_event(method_call, arguments, start_time, result)
84
84
  timing = Timing.new(@start, start_time, Time.now)
85
- if verbose(:high)
85
+ if verbose(:debug)
86
86
  logger.debug{ "Finishing event: #{method_call.context} #{method_call.kind} #{method_call.method}" }
87
87
  end
88
88
  collectors_for(method_call).each do |collector|
@@ -1,40 +1,47 @@
1
1
  module Rack::Insight
2
-
3
2
  class RedisPanel < Panel
4
- require "rack/insight/panels/redis_panel/redis_extension"
5
-
6
3
  require "rack/insight/panels/redis_panel/stats"
7
4
 
8
- self.has_table = false
9
-
10
- def self.record(redis_command_args, backtrace, &block)
11
- return block.call unless Rack::Insight.enabled?
12
-
13
- start_time = Time.now
14
- result = block.call
15
- total_time = Time.now - start_time
16
- stats.record_call(total_time * 1_000, redis_command_args, backtrace)
17
- return result
5
+ def initialize(app)
6
+ super
7
+
8
+ unless is_probing?
9
+ probe(self) do
10
+ if defined?(Redis::Client)
11
+ # Redis >= 3.0.0
12
+ instrument "Redis::Client" do
13
+ instance_probe :call
14
+ end
15
+ elsif defined?(Redis)
16
+ # Redis < 3.0.0
17
+ instrument "Redis" do
18
+ instance_probe :call_command
19
+ end
20
+ end
21
+ end
22
+ end
18
23
  end
19
24
 
20
- def self.reset
21
- Thread.current["rack-insight.redis"] = Stats.new
25
+ def request_start(env, start)
26
+ @stats = Stats.new
22
27
  end
23
28
 
24
- def self.stats
25
- Thread.current["rack-insight.redis"] ||= Stats.new
29
+ def request_finish(env, status, headers, body, timing)
30
+ store(env, @stats)
31
+ @stats = nil
26
32
  end
27
33
 
28
- def heading
29
- "Redis: %.2fms (#{self.class.stats.queries.size} calls)" % self.class.stats.time
34
+ def after_detect(method_call, timing, args, message)
35
+ @stats.record_call(timing.duration, args, method_call)
30
36
  end
31
37
 
32
- def content
33
- result = render_template "panels/redis", :stats => self.class.stats
34
- self.class.reset
35
- return result
38
+ def heading_for_request(number)
39
+ stats = retrieve(number).first
40
+ "Redis: %.2fms (#{stats.queries.size} calls)" % stats.time
36
41
  end
37
42
 
43
+ def content_for_request(number)
44
+ render_template "panels/redis", :stats => retrieve(number).first
45
+ end
38
46
  end
39
-
40
47
  end
@@ -8,10 +8,10 @@ module Rack::Insight
8
8
  attr_reader :time
9
9
  attr_reader :command
10
10
 
11
- def initialize(time, command_args, backtrace)
11
+ def initialize(time, command_args, method_call)
12
12
  @time = time
13
13
  @command = command_args.inspect
14
- @backtrace = backtrace
14
+ @backtrace = method_call.backtrace
15
15
  end
16
16
 
17
17
  def display_time
@@ -28,8 +28,8 @@ module Rack::Insight
28
28
  @time = 0.0
29
29
  end
30
30
 
31
- def record_call(time, command_args, backtrace)
32
- @queries << Query.new(time, command_args, backtrace)
31
+ def record_call(time, command_args, method_call)
32
+ @queries << Query.new(time, command_args, method_call)
33
33
  @calls += 1
34
34
  @time += time
35
35
  end
@@ -1,39 +1,27 @@
1
1
  module Rack::Insight
2
-
3
2
  class SphinxPanel < Panel
4
- require "rack/insight/panels/sphinx_panel/sphinx_extension"
5
3
  require "rack/insight/panels/sphinx_panel/stats"
6
4
 
7
- self.has_table = false
8
-
9
- def self.record(*sphinx_command_args, &block)
10
- return block.call unless Rack::Insight.enabled?
11
-
12
- start_time = Time.now
13
- result = block.call
14
- total_time = Time.now - start_time
15
- stats.record_call(total_time * 1_000, sphinx_command_args)
16
- return result
5
+ def request_start(env, start)
6
+ @stats = Stats.new
17
7
  end
18
8
 
19
- def self.reset
20
- Thread.current["rack-insight.sphinx"] = Stats.new
9
+ def request_finish(env, status, headers, body, timing)
10
+ store(env, @stats)
11
+ @stats = nil
21
12
  end
22
13
 
23
- def self.stats
24
- Thread.current["rack-insight.sphinx"] ||= Stats.new
14
+ def after_detect(method_call, timing, args, message)
15
+ @stats.record_call(timing.duration, args, method_call)
25
16
  end
26
17
 
27
- def heading
28
- "Sphinx: %.2fms (#{self.class.stats.queries.size} calls)" % self.class.stats.time
18
+ def heading_for_request(number)
19
+ stats = retrieve(number).first
20
+ "Sphinx: %.2fms (#{stats.queries.size} calls)" % stats.time
29
21
  end
30
22
 
31
- def content
32
- result = render_template "panels/sphinx", :stats => self.class.stats
33
- self.class.reset
34
- return result
23
+ def content_for_request(number)
24
+ render_template "panels/sphinx", :stats => retrieve(number).first
35
25
  end
36
-
37
26
  end
38
-
39
27
  end
@@ -3,16 +3,28 @@ module Rack::Insight
3
3
 
4
4
  class Stats
5
5
  class Query
6
+ include Rack::Insight::FilteredBacktrace
7
+
8
+ require 'riddle/client'
9
+ MatchModes = Riddle::Client::MatchModes.invert
10
+ RankModes = Riddle::Client::RankModes.invert
11
+ SortModes = Riddle::Client::SortModes.invert
12
+ AttributeTypes = Riddle::Client::AttributeTypes.invert
13
+ GroupFunctions = Riddle::Client::GroupFunctions.invert
14
+ FilterTypes = Riddle::Client::FilterTypes.invert
15
+
6
16
  attr_reader :time
7
17
  attr_reader :command
8
18
 
9
- def initialize(time, *command_args)
19
+ def initialize(time, command_args, method_call)
20
+ riddle_command, messages = *command_args
10
21
  @time = time
11
- if command_args.flatten.first == :search
12
- @command = "search: " + decode_message(command_args.first.flatten.last).collect{|k,v| "#{k} => #{v}"}.join(", ")
22
+ if riddle_command == :search
23
+ @command = "search: " + decode_message(messages.first).inspect
13
24
  else
14
- @command = command_args.flatten.first.to_s + ": No more info is available for this Sphinx request type"
25
+ @command = command_args.inspect + ": No more info is available for this Sphinx request type"
15
26
  end
27
+ @backtrace = method_call.backtrace
16
28
  end
17
29
 
18
30
  def display_time
@@ -23,43 +35,136 @@ module Rack::Insight
23
35
  @m = m.clone
24
36
  params = ActiveSupport::OrderedHash.new
25
37
 
38
+ # Mode, Limits
26
39
  params[:offset] = consume_int
27
40
  params[:limit] = consume_int
28
- params[:match_mode] = consume_int
29
- params[:rank_mode] = consume_int
30
- params[:sort_mode] = consume_int
31
- params[:sort_by] = consume_string
41
+ params[:match_mode] = MatchModes[consume_int]
42
+
43
+ # Ranking
44
+ params[:rank_mode] = RankModes[consume_int]
45
+ if params[:rank_mode] == :expr
46
+ params[:rank_expr] = consume_string
47
+ end
48
+
49
+ # Sort Mode
50
+ params[:sorting] = {
51
+ mode: SortModes[consume_int],
52
+ by: consume_string,
53
+ }
54
+
55
+ # Query
32
56
  params[:query] = consume_string
33
- wl = consume_int
34
- weights = []
35
- wl.times do weights << consume_int end
36
- params[:weights] = weights
37
57
 
58
+ # Weights
59
+ params[:weights] = (1..consume_int).map { consume_int }
60
+
61
+ # Index
38
62
  params[:index] = consume_string
39
63
 
40
- consume_string
64
+ # ID Range
65
+ consume_int
66
+ params[:id_range] = consume_64int..consume_64int
67
+
68
+ # Filters
69
+ params[:filters] = (1..consume_int).map do
70
+ attribute = consume_string
71
+ type = FilterTypes[consume_int]
72
+ values =
73
+ case type
74
+ when :values
75
+ (1..consume_int).map { consume_64int }
76
+ when :range
77
+ consume_64int..consume_64int
78
+ when :float_range
79
+ consume_float..consume_float
80
+ end
81
+ exclude = consume_int
82
+ {attribute: attribute, values: values, exclude: exclude}
83
+ end
84
+
85
+ # Grouping
86
+ params[:group] = {
87
+ function: GroupFunctions[consume_int],
88
+ by: consume_string,
89
+ max_matches: consume_int,
90
+ clause: consume_string,
91
+ retry: {cutoff: consume_int, count: consume_int, delay: consume_int},
92
+ distinct: consume_string,
93
+ }
94
+
95
+ # Anchor Point
96
+ if consume_int == 0
97
+ params[:anchor] = nil
98
+ else
99
+ params[:anchor] = {
100
+ attributes: [consume_string, consume_string],
101
+ values: [consume_int, consume_int],
102
+ }
103
+ end
104
+
105
+ # Per Index Weights
106
+ per_index_weights = params[:per_index_weights] = {}
107
+ (1..consume_int).each do |key, value|
108
+ key = consume_string
109
+ value = consume_int
110
+ per_index_weights[key] = value
111
+ end
112
+
113
+ # Max Query Time
114
+ params[:max_query_time] = consume_int
115
+
116
+ # Per Field Weights
117
+ per_field_weights = params[:per_field_weights] = {}
118
+ (1..consume_int).each do |key, value|
119
+ key = consume_string
120
+ value = consume_int
121
+ per_field_weights[key] = value
122
+ end
123
+
124
+ params[:comments] = consume_string
125
+
126
+ return params if Riddle::Client::Versions[:search] < 0x116
127
+
128
+ # Overrides
129
+ overrides = params[:overrides] = {}
130
+ (1..consume_int).each do
131
+ key = consume_string
132
+ type = AttributeTypes[consume_int]
133
+ method =
134
+ case type
135
+ when :float
136
+ :consume_float
137
+ when :bigint
138
+ :consume_64int
139
+ else
140
+ :consume_int
141
+ end
142
+ values = (1..consume_int).map { send(method) }
143
+ overrides[key] = values
144
+ end
145
+
146
+ params[:select] = consume_string
147
+
148
+ @m.empty? or
149
+ params[:unknown] = @m
41
150
 
42
- params[:id_range] = [consume_64int, consume_64int]
43
151
  params
44
152
  end
45
153
 
46
154
  def consume_int
47
- i = @m.unpack("N").first
48
- @m = @m.slice(4, @m.length - 4)
49
- i
155
+ @m.slice!(0, 4).unpack("N").first
50
156
  end
51
157
 
52
158
  def consume_64int
53
- i = @m.unpack("NN").first
54
- @m = @m.slice(8, @m.length - 8)
55
- i
159
+ @m.slice!(0, 8).unpack("NN").first
160
+ end
161
+
162
+ def consume_float
163
+ @m.slice!(0, 4).unpack('N').pack('L*').unpack('f').first
56
164
  end
57
165
 
58
166
  def consume_string
59
- len = consume_int
60
- s = @m.slice(0, len)
61
- @m = @m.slice(len, @m.length - len)
62
- s
167
+ @m.slice!(0, consume_int)
63
168
  end
64
169
  end
65
170
 
@@ -72,9 +177,8 @@ module Rack::Insight
72
177
  @time = 0.0
73
178
  end
74
179
 
75
- def record_call(time, *command_args)
76
-
77
- @queries << Query.new(time, command_args)
180
+ def record_call(time, command_args, method_call)
181
+ @queries << Query.new(time, command_args, method_call)
78
182
  @calls += 1
79
183
  @time += time
80
184
  end
@@ -1266,150 +1266,150 @@ jQuery.each({
1266
1266
  function num(elem, prop) {
1267
1267
  return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1268
1268
  }
1269
- var expando = "jQuery" + now(), uuid = 0, windowData = {};
1270
-
1271
- jQuery.extend({
1272
- cache: {},
1273
-
1274
- data: function( elem, name, data ) {
1275
- elem = elem == window ?
1276
- windowData :
1277
- elem;
1278
-
1279
- var id = elem[ expando ];
1280
-
1281
- // Compute a unique ID for the element
1282
- if ( !id )
1283
- id = elem[ expando ] = ++uuid;
1284
-
1285
- // Only generate the data cache if we're
1286
- // trying to access or manipulate it
1287
- if ( name && !jQuery.cache[ id ] )
1288
- jQuery.cache[ id ] = {};
1289
-
1290
- // Prevent overriding the named cache with undefined values
1291
- if ( data !== undefined )
1292
- jQuery.cache[ id ][ name ] = data;
1293
-
1294
- // Return the named cache data, or the ID for the element
1295
- return name ?
1296
- jQuery.cache[ id ][ name ] :
1297
- id;
1298
- },
1299
-
1300
- removeData: function( elem, name ) {
1301
- elem = elem == window ?
1302
- windowData :
1303
- elem;
1304
-
1305
- var id = elem[ expando ];
1306
-
1307
- // If we want to remove a specific section of the element's data
1308
- if ( name ) {
1309
- if ( jQuery.cache[ id ] ) {
1310
- // Remove the section of cache data
1311
- delete jQuery.cache[ id ][ name ];
1312
-
1313
- // If we've removed all the data, remove the element's cache
1314
- name = "";
1315
-
1316
- for ( name in jQuery.cache[ id ] )
1317
- break;
1318
-
1319
- if ( !name )
1320
- jQuery.removeData( elem );
1321
- }
1322
-
1323
- // Otherwise, we want to remove all of the element's data
1324
- } else {
1325
- // Clean up the element expando
1326
- try {
1327
- delete elem[ expando ];
1328
- } catch(e){
1329
- // IE has trouble directly removing the expando
1330
- // but it's ok with using removeAttribute
1331
- if ( elem.removeAttribute )
1332
- elem.removeAttribute( expando );
1333
- }
1334
-
1335
- // Completely remove the data cache
1336
- delete jQuery.cache[ id ];
1337
- }
1338
- },
1339
- queue: function( elem, type, data ) {
1340
- if ( elem ){
1341
-
1342
- type = (type || "fx") + "queue";
1343
-
1344
- var q = jQuery.data( elem, type );
1345
-
1346
- if ( !q || jQuery.isArray(data) )
1347
- q = jQuery.data( elem, type, jQuery.makeArray(data) );
1348
- else if( data )
1349
- q.push( data );
1350
-
1351
- }
1352
- return q;
1353
- },
1354
-
1355
- dequeue: function( elem, type ){
1356
- var queue = jQuery.queue( elem, type ),
1357
- fn = queue.shift();
1358
-
1359
- if( !type || type === "fx" )
1360
- fn = queue[0];
1361
-
1362
- if( fn !== undefined )
1363
- fn.call(elem);
1364
- }
1365
- });
1366
-
1367
- jQuery.fn.extend({
1368
- data: function( key, value ){
1369
- var parts = key.split(".");
1370
- parts[1] = parts[1] ? "." + parts[1] : "";
1371
-
1372
- if ( value === undefined ) {
1373
- var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1374
-
1375
- if ( data === undefined && this.length )
1376
- data = jQuery.data( this[0], key );
1377
-
1378
- return data === undefined && parts[1] ?
1379
- this.data( parts[0] ) :
1380
- data;
1381
- } else
1382
- return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
1383
- jQuery.data( this, key, value );
1384
- });
1385
- },
1386
-
1387
- removeData: function( key ){
1388
- return this.each(function(){
1389
- jQuery.removeData( this, key );
1390
- });
1391
- },
1392
- queue: function(type, data){
1393
- if ( typeof type !== "string" ) {
1394
- data = type;
1395
- type = "fx";
1396
- }
1397
-
1398
- if ( data === undefined )
1399
- return jQuery.queue( this[0], type );
1400
-
1401
- return this.each(function(){
1402
- var queue = jQuery.queue( this, type, data );
1403
-
1404
- if( type == "fx" && queue.length == 1 )
1405
- queue[0].call(this);
1406
- });
1407
- },
1408
- dequeue: function(type){
1409
- return this.each(function(){
1410
- jQuery.dequeue( this, type );
1411
- });
1412
- }
1269
+ var expando = "jQuery" + now(), uuid = 0, windowData = {};
1270
+
1271
+ jQuery.extend({
1272
+ cache: {},
1273
+
1274
+ data: function( elem, name, data ) {
1275
+ elem = elem == window ?
1276
+ windowData :
1277
+ elem;
1278
+
1279
+ var id = elem[ expando ];
1280
+
1281
+ // Compute a unique ID for the element
1282
+ if ( !id )
1283
+ id = elem[ expando ] = ++uuid;
1284
+
1285
+ // Only generate the data cache if we're
1286
+ // trying to access or manipulate it
1287
+ if ( name && !jQuery.cache[ id ] )
1288
+ jQuery.cache[ id ] = {};
1289
+
1290
+ // Prevent overriding the named cache with undefined values
1291
+ if ( data !== undefined )
1292
+ jQuery.cache[ id ][ name ] = data;
1293
+
1294
+ // Return the named cache data, or the ID for the element
1295
+ return name ?
1296
+ jQuery.cache[ id ][ name ] :
1297
+ id;
1298
+ },
1299
+
1300
+ removeData: function( elem, name ) {
1301
+ elem = elem == window ?
1302
+ windowData :
1303
+ elem;
1304
+
1305
+ var id = elem[ expando ];
1306
+
1307
+ // If we want to remove a specific section of the element's data
1308
+ if ( name ) {
1309
+ if ( jQuery.cache[ id ] ) {
1310
+ // Remove the section of cache data
1311
+ delete jQuery.cache[ id ][ name ];
1312
+
1313
+ // If we've removed all the data, remove the element's cache
1314
+ name = "";
1315
+
1316
+ for ( name in jQuery.cache[ id ] )
1317
+ break;
1318
+
1319
+ if ( !name )
1320
+ jQuery.removeData( elem );
1321
+ }
1322
+
1323
+ // Otherwise, we want to remove all of the element's data
1324
+ } else {
1325
+ // Clean up the element expando
1326
+ try {
1327
+ delete elem[ expando ];
1328
+ } catch(e){
1329
+ // IE has trouble directly removing the expando
1330
+ // but it's ok with using removeAttribute
1331
+ if ( elem.removeAttribute )
1332
+ elem.removeAttribute( expando );
1333
+ }
1334
+
1335
+ // Completely remove the data cache
1336
+ delete jQuery.cache[ id ];
1337
+ }
1338
+ },
1339
+ queue: function( elem, type, data ) {
1340
+ if ( elem ){
1341
+
1342
+ type = (type || "fx") + "queue";
1343
+
1344
+ var q = jQuery.data( elem, type );
1345
+
1346
+ if ( !q || jQuery.isArray(data) )
1347
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
1348
+ else if( data )
1349
+ q.push( data );
1350
+
1351
+ }
1352
+ return q;
1353
+ },
1354
+
1355
+ dequeue: function( elem, type ){
1356
+ var queue = jQuery.queue( elem, type ),
1357
+ fn = queue.shift();
1358
+
1359
+ if( !type || type === "fx" )
1360
+ fn = queue[0];
1361
+
1362
+ if( fn !== undefined )
1363
+ fn.call(elem);
1364
+ }
1365
+ });
1366
+
1367
+ jQuery.fn.extend({
1368
+ data: function( key, value ){
1369
+ var parts = key.split(".");
1370
+ parts[1] = parts[1] ? "." + parts[1] : "";
1371
+
1372
+ if ( value === undefined ) {
1373
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1374
+
1375
+ if ( data === undefined && this.length )
1376
+ data = jQuery.data( this[0], key );
1377
+
1378
+ return data === undefined && parts[1] ?
1379
+ this.data( parts[0] ) :
1380
+ data;
1381
+ } else
1382
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
1383
+ jQuery.data( this, key, value );
1384
+ });
1385
+ },
1386
+
1387
+ removeData: function( key ){
1388
+ return this.each(function(){
1389
+ jQuery.removeData( this, key );
1390
+ });
1391
+ },
1392
+ queue: function(type, data){
1393
+ if ( typeof type !== "string" ) {
1394
+ data = type;
1395
+ type = "fx";
1396
+ }
1397
+
1398
+ if ( data === undefined )
1399
+ return jQuery.queue( this[0], type );
1400
+
1401
+ return this.each(function(){
1402
+ var queue = jQuery.queue( this, type, data );
1403
+
1404
+ if( type == "fx" && queue.length == 1 )
1405
+ queue[0].call(this);
1406
+ });
1407
+ },
1408
+ dequeue: function(type){
1409
+ return this.each(function(){
1410
+ jQuery.dequeue( this, type );
1411
+ });
1412
+ }
1413
1413
  });/*!
1414
1414
  * Sizzle CSS Selector Engine - v0.9.3
1415
1415
  * Copyright 2009, The Dojo Foundation
@@ -1,7 +1,7 @@
1
1
  module Rack
2
2
  module Insight
3
3
 
4
- VERSION = '0.5.23'
4
+ VERSION = '0.5.24'
5
5
 
6
6
  end
7
7
  end
@@ -16,6 +16,7 @@
16
16
  <tr>
17
17
  <th>Time&nbsp;(ms)</th>
18
18
  <th>Command</th>
19
+ <th class="backtrace"></th>
19
20
  </tr>
20
21
  </thead>
21
22
  <tbody>
@@ -24,7 +25,20 @@
24
25
  <tr class="<%= i % 2 == 0 ? "even" : "odd" %>">
25
26
  <td><%= query.display_time %></td>
26
27
  <td><%= query.command %></td>
28
+ <td><%= "<a href='#' class='reveal_backtrace'>Show Backtrace</a>" if query.has_backtrace? %></td>
27
29
  </tr>
30
+ <% if query.has_backtrace? %>
31
+ <tr style="display:none">
32
+ <td></td>
33
+ <td colspan="2">
34
+ <ul>
35
+ <% query.filtered_backtrace.each do |line| %>
36
+ <li><%=h line %></li>
37
+ <% end %>
38
+ </ul>
39
+ </td>
40
+ </tr>
41
+ <% end %>
28
42
  <% i += 1 %>
29
43
  <% end %>
30
44
  </tbody>
@@ -11,7 +11,7 @@
11
11
  @import url(/__insight__/insight.css);
12
12
  </style>
13
13
  <script>
14
- $(function($) {
14
+ jQuery(function($) {
15
15
  $.insight.request_id = <%= request_id %>
16
16
  if(document.readCookie('rack-insight_position')) {
17
17
  $('#rack-insight').removeClass('rack-insight_top rack-insight_bottom')
data/rack-insight.gemspec CHANGED
@@ -34,7 +34,5 @@ Gem::Specification.new do |s|
34
34
  s.add_development_dependency "rspec", ">= 2.11.0"
35
35
  s.add_development_dependency "sinatra"
36
36
  s.add_development_dependency "webrat"
37
- s.add_development_dependency "ruby-debug19"
38
-
39
-
37
+ s.add_development_dependency "debugger"
40
38
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-insight
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.23
4
+ version: 0.5.24
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2012-09-14 00:00:00.000000000 Z
15
+ date: 2013-01-02 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rack
@@ -175,7 +175,7 @@ dependencies:
175
175
  - !ruby/object:Gem::Version
176
176
  version: '0'
177
177
  - !ruby/object:Gem::Dependency
178
- name: ruby-debug19
178
+ name: debugger
179
179
  requirement: !ruby/object:Gem::Requirement
180
180
  none: false
181
181
  requirements:
@@ -251,7 +251,6 @@ files:
251
251
  - lib/rack/insight/panels/mongo_panel/stats.rb
252
252
  - lib/rack/insight/panels/rails_info_panel.rb
253
253
  - lib/rack/insight/panels/redis_panel.rb
254
- - lib/rack/insight/panels/redis_panel/redis_extension.rb
255
254
  - lib/rack/insight/panels/redis_panel/stats.rb
256
255
  - lib/rack/insight/panels/request_variables_panel.rb
257
256
  - lib/rack/insight/panels/speedtracer_panel.rb
@@ -387,4 +386,3 @@ test_files:
387
386
  - spec/rcov.opts
388
387
  - spec/spec.opts
389
388
  - spec/spec_helper.rb
390
- has_rdoc:
@@ -1,25 +0,0 @@
1
- if defined?(Redis)
2
- Redis.class_eval do
3
- if Redis.methods.include?('call_command') # older versions of redis-rb
4
- def call_command_with_insight(*argv)
5
- Rack::Insight::RedisPanel.record(argv, Kernel.caller) do
6
- call_command_without_insight(*argv)
7
- end
8
- end
9
-
10
- alias_method_chain :call_command, :insight
11
-
12
- elsif defined?(Redis::Client) # newer versions of redis-rb
13
-
14
- Redis::Client.class_eval do
15
- def call_with_insight(command, &block)
16
- Rack::Insight::RedisPanel.record(command, Kernel.caller) do
17
- call_without_insight(command, &block)
18
- end
19
- end
20
- end
21
-
22
- Redis::Client.alias_method_chain :call, :insight
23
- end
24
- end
25
- end