class Process::Daemon::LogFile

This is a special file instance which provides the ability to read a log file from the end backwards.

Constants

REVERSE_BUFFER_SIZE

Public Instance Methods

tail_log() { |line| ... } click to toggle source

Yields the lines of a log file in reverse order, once the yield statement returns true, stops, and returns the lines in order.

# File lib/process/daemon/log_file.rb, line 26
def tail_log
        lines = []

        seek_end
        
        reverse_each_line do |line|
                lines << line
                
                break if block_given? and yield line
        end

        return lines.reverse
end

Private Instance Methods

read_reverse(length) click to toggle source

Read a chunk of data and then move the file pointer backwards.

Calling this function multiple times will return new data and traverse the file backwards.

# File lib/process/daemon/log_file.rb, line 51
def read_reverse(length)
        offset = tell

        if offset == 0
                return nil
        end

        start = [0, offset-length].max

        seek(start, IO::SEEK_SET)

        buf = read(offset-start)

        seek(start, IO::SEEK_SET)

        return buf
end
reverse_each_line(sep_string=$/) { |line| ... } click to toggle source

Similar to each_line but works in reverse. Don’t forget to call seek_end before you start!

# File lib/process/daemon/log_file.rb, line 105
def reverse_each_line(sep_string=$/, &block)
        return to_enum(:reverse_each_line) unless block_given?
                
        line = reverse_gets(sep_string)

        while line != nil
                yield line

                line = reverse_gets(sep_string)
        end
end
reverse_gets(sep_string=$/) click to toggle source

This function is very similar to gets but it works in reverse.

You can use it to efficiently read a file line by line backwards.

It returns nil when there are no more lines.

# File lib/process/daemon/log_file.rb, line 76
def reverse_gets(sep_string=$/)
        end_pos = tell

        offset = nil
        buf = ""

        while offset == nil
                chunk = read_reverse(REVERSE_BUFFER_SIZE)

                return (buf == "" ? nil : buf) if chunk == nil

                buf = chunk + buf

                # Don't consider the last newline.
                offset = buf.rindex(sep_string, -(sep_string.length + 1))
        end

        # Don't include newline:
        offset += 1

        line = buf[offset...buf.size]

        seek((end_pos - buf.size) + offset, IO::SEEK_SET)

        return line
end
seek_end(offset = 0) click to toggle source

Seek to the end of the file

# File lib/process/daemon/log_file.rb, line 43
def seek_end(offset = 0)
        seek(offset, IO::SEEK_END)
end