【问题标题】:puts vs logger in rails rake tasks将 vs 记录器放入 rails rake 任务
【发布时间】:2011-01-15 19:28:47
【问题描述】:

在 rake 任务中,如果我使用 puts 命令,那么我会在控制台上看到输出。但是,当应用程序部署到生产环境时,我不会在日志文件中看到该消息。

但是,如果我说 Rails.logger.info,那么在开发模式下,我在控制台上什么也看不到。我需要去日志文件并跟踪它。

理想情况下,我希望在 rake 任务中使用 Rails.logger.info,并且在开发模式下,记录器的输出也应该发送到控制台。

有没有办法做到这一点?

【问题讨论】:

    标签: ruby-on-rails rake


    【解决方案1】:

    代码

    对于 Rails 4 及更高版本,您可以使用 Logger broadcast

    如果您想在开发模式下同时获取 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

    【讨论】:

    • 在 Rails 5 中,basename($0) == 'rake' 技巧不再有效,因为rails 命令本身运行rake。除了依赖于设置broadcast 的任务之外,我很想找到一个很好的替代品。 (至少那部分仍然可以正常工作。)
    • @BrentRoyal-Gordon 在开发中不需要这个条件,你可以将代码添加到项目根目录下的Rakefile
    【解决方案2】:

    使用 '&' 执行后台作业并打开脚本/控制台或其他... 这样您就可以在同一个窗口中运行多个命令。

    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 当有大量日志输出时,可能会很快变得草率。

    【讨论】:

      【解决方案3】:

      你可以创建一个新的 rake 任务来让它工作。

      desc "switch logger to stdout"
      task :to_stdout => [:environment] do
       Rails.logger = Logger.new(STDOUT)
      end
      

      这样,当您执行 rake 任务时,您可以先添加 to_stdout 以获取标准输出日志消息,或者不包含它以将消息发送到默认日志文件

      rake to_stdout some_task
      

      【讨论】:

        【解决方案4】:

        在 Rails 2.X 中将记录器重定向到模型中的 STDOUT:

        ActiveRecord::Base.logger = Logger.new(STDOUT)
        

        在控制器中重定向记录器:

        ActionController::Base.logger = Logger.new(STDOUT)
        

        【讨论】:

        【解决方案5】:

        把这个放在application.rb,或者一个rake任务初始化代码中

        if defined?(Rails) && (Rails.env == 'development')
          Rails.logger = Logger.new(STDOUT)
        end
        

        这是 Rails 3 代码。请注意,这将覆盖对development.log 的日志记录。如果你想要STDOUTdevelopment.log,你需要一个包装函数。

        如果您只希望在 Rails 控制台中使用此行为,请将相同的代码块放入您的 ~/.irbrc

        【讨论】:

        • Rails.logger = Logger.new(STDOUT) 放在 development.rb 中不是更容易吗?
        • 对于 rails 2,把它放在你的 development.rb 中:config.logger = Logger.new(STDOUT)
        【解决方案6】:

        如何创建一个应用程序助手来检测正在运行的环境并执行正确的操作?

        def output_debug(info)
           if RAILS_ENV == "development"
              puts info
           else
              logger.info info
           end
        end
        

        然后调用 output_debug 而不是 puts 或 logger.info

        【讨论】:

        • 我认为这不是一个好主意。 Rails 记录器本来是可配置的,但不是使用这种可配置性,您只是在此处堆积更多层。
        • 是的,这不是一个好主意,因为每次您要记录某些内容时都会进行相同的检查。
        【解决方案7】:

        Rake 任务由用户在命令行上运行。他们需要立即知道的任何内容(“已处理 5 行”)都应在终端上以puts 输出。

        任何需要为后代保留的内容(“向 jsmith@example.com 发送警告电子邮件”)应发送至Rails.logger

        【讨论】:

        • 使用 cron 运行 rake 任务并不少见。
        • 是的。如果您希望在 cron 作业完成时通过电子邮件将日志消息发送给您,请将它们发送到 $stdout 或 $stderr。
        • @JohannesGorset 即便是这样,但运行其他打算由用户在 cron 命令行上运行的程序也并不罕见。这些程序通常与标准输出交互,错误。因此,日志记录应该是维护 cronjob 的管理员的问题,而不是程序本身的问题。所以我发现这个答案很有启发性,现在对我来说很有意义。
        【解决方案8】:

        我会说使用Rails.logger.info 是可行的方法。

        您将无法在服务器控制台中看到它,因为它不会通过服务器运行。只需打开一个新控制台并tail -f 日志文件,它就可以解决问题。

        许多用户都知道 UNIX® 命令'tail',可用于 显示大的最后几行 文件。这对于查看很有用 日志文件等

        在某些情况下更有用, 是 'tail' 的 '-f' 参数 命令。这会导致尾巴“跟随” 文件的输出。最初, 响应将与 'tail' 本身 - 最后几行 将显示该文件的名称。 但是,该命令不返回 提示,而是继续 “关注”文件。当额外 行被添加到文件中,它们将 显示在终端上。这是 对于查看日志文件非常有用,或者 可能附加的任何其他文件 随着时间的推移。输入“人尾巴”了解更多信息 关于这个和其他尾巴的细节 选项。

        (via)

        【讨论】:

        • 但是在本地机器上工作时不是很舒服,因为在调用任务的同一窗口中看不到输出。特别是如果您没有大屏幕来并排放置多个窗口。
        • 更好的是使用tailf“它类似于tail -f,但在文件不增长时不访问文件”(来自手册页)。它也更短
        • @tomas 为什么不将服务器日志控制台最小化,并且只有一个运行 tail-f 的控制台?无论如何,这不是一个真正的问题......我像 8 个控制台一样运行,跟踪我的应用程序中发生的事情,当你在系统的特定部分工作时,只需在选项卡之间切换没什么大不了的,恕我直言
        • @mbo nice :) 哈哈,它看起来不像在我的机器上可用(mac os@leopard)
        • @marcgg:我没有“服务器控制台”(我使用乘客),但问题是关于 rake 任务,如果你从一个终端窗口运行任务,你看不到该窗口中记录器中的任何内容。您必须有另一个带有 development.log 的窗口才能查看输出。理想情况下,我会以某种方式将 stdout 作为另一个输出流添加到 Rails.logger,但不会删除原始输出流。
        猜你喜欢
        • 1970-01-01
        • 2013-09-14
        • 1970-01-01
        • 1970-01-01
        • 2012-02-19
        • 1970-01-01
        • 2011-10-11
        • 2011-09-03
        • 1970-01-01
        相关资源
        最近更新 更多