アクセスログの記録 |
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> |