0

I want to read a log file using php but I only want to return the last lines of the file, meaning the most recent log. I am creating a browser tail for my log file using php and ajax.

So my approach will be something like:

  1. Write a log file, that appends line with a timestamp H:i:s
  2. Allow php to return lines with the timestamp equals to current timestamp of a get request.

Nevermind the logfile, I had it working with the timestamp, now the problem is reading the file starting from bottom to keep the script efficient by allowing to read only the newest lines instead of the whole file.

This answer: https://stackoverflow.com/a/3686287/1328014 would read the whole file and return all lines that match a string. This is similar to what I want but I don't want to read the whole file since I only want the recent.

<?php
date_default_timezone_set('Asia/Manila');

$date = new DateTime();
$timeNow = '01:30:46';

function parse($str) {
  preg_match("/(?P<time>\d{2}:\d{2}:\d{2}) (?P<status>\w*) (?P<message>[^:]*) : (?P<user>.*)/", $str, $re);
  return $re;
}

$matches = array();

$handle = @fopen("logs/log(".date('m-d-Y').").txt", "r");
if ($handle)
{
  while (!feof($handle))
  {
    $buffer = fgets($handle);
    if(strpos($buffer, $timeNow) !== FALSE)
      $matches[] = $buffer;
  }
  fclose($handle);
}

//show results:
print_r($matches);

That'll work, but it's reading the whole file, and will be really slow if the file is more than a gig already.

Community
  • 1
  • 1
Joey Hipolito
  • 3,108
  • 11
  • 44
  • 83

1 Answers1

1

Use the linux "tail" command to read from the bottom of the files. Use shell_exec PHP function to execute it and return the output.

$last = shell_exec('tail -n 10 ' . "logs/log(".date('m-d-Y').").txt");

This returns the last 10 lines from that file, as string. Read each line by exploding that string with "\n". They are still in order so to read in reverse order (last to 10th last) remember to loop from the end of the array to the start after exploding it. Change -n 10 to whatever max amount of lines you want to return.

Joey Hipolito
  • 3,108
  • 11
  • 44
  • 83
  • was it the only way? as much as possible I don't want to use shell_exec – Joey Hipolito Apr 16 '14 at 18:24
  • I don't know of another way where you won't have to process the whole file to get to the end. tail already does it well on the shell, why not use it? If no user input is passed into shell_exec I can't see a reason not to use it, other than portability. – LP Papillon Apr 16 '14 at 18:30