2012-05-24 64 views
1

我想建立一個PHP小惡魔,分析在Linux系統上的日誌文件時檢測在PHP中丟失的FileHandler。 (例如,遵循系統日誌)。聽日誌文件

我設法通過fopen打開文件,並連續閱讀stream_get_line。當受監控的文件被刪除並重新創建時(例如,在旋轉日誌時),我的問題就開始了。該程序然後不再讀取任何東西,即使該文件增長比以前更大。

對此有一個優雅的解決方案? stream_get_meta_data沒有幫助和命令行上使用tail -f顯示了同樣的問題。

編輯,添加示例代碼 我試圖代碼歸結到最低,說明我所期待的

<?php 
$break=FALSE; 
$handle = fopen('./testlog.txt', 'r'); 
do { 
    $line = stream_get_line($handle, 100, "\n"); 
    if(!empty($line)) { 
     // do something 
     echo $line; 
    } 
    while (feof($handle)) { 
     sleep (5); 
     $line = stream_get_line($handle, 100, "\n"); 
     if(!empty($line)) { 
     // do something 
     echo $line; 
     } 
     // a commented on php.net indicated it is possible 
     // with tcp streams to distinguish empty and lost 
     // does NOT work here --> need somefunction($handle) 
     if($line !== FALSE && $line ='') $break=TRUE; 
    } 
} while (!$break); 
fclose($handle); 
?> 
+0

請你怎麼做到這一點的代碼添加到您的問題,這樣的改進具體的建議可以進行。 – hakre

+0

@hakre我添加了一些代碼 – Martin

+0

你有與流回調試驗以及http://php.net/manual/en/function.stream-notification-callback.php?他們可能會給你一些提示。 – hakre

回答

2

當日志文件旋轉時,原來的文件被複制,然後刪除,將創建一個具有相同名稱的新文件。它可能與原始文件具有相同的名稱,但它具有不同的inode。 Inodes(簡稱下面的描述)就像您的文件的隱藏增量索引號。您可以更改文件的名稱或將其移動,但它需要inode。一旦原始日誌文件被刪除,就不能使用相同的文件處理程序重新打開具有相同名稱的文件,因爲inode已更改。您最好的選擇是檢測失敗,並嘗試打開新文件。

+0

謝謝Mrbinky,但基本上這是我的問題,我如何檢測文件已被刪除? stream_get_metadata不會改變,句柄仍然是一個流對象。 – Martin

+0

stream_meta_data()返回的數組是什麼?您應該能夠檢測到流等待讀取時是否超時。嘗試並將stream_set_timeout()的值縮短爲4秒。如果使用read()而不是stream_get_line(),stream_meta_data()可能只會檢測到超時。 – mrbinky3000

+0

超時的事情沒有奏效,但你使用read的指針確實讓我朝着正確的方向發展。據我所知,我可以檢測到fstat的變化。無論如何,解決方案是使用文件相關的功能,而不是依賴流功能。 – Martin