5

I'm writing a project at the moment in Ruby which makes use of the ActiveRecord gem for database interaction and I'm trying to log all the database activity using the ActiveRecord::Base.logger attribute with the following code

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

This works fine for migrations etc (which for some reason seem to require that logging be enabled as it gives a NilClass error when it's disabled) but when I try to run the project which includes a threaded daemon calling the ActiveRecord object the script fails with the following error

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

Any ideas on how to solve this problem would be greatly appreciated. For the moment I've started to look through other code to see if people have other ways of implementing ActiveRecord logging in a more thread-safe manner

Thanks

Patrick

Marc-André Lafortune
  • 78,216
  • 16
  • 166
  • 166
Patrick O'Doherty
  • 1,642
  • 2
  • 14
  • 20

3 Answers3

4

I ran into the same issue. You need to daemonize first, and then load the Rails environment.

Logan Koester
  • 1,126
  • 8
  • 22
  • Could you explain what you mean by "daemonize and then load Rails env" – Chris Kimpton Sep 24 '10 at 21:14
  • Daemons.run_proc('your_daemon', daemon_options) { require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) # do stuff } – Logan Koester Oct 02 '10 at 21:58
  • @LoganKoester Note that trying to get dir info on `__FILE__` won't work after you've daemonized, since the process loses this information. You'll have to save that path before daemonizing. – Kelvin Jul 26 '13 at 18:54
4

the delayed_job have used daemons and activerecord, before daemonize,get the files have opend,and then reopen in 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
user510319
  • 311
  • 4
  • 5
2

It turns out that for migrations to work the ActiveRecord::Base.logger variable cannot be nil, which explains the first half of the problem. I am as yet unable to fix the IOError though when a file is used instead of STDERR.

Patrick O'Doherty
  • 1,642
  • 2
  • 14
  • 20