I am having a log file like this :
2013-04-08-03-17-52: Cleaning Up all data for restart operation
2013-04-08-03-18-02: Creating new instance of app before closing
2013-04-08-03-18-03: New instance created and running
2013-04-08-03-18-03: Application started
Currently, i am loading full log file every second to show it to the user using jquery ajax, As this being soo inefficient i am trying to figure out some way to load only the updated lines from log file.
Is their any way to get lines only after a particular time stamp 2013-04-08-03-18-03
, For this i will be managing a variable with last timestamp and will be updating it every time i get new lines.
I am kind of New to Php and know only the basics of reading and writing files.
You might want to check the file modification time first to see whether or not you need to reload the log file. You can use the filemtime
-function for that.
Furthermore, you can use the file_get_contents
-function using an offset to read the file from a certain point.
Edit: So, how does it work?
Suppose you have stored the last modification time in a session variable $_SESSION['log_lastmod']
and the most recent offset in $_SESSION['log_offset']
.
session_start();
// First, check if the variables exist. If not, create them so that the entire log is read.
if (!isset($_SESSION['log_lastmod']) && !isset($_SESSION['log_offset'])) {
$_SESSION['log_lastmod'] = 0;
$_SESSION['log_offset'] = 0;
}
if (filemtime('log.txt') > $_SESSION['log_lastmod']) {
// read file from offset
$newcontent = file_get_contents('log.txt', NULL, NULL, $_SESSION['log_offset']);
// set new offset (add newly read characters to last offset)
$_SESSION['log_offset'] += strlen($newcontent);
// set new lastmod-time
$_SESSION['log_lastmod'] = filemtime('log.txt');
// manipulate $newcontent here to what you want it to show
} else {
// put whatever should be returned to the client if there are no updates here
}
Try something like this:
<?php
session_start();
$lines = file(/*Insert logfile path here*/);
if(isset($_SESSION["last_date_stamp"])){
$new_lines = array();
foreach($lines as $line){
// If the date stamp is newer than the session variable, add it to $new_lines
}
$returnLines = array_reverse($newLines); // the reverse is to put the lines in the right order
} else {
$returnLines = $lines;
}
$_SESSION['last_date_stamp'] = /* Insert the most recent date stamp here */;
// return the $returnLines variable
?>
What this does is reads a file line by line and, if a session variable already exists, add all of the lines where the date stamp is newer than the one in the session variable to a return variable $returnLines
, if no session variable exists it will put all of the lines in the file in $returnLines
.
After this, it create.updates the session variable for use the next time the code is executed. Finally it returns the log file data by using the $returnLines
variable.
Hope this helps.
You can try
session_start();
if (! isset($_SESSION['log'])) {
$log = new stdClass();
$log->timestamp = "2013-04-08-03-18-03";
$log->position = 0;
$log->max = 2;
$_SESSION['log'] = &$log;
} else {
$log = &$_SESSION['log'];
}
$format = "Y-m-d-:g:i:s";
$filename = "log.txt";
// Get last date
$dateLast = DateTime::createFromFormat($format, $log->timestamp);
$fp = fopen($filename, "r");
fseek($fp, $log->position); // prevent loading all file to memory
$output = array();
$i = 0;
while ( $i < $log->max && ! feof($fp) ) {
$content = fgets($fp);
// Check if date is current
if (DateTime::createFromFormat($format, $log->timestamp) < $dateLast)
continue;
$log->position = ftell($fp); // save current position
$log->timestamp = strstr($content, ":", true); // save curren time;
$output[] = $content;
$i ++;
}
fclose($fp);
echo json_encode($output); // send to ajax