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
2009-08-18 13:25:33
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
2009-08-18 13:38:11
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
2009-08-18 14:01:10
+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
2009-08-18 13:48:37
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
2009-08-18 14:09:52
"...output something to the screen when the new line contains the string 'ERROR'" is not dynamic behavior :)
cakeforcerberus
2009-08-18 14:18:51
This works best for me. Meta-programming around the error log seems like effort better spent elsewhere.
MattC
2009-08-18 14:21:23
+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
2009-08-18 15:07:26