Rails Logging Tips
-
In this article, we’ll take a look at how to use the logging facilities built into Rails and then share a few tips:
- Accessing the Rails Logger
- Log Levels
- Filtering Sensitive Parameters
- Creating Audit Logs
- ActiveRecord Logging to the Console
- ActionController Logging to the Console
- Firebug Console
Accessing the Rails Logger
Rails automatically sets up logging to a file in the
log/directory using Logger from the Ruby Standard Library. Do not confuse this with Log4r, a completely different library. The logfile will be named corresponding to your environment, e.g.log/development.log.To log a message from either a controller or a model, access the Rails logger instance with the
loggermethod:class HomeController < ActionController::Base def index logger.info 'informational message' end endFrom outside a controller or model, you can pass the logger instance or access it with the constant
RAILS_DEFAULT_LOGGER.Log Levels
In the snippet above, a message is logged at the INFO level by calling a method of the same name (
info).The levels available on the logger are (in ascending order):
debug,info,warn,error, andfatal.Ruby's Logger supports masking levels so the types of messages recorded in the log can be controlled. By default, Rails will log all levels (
debugand higher) in every environment except production. In the production environment, it will only loginfoand higher. This behavior can be changed in the configuration for each environment.Filtering Sensitive Parameters
When Rails receives a request, ActionController logs the request parameters. This is very handy for debugging but sometimes it's not desirable to have certain parameters, such as passwords, stored as plain text in the log.
Rails 1.2 introduced the
filter_parameter_loggingclass method to remedy this:class ApplicationController < ActionController::Base filter_parameter_logging :password end
The above will cause any parameter name matching
/password/ito have its value replaced with[FILTERED]in the log. To filter multiple parameters, simply add them as extra arguments tofilter_parameter_loggingby separating them with commas. For other uses offilter_parameter_logging, see the ActionController documentation.Note: it's important to remember that
filter_parameter_loggingwill only filter ActionController request information. The parameters could still appear in any SQL queries being logged by ActiveRecord. However, SQL queries are not logged in the production environment by default.Creating Audit Logs
Sometimes logging is required but putting the messages in the Rails log isn't desirable. One such case is when keeping a separate logfile for auditing is a business requirement.
To create an audit log, simply create a new instance of
Loggerand pass it aFileinstance for your own logfile.One possible source of confusion is the formatting of the log message due to a patch Rails makes to
Logger. This can be seen when usingirbas opposed toscript/console:$ irb irb(main):001:0> require 'logger' => true irb(main):002:0> Logger.new(STDOUT).info('message') I, [2007-02-24T09:45:51.236763 #557] INFO -- : message$ script/console Loading development environment. >> Logger.new(STDOUT).info('message') messageAs you can see, the message formatting is lost when run in the Rails environment. To format a log message when using Rails, create your own Logger subclass and implement the
format_messagemethod:class AuditLogger < Logger def format_message(severity, timestamp, progname, msg) "#{timestamp.to_formatted_s(:db)} #{severity} #{msg}\n" end endTo use the new
AuditLogger, instantiate it with aFileinstance:logfile = File.open('/path/to/audit.log', 'a') audit_log = AuditLogger.new(logfile)Your new log is now ready to use by calling methods on it like
audit_log.info 'message'.One important point to remember is that the
logfileobject does not implicitly flush to the file by default. This means that your code must calllogfile.flushfor the data to be written out. Alternatively, you can setlogfile.sync = trueto turn on implicit flushing.ActiveRecord Logging on the Console
When debugging your applications with
script/console, it can be very useful to see the SQL output of your ActiveRecord queries. One way to do this is to usetail -fon your logfile.However, this isn't very convenient and shows all other log information as well. An easier way that can be done directly from script/console is to enter this line:
ActiveRecord::Base.logger = Logger.new(STDOUT)
This will cause the queries to be displayed immediately on the console as you interact with your ActiveRecord objects with method calls like
Article.find :all.ActionController Logging on the Console
Just like with ActiveRecord above, you can also redirect ActionController's log output to the console when using
script/console:ActionController::Base.logger = Logger.new(STDOUT)
You can then observe ActionController activities when using using using the app object on the console, such as app.get '/'. For a brief tutorial on using app, see this post on Mike Clark's weblog.
Firebug Console
Firebug is a popular extension for the Firefox browser that provides a number of useful capabilities, with a Javascript console being among them. The console is accessed by
console.log('message')in Javascript.This means that any Rails view emitting this little Javascript call between
<script>tags can write to the Firebug console.It also means that any RJS template can write to the Firebug console for debugging:
page.call 'console.log', 'informational message'
This can be very useful for logging debug information during AJAX requests where a popup from
alert()isn't desirable.
