Skip to content

Instantly share code, notes, and snippets.

@hukl
Created February 12, 2011 20:21
Show Gist options
  • Save hukl/824080 to your computer and use it in GitHub Desktop.
Save hukl/824080 to your computer and use it in GitHub Desktop.
Yields the last 5 minutes of a pound log file
require 'time'
require 'stringio'
class LogfileParser
TIME_REGEXP = /\[\d{2}\/\w{3}\/\d{4}\:\d{2}:\d{2}:\d{2}\s.{5}\]/
def initialize path, starting_at
raise ArgumentError unless File.exists?( path )
@log = File.open( path )
@ending_at = Time.parse( starting_at )
@starting_at = (@ending_at - 300)
end
def backwards
filesize = @log.stat.size
buffer_size = 128000
offset = buffer_size
@log.seek(0, File::SEEK_END)
while @log.tell > 0
@log.seek(-offset, File::SEEK_END)
# Making the buffer a StringIO to get #tell() for calculating the offset
buffer = StringIO.new( @log.read( buffer_size ) )
minute = @starting_at.strftime("%M").chars.first
time_range = Regexp.new(
@starting_at.strftime(
"\\[%d\\/%b\\/%Y\\:%H\\:%M\\:%S\\s.{5}\\]"
)
)
buffer.each_line do |line|
if timestamp = line.match( time_range )
# Calculate the final offset
offset = filesize-([email protected])-buffer_size+buffer.tell
@log.seek(offset, File::SEEK_SET)
return
end
end
offset += buffer_size
return if offset > filesize
end
end
def emit &block
backwards
@log.each_line do |line|
yield line
end
end
end
parser = LogfileParser.new( *ARGV )
parser.emit {|l| puts l }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment