2009-06-27 31 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