我正在尝试在 Rails 中启用 详细查询日志记录,但是
ActiveRecord::LogSubscriber
的行为很奇怪,这导致详细查询日志记录不起作用。
问题似乎源于此处:https://github.com/rails/rails/blob/v6.0.0/activerecord/lib/active_record/log_subscriber.rb#L113
如果我
inspect
locations
变量,我可以看到它确实有内容:
[
"/Users/jeff/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/activerecord-6.0.0/lib/active_record/log_subscriber.rb:100:in `debug'",
"/Users/jeff/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/activerecord-6.0.0/lib/active_record/log_subscriber.rb:45:in `sql'",
"/Users/jeff/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/subscriber.rb:145:in `finish'",
"/Users/jeff/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/log_subscriber.rb:107:in `finish'",
"/Users/jeff/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications/fanout.rb:160:in `finish'",
"/Users/jeff/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications/fanout.rb:62:in `block in finish'",
"/Users/jeff/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/activesupport-6.0.0/lib/active_support/notifications/fanout.rb:62:in `each'",
...
]
但是一旦经过
clean
方法,它就是一个空数组。所以这个:
backtrace_cleaner.clean(locations.lazy).first
正在回归
nil
。因此,第 105 行上的
source
赋值为 nil
,这意味着第 107 行上的
if source
计算结果为 false,并且不记录任何内容。
更新↳ /Users/jeff/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/activerecord-6.0.0/lib/active_record/log_subscriber.rb:100:in `debug'
所以问题来了。由于某种原因,我们的应用程序代码没有注册为调用者。关于如何发生这种情况有什么想法吗?
将始终关闭控制台中执行的活动的详细查询日志记录:
# ActiveRecord::Railtie
console do |app|
require "active_record/railties/console_sandbox" if app.sandbox?
require "active_record/base"
unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
console = ActiveSupport::Logger.new(STDERR)
Rails.logger.extend ActiveSupport::Logger.broadcast console
end
ActiveRecord::Base.verbose_query_logs = false # <--- HERE
end
。提交消息提供了更多详细信息并引用此问题。这是故意的,这样做是为了减少 Rails 控制台中的噪音。 如果您想在 Rails 控制台中重新打开详细日志记录,则必须使用以下命令手动重置该标志:
ActiveRecord::Base.verbose_query_logs = true
或者您可以将其添加到应用程序的初始化程序中,以便在控制台启动时将其打开:
# config/initializers/verbose_logging.rb
Rails.application.console do
ActiveRecord::Base.verbose_query_logs = true
end
请注意,Rails Guide
建议不要在生产中打开此功能,因为会占用内存,因此您可能希望在该环境中将其关闭,具体取决于运行生产控制台的可用资源。
要测试ActiveSupport::BacktraceCleaner
是否意外清除了您的代码,您可以执行以下操作:
# Get the source location for a class method somewhere in your app
path = MyClass.method(:my_class_method).first
# Run it through the BacktraceCleaner
backtrace_cleaner = ActiveSupport::BacktraceCleaner.new
backtrace_cleaner.clean([path])
如果返回
[]
,您可能需要检查是否将应用程序代码放入
RbConfig::CONFIG["rubylibdir"]
文件夹中。 BacktraceCleaner 将假定那里的代码是标准 Ruby 库的一部分,并将其从回溯中删除。