Ruby on Rails 3 Debugging

Debugging Ruby on Rails

To display a variable in a view

View
<%= debug @account %>
HTML Output
- !ruby/object:Account
  attributes:
    premium: "1"
    updated_at: 2009-10-02 18:56:57
    ranking: "3.67"
    id: "2"
    description: Study in SF High School
    fee:
    birthday: "2004-01-02"
    login_time: "18:55:00"
    user_name: John
    income: "500"
    created_at: 2009-10-02 18:56:57
  attributes_cache: {}

Output debug message in a more readable Yaml format

<%= simple_format @account.to_yaml %>

Display an object using "inspect"

<%= obj1.inspect %>

Ruby on Rails Logging

Logging in a controller

Controller
logger.info "User name: #{@accounts[0].user_name.inspect}"

Logging method
:debug, :info, :warn, :error, :fatal

Logging in a view

<%= logger.info 'some debug message' %>

Log messages are logged in log/environment.log

Logging level can be changed in the environment configuration file

Environment configuration file under config/environments
config.log_level = Logger::WARN

Or in real time

Rails.logger.level = 0
  • Log level: :debug, :info, :warn, :error, and :fatal, corresponding to the log level 0 to 4 respectively
  • The default Rails log level is info for production and debug in development/test

Re-configure Rails to use other logger

Re-define the logger in environment.rb

Rails.logger = Logger.new(STDOUT)

Rails.logger = Log4r::Logger.new("Rails Application Log")

Or re-define the logger in the initializers

config.logger = Logger.new(STDOUT)

config.logger = Log4r::Logger.new("Rails Application Log")

Rails Configuration

Rail configuration files

File Location Description
config/environment.rb Apply to all environments
config/environments/development.rb For development environment
config/environments/production.rb For production environment
config/environments/test.rb For test environment

Debug with Ruby-debug

  def check
    debugger
    ...
  end
end
  • Server must be started with rails server --debugger

Ruby-debug command

Debug command Description
help Display help information
l list: Show the code
where or backtrace Print application backtrace
frame 3 Move to backtrace 3
up 3 Move up 3 backtrace
down 3 Move down 3 backtrace
thread Shows the current thread
thread list List all threads and their statuses
thread stop 3 Stop thread 3
thread resume 3 Resumes thread 3
thread switch 3 Switches the current thread context to 3
instance_variables Print instance variables
instance_variables.include? "@account" Is account initialized
next Execute next line (Step over)
step 3 or step -3 Move forward or backward
v const T1 Show constant
v g Show global variables
v i o1 show instance variables o1
v l Show locals
v i Account.new Execute a method
pp Ruby_Expression Pretty print a value of a Ruby expression
display @account Watch a variable
undisplay 3 Un-display the watched variable 3
break 10 Break at line 10
break account.rb:10 [if expression] Set breakpoint in a file with an optional if conditional
break Account#view [if expression] Set breakpoint in a instance method
break Account.view [if expression] Set breakpoint in a class method
info breakpoints List breakpoints
delete 3 Delete breakpoint
c Resume execution after a break point
fin finish until the current selected frame
fin 3 finish after frame 3
tm 3 textmate frame 3
edit account.rb:10 edit file at line 10
q quit

Ruby-debug setting

Debugger setting Description
set reload Reload changed source code automatically
set autolist Execute list after breakpoint
set listsize 20 Set number of source lines to list
set forcestep Make sure the next and step commands move to a new line
  • Put it inside a .rdebugrc file
  • Or set it in the debugger

Memory Leak Detection with BleakHouse

Install BleakHouse

 sudo gem install bleak_house

Change config/environment.rb

 require 'bleak_house' if ENV['BLEAK_HOUSE']

Start server with BleakHouse

 RAILS_ENV=production BLEAK_HOUSE=1 ruby-bleak-house rails server

To detect leak

  • Run the suspected request many times
  • Ctrl-c
  • A dump file is created in /tmp
  • Use list command to analysis the log

To detect C level leaking, use Valgrind

Debug RJS

Enable RJS debugging (Pop up an alert when a JavaScript exception is raised)

Rail Configuration
config.action_view.debug_rjs = true

Or doing it programmatic

ActionView::Base.debug_rjs = true