实时更新日志文件中的逐行读取

时间:2016-12-28 07:34:37

标签: php logging real-time

我有一个日志文件,我将数据写入php文件。这是代码:

$filename='/var/log/siawa/dashboard/iot.log';

$source_file = fopen( $filename, "r" ) or die("Couldn't open $filename");

while (!feof($source_file)) {
    $buffer = fgets($source_file, 4096);  // use a buffer of 4KB
    $buffer = str_replace($old,$new,$buffer);
    echo $buffer. "<br />" . "\n";
}

这是有效的,但是我希望在原始日志文件中写入后每隔10秒更新一次php日志数据。怎么做。

1 个答案:

答案 0 :(得分:2)

您需要在无限while(true)循环中读取文件内容。我将通过代码注释进行解释。

// read.php
<?php

// Last read position
$last = 0;

// Path to the updating log file
$file = 'log.txt';

while (true) {
    // PHP caches file information in order to provide faster
    // performance; In order to read the new filesize, we need
    // to flush this cache.
    clearstatcache(false, $file);

    // Get the current size of file
    $current = filesize($file);

    // Reseted the file?
    if ($current < $last) {
        $last = $current;
    }
    // If there's new content in the file
    elseif ($current > $last) {
        // Open the file in read mode
        $fp = fopen($file, 'r');

        // Set the file position indicator to the last position
        fseek($fp, $last);

        // While not reached the end of the file
        while (! feof($fp)) {
            // Read a line and print
            print fgets($fp);
        }

        // Store the current position of the file for the next pass
        $last = ftell($fp);

        // Close the file pointer
        fclose($fp);
    }
}

要测试此功能,请打开终端窗口并发出:

while true; do echo `date` >> log.txt; sleep 1; done

这会将当前日期时间字符串附加到文件中,每一秒。现在打开另一个终端并发出php read.php以查看是否正在实时读取该文件。它将输出如下内容:

Wed Dec 28 18:01:12 IRST 2016
Wed Dec 28 18:01:13 IRST 2016
Wed Dec 28 18:01:14 IRST 2016
Wed Dec 28 18:01:15 IRST 2016
Wed Dec 28 18:01:16 IRST 2016
Wed Dec 28 18:01:17 IRST 2016
Wed Dec 28 18:01:18 IRST 2016
# Keeps updating...

如果您倾向于通过HTTP提供此服务,则在打印读取缓冲区后,您需要添加ob_flush()调用:

// While not reached the end of the file
 while (! feof($fp)) {
     print fgets($fp) . '<br>';

     // Flush the output cache
     ob_flush();
 }