导致 ActiveRecord 记录器 IOError 的 Ruby 守护进程

Posted

技术标签:

【中文标题】导致 ActiveRecord 记录器 IOError 的 Ruby 守护进程【英文标题】:Ruby Daemons causing ActiveRecord logger IOError 【发布时间】:2010-12-15 06:13:03 【问题描述】:

我目前正在用 Ruby 编写一个项目,该项目利用 ActiveRecord gem 进行数据库交互,我正在尝试使用 ActiveRecord::Base.logger 属性和以下代码记录所有数据库活动

ActiveRecord::Base.logger = Logger.new(File.open('logs/database.log', 'a'))

这适用于迁移等(由于某种原因,这似乎需要启用日志记录,因为它在禁用时会给出 NilClass 错误)但是当我尝试运行包含调用 ActiveRecord 对象的线程守护程序的项目时脚本失败并出现以下错误

/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/logger.rb:504:in `write': closed stream (IOError)

任何有关如何解决此问题的想法将不胜感激。目前我已经开始查看其他代码,看看人们是否有其他方式以更线程安全的方式实现 ActiveRecord 日志记录

谢谢

帕特里克

【问题讨论】:

【参考方案1】:

事实证明,要使迁移工作,ActiveRecord::Base.logger 变量不能为零,这解释了问题的前半部分。尽管使用文件而不是 STDERR 时,我仍然无法修复 IOError。

【讨论】:

问题是否源于同步?你能改用 Rails 的 BufferedLogger,看看是否能解决问题? 我们最终使用 DRB 为我们的需要编写了一个简单的日志记录应用程序,它处理了我们所有线程的错误 我用Rails.logger = ActiveRecord::Base.logger = Logger.new(STDOUT)修复【参考方案2】:

我遇到了同样的问题。您需要先进行守护进程,然后然后加载 Rails 环境。

【讨论】:

你能解释一下“守护然后加载 Rails env”是什么意思吗 Daemons.run_proc('your_daemon', daemon_options) 需要 File.expand_path(File.join(File.dirname(FILE), '..', 'config' , '环境')) # 做事 @LoganKoester 请注意,在您守护进程后,尝试获取__FILE__ 上的目录信息将不起作用,因为该进程会丢失此信息。您必须在守护进程之前保存该路径。【参考方案3】:

delayed_job 使用了守护进程和 activerecord, 在daemonize之前,获取文件已经打开,然后在daemonize中重新打开

@files_to_reopen = []
ObjectSpace.each_object(File) do |file|
  @files_to_reopen << file unless file.closed?
end

Daemons.run_proc("xxxxx_name",:dir=>pid_file,:dir_mode=>:normal) do
  Dir.chdir(Rails.root)
  # Re-open file handles
  @files_to_reopen.each do |file|
    begin
      file.reopen file.path
      file.sync = true
    rescue ::Exception
    end
  end
end

【讨论】:

别忘了添加写权限。 file.reopen file.path, "a"

以上是关于导致 ActiveRecord 记录器 IOError 的 Ruby 守护进程的主要内容,如果未能解决你的问题,请参考以下文章

转换为 ActiveRecord 查询(火鸟数据库)时导致错误的原始 SQL 查询

是啥导致了这个 ActiveRecord::ReadOnlyRecord 错误?

复制 activerecord 记录的最简单方法是啥?

在更新操作中调用 ActiveRecord .reload 方法导致规范对象具有 nil id

如何禁用某个列的 ActiveRecord 日志记录?

Rails 4 - 生产资产:预编译导致 ActiveRecord::NoDatabaseError: FATAL: database does not exist