2012-05-24 63 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