When something is logged, it's printed into the corresponding log if the log
level of the message is equal to or higher than the configured log level. If you
want to know the current log level, you can call the Rails.logger.level
method.

The available log levels are: :debug, :info, :warn, :error, :fatal,
and :unknown, corresponding to the log level numbers from 0 up to 5,
respectively. To change the default log level, use

config.log_level = :warn # In any environment initializer, or
Rails.logger.level = 0 # at any time

This is useful when you want to log under development or staging without flooding your production log with unnecessary information.

Adding extra logging like this makes it easy to search for unexpected or unusual behavior in your logs. If you add extra logging, be sure to make sensible use of log levels to avoid filling your production logs with useless trivia.

After running ActiveRecord::Base.verbose_query_logs = true in the rails console session to enable verbose query logs and running the method again, it becomes obvious what single line of code is generating all these discrete database calls:

Below each database statement you can see arrows pointing to the specific source filename (and line number) of the method that resulted in a database call. This can help you identify and address performance problems caused by N+1 queries: single database queries that generates multiple additional queries.

Verbose query logs are enabled by default in the development environment logs after Rails 5.2.

We recommend against using this setting in production environments. It relies on Ruby's Kernel#caller method which tends to allocate a lot of memory in order to generate stacktraces of method calls.

When running multi-user, multi-account applications, it's often useful
to be able to filter the logs using some custom rules. TaggedLogging
in Active Support helps you do exactly that by stamping log lines with subdomains, request ids, and anything else to aid debugging such applications.

Logging will always have a small impact on the performance of your Rails app,
particularly when logging to disk. Additionally, there are a few subtleties:

Using the :debug level will have a greater performance penalty than :fatal,
as a far greater number of strings are being evaluated and written to the
log output (e.g. disk).

Another potential pitfall is too many calls to Logger in your code:

logger.debug "Person attributes hash: #{@person.attributes.inspect}"

In the above example, there will be a performance impact even if the allowed
output level doesn't include debug. The reason is that Ruby has to evaluate
these strings, which includes instantiating the somewhat heavy String object
and interpolating the variables.
Therefore, it's recommended to pass blocks to the logger methods, as these are
only evaluated if the output level is the same as — or included in — the allowed level
(i.e. lazy loading). The same code rewritten would be:

The contents of the block, and therefore the string interpolation, are only
evaluated if debug is enabled. This performance savings are only really
noticeable with large amounts of logging, but it's a good practice to employ.

When your code is behaving in unexpected ways, you can try printing to logs or
the console to diagnose the problem. Unfortunately, there are times when this
sort of error tracking is not effective in finding the root cause of a problem.
When you actually need to journey into your running source code, the debugger
is your best companion.

The debugger can also help you if you want to learn about the Rails source code
but don't know where to start. Just debug any request to your application and
use this guide to learn how to move from the code you have written into the
underlying Rails code.

As soon as your application calls the byebug method, the debugger will be
started in a debugger shell inside the terminal window where you launched your
application server, and you will be placed at the debugger's prompt (byebug).
Before the prompt, the code around the line that is about to be run will be
displayed and the current line will be marked by '=>', like this:

When you start debugging your application, you will be placed in different
contexts as you go through the different parts of the stack.

The debugger creates a context when a stopping point or an event is reached. The
context has information about the suspended program which enables the debugger
to inspect the frame stack, evaluate variables from the perspective of the
debugged program, and know the place where the debugged program is stopped.

At any time you can call the backtrace command (or its alias where) to print
the backtrace of the application. This can be very helpful to know how you got
where you are. If you ever wondered about how you got somewhere in your code,
then backtrace will supply the answer.

The current frame is marked with -->. You can move anywhere you want in this
trace (thus changing the context) by using the frame n command, where n is
the specified frame number. If you do that, byebug will display your new
context.

(byebug) frame 2
[176, 185] in /PathToGems/actionpack-5.1.0/lib/abstract_controller/base.rb
176: # is the intended way to override action dispatching.
177: #
178: # Notice that the first argument is the method to be dispatched
179: # which is *not* necessarily the same as the action name.
180: def process_action(method_name, *args)
=> 181: send_action(method_name, *args)
182: end
183:
184: # Actually call the method associated with the action. Override
185: # this method if you wish to change how action methods are called,
(byebug)

The available variables are the same as if you were running the code line by
line. After all, that's what debugging is.

