Class: Rack::Insight::Panel
Overview
Panels are also Rack middleware
Direct Known Subclasses
ActiveRecordPanel, ActiveResourcePanel, CachePanel, LogPanel, MemoryPanel, MongoPanel, RailsInfoPanel, RedisPanel, RequestVariablesPanel, SQLPanel, SpeedTracer::Panel, SphinxPanel, TemplatesPanel, TimerPanel
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
included
included
Methods included from Logging
logger, verbose, verbosity
#before_detect, #probe, #request_finish, #request_start
#count, #key_sql_template, #retrieve, #store, #table_length, #table_setup
Methods included from Render
#compile, #compile!, #compiled_source, #method_name, #method_name_without_locals, #render_template, #signed_params
Constructor Details
#initialize(app) ⇒ Panel
Returns a new instance of Panel.
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
# File 'lib/rack/insight/panel.rb', line 105
def initialize(app)
if panel_app
@app = Rack::Cascade.new([panel_app, app])
else
@app = app
end
panel_name = self.underscored_name.to_sym
if self.has_custom_probes?(panel_name)
custom_probes = Rack::Insight::Config.config[:panel_configs][panel_name][:probes]
if custom_probes.kind_of?(Hash)
probe(self) do
custom_probes.each do |klass, method_probes|
instrument klass do
self.send("#{method_probes[0]}_probe", *(method_probes[1..-1]))
end
end
end
elsif custom_probes.kind_of?(Array) && custom_probes.length >=3
probe(self) do
custom_probes.each do |probe|
klass = probe.shift
probe_type = probe.shift
instrument klass do
self.send("#{probe_type}_probe", *probe)
end
end
end
else
raise "Expected Rack::Insight::Config.config[:panel_configs][#{panel_name}][:probes] to be a kind of Hash or an Array with length >= 3, but is a #{Rack::Insight::Config.config[:panel_configs][self.as_sym][:probes].class}"
end
end
if !has_table?
table_setup(self.name)
end
end
|
Instance Attribute Details
#request ⇒ Object
Returns the value of attribute request
17
18
19
|
# File 'lib/rack/insight/panel.rb', line 17
def request
@request
end
|
Class Method Details
.current_panel_file(sub) ⇒ Object
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/rack/insight/panel.rb', line 69
def current_panel_file(sub)
file_name = nil
matched_line = nil
caller.each do |line|
next if line =~ /rack-insight.*\/lib\/rack\/insight\/.*panel.rb:/
Rack::Insight::Config.config[:panel_load_paths].each do |load_path|
regex = %r{^[^:]*#{load_path}/([^:]*)\.rb:}
md = regex.match line
file_name = md[1] unless md.nil?
matched_line = line unless file_name.nil?
break unless file_name.nil?
end
break unless file_name.nil?
end
set_sub_class_template_root(sub, File.dirname(matched_line.split(':')[0])) if matched_line.respond_to?(:split)
return Thread::current['rack-panel_file'] || file_name
end
|
.excluded(klass = nil) ⇒ Object
99
100
101
|
# File 'lib/rack/insight/panel.rb', line 99
def excluded(klass = nil)
Panel::panel_exclusion << klass || self
end
|
.file_index ⇒ Object
33
34
35
36
37
|
# File 'lib/rack/insight/panel.rb', line 33
def file_index
return @file_index ||= Hash.new do |h,k|
h[k] = []
end
end
|
.from_file(rel_path) ⇒ Object
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
# File 'lib/rack/insight/panel.rb', line 43
def from_file(rel_path)
old_rel, Thread::current['rack-panel_file'] = Thread::current['rack-panel_file'], rel_path
num_load_paths_to_check = Rack::Insight::Config.config[:panel_load_paths].length
Rack::Insight::Config.config[:panel_load_paths].each_with_index do |load_path, index|
begin
require File::join(load_path, rel_path)
break rescue LoadError => e
if !verbose(:high) && (index + 1) == num_load_paths_to_check warn "Rack::Insight #{e.class} while attempting to load '#{rel_path}' from :panel_load_paths #{Rack::Insight::Config.config[:panel_load_paths].inspect}."
elsif verbose(:high)
warn "Rack::Insight #{e.class} #{e.message} while attempting to load '#{rel_path}' from :panel_load_paths #{Rack::Insight::Config.config[:panel_load_paths].inspect} (just checked: #{load_path})."
end
end
end
return (file_index[rel_path] - panel_exclusion)
ensure
Thread::current['rack-panel_file'] = old_rel
end
|
.has_table ⇒ Object
has table defaults to true for panels.
20
21
22
|
# File 'lib/rack/insight/panel.rb', line 20
def self.has_table
self.has_table.nil? ? true : self.class.table.nil?
end
|
.inherited(sub) ⇒ Object
90
91
92
93
94
95
96
97
|
# File 'lib/rack/insight/panel.rb', line 90
def inherited(sub)
if filename = current_panel_file(sub)
logger.debug("panel inherited by #{sub.inspect} with template_root: #{sub.template_root}") if verbose(:high)
Panel::file_index[filename] << sub
else
warn "Rack::Insight::Panel inherited by #{sub.name} outside rack-insight's :panel_load_paths. Discarded. Configured panel load paths are: #{Rack::Insight::Config.config[:panel_load_paths].inspect}"
end
end
|
.panel_exclusion ⇒ Object
39
40
41
|
# File 'lib/rack/insight/panel.rb', line 39
def panel_exclusion
return @panel_exclusion ||= []
end
|
.panel_mappings ⇒ Object
181
182
183
|
# File 'lib/rack/insight/panel.rb', line 181
def self.panel_mappings
{}
end
|
.set_sub_class_template_root(sub_class, path) ⇒ Object
65
66
67
|
# File 'lib/rack/insight/panel.rb', line 65
def set_sub_class_template_root(sub_class, path)
sub_class.template_root = path
end
|
Instance Method Details
#after(env, status, headers, body) ⇒ Object
313
314
|
# File 'lib/rack/insight/panel.rb', line 313
def after(env, status, , body)
end
|
#after_detect(method_call, timing, args, result) ⇒ Object
Override in subclasses. This is to make magic classes work.
304
305
306
307
308
|
# File 'lib/rack/insight/panel.rb', line 304
def after_detect(method_call, timing, args, result)
if self.is_magic? && self.has_table? && self.is_probing?
store(@env, Rack::Insight::DefaultInvocation.new(method_call.method.to_s, timing, args, result, method_call.backtrace[2..-1]))
end
end
|
#before(env) ⇒ Object
310
311
|
# File 'lib/rack/insight/panel.rb', line 310
def before(env)
end
|
#bool_prop(prop) ⇒ Object
161
162
163
|
# File 'lib/rack/insight/panel.rb', line 161
def bool_prop(prop)
self.send(prop) ? 'Y' : 'N'
end
|
#call(env) ⇒ Object
165
166
167
168
169
170
171
172
173
174
175
|
# File 'lib/rack/insight/panel.rb', line 165
def call(env)
@env = env
logger.debug{ "Before call: #{self.name}" } if verbose(:debug)
before(env)
status, , body = @app.call(env)
@request = Rack::Request.new(env)
logger.debug{ "After call: #{self.name}" } if verbose(:debug)
after(env, status, , body)
env["rack-insight.panels"] << self
return [status, , body]
end
|
#camelized_name(str = self.underscored_name) ⇒ Object
235
236
237
|
# File 'lib/rack/insight/panel.rb', line 235
def camelized_name(str = self.underscored_name)
str.split('_').map {|w| w.capitalize}.join
end
|
#content ⇒ Object
285
286
287
288
289
290
|
# File 'lib/rack/insight/panel.rb', line 285
def content
logger.info("Rack::Insight is using default content for #{self.class}") if verbose(:med)
render_template 'no_content', :name => self.camelized_name
rescue StandardError => exception
handle_error_for('content', exception)
end
|
#content_for_request(number) ⇒ Object
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
|
# File 'lib/rack/insight/panel.rb', line 258
def content_for_request(number)
logger.info("Rack::Insight is using default content_for_request for #{self.class}") if verbose(:med)
if !self.has_table?
logger.info("#{self.class} is being used without a table") if verbose(:med)
content
elsif self.is_probing? invocations = retrieve(number)
if invocations.length > 0
logger.info("Rack::Insight is using #{self.is_magic? ? 'magic' : 'default'} content for #{self.class}, which is probed") render_template 'magic_panel', :magic_insights => invocations, :name => self.camelized_name
else
logger.info("Rack::Insight has no data for #{self.is_magic? ? 'magic' : 'default'} content for #{self.class}, which is probed")
render_template 'no_data', :name => self.camelized_name
end
else
content
end
rescue StandardError => exception
handle_error_for('content_for_request', exception)
end
|
#handle_error_for(method_name, exception) ⇒ Object
292
293
294
295
296
297
298
299
300
|
# File 'lib/rack/insight/panel.rb', line 292
def handle_error_for(method_name, exception)
nom = self.name rescue "xxx"
msg = ["#{self.class}##{method_name} failed","#{exception.class}: #{exception.message}"] + exception.backtrace
logger.error(msg.join("\n"))
"Error in #{nom}
<!-- Panel: #{self.inspect}\n
#{msg.join("\n")} -->"
end
|
#has_content? ⇒ Boolean
193
194
195
|
# File 'lib/rack/insight/panel.rb', line 193
def has_content?
true
end
|
#has_custom_probes?(panel_name = self.underscored_name.to_sym) ⇒ Boolean
201
202
203
204
|
# File 'lib/rack/insight/panel.rb', line 201
def has_custom_probes?(panel_name = self.underscored_name.to_sym)
Rack::Insight::Config.config[:panel_configs][panel_name].respond_to?(:[]) &&
!Rack::Insight::Config.config[:panel_configs][panel_name][:probes].nil?
end
|
#has_table? ⇒ Boolean
185
186
187
|
# File 'lib/rack/insight/panel.rb', line 185
def has_table?
!!self.class.has_table
end
|
#heading ⇒ Object
279
280
281
282
283
|
# File 'lib/rack/insight/panel.rb', line 279
def heading
self.camelized_name
rescue StandardError => exception
handle_error_for('heading', exception)
end
|
#heading_for_request(number) ⇒ Object
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
# File 'lib/rack/insight/panel.rb', line 239
def heading_for_request(number)
if !self.has_table?
heading
else
num = count(number)
if num.kind_of?(Numeric)
if num == 0
heading
else
"#{self.camelized_name} (#{num})"
end
else
heading
end
end
rescue StandardError => exception
handle_error_for('heading_for_request', exception)
end
|
#inspect ⇒ Object
157
158
159
|
# File 'lib/rack/insight/panel.rb', line 157
def inspect
"#{self.underscored_name} Magic:#{self.bool_prop(:is_magic?)} Table:#{self.bool_prop(:has_table?)} Probe:#{self.bool_prop(:is_probing?)} Custom:#{self.bool_prop(:has_custom_probes?)}" rescue "XXX inspect failed"
end
|
#is_magic? ⇒ Boolean
189
190
191
|
# File 'lib/rack/insight/panel.rb', line 189
def is_magic?
!!self.class.is_magic
end
|
#is_probing? ⇒ Boolean
197
198
199
|
# File 'lib/rack/insight/panel.rb', line 197
def is_probing?
!!self.class.is_probing
end
|
#name ⇒ Object
The name informs the table name, and the panel_configs hash among other things. Override in subclass panels if you want a custom name
208
209
210
|
# File 'lib/rack/insight/panel.rb', line 208
def name
self.underscored_name
end
|
#panel_app ⇒ Object
177
178
179
|
# File 'lib/rack/insight/panel.rb', line 177
def panel_app
nil
end
|
#render(template) ⇒ Object
316
317
|
# File 'lib/rack/insight/panel.rb', line 316
def render(template)
end
|
#underscored_name(word = self.class.to_s) ⇒ Object
Mostly stolen from Rails' ActiveSupport' underscore method: See activesupport/lib/active_support/inflector/methods.rb, line 77 HTTPClientPanel => http_client LogPanel => log ActiveRecordPanel => active_record
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
# File 'lib/rack/insight/panel.rb', line 217
def underscored_name(word = self.class.to_s)
@underscored_name ||= begin
words = word.dup.split('::')
word = words.last
if word == 'Panel'
word = words[-2] end
word.gsub!(/Panel$/,'')
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
word.tr!("-", "_")
word.downcase!
word
end
end
|