ChatGPT解决这个技术问题 Extra ChatGPT

在控制台中禁用 Rails SQL 日志记录

当我在控制台中执行命令时,有没有办法禁用 SQL 查询日志记录?理想情况下,如果我可以禁用它并使用控制台中的命令重新启用它,那就太好了。

我正在尝试调试某些东西并使用“puts”打印出一些相关数据。但是,sql 查询输出使其难以阅读。

编辑:我找到了另一个解决方案,因为将记录器设置为 nil 有时会引发错误,如果我的代码以外的其他内容试图调用 logger.warn

您可以将记录器的级别设置为 1,而不是将记录器设置为 nil

ActiveRecord::Base.logger.level = 1 # or Logger::INFO
since setting the logger to nil sometimes raised an error 是的。我在尝试运行 rake db:migrate stackoverflow.com/questions/1719212/… 时得到了这个
在初始化程序中确认这在 Rails 4.1.0 中有效。

R
Ryan Bigg

要关闭它:

old_logger = ActiveRecord::Base.logger
ActiveRecord::Base.logger = nil

要重新打开它:

ActiveRecord::Base.logger = old_logger

有什么地方可以放这个所以我永久禁用 SQL 输出?我尝试将它添加到 envs/dev.rb 但不是运气。
您可以将此代码放在 .irbrc 中,它基本上是 Rails 控制台的 .bashrc。事实上,如果您愿意,您几乎可以在 .irbrc 中做任何事情,例如语法着色、历史记录、在 vi 中编辑代码然后在 Rails 控制台中执行等。如果您使用 Ruby,请查看我的 gem utility_belt 1.8 或称为 flyrb 的 Ruby 1.9 端口
@giles bowkett:实际上,.irbrc类似于 .bashrc,但实际上是针对您的 ruby 交互式命令行。这不是铁轨的事情。我想如果您在 rails 环境之外运行 irb 时尝试引用 rails 类,您可能会遇到错误。
@samvermette 您可以在配置文件中使用它。例如:config/initializers/activerecord_logger.rb
ActiveRecord::Base.logger.level = 1 是一个更好的答案,因为如果您使用 .info 等,它不会引发异常。
j
jrochkind

这是我认为更简洁的一个变体,它仍然允许来自 AR 的潜在其他日志记录。在 config/environments/development.rb :

config.after_initialize do
  ActiveRecord::Base.logger = Rails.logger.clone
  ActiveRecord::Base.logger.level = Logger::INFO
end

在 Rails 3.0 或 3.1 中,奇怪,不适合我。为什么您的 Rails.logger 在 after_initialize 块中为零,您是否做了其他事情来自定义 Rails 初始化堆栈,或者您忘记了 config.after_initialize ?
在我的 Rails 3.1 应用程序中运行良好。似乎是最好的解决方案。 +1
对我不起作用...在 after_initialize 块中设置级别 OK,但在控制台打开时级别又回到 0。奇怪的。 (我使用 Pry 作为控制台替代品,这是为什么呢?)
C
Christoph Petschnig

这可能不是控制台的合适解决方案,但 Rails 有解决此问题的方法:Logger#silence

ActiveRecord::Base.logger.silence do
  # the stuff you want to be silenced
end

仅适用于 Rails 3:“弃用警告:不推荐使用静音并将从 Rails 4.0 中删除”
@Kangur我在rails 4.2上,沉默似乎工作正常
@Kangur 我还可以确认这种方法在 Rails 4.2 上运行良好
在 Rails 5 中工作,我没有看到任何警告。这是国际海事组织的最佳答案。
在 Rails 6 中运行良好。也许只是稍微移动了一下?
M
Micah

对于 Rails 4,您可以将以下内容放入环境文件中:

# /config/environments/development.rb

config.active_record.logger = nil

这只会在生产中生效,无论如何,伐木大多受到抑制......
在 rails 5 这不起作用。如果您在 linux 环境中工作,则以下内容将起作用: config.active_record.logger = Logger.new('/dev/null') 不确定是否与 6 和 7 等较新版本相同
D
Dorian

如果有人想真正取消 SQL 语句日志记录(不更改日志记录级别,同时保留他们的 AR 模型的日志记录):

写入日志的行(无论如何在 Rails 3.2.16 中)是对 lib/active_record/log_subscriber.rb:50 中的 debug 的调用。

该调试方法由 ActiveSupport::LogSubscriber 定义。

所以我们可以像这样覆盖它来取消日志记录:

module ActiveSupport
  class LogSubscriber
    def debug(*args, &block)
    end
  end
end

好一个。这适用于 SQL 日志记录而不影响 Rails.logger.debug 语句。
总菜鸟在这里。我们应该把它放在哪里?
我将它保存在 lib/monkeypatch.rb 中,并让 rails 在 config/application.rb 中使用以下行将其拉入:Dir.glob( "./lib/*.{rb}" ).each{ | file | require file }。请记住,某些人不赞成猴子修补。可能不应该将此检查到您的生产代码中。
我将此作为我的 Rails / ActiveRecord 6 解决方案的起点,我已将其添加为此处的答案。这个版本不太好用,因为它实际上抑制了很多我想看到的其他日志。
N
Nate Ben

我使用了这个:config.log_level = :info 编辑config/environments/performance.rb

对我来说工作得很好,拒绝 SQL 输出,只显示渲染和重要信息。


我在 Rails 4.1.0 上,对我来说效果很好。谢谢
感谢您提到这一点,如果放 config.log_level = :fatal 它基本上几乎完全禁用了对生产日志文件的输出,这就是我需要的,因为有一个自定义请求记录器正在播放
J
Joshua Pinter

在 Rails 3.2 中,我在 config/environment/development.rb 中执行以下操作:

module MyApp
  class Application < Rails::Application
    console do
      ActiveRecord::Base.logger = Logger.new( Rails.root.join("log", "development.log") )
    end
  end
end

M
Max Williams

仅供参考,在 Rails 2 中你可以做

ActiveRecord::Base.silence { <code you don't want to log goes here> }

显然,如果您愿意,可以用 do end 块替换花括号。


n
nwnoll

我使用 activerecord 6.0.3.3,我必须包括 ActiveSupport::LoggerSilence

include ActiveSupport::LoggerSilence

ActiveSupport::LoggerSilence.silence do
    ## everything you want to silence
end

但是,这不适用于与创建或删除 SQL 表(如 ActiveRecord::Migration.drop_table)相关的任何内容。为了使它静音,我补充说:

ActiveRecord::Schema.verbose = false

C
Chris R

我必须为 ActiveRecord 6 解决这个问题,并且我的答案基于 fakeleft 的响应,但这并不完全正确,因为它抑制了其他日志记录,例如嵌套视图的日志记录。我所做的是创建 config/initializers/activerecord_logger.rb

# Suppress SQL statement logging if necessary
# This is a dirty, dirty trick, but it works:
if ENV["ACTIVERECORD_HIDE_SQL"].present?
  module ActiveRecord
    class LogSubscriber
      def sql(event)
      end
    end
  end
end

AR 6 中的日志订阅者有一个我们想要隐藏的 sql 事件,因此这是非常狭窄的目标,以跳过 that 事件。