You can also use up [n] and down [n] commands in order to change the context
n frames up or down the stack respectively. n defaults to one. Up in this
case is towards higher-numbered stack frames, and down is towards lower-numbered
stack frames.

As you may have figured out, all of the variables that you can access from a
controller are displayed. This list is dynamically updated as you execute code.
For example, run the next line using next (you'll learn more about this
command later in this guide).

You can also use display to start watching variables. This is a good way of
tracking the values of a variable while the execution goes on.

(byebug) display @articles
1: @articles = nil

The variables inside the displayed list will be printed with their values after
you move in the stack. To stop displaying a variable use undisplay n where
n is the variable number (1 in the last example).

Now you should know where you are in the running trace and be able to print the
available variables. But let's continue and move on with the application
execution.

Use step (abbreviated s) to continue running your program until the next
logical stopping point and return control to the debugger. next is similar to
step, but while step stops at the next line of code executed, doing just a
single step, next moves to the next line without descending inside methods.

If we use next, we won't go deep inside method calls. Instead, byebug will
go to the next line within the same context. In this case, it is the last line
of the current method, so byebug will return to the next line of the caller
method.

There are two ways to resume execution of an application that is stopped in the
debugger:

continue [n]: resumes program execution at the address where your script last
stopped; any breakpoints set at that address are bypassed. The optional argument
n allows you to specify a line number to set a one-time breakpoint which is
deleted when that breakpoint is reached.

finish [n]: execute until the selected stack frame returns. If no frame
number is given, the application will run until the currently selected frame
returns. The currently selected frame starts out the most-recent frame or 0 if
no frame positioning (e.g up, down, or frame) has been performed. If a frame
number is given it will run until the specified frame returns.

(byebug) help set
set <setting> <value>
Modifies byebug settings
Boolean values take "on", "off", "true", "false", "1" or "0". If you
don't specify a value, the boolean setting will be enabled. Conversely,
you can use "set no<setting>" to disable them.
You can see these environment settings with the "show" command.
List of supported settings:
autosave -- Automatically save command history record on exit
autolist -- Invoke list command on every stop
width -- Number of characters per line in byebug's output
autoirb -- Invoke IRB on every stop
basename -- <file>:<line> information after every stop uses short paths
linetrace -- Enable line execution tracing
autopry -- Invoke Pry on every stop
stack_on_error -- Display stack trace when `eval` raises an exception
fullpath -- Display full file names in backtraces
histfile -- File where cmd history is saved to. Default: ./.byebug_history
listsize -- Set number of source lines to list by default
post_mortem -- Enable/disable post-mortem mode
callstyle -- Set how you want method call parameters to be displayed
histsize -- Maximum number of commands that can be stored in byebug history
savefile -- File where settings are saved to. Default: ~/.byebug_save

You can save these settings in an .byebugrc file in your home directory.
The debugger reads these global settings when it starts. For example:

Web Console is a bit like byebug, but it runs in the browser. In any page you
are developing, you can request a console in the context of a view or a
controller. The console would be rendered next to your HTML content.

Valgrind is an application for detecting C-based memory
leaks and race conditions.

There are Valgrind tools that can automatically detect many memory management
and threading bugs, and profile your programs in detail. For example, if a C
extension in the interpreter calls malloc() but doesn't properly call
free(), this memory won't be available until the app terminates.

For further information on how to install Valgrind and use with Ruby, refer to
Valgrind and Ruby
by Evan Weaver.

Query Reviewer This Rails plugin
not only runs "EXPLAIN" before each of your select queries in development, but
provides a small DIV in the rendered output of each page with the summary of
warnings for each query that it analyzed.

Exception Notifier
Provides a mailer object and a default set of templates for sending email
notifications when errors occur in a Rails application.

Better Errors Replaces the
standard Rails error page with a new one containing more contextual information,
like source code and variable inspection.

RailsPanel Chrome extension for Rails
development that will end your tailing of development.log. Have all information
about your Rails app requests in the browser — in the Developer Tools panel.
Provides insight to db/rendering/total times, parameter list, rendered views and
more.

Feedback

You may also find incomplete content or stuff that is not up to date.
Please do add any missing documentation for master. Make sure to check
Edge Guides first to verify
if the issues are already fixed or not on the master branch.
Check the Ruby on Rails Guides Guidelines
for style and conventions.

If for whatever reason you spot something to fix but cannot patch it yourself, please
open an issue.