我有一个不断增长的日志文件。如何通过Ruby脚本观察和解析它?
当新行包含字符串'ERROR'
时,脚本将在写入文件时解析每个新行并输出一些内容。答案 0 :(得分:17)
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/)
感谢ezpz的想法,使用select方法可以得到你想要的东西。 select方法正在监听IO的流,读取“迟到”的字节。
答案 1 :(得分:8)
您可以通过以下方式使用Kernel#select
:
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
然后称之为:
watch_for("some_file", /ERROR/)
我已经省略了所有的错误检查等等 - 你会想要这个以及可能有一些机制来摆脱循环。但基本的想法就在那里。
答案 2 :(得分:5)
如果你在Linux上......
tail -f log/development.log | grep "ERROR"
除非你真的希望它出于某种原因成为Ruby脚本。
答案 3 :(得分:5)
有两种方法:
sleep
置于无限循环中)这是我写的一篇文章:Ruby for Admins: Reading Growing Files。因此,结合事件子系统和轮询的程序如下所示:
def tail_dash_f(filename)
open(ARGV.first) do |file|
file.read
case RUBY_PLATFORM # string with OS name, like "amd64-freebsd8"
when /bsd/, /darwin/
require 'rb-kqueue'
queue = KQueue::Queue.new
queue.watch_file(ARGV.first, :extend) do
yield file.read
end
queue.run
when /linux/
require 'rb-inotify'
queue = INotify::Notifier.new
queue.watch(ARGV.first, :modify) do
yield file.read
end
queue.run
else
loop do
changes = file.read
unless changes.empty?
yield changes
end
sleep 1.0
end
end
end
end
tail_dash_f ARGV.first do |data|
print data
if data =~ /error/i
# do something else, for example send an email to administrator
end
end
答案 4 :(得分:3)
查看file-tail gem
答案 5 :(得分:3)
穷人的快速做法:
执行
的Ruby脚本ARGF.each do |line|
...
运行屏幕:
tail -f file | ruby script
答案 6 :(得分:2)
研究@Qianjigui的想法但不使用100%CPU:
def watch_for(file, pattern)
# Replace -n0 with -n+1 if you want to read from the beginning of file
f = IO.popen(%W[tail -f -n0 #{file}])
loop do
select([f])
while line = f.gets
puts "Found it! #{line}" if line =~ pattern
end
end
end
watch_for('g.txt', /ERROR/)