tags:

views:

548

answers:

4

I have a log file that is constantly growing, how can I watch and parse it via a ruby script. The script will parse each new line as it is written to the file and output something to the screen when the new line contains the string 'ERROR'

+1  A: 

You can use Kernel#select in the following way:

def watch_for(file,pattern)
   f = File.open(file,"r")

   # Since this file exists and is growing, seek to the end of the most recent entry
   f.seek(0,IO:SEEK_END)

   while true
      select([f])
      puts "Found it!" if f.gets =~ pattern
   end
end

Then call it like:

watch_for("some_file", /ERROR/)

I've elided all error checking and such - you will want to have that and probably some mechanism to break out of the loop. But the basic idea is there.

ezpz
yeah I have something similar and it works but it doesn't seems to work when the file is being written to.And calling watch_for will then scan the file from the start finding errors it already found, during the previous pass
KingInk
You can seek to the end of the file. just add f.seek(0,IO:SEEK_END). I'll update my post to reflect this
ezpz
+3  A: 

If you're on linux...

tail -f log/development.log | grep "ERROR"

Unless you really wanted it to be a ruby script for some reason. :)

cakeforcerberus
Wrapping this in a script gives you the ability to react to an error in a more meaningful way than by noting that it occurred. grepping is good when you want to post-process, but it is rather limited in its ability to invoke dynamic behavior.
ezpz
"...output something to the screen when the new line contains the string 'ERROR'" is not dynamic behavior :)
cakeforcerberus
This works best for me. Meta-programming around the error log seems like effort better spent elsewhere.
MattC
thanks ezpz this is useful
rado
+3  A: 
def watch_for(file, pattern)
  f = File.open(file,"r")
  f.seek(0,IO::SEEK_END)
  while true do
    select([f])
    line = f.gets
    puts "Found it! #{line}" if line=~pattern
  end
end

watch_for("g.txt",/ERROR/)

Thanks for the ezpz's idea, using the select method you get get what you want. The select method is listening the IO's stream, read the bytes what comes 'late'.

Qianjigui
A: 

check out file-tail gem

Douglas Campos