| アクセスログの記録 |
http://your_server/cgi-bin/log.cgi?URL=/path/some.html |
のような形式です。URLパラメタの指定をせずに
http://your_server/cgi-bin/log.cgi |
とすると http://your_server/ に接続するようにします。
もし、あなたのホームページを表示したときにログを採りたい場合は、ホームページに次のようなものを使うこともできます(JavaScript
の onLoad を使っています)。この例では、log.cgiを起動したあとにホームページ(/)に移動します。
<HTML>
<HEAD>
<TITLE>アクセスログの採取サンプル</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
function goURL(path)
{
url = "/cgi-bin/log.cgi?URL=" + path;
document.location.href = url;
}
//-->
</SCRIPT>
</HEAD>
<BODY onLoad=goURL('/')>
</BODY>
</HTML>
|
アクセスログは次のようなフォーマットでファイルに記録します。
the.remote.host 123.456.789 [Wed Feb 10 16:15:31 1999] "Mozilla/4.5 [ja] (Win95; I)" /index.html
クッキーを使い、ある一定時間内のアクセスは記録しないことにします。
さらに、集計表示をしてみます。
#!/usr/bin/perl
#
# log.cgi
#
# (C)1999 Kaoru Fujita
#
use lib './lib';
require 'util.pl';
#
# 定数
#
$Title = 'アクセスログ サンプル プログラム';
# CGI の仮想パス
$CGIPath = '/cgi-bin';
# プログラム名
use File::Basename;
$Program = basename($0);
# 漢字コード
$CharSet = 'Shift_JIS';
# ログファイル名
$File = './tmp/access.log';
# 古いログファイル名
$OldFile = './tmp/OLDaccess.log';
# フォーマット
#REMOTE_HOST REMOTE_ADDR [Date] HTTP_USER_AGENT
# 棒グラフの色
$BarColor = "#0000F0";
$MaxNumColor = "#F00000";
# ログの行数の最大値 1000行で20Kbytesくらい
$MaxLine = 1000;
#
$Expiration = '1MINUTES';
#
@Field = qw(リモートホスト リモートIPアドレス
時間帯 ブラウザコード名 ブラウザバージョン Webページ);
#
# メインプログラム
#
(*data) = parseInput();
# テスト
#$data{'Action'} = 'Stats';
#$data{'Target'} = 2;
$MaxLine = 300;
$act = $data{'Action'};
if ($act eq 'Stats') {
viewStats($data{'Target'});
}
else {
logLog();
}
exit(0);
#
# サブルーチン
#
sub logLog
{
$date = localtime();
if ($data{'URL'}) {
$url = $data{'URL'};
}
else {
#
# PWS で http://the.web.server/cgi-bin/log.cgi
# のように呼び出されると PATH_INFO には /cgi-bin/log.cgi
# が設定されてしまい、プログラムがループしてしまう
# のでそれを回避する。
if ($ENV{'PATH_INFO'} =~ /$CGIPath\/$Program/) {
$url = '/';
}
else {
($url) = ($ENV{'PATH_INFO'} =~ (/^(\/.+)/));
}
}
local(%cookies);
if ($ENV{'HTTP_COOKIE'}) {
(*cookies) = &getCookie();
$cookies{'count'}++;
$cookie = &setCookie(*cookies);
openURL($url, $cookie);
return;
}
else {
# 初回のアクセスでは 0 を設定する。
$cookies{'count'} = 0;
$cookies{'expires'} = &getDate.qq( \+ $Expiration);
$cookie = setCookie(*cookies);
}
if (-e $File) {
openLock(LOG, "+>>$File")
or exitError("ファイル $File がオープンできません。");
}
else {
openLock(LOG, ">$File")
or exitError("ファイル $File が作成できません。");
}
my(@lines) = <LOG>;
if (@lines > $MaxLine) {
if (! openLock(OLDLOG, ">$OldFile")) {
closeUnlock(LOG, $File);
exitError("古いログファイル $OldFile がオープンできません。");
}
print OLDLOG join(/\n/, @lines);
closeUnlock(OLDLOG, $OldFile);
truncate(LOG, 0); # ファイルサイズを0に
}
seek(LOG, 0, 2); # ファイルの最後に移動
print LOG $ENV{'REMOTE_HOST'}, ' ', $ENV{'REMOTE_ADDR'}, ' [',
$date, '] "', $ENV{'HTTP_USER_AGENT'}, '" ', $url, "\n";
closeUnlock(LOG, $File);
openURL($url, $cookie);
}
sub openURL
{
my($url, $cookie) = @_;
print <<END_OF_HTML;
Content-type: text/html
$cookie
<HTML>
<HEAD>
<TITLE>$Title</TITLE>
<SCRIPT language="JavaScript">
<!--
function viewURL(url)
{
document.location.href = url;
}
//-->
</SCRIPT>
</HEAD>
<!--BODY onLoad="JavaScript:document.location.href='$url'"-->
<BODY onLoad="viewURL('$url')">
</BODY>
</HTML>
END_OF_HTML
}
sub viewStats
{
my($key) = @_;
openLock(LOG, "<$File")
or exitError("ファイル $File がオープンできません。");
while (<LOG>) {
# localhost 127.0.0.1 [Thu Feb 11 02:04:57 1999] "Mozilla/4.5 [ja] (Win95; I)" /
# 127.0.0.1 127.0.0.1 [Thu Feb 11 06:53:10 1999] "Mozilla/2.0 (compatible; MSIE 3.01; Windows 95)" /
@line = (/^(.+?)\s+(.+?)\s+\[\w+\s\w+\s\d+\s(\d\d):\d\d:\d\d\s\d+]\s+"(.+?)\s*\((.+)\)"+(.+)/);
$target = @line[$key];
$log{$target}++;
}
closeUnlock(LOG, $File);
print qq(Content-type: text/html\n\n);
print qq(<HTML>\n);
print qq(<HEAD>\n);
print qq(<META HTTP-EQUIV="Content-Type" CONTENT="text/html\; charset=$CharSet">);
print qq(<TITLE>$Title</TITLE>\n);
print qq(<BODY>\n);
print qq(<TABLE border="0" cellspacing="0">\n);
print qq(<TR><TD>$Field[$key]</TD><TD>回数</TD><TD>(割合 %)</TD>);
my($max, $maxkey, $increase, $amount);
foreach (keys %log) {
$max = $log{$_}, $maxkey = $_ if ($max < $log{$_});
$amount += $log{$_};
}
$increase = $max / 50;
foreach (sort keys %log) {
my($val) = $log{$_};
my($rate) = sprintf("%.3f", ($val/$amount)*100);
print qq(<TR>\n);
print qq(<TD>$_</TD>\n);
if ($_ eq $maxkey) {
print qq(<TD align="right" bgcolor="$MaxNumColor">$val</TD>\n);
print qq(<TD align="right" bgcolor="$MaxNumColor">($rate)</TD>\n);
}
else {
print qq(<TD align="right">$val</TD>\n);
print qq(<TD align="right">($rate)</TD>\n);
}
for ($i=0; $i < $val/$increase; $i++) {
print qq(<TD BGCOLOR="$BarColor"> </TD>);
}
print qq(\n</TR>\n);
}
print qq(<TR><TD align="right">合計</TD><TD align="right">$amount</TD><TD></TD>);
print "</TABLE>\n";
print "</BODY>\n";
print "</HTML>\n";
}
#
# <IN> なし
# <OUT> 日時(String)
#
sub getDate
{
@Mon = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
@Wday = qw(Sun Mon Tue Wed Thu Fri Sat);
my($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime(time);
$wday = $Wday[$wday];
$mon = $Mon[$mon];
return qq($wday, $mday-$mon-$year $hour:$min:$sec GMT);
}
#--End of log.cgi
|
<HTML> <HEAD> <TITLE>アクセスログ</TITLE> </HEAD> <BODY> <B>ログの採取</B><BR> <A HREF="/cgi-bin/log.cgi">http://localhost/ でログを採ります。</A> <P> <HR noshade> <P> <B>ログの集計表示</B><BR> 集計条件を選んでください。 <FORM action="/cgi-bin/log.cgi"> <INPUT type="hidden" name="Action" value="Stats"> <SELECT name="Target"> <OPTION value="0" selected>リモートホスト <OPTION value="1" selected>リモートIPアドレス <OPTION value="2">時間帯 <OPTION value="3">ブラウザコード名 <OPTION value="4">ブラウザバージョン <OPTION value="5">Webページ </SELECT> <INPUT type="submit" value="集計"> </FORM> </BODY> </HTML> |