Class: Resque::Integration::LogsRotator

Inherits:
Object
  • Object
show all
Defined in:
lib/resque/integration/logs_rotator.rb

Class Method Summary collapse

Class Method Details

.redirect_stdObject

Перенаправить стандартный вывод в файл



8
9
10
11
12
13
# File 'lib/resque/integration/logs_rotator.rb', line 8

def redirect_std
  log_path = ::Resque.config.log_file
  STDOUT.reopen File.open(log_path, 'a')
  STDERR.reopen File.open(log_path, 'a')
  STDOUT.sync = STDERR.sync = true
end

.register_hup_signalObject



15
16
17
# File 'lib/resque/integration/logs_rotator.rb', line 15

def register_hup_signal
  Signal.trap('HUP') { ::Resque::Integration::LogsRotator.reopen_logs }
end

.reopen_logsObject

Переоткрытие всех логов

See Also:

  • Unicorn::Utils


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/resque/integration/logs_rotator.rb', line 22

def reopen_logs
  to_reopen = []
  nr = 0
  ObjectSpace.each_object(File) { |fp| is_log?(fp) and to_reopen << fp }

  to_reopen.each do |fp|
    orig_st = begin
      fp.stat
    rescue IOError, Errno::EBADF # race
      next
    end

    begin
      b = File.stat(fp.path)
      next if orig_st.ino == b.ino && orig_st.dev == b.dev
    rescue Errno::ENOENT
    end

    begin
      # stdin, stdout, stderr are special.  The following dance should
      # guarantee there is no window where `fp' is unwritable in MRI
      # (or any correct Ruby implementation).
      #
      # Fwiw, GVL has zero bearing here.  This is tricky because of
      # the unavoidable existence of stdio FILE * pointers for
      # std{in,out,err} in all programs which may use the standard C library
      if fp.fileno <= 2
        # We do not want to hit fclose(3)->dup(2) window for std{in,out,err}
        # MRI will use freopen(3) here internally on std{in,out,err}
        fp.reopen(fp.path, "a")
      else
        # We should not need this workaround, Ruby can be fixed:
        #    http://bugs.ruby-lang.org/issues/9036
        # MRI will not call call fclose(3) or freopen(3) here
        # since there's no associated std{in,out,err} FILE * pointer
        # This should atomically use dup3(2) (or dup2(2)) syscall
        File.open(fp.path, "a") { |tmpfp| fp.reopen(tmpfp) }
      end

      fp.sync = true
      fp.flush # IO#sync=true may not implicitly flush
      new_st = fp.stat

      # this should only happen in the master:
      if orig_st.uid != new_st.uid || orig_st.gid != new_st.gid
        fp.chown(orig_st.uid, orig_st.gid)
      end

      nr += 1
    rescue IOError, Errno::EBADF
      # not much we can do...
    end
  end
  nr
end