在 rake 任务中,如果我使用 put 命令,那么我会在控制台上看到输出。但是,当应用程序部署在生产环境中时,我不会在日志文件中看到该消息。
但是,如果我说 Rails.logger.info 那么在开发模式下我在控制台上看不到任何内容。我需要去日志文件并跟踪它。
我理想地希望使用 Rails.logger.info 并在 rake 任务内的开发模式下,记录器的输出也应该发送到控制台。
有办法实现吗?
将其放入
application.rb
,或者放在 rake 任务初始化代码中
if defined?(Rails) && (Rails.env == 'development')
Rails.logger = Logger.new(STDOUT)
end
这是 Rails 3 代码。请注意,这将覆盖记录到
development.log
。如果您同时想要 STDOUT
和 development.log
,您将需要一个包装函数。
如果您只希望在 Rails 控制台中实现此行为,请将相同的代码块放入您的
~/.irbrc
中。
您可以创建一个新的 rake 任务来使其发挥作用。
desc "switch logger to stdout"
task :to_stdout => [:environment] do
Rails.logger = Logger.new(STDOUT)
end
这样,当您执行 rake 任务时,您可以首先添加 to_stdout 以获取 stdout 日志消息,或者不包含它以将消息发送到默认日志文件
rake to_stdout some_task
对于 Rails 4 及更高版本,您可以使用 Logger 广播。
如果您想在开发模式下同时获取 rake 任务的 STDOUT 和文件日志记录,您可以将此代码添加到
config/environments/development.rb
:
if File.basename($0) == 'rake'
# http://stackoverflow.com/questions/2246141/puts-vs-logger-in-rails-rake-tasks
log_file = Rails.root.join("log", "#{Rails.env}.log")
Rails.logger = ActiveSupport::Logger.new(log_file)
Rails.logger.extend(ActiveSupport::Logger.broadcast(ActiveSupport::Logger.new(STDOUT)))
end
这是一个小的 Rake 任务来测试上面的代码:
# lib/tasks/stdout_and_log.rake
namespace :stdout_and_log do
desc "Test if Rails.logger outputs to STDOUT and log file"
task :test => :environment do
puts "HELLO FROM PUTS"
Rails.logger.info "HELLO FROM LOGGER"
end
end
运行
rake stdout_and_log:test
输出
HELLO FROM PUTS
HELLO FROM LOGGER
同时
HELLO FROM LOGGER
已添加到
log/development.log
。
运行
rake stdout_and_log:test RAILS_ENV=production
输出
HELLO FROM PUTS
同时
HELLO FROM LOGGER
已添加到
log/production.log
。
Rake 任务由用户在命令行上运行。他们需要立即了解的任何内容(“已处理 5 行”)都应在终端上输出
puts
。
任何需要为后代保留的内容(“向 [email protected] 发送警告电子邮件”)都应发送至
Rails.logger
。
我想说使用
Rails.logger.info
是正确的方法。
您将无法在服务器控制台中看到它,因为它不会通过服务器运行。只需打开一个新控制台和
tail -f
日志文件,它就可以了。
许多用户都知道 UNIX® 命令“tail”,可用于 显示大文件的最后几行 文件。这对于查看很有用 日志文件等
在某些情况下甚至更有用, 是“tail”的“-f”参数 命令。这会导致尾巴“跟随” 文件的输出。最初, 响应将与相同 “尾巴”本身 - 最后几行 将显示文件的内容。 但是,该命令不返回 到提示符,然后继续 “关注”该文件。当额外 行被添加到文件中,它们将 会显示在终端上。这是 对于查看日志文件非常有用,或者 任何其他可能附加的文件 随着时间的推移。输入“man tail”了解更多 这条尾巴和其他尾巴的详细信息 选项。
(通过)
在 Rails 2.X 中将记录器重定向到模型中的 STDOUT:
ActiveRecord::Base.logger = Logger.new(STDOUT)
在控制器中重定向记录器:
ActionController::Base.logger = Logger.new(STDOUT)
使用“&”执行后台作业并打开脚本/控制台或其他内容。 这样您就可以在同一窗口中运行多个命令。
tail -f log/development.log &
script/console
Loading development environment (Rails 2.3.5)
>> Product.all
2011-03-10 11:56:00 18062 DEBUG Product Load (6.0ms) SELECT * FROM "products"
[<Product.1>,<Product.2>]
note 当有大量日志输出时,可能会很快变得马虎。
创建一个应用程序助手来检测正在运行的环境并执行正确的操作怎么样?
def output_debug(info)
if RAILS_ENV == "development"
puts info
else
logger.info info
end
end
然后调用output_debug而不是puts或logger.info
扩展@Eric Duminil 的答案。我们可以使用rails提供的
rake_tasks
钩子仅在调用rake任务时运行代码块,即当服务器或控制台运行时该块不会运行。
# config/application.rb
module MyApp
class Application < Rails::Application
rake_tasks do
config.after_initialize do
Rails.logger.extend(
ActiveSupport::Logger.broadcast(ActiveSupport::Logger.new(STDOUT))
)
end
end
end
end
输出:
cat lib/tasks/logger_test.rake
namespace :stdout_and_log do
desc "Test if Rails.logger outputs to STDOUT and log file"
task test: :environment do
puts "HELLO FROM PUTS"
Rails.logger.info "HELLO FROM LOGGER"
end
end
❱ bundle exec rails stdout_and_log:test
HELLO FROM PUTS
HELLO FROM LOGGER