我是根据下面的PHP代码捕获网页查看器日志的…
$viewerlog = "../SiteLogFiles/live-smoothstreaming-" . date('Ymd') . ".txt";
$fp = fopen($viewerlog,"a");
if ($fp) {
fputs($fp,"-----------------------------------------------------------------------rn");
fputs($fp,"Server Date: $nowrn");
fputs($fp,"IP Address: $iprn");
fputs($fp,"City: $cityrn");
fputs($fp,"State: $statern");
fputs($fp,"Country Name: $countrynamern");
fputs($fp,"Continent: $continentrn");
fputs($fp,"-----------------------------------------------------------------------rn");
fclose($fp);
}
它产生了一个像这样的日志…
-----------------------------------------------------------------------
Server Date: 2013-01-06T05:32:06-06:00
IP Address: 157.55.32.61
City: Unknown
State: Unknown
Country Name: United States
Continent: North America
-----------------------------------------------------------------------
-----------------------------------------------------------------------
Server Date: 2013-01-06T06:02:40-06:00
IP Address: 157.55.32.187
City: Unknown
State: Unknown
Country Name: United States
Continent: North America
-----------------------------------------------------------------------
但是每隔一段时间,日志就会被损坏,看起来像这样…
-----------------------------------------------------------------------
Server Date: 2012-12-21T18:27:27-06:00
IP Address: 99.54.103.128
City: Columbus
State: Ohio
Country Name: United States
Continent: North America
-----------------------------------------------------------------------
-----------------------------------------------------------------------
Server Date: 2012-12-21T18:27:53-06:00
IP Address: 75.97.98.115
City: Palmerton
State: Pennsylvania
--------------------------------------Continent: North America
Server Date: 2012-12-21T18:27:54-06:00
---------------------
IP Address: 70.76.36.232
City: Saskatoon
State: Saskatchewan
Country Name: Canada
Continent: North America
-----------------------------------------------------------------------
-----------------------------------------------------------------------
Server Date: 2012-12-21T18:28:04-06:00
IP Address: 173.17.240.190
City: Springfield
State: Missouri
Country Name: United States
Continent: North America
-----------------------------------------------------------------------
可能值得注意的是,我正在使用使用http://www.easyjquery.com从IP地址获取位置信息。
因此,许多人建议使用SQL数据库进行日志记录,而不是使用纯文本日志。有了这些建议,我就可以建立SQL数据库了。我能够在1秒内写7条记录(和我按F5一样快),没有任何问题。使用的PHP代码如下…
try {
$dbh = new PDO("sqlsrv:Server=localhost;Database=ViewerLogs", "", "");
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->query("INSERT INTO dbo.LiveSmoothStreaming (DateTime, Ip, City, State, Country, Continent) VALUES('$now', '$ip', '$city', '$state', '$countryname', '$continent')");
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$dbh = null;
}
catch(PDOException $e) {
echo $e->getMessage();
}
但是有一个问题。我的平面文本日志似乎比SQL日志捕获了更多的记录。
平面文本日志正在生成…
Tue 5:58pm 68.55.34.32 Laurel Maryland United States North America
Tue 5:58pm 70.88.57.62 Port Charlotte Florida United States North America
Tue 5:59pm 98.19.198.54 Eastview Kentucky United States North America
Tue 5:59pm 71.3.202.110 Cape Coral Florida United States North America
Tue 5:59pm 173.218.32.154 Branson Missouri United States North America
Tue 5:59pm 184.38.238.64 Unknown Unknown United States North America
Tue 5:59pm 67.239.18.161 Naples Florida United States North America
SQL日志正在生成…
2013-02-05T17:58:45-06:00 68.55.34.32 Laurel Maryland United States North America
2013-02-05T17:58:52-06:00 70.88.57.62 Port Charlotte Florida United States North America
2013-02-05T17:59:06-06:00 71.3.202.110 Cape Coral Florida United States North America
2013-02-05T17:59:23-06:00 67.239.18.161 Naples Florida United States North America
你可以看到,在短短几分钟内,有不同。在几个小时的过程中,差异可能会有数百个。
在这个特殊的平面文本日志中没有损坏,所以我不知道它怎么可能是错的。这将指向SQL日志的一个问题。我在我的PHP错误日志中查找可能的问题,没有看到任何明显的问题(我只是搜索有问题的页面并查看这些错误)。
有什么想法为什么SQL不会捕获记录,平面文本日志是?在我的代码中,SQL日志直接出现在平面文本日志之后(也许将SQL放在平面文本之前会产生相反的结果?)。
据我所知,您可以使用文件锁定或syslog。既然你似乎想让你的应用程序编写不间断的文本块,我认为锁定是可取的。
$lockwait = 2; // seconds to wait for lock
$waittime = 250000; // microseconds to wait between lock attempts
// 2s / 250000us = 8 attempts.
$myfile = '/path/to/file.log';
if( $fh = fopen($myfile, 'a') ) {
$waitsum = 0;
// attempt to get exclusive, non-blocking lock
$locked = flock($fh, LOCK_EX | LOCK_NB);
while( !$locked && ($waitsum <= $lockwait) ) {
$waitsum += $waittime/1000000; // microseconds to seconds
usleep($waittime);
$locked = flock($fh, LOCK_EX | LOCK_NB);
}
if( !$locked ) {
echo "Could not lock $myfile for write within $lockwait seconds.";
} else {
// write out your data here
flock($fh, LOCK_UN); // ALWAYS unlock
}
fclose($fh); // ALWAYS close your file handle
} else {
echo "Could not open $myfile";
exit 1;
}
你也可以使用这个稍微复杂一点的算法来做一个随机的"后退"等待,类似于TCP和CSMA/CD使用来避免拥塞。
$max_wait = 1000000; // 1 s
$min_interval = 10000; // 10 ms
$max_interval = 50000; // 50 ms
$cur_wait = $min_interval;
$tot_wait = 0;
$locked = flock($fh, LOCK_EX | LOCK_NB);
while( !$locked && ($tot_wait <= $max_wait) ) {
tot_wait += $cur_wait;
usleep($cur_wait);
cur_wait += rand($min_interval, $max_interval);
$locked = flock($fh, LOCK_EX | LOCK_NB);
}
if( !$locked ) {
echo "Could not lock $myfile for write within $lockwait seconds.";
} else {
// write out your data here
flock($fh, LOCK_UN);
}
fclose($fh);
如果无法获得锁,脚本将在两次锁尝试之间等待越来越长的时间,直到超过$max_wait
中定义的时间。
在写完所有这些之后,我认为你可能只是想考虑将所有这些插入到数据库中,如果你需要一个日志文件,那么每天运行一次cron作业,一次将文件写出来,并可选择清空表。