Reputation: 179
I have written a very simple page counter and a logging script that increments a counter stored in a file and logs information about the client's operating system and which browser they use. It's a simple spare time project I've been working on, and as such it is extremely rudimentary, writing the counter and the logged information in a designated folder for each page on the site, in a new file for each day.
The thing is, I recently used blitz.io to test my site, and when I ran a "Rush" of 250 requests per second, the counters and the logs were completely flushed, except for the very last query.
I'm not perfectly sure what happened, but I suspect something along the lines of PHP not properly finishing up the previous query before taking on the next one.
I use file_get_contents()/file_put_contents() for the both of them, instead of file(). Would changing to file() solve the problem?
Here's the counter:
$filename = '.' . $_SERVER['PHP_SELF'];
$counterpath = '/Websites/inc/logs/counters/total/' . getCurrentFileName() . '-counter.txt';
$globalcounter = '/Websites/inc/logs/counters/total/global-counter.txt';
if (file_exists($counterpath)) {
$hit_count = file_get_contents($counterpath);
$hit_count++;
file_put_contents($counterpath,$hit_count);
}
else {
$hit_count = "1";
file_put_contents($counterpath, $hit_count);
}
And here's the logger:
$logdatefolder = '/Websites/inc/logs/ip/' . date('Y-m-d',$_SERVER['REQUEST_TIME_FLOAT']);
$logfile = $logdatefolder . "/" . getCurrentFileName() . '-iplog.html';
$ua = getbrowser();
if (false == (file_exists($logdatefolder))) {
mkdir($logdatefolder);
}
function checkRef() {
if (!isset($_SERVER['HTTP_REFERER'])) {
//If not isset -> set with dummy value
$_SERVER['HTTP_REFERER'] = 'N/A';
}
return $_SERVER['HTTP_REFERER'];
}
/* Main logger */
$logheader = "<!DOCTYPE html><html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en-US\"><head><title>" . getCurrentFileName() . " log</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head><body>";
$logentry = date("Y-m-d, H:i:s, O T") . ":" .
"<br />- Requesting: http://giphtbase.org" . $_SERVER['REQUEST_URI'] .
"<br />- Arriving from: " . checkRef() .
"<br />- Browser: " . $ua['browser'] .
"<br />- Full browser name: " . $ua['name'] .
"<br />- Operating system: " . $ua['platform'] .
"<br />- Full user agent: " . $ua['userAgent'] .
"<br />";
$logfooter = "<!-- Bottom --></body></html>";
if (file_exists($logfile)) {
$logPage = file_get_contents($logfile);
$logContents = str_replace("<!-- Bottom --></body></html>","",$logPage);
file_put_contents($logfile, $logContents . $logentry . $logfooter);
}
elseif (false == (file_exists($logfile))) {
file_put_contents($logfile, $logheader . $logentry . $logfooter);
}
Upvotes: 2
Views: 109
Reputation: 14237
You should use the FILE_APPEND
flag in your file_put_contents()
otherwise you will only ever see the last entry:
file_put_contents($logfile, $logContents . $logentry . $logfooter, FILE_APPEND);
As for the counter, it looks like the file is trying to be written to too many times by different threads, causing it to be inaccessible. You should either use a database, or create a file_lock, or create temporary files and run a cronjob to do the math.
Upvotes: 1