Class: Pipemaster::Util

Inherits:
Object
  • Object
show all
Defined in:
lib/pipemaster/util.rb

Class Method Summary collapse

Class Method Details

.chown_logs(uid, gid) ⇒ Object



20
21
22
23
24
25
# File 'lib/pipemaster/util.rb', line 20

def chown_logs(uid, gid)
  ObjectSpace.each_object(File) do |fp|
    is_log?(fp) or next
    fp.chown(uid, gid)
  end
end

.is_log?(fp) ⇒ Boolean

Returns:

  • (Boolean)


11
12
13
14
15
16
17
18
# File 'lib/pipemaster/util.rb', line 11

def is_log?(fp)
  append_flags = File::WRONLY | File::APPEND

  ! fp.closed? &&
    fp.sync &&
    fp.path[0] == ?/ &&
    (fp.fcntl(Fcntl::F_GETFL) & append_flags) == append_flags
end

.reopen_logsObject

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) opened with an absolute path (starts with "/")
3) the current open file handle does not match its original open path
4) unbuffered (as far as userspace buffering goes, not O_SYNC)

Returns the number of files reopened



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
# File 'lib/pipemaster/util.rb', line 35

def reopen_logs
  nr = 0

  ObjectSpace.each_object(File) do |fp|
    is_log?(fp) or next
    orig_st = fp.stat
    begin
      b = File.stat(fp.path)
      next if orig_st.ino == b.ino && orig_st.dev == b.dev
    rescue Errno::ENOENT
    end

    open_arg = 'a'
    if fp.respond_to?(:external_encoding) && enc = fp.external_encoding
      open_arg << ":#{enc.to_s}"
      enc = fp.internal_encoding and open_arg << ":#{enc.to_s}"
    end
    fp.reopen(fp.path, open_arg)
    fp.sync = true
    new_st = fp.stat
    if orig_st.uid != new_st.uid || orig_st.gid != new_st.gid
      fp.chown(orig_st.uid, orig_st.gid)
    end
    nr += 1
  end # each_object
  nr
end