侦听日志文件时检测PHP中丢失的filehandler

侦听日志文件时检测PHP中丢失的filehandler,php,linux,logging,Php,Linux,Logging,我正在尝试用PHP构建一个小型demon,用于分析linux系统上的日志文件。(例如,遵循系统日志) 我已设法通过fopen打开该文件,并使用stream\u get\u line继续读取该文件。我的问题始于删除并重新创建受监视的文件(例如,在旋转日志时)。然后,程序不再读取任何内容,即使文件比以前更大 有没有优雅的解决方案stream\u get\u meta\u data没有帮助,在命令行上使用tail-f也会出现同样的问题 编辑,添加示例代码 我试图将代码浓缩到最低限度,以说明我在寻找什么

我正在尝试用PHP构建一个小型demon,用于分析linux系统上的日志文件。(例如,遵循系统日志)

我已设法通过
fopen
打开该文件,并使用
stream\u get\u line
继续读取该文件。我的问题始于删除并重新创建受监视的文件(例如,在旋转日志时)。然后,程序不再读取任何内容,即使文件比以前更大

有没有优雅的解决方案
stream\u get\u meta\u 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);
?>


旋转日志文件时,会复制原始文件,然后删除,并创建一个同名的新文件。它可能与原始文件具有相同的名称,但具有不同的inode。inode(以下是简化的描述)类似于文件的隐藏增量索引号。您可以更改文件名,也可以移动文件名,但它会使用inode。删除原始日志文件后,无法使用相同的文件处理程序重新打开具有相同名称的文件,因为inode已更改。您最好的选择是检测失败,并尝试打开新文件。

请将代码添加到问题中,以便提出具体的改进建议。@hakre我添加了一些代码您也尝试过流回调吗?他们可能会给你们一些提示。为了回答这个问题,这个问题现在似乎已经解决了:正如这条评论所暗示的,它对我不起作用。我想流函数可以非常高效地读取任何内容,而不必监视其他内容。谢谢Binky先生,但基本上这就是我的问题,如何检测文件已被删除?stream\u get\u元数据不会更改,句柄仍然是一个stream对象。stream\u meta\u data()返回的数组是什么?您应该能够在等待读取时检测流是否超时。尝试将stream_set_timeout()的值缩短为4秒左右。只有在使用诸如read()之类的内容而不是stream\u get\u line()时,stream\u meta\u data()才可能检测到超时。超时功能不起作用,但您指向使用read的指针确实让我找到了正确的方向。就我所见,我可以检测到fstat中的变化。无论如何,解决方案是使用与文件相关的函数,而不是依赖于流函数。