Debugging Rails Applications
You must hear 'pry'?
From: /Users/twer/Projects/eportfolio/eportfolio/app/controllers/api/timeline_controller.rb @ line 6 Api::TimelineController#index:
4: def index
5: found?(@user = User.find(params[:user_id])) do
=> 6: binding.pry
7: timeline_activities = @user.timeline_activities.order_by(:created_at.desc)
8: timeline_activities = timeline_activities.where(type: params[:category]) if params[:category].present?
......
[1] pry(#<Api::TimelineController>)>
Sounds like inspecting variables?
Rails View Helpers
- debug
- to_yaml
- inspect
debug
<%= debug @post %>
<p>
<b>Title:</b>
<%= @post.title %>
</p>
<pre>--- !ruby/object:Post
attributes:
updated_at: 2008-09-05 22:55:47
body: It's a very helpful guide for debugging your Rails app.
title: Rails debugging guide
published: t
id: "1"
created_at: 2008-09-05 22:55:47
attributes_cache: {}</pre>
Title: Rails debugging guide
to_yaml
<%= simple_format @post.to_yaml %>
<p>
<b>Title:</b>
<%= @post.title %>
</p>
--- !ruby/object:Post
attributes:
updated_at: 2008-09-05 22:55:47
body: It's a very helpful guide for debugging your Rails app.
title: Rails debugging guide
published: t
id: "1"
created_at: 2008-09-05 22:55:47
attributes_cache: {}
Title: Rails debugging guide
inspect
<%= [1, 2, 3, 4, 5].inspect %>
<p>
<b>Title:</b>
<%= @post.title %>
</p>
[1, 2, 3, 4, 5]
Title: Rails debugging guide
The Logger
What?
ActiveSupport::Logger/Log4r
How?
All logs are under Rails.root/log/, and named environment_name.log by default.
config/environment.rb
Rails.logger = Logger.new(STDOUT)
Rails.logger = Log4r::Logger.new("Application Log")
initializers
config.logger = Logger.new(STDOUT)
config.logger = Log4r::Logger.new("Application Log")
Log levels
Data in log files will not have level higher than configured log levels.
Use Rails.logger.level to view the current log level.
config.log_level = :warn # In any environment initializer, or
Rails.logger.level = 0 # at any time
:debug, :info, :warn, :error, :fatal, and :unknown
0 1 2 3 4 5
Logging
logger.(debug|info|warn|error|fatal)
logger.debug "Person hash: #{@person.attributes.inspect}"
logger.info "Processing the request..."
logger.fatal "Terminating application, raised unrecoverable error!!!"
:debug, :info, :warn, :error, :fatal, and :unknown
within a controller, model or mailer
Tagged Logging
logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
logger.tagged("BCX") { logger.info "Stuff" } # Logs "[BCX] Stuff"
logger.tagged("BCX", "Jason") { logger.info "Stuff" } # Logs "[BCX] [Jason] Stuff"
logger.tagged("BCX") { logger.tagged("Jason") { logger.info "Stuff" } } # Logs "[BCX] [Jason] Stuff"
Impact of Logs on Performance
Bad performance if always using debug as logger level. (Disk I/O)
logger.debug "Person attributes hash: #{@person.attributes.inspect}"
logger.debug {"Person attributes hash: #{@person.attributes.inspect}"}
Still love pry?
try "debugger"
gem install debugger
and
use debugger on any line
restart server
rails server --debugger
dynamic require
under development env, require 'debugger'
Usage
(rdb:1) l
[4, 13] in /Users/twer/Projects/eportfolio/eportfolio/app/controllers/api/timeline_controller.rb
8 debugger
=> 9 timeline_activities = @user.timeline_activities.order_by(:created_at.desc)
10 timeline_activities = timeline_activities.where(type: params[:category])
(rdb:1) help
Available commands:
backtrace delete enable help list ps save start undisplay
break disable eval info method putl set step up
catch display exit irb next quit show thread var
condition down finish jump p reload skip tmate where
continue edit frame kill pp restart source trace
Usage
list/l, l-, l=
backtrace/where, frame n, up n, down n
thread list, stop n, resume n, switch n
instance_variables
irb
v const, global, instance, local
display, undisplay
step/s, s+ n, s- n, next
break/b, b line, b file:line, b class(.|\#)method [if expression]
info breakpoints/break/b, delete n
enable, disable breakpoints
catch/cat exception-name
continue/c n, finish/fin [frame number]
Usage
edit file:line, tmate n
quit/q/exit
set reload, autolist, listsize n, forcestep, or save in ~/.rdebugrc
But it's dead after ruby 2.x
1.9: https://github.com/mark-moseley/ruby-debug
1.9.2/1.9.3: https://github.com/cldwalker/debugger
Use 'byebug' instead
ruby 2.x: https://github.com/deivid-rodriguez/byebug
Seems more powerful than pry?
https://github.com/pry/pry
Pry is not real debugger (REPL)
https://github.com/nixme/pry-debugger
https://github.com/deivid-rodriguez/pry-byebug
Enough?
Ruby is not perfect
Ruby Profiler
http://ruby-doc.org/stdlib-2.1.3/libdoc/profiler/rdoc/Profiler__.html
https://github.com/ruby-prof/ruby-prof
Usage
1. ruby-prof executable
2. ruby-prof API:
result = RubyProf.profile do
...
end
printer = RubyProf::FlatPrinter.new(result)
printer.print(STDOUT)
3. mode:
RubyProf.measure_mode = PROCESS_TIME, WALL_TIME, CPU_TIME, ALLOCATIONS, MEMORY, GC_RUNS, GC_TIME
or use
export RUBY_PROF_MEASURE_MODE
Still want easier?
To be continued...
Debugging Rails Applications
By hanyi8000
Debugging Rails Applications
- 2,099