rack-insight 0.5.23 → 0.5.24
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.
- 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 [](https://gemnasium.com/pboling/rack-insight) [](https://codeclimate.com/github/pboling/rack-insight) [](https://travis-ci.org/pboling/rack-insight) [](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: [](https://travis-ci.org/pboling/rack-insight) - Please help if you have time!
|
61
|
+
|
62
|
+
CodeClimate: [](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
|