观察/阅读不断增长的日志文件

我有一个不断增长的日志文件。 如何通过Ruby脚本观察和解析它?

该脚本将在写入文件时解析每个新行,并在新行包含字符串’ERROR’时将某些内容输出到屏幕

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的流,读取“迟到”的字节。

您可以通过以下方式使用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/) 

我已经省略了所有错误检查等等 – 你会想要这个以及可能有一些机制来摆脱循环。 但基本的想法是存在的。

有两种方法:

  • 在无限循环中轮询文件(就像在钱ig贵的回答中一样,但是在无限循环中放置一些sleep是好的)
  • 使用OS事件子系统:BSD上的kqueue,Linux上的inotify

这是我写的一篇文章: Ruby for Admins:阅读成长文件 。 因此,结合事件子系统和轮询的程序如下所示:

 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 

如果你在Linux上…

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

除非你真的希望它出于某种原因成为Ruby脚本。

看看文件尾gem

穷人的快速做法:

  1. 这样做的Ruby脚本

     ARGF.each do |line| ... 
  2. 运行屏幕:

     tail -f file | ruby script 

研究@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/)