-1

I am programming a web tail -f utility in PHP at the moment. I already finished the part which ajax-requests tail.php every x milliseconds to get the last added lines.
Now I am at the point where I somehow need to keep track of what the last printed line was. I thought about using ftell and saving it in a cookie, but since it can also happen that lines get cut in the beginning in the file, this is not always going to work.

Any ideas on how to do that? I would like to do it without a additional database, but by using a cookie/session and the size of the "pointer" data must though be small.

Please ask if you don't understand something, it's not that easy to describe ;-)

Zulakis
  • 7,859
  • 10
  • 42
  • 67
  • It's just a jquery ajax request `GET`'ing `tail.php?file=FILE&getlog`. No need to post that. – Zulakis Oct 06 '12 at 14:05
  • Some ideas here: http://serverfault.com/questions/355311/how-to-write-a-script-that-only-acts-on-new-log-entries – deizel. Oct 06 '12 at 14:07
  • @Zulakis: You should paste the PHP code what you've tried so far so that your question is more clear. Also you should make your question much more concrete. What is the exact problem you're running into with your implementation? Also how likely is it that you do not use `tail` at all in that php script? – hakre Oct 06 '12 at 14:09
  • How much access do you have on this server? Are we looking for a pure PHP solution here? Is Windows support required? – deizel. Oct 06 '12 at 14:18
  • deizel: Looking for a pure PHP solution, yes. hakre: No, I am going to use just the PHP file functions. Problem is that I don't know how to keep track at which point the last display line (with the last request) was. – Zulakis Oct 06 '12 at 14:22
  • well than make that your question. – hakre Oct 06 '12 at 14:56

2 Answers2

1

I didn't try this, but perhaps you can use a JS library such as Prototype to determine the length of the output, then compare it to the length of the last response and then act accordingly by cutting the string at the proper position.

Untested example:

var lastLength;
Ajax.Request('/tail.php', {
    onSuccess: function(data){
        /* this is our callback and data.responseText will contain the raw response from the server */
        var curLength=String(data.responseText).length;
        if(curLength>lastLength) {
            $('myDiv').insert(data.responseText.substr(lastLength)); // append the new part of the string to a DIV with id 'myDiv'  
            lastLength=curLength;
        }
    }
});

If that solution for some reason is not satisfactory or leads to issues, you could try to have tail.php send more than just raw data. Instead, JSON could be used to include the byte count along with the data.

Assuming that

$tailOutput

contains the latest output, using

echo json_encode(array(
    'tailOutput' => substr($tailOutput, $_REQUEST['tailLength']),
    'curLength'     => strlen($tailOutput)
));

to send the data back to the client, now including the last length information, and then adapting the JS code accordingly.

var lastLength;
Ajax.Request('/tail.php', {
    parameters: {
        tailLength: lastLength
    },
    onSuccess: function(data){
            var obj=data.responseText.evalJSON(); //convert to json object
            $('myDiv').insert(obj.tailOutput);
            lastLength=obj.curLength;
        }
    }
});
SquareCat
  • 5,699
  • 9
  • 41
  • 75
  • I only want to submit the new line(s), the checking should be done on server-side. This is necessary because it gets pulled atleast once a second and would cause way too much traffic. – Zulakis Oct 06 '12 at 14:17
  • @Zulakis: You would have not caused so much useless work for Cummander Checkov if you would have posted your (as you wrote trivial anyway) code with the question. This is a good example why it is good to actually post your own code even though you think it's just too easy. – hakre Oct 06 '12 at 14:43
  • No biggie. Adapting code so that it can be presented out of context can be too much effort compared to providing a rough description of the coding situation. – SquareCat Oct 06 '12 at 14:49
0

If you wish to do this purely in PHP, even though i wonder how - if you already have to have AJAX handling function on the client side anyway - you could simply use the session variable.

In PHP

$outputToClient=substr($tailOutput, ($_SESSION['lastTailLength']?$_SESSION['lastTailLength']:0));
$_SESSION['lastTailLength']=strlen($tailOutput);
echo $outputToClient;

Something like this should do the job. If you have problems with PHP not recognizing the session coming from the AJAX request (although these times are long gone and this problem should not occur) - try sending the PHPSESSID along with your ajax request everytime it is sent to the server.

SquareCat
  • 5,699
  • 9
  • 41
  • 75
  • Another way would be to maintain a constant connection to the server, during which you would respond back to the client everytime you notice that the total amount of lines (or content length) has changed/increased. – SquareCat Oct 06 '12 at 15:11