【问题标题】:Detect lost filehandler in PHP when listening to logfiles侦听日志文件时检测 PHP 中丢失的文件处理程序
【发布时间】:2012-05-31 06:55:18
【问题描述】:

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

我已经设法通过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);
?>

【问题讨论】:

  • 请将您如何执行此操作的代码添加到您的问题中,以便提出具体的改进建议。
  • @hakre 我添加了一些代码
  • 您是否也尝试过流回调php.net/manual/en/function.stream-notification-callback.php?他们可能会给你一些提示。
  • 只是回答这个问题,现在问题似乎解决了:它对我不起作用,就像这条评论 php.net/manual/en/… 建议的那样。我猜流函数非常有效地读取任何内容,但不监视其他内容。

标签: php linux logging


【解决方案1】:

当日志文件被轮换时,原始文件被复制,然后被删除,并创建一个同名的新文件。它可能与原始文件具有相同的名称,但具有不同的 inode。索引节点(下面是简化的描述)就像文件的隐藏增量索引号。您可以更改文件的名称,或移动它,但它需要 inode。删除原始日志文件后,您将无法使用相同的文件处理程序重新打开具有相同名称的文件,因为 inode 已更改。最好的办法是检测故障,然后尝试打开新文件。

【讨论】:

  • 谢谢 Mrbinky,但基本上这是我的问题,我如何检测文件已被删除? stream_get_metadata 没有变化,句柄还是一个流对象。
  • stream_meta_data() 返回的数组是什么?您应该能够检测到流在等待读取时是否超时。尝试将 stream_set_timeout() 的值缩短到 4 秒左右。如果您使用类似 read() 而不是 stream_get_line(),stream_meta_data() 可能只会检测到超时。
  • 超时事情不起作用,但你指向使用 read 的指针确实让我朝着正确的方向前进。据我所知,我可以检测到 fstat 的变化。无论如何,解决方法是使用文件相关的函数,而不是依赖流函数。
猜你喜欢
  • 1970-01-01
  • 2015-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
  • 2021-07-08
相关资源
最近更新 更多