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 +13 -5
- data/Gemfile.lock +9 -15
- data/README.md +17 -11
- data/lib/rack/insight/app.rb +1 -1
- data/lib/rack/insight/config.rb +4 -3
- data/lib/rack/insight/instrumentation/instrument.rb +2 -2
- data/lib/rack/insight/panels/redis_panel.rb +31 -24
- data/lib/rack/insight/panels/redis_panel/stats.rb +4 -4
- data/lib/rack/insight/panels/sphinx_panel.rb +12 -24
- data/lib/rack/insight/panels/sphinx_panel/stats.rb +131 -27
- data/lib/rack/insight/public/__insight__/jquery-1.3.2.js +144 -144
- data/lib/rack/insight/version.rb +1 -1
- data/lib/rack/insight/views/panels/sphinx.html.erb +14 -0
- data/lib/rack/insight/views/toolbar.html.erb +1 -1
- data/rack-insight.gemspec +1 -3
- metadata +3 -5
- data/lib/rack/insight/panels/redis_panel/redis_extension.rb +0 -25
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.
|
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
|
-
*
|
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
|
-
|
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
|
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
|
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
|
data/lib/rack/insight/app.rb
CHANGED
data/lib/rack/insight/config.rb
CHANGED
@@ -8,7 +8,7 @@ module Rack::Insight
|
|
8
8
|
@log_file = STDOUT
|
9
9
|
@log_level = ::Logger::DEBUG
|
10
10
|
@logger = nil
|
11
|
-
@verbosity =
|
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
|
51
|
-
:filtered_backtrace => @filtered_backtrace, # Full
|
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(:
|
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(:
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
21
|
-
|
25
|
+
def request_start(env, start)
|
26
|
+
@stats = Stats.new
|
22
27
|
end
|
23
28
|
|
24
|
-
def
|
25
|
-
|
29
|
+
def request_finish(env, status, headers, body, timing)
|
30
|
+
store(env, @stats)
|
31
|
+
@stats = nil
|
26
32
|
end
|
27
33
|
|
28
|
-
def
|
29
|
-
|
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
|
33
|
-
|
34
|
-
|
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,
|
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,
|
32
|
-
@queries << Query.new(time, command_args,
|
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
|
-
|
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
|
20
|
-
|
9
|
+
def request_finish(env, status, headers, body, timing)
|
10
|
+
store(env, @stats)
|
11
|
+
@stats = nil
|
21
12
|
end
|
22
13
|
|
23
|
-
def
|
24
|
-
|
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
|
28
|
-
|
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
|
32
|
-
|
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,
|
19
|
+
def initialize(time, command_args, method_call)
|
20
|
+
riddle_command, messages = *command_args
|
10
21
|
@time = time
|
11
|
-
if
|
12
|
-
@command = "search: " + decode_message(
|
22
|
+
if riddle_command == :search
|
23
|
+
@command = "search: " + decode_message(messages.first).inspect
|
13
24
|
else
|
14
|
-
@command = command_args.
|
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
|
-
|
30
|
-
|
31
|
-
params[:
|
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
|
-
|
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
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
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
|
-
|
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,
|
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
|
data/lib/rack/insight/version.rb
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
<tr>
|
17
17
|
<th>Time (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
|
-
|
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 "
|
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.
|
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:
|
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:
|
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
|