When creating Ruby to be executed interactively, you might want to ensure that you see the output on the console.
However, rubocop will flag the use of puts
in Rails files unless you disable the rule like this:
# rubocop:disable Rails/Output
puts(*args)
# rubocop:enable Rails/Output
If you use Rails.logger.info
, then your output gets buried in the log file if run during development. When running a command interactively, you typically want the important output to go to the console.
One way to get all logs to redirect to the console during development is to use this Rake task
# https://stackoverflow.com/a/13649373
desc <<~DESC.strip_heredoc
Switch logger to stdout
Example:
rake to_stdout other_task
DESC
task to_stdout: [:environment] do
Rails.logger = ActiveSupport::TaggedLogging.new(Logger.new($stdout))
end
But this is too blunt. You might want some logs like the SQL logs to go to log/development.log
.
Solution – Custom log
method
On Heroku, there’s no need to redirect logs since the RAILS_ENV is “production” and all logs go to stdout. So it’s better to keep the log level.
But outside of Heroku, it’s best to use warn
as that’s the standard used by Rake
def self.on_heroku?
ENV['HEROKU_APP_NAME'].present?
end
# For rake tasks where Rails.logger might not be available, and so that
# messages from the Rake task either go to level WARN
def self.log(*args)
msg = if block_given?
[yield]
else
args
end
# On Heroku, there's no need to redirect logs since the RAILS_ENV is "production"
# and all logs go to stdout. So it's better to keep the log level.
# But outside of Heroku, it's best to use `warn` as that's the standard used by `Rake`
if Rails.logger && on_heroku?
# Warn level to highlight messages
Rails.logger.warn(*msg)
else
# Same as what rake/file_utils_ext rake_output_message does
warn(*msg)
end
end
With this utility method, you can use Utils.log(*args) instead of puts
and Rails.logger.info
.
What’s does this accomplish?
- No need to clutter the code by disabling the RuboCop rule.
- When running on Heroku, logs can be filtered for
warn
to find the important messages. - When running at the command line, the important messages show on the console.