Reputation: 4267
I have a php
page that shows the server logs in a web interface. It is pretty simple. Basically there is an ajax call
inside a setinterval()
which hits a backend php file, which will read the log and echo it. The relevant code is:
setInterval(function()
{
$.get("log.php",{logId: $('#logId').val()}, function(data)
{
$("#logDetails").html(data);
//scroll to the bottom when updated...
$("#logDetails").stop().animate({scrollTop: $("#logDetails")[0].scrollHeight}, 800);
});
}, 2000);
As you can see, this just update a div with an id called logDetails
with content from the log file in the server.
The div has a style="overflow:scroll"
and the line $("#logDetails").stop().animate..
is to scroll to the bottom of the div when new content is added. All this works very well.
If a user has scrolled up the div and is examining the logs, and new content comes in then the div scrolls down. That is also fine. The problem is that the server log can have many hours of inactivity. During that time, when the user scrolls up, since setinterval is still working, he gets scrolled down even though new content is not available. This can become a real nuisance.
I wanted to handle this in the minimal way possible and I thought doing this might suffice:
$.get("log.php",{logId: $('#logId').val()}, function(data)
{
//new condition to check id new content has come
if($('#logDetails').val() != data)
{
//update div and scroll to the bottom..
}
...
However this is not working. I am aware of other ways like check the log modified time in server side etc, but I cannot modify any of those files due to other reasons.
So my question is - why does this not work? And how can I do this inside the interface file itself instead of resorting to other means?
The PHP code that pushes out the log is:
$contents = "";
$handle = @fopen($logFile, 'r');
if($handle)
{
while(($line = fgets($handle)) !== false)
{
//highlight errors
$txt = "Execution stopped because of error";
if(strstr($line,$txt))
{
$line = "<span style='color:red'>".$line."</span>";
}
$contents .= $line;
}
}
@fclose($handle);
echo nl2br($contents);
Upvotes: 0
Views: 83
Reputation: 5803
You could try this to make sure you are only ever getting new data back. Obviously I don't know anything about your system so this would have to be modified to work with the data you have:
$contents = "";
$handle = @fopen($logFile, 'r');
$lastHash = !empty($_GET['last_hash']) ? $_GET['last_hash'] : nulll
if($handle)
{
$stale = true;
while(($line = fgets($handle)) !== false)
{
//highlight errors
$txt = "Execution stopped because of error";
if(strstr($line,$txt))
{
$line = "<span style='color:red'>".$line."</span>";
}
if (empty($lastHash) || md5($line) == $lastHash) {
// this is the last stale line
$stale = false;
}
if (!$stale) {
$contents .= $line;
$lastHash = md5($line);
}
}
}
@fclose($handle);
echo json_encode(array('log_data' => nl2br($contents), 'last_hash'=> $lastHash));
and in javascript:
var lastHash = null;
setInterval(function()
{
$.getJSON("log.php",{logId: $('#logId').val(), last_hash : lastHash}, function(data)
{
lastHash = data.last_hash
if (data.log_data && data.log_data.length) {
$("#logDetails").html(data.log_data);
//scroll to the bottom when updated...
$("#logDetails").stop().animate({scrollTop: $("#logDetails")[0].scrollHeight}, 800);});
}
}, 2000);
Upvotes: 0
Reputation: 12826
It would be difficult to exactly pinpoint what is wrong since you mentioned the data coming from the log will by dynamic. However you can figure it out by:
console.log
of $('#logDetails').val()
and data
kDiff
to find out what their differences are.Once you find the differences, then you can think about ways to solve it.
Hope that helps!
Upvotes: 1
Reputation: 2915
.val()
is unlikely to work, but since you haven't provided the contents of the html you're trying to work with, we can only offer suggestions. try either $('#logDetails').text()
as mentioned in djidi's comment or $('#logDetails').html()
.
Upvotes: 0