2009-06-27 67 views
4

我想用ruby做日志文件解析器,这个解析器应该在日志文件增长时解析日志文件。它应该逐行解析直到结束,然后等待(以某种方式?)更多的行来,所以我的问题是如何最好地处理它增长?解析日益增长的日志文件

编辑: 即使我的日志文件在Windows上(目前),也希望采用可移植的方式进行此操作。

回答

1

对于Windows,您可以使用Directory Change Notifications。您告诉Windows(使用FindFirstChangeNotification)来监视目录c:/ foo/logs,然后Windows在该目录中发生事件时更新您的句柄。此时,您会检查是否有更改涉及您关心的文件。

Ruby绑定了Win32 API,并且有an example获取这些通知。

0

有一个很好的脚本发布在http://www.biterscripting.com/SS_WebLogParser.html。它是为Web服务器日志编写的示例脚本,但可用作编写任何类型日志的自己的日志解析器的起点。要以连续的方式使用它,当日志文件不断增长时,这里是一个脚本。

# Script LogParser.txt 
# Go in a continuous loop, sleeping 1 hr each time. 
while (true) 
do 
    # The number of lines in the log file the last time we checked is in following 
    # variable. Initially, it will be 0. 
    var int lines_old 

    # Read the log file into a str variable. 
    var str log ; cat "file.log" > $log 

    # Get the number of lines found this time. 
    var str lines_new ; set $lines_new = { len -e $log } 

    # Strip off the first $lines lines. 
    lex -e (makestr(int($lines))+"]") $log > null 

    # The new lines are now available in $log. Process them with something similar to 
    # SS_WebLogParser script. 

    # Update $lines_old, then, sleep. 
    set $lines_old = $lines_new 
    sleep 3600         # 3600 seconds = 1 hour 
done 

尝试,

  1. 保存这个脚本到,比方说,C:\ LogParser.txt(因为你是在 窗口)。
  2. 下载biterscripting。谷歌它。
  3. 通过输入以下命令来调用我们的脚本。

    脚本“\ LogParser.txt”

如果你需要使用他们的任何示例脚本,用下面的命令来安装。

script "http://www.biterscripting.com/Download/SS_AllSamples.txt" 

帕特里克

0

对于这个任务,你可以使用IO.popen工作再上一个命令行的成长结果的管道的文件流。然后在while循环中使用readline函数。 这里是用“亚行logcat”命令,获取实时成长日志Android设备的一个例子:

#! /usr/bin/env ruby 

IO.popen("adb logcat") do |io| 
    while line = io.readline 
     line.strip! 

     # Process here 
     print "#{line}\n" 
    end 
end 

编辑

对于一个文件,它是一个有点不同。我会在文件流的轮询中“readline”。

#! /usr/bin/env ruby 

File.open("test.log") do |io| 
    loop do 
     begin 
      line = io.readline 
      line.strip! 
     rescue 
      sleep 0.2 
      retry 
     end 

     # Process here 
     print "#{line}\n" 
    end 
end