Module: Resque::Pool::Logging

Extended by:
Logging
Included in:
Resque::Pool, Resque::Pool, CLI, CLI, Killer, Logging
Defined in:
lib/resque/pool/logging.rb

Constant Summary collapse

PROCLINE_PREFIX =
"resque-pool-master"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.reopen_logs!Object

This reopens ALL logfiles in the process that have been rotated using logrotate(8) (without copytruncate) or similar tools. A File object is considered for reopening if it is:

1) opened with the O_APPEND and O_WRONLY flags
2) the current open file handle does not match its original open path
3) unbuffered (as far as userspace buffering goes, not O_SYNC)

Returns the number of files reopened

This was mostly copied from Unicorn 4.8.2 to simplify reopening logs in the same way that Unicorn does. Original comments and explanations are left intact.



17
18
19
20
21
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/pool/logging.rb', line 17

def self.reopen_logs!
  to_reopen      = [ ]
  reopened_count = 0

  ObjectSpace.each_object(File) { |fp| is_log?(fp) and to_reopen << fp }
  log "Flushing #{to_reopen.length} logs"

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

    begin
      b = File.stat(fp.path)
      # Skip if reopening wouldn't do anything
      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

      log "Reopened logfile: #{fp.path}"
      reopened_count += 1
    rescue IOError, Errno::EBADF
      # not much we can do...
    end
  end

  reopened_count
end

Instance Method Details

#appObject

Include optional app name in procline



102
103
104
105
106
# File 'lib/resque/pool/logging.rb', line 102

def app
  app_name   = self.respond_to?(:app_name)       && self.app_name
  app_name ||= self.class.respond_to?(:app_name) && self.class.app_name
  app_name ? "[#{app_name}]" : ""
end

#log(message) ⇒ Object

TODO: make this use an actual logger



88
89
90
91
92
# File 'lib/resque/pool/logging.rb', line 88

def log(message)
  return if $skip_logging
  puts "resque-pool-manager#{app}[#{Process.pid}]: #{message}"
  #$stdout.fsync
end

#log_worker(message) ⇒ Object

TODO: make this use an actual logger



95
96
97
98
99
# File 'lib/resque/pool/logging.rb', line 95

def log_worker(message)
  return if $skip_logging
  puts "resque-pool-worker#{app}[#{Process.pid}]: #{message}"
  #$stdout.fsync
end

#procline(string) ⇒ Object

Given a string, sets the procline ($0) Procline is always in the format of:

resque-pool-master: STRING


83
84
85
# File 'lib/resque/pool/logging.rb', line 83

def procline(string)
  $0 = "#{PROCLINE_PREFIX}#{app}: #{string}"
end