ウェブページへのアクセスログを記録する方法は、いろいろな方法があると思う。もっとも簡単なのは Apache などのウェブサーバが自動的に記録するログをチェックすることで、これには何の手間もいらない。しかし、レンタルサーバなどでログが自由に扱えない場合はどうしたらいいのだろう?
そのひとつが、
画像としてリンクされている Perl などの CGI を呼び出す方法だ。利用者に知られずこっそりとアクセスログを取るには 1x1 ピクセルの画像をそのウェブページの背景と共に表示してしまえば、そのウェブページのソースをチェックされない限り、ほとんどの場合は気づかれずにすむだろう。
そんなわけで、以下のように JavaScript と対応する Perl スクリプトで、アクセスログを記録する仕組みを作ってみた。ログの形式は Apache に準拠する(たぶん)。
サーバ側 CGI Perl 設定ファイル (xlog.conf)
# xlog.conf
our $LOG_PATH = '/path_to_log_file/temp'; # Specify the path to the location of the log
our $FILE_EXT = 'log'; # Specify the file extension
# このほかに、/path_to_log_file/lock を mkdir して、 chmod 777 しておく。
use strict;
use GD;
use CGI;
use URI;
use POSIX;
サーバ側 CGI Perl ファイル (xlog.cgi)
#!/usr/bin/perl
# xlog.cgi
#
# Access log system
# E-mail: support@twinkle.cc
# (c) Copyright 2005, 2006, twinkle.cc, All Rights Reserverd.
require 'xlog.conf';
my $cgi = new CGI;
##### Initialize
# my $r = $cgi->param('r') ? $cgi->param('r') : 0;
# my $g = $cgi->param('g') ? $cgi->param('g') : 0;
# my $b = $cgi->param('b') ? $cgi->param('b') : 0;
my $r = 0;
my $g = 0;
my $b = 0;
$ENV{REMOTE_ADDR} = $ENV{REMOTE_ADDR} ? $ENV{REMOTE_ADDR} : '-';
$ENV{REMOTE_IDENT} = $ENV{REMOTE_IDNET} ? $ENV{REMOTE_IDENT} : '-';
$ENV{REMOTE_USER} = $ENV{REMOTE_USER} ? $ENV{REMOTE_USER} : '-';
my $ref = $cgi->param('ref') ? $cgi->param('ref') : '-';
my $uri = $cgi->param('uri') ? new URI($cgi->param('uri'))->path : '-';
my $host = $cgi->param('uri') ? new URI($cgi->param('uri'))->host : 'unknown';
my $id = $cgi->param('id') ? $cgi->param('id') : 'unknown';
my $date = strftime("%d/%b/%Y:%H:%M:%S %z", localtime(time));
##### Write a record for a log
file_lock;
open(LOG, ">>$LOG_PATH/$host.$FILE_EXT") || die;
# ex: /path_to_the_file/yourserver.com.log
print LOG qq|$ENV{REMOTE_ADDR} $ENV{REMOTE_IDENT} $ENV{REMOTE_USER} [$date] "$ENV{REQUEST_METHOD} $uri $ENV{SERVER_PROTOCOL}" 200 - "$ref" "$ENV{HTTP_USER_AGENT}"\n|;
close(LOG);
file_unlock;
##### Show an image
my $image = new GD::Image(1,1); # Create a new image
my $background = $image->colorAllocate($r ,$g, $b);
$image->transparent($background); # Transparent the background color
# $image->interlaced('true'); # Interlaced
binmode STDOUT; # Make sure to write to binary stream
print "Content-type: image/png\n\n";# Print Content Header
print $image->png; # Output STDOUT by converting the image to PNG
##### Libs
sub file_lock {
my $wait = 5;
while (!symlink(".","$LOG_PATH/lock/.$LOG_EXT")) {
if (--$wait <= 0) {
# &error( '現在他の方が使用中です。',
# 'しばらくしてから再度ご利用ください。');
}
sleep (1);
}
}
sub file_unlock {
unlink ("$LOG_PATH/lock/.$LOG_EXT");
}
1;
サーバ側に置く JavaScript (xlog.js)
function tracker() {
document.write('<img src=https://yourserver.com/path_to_the_xlog.cgi/xlog.cgi?uri=' + document.URL + '&id=' + xlog_id + '&ref=' + document.referrer + ' width=1 height=1>');
}
アクセスログを残したい(トラッキングしたい)ウェブページ(の最後)に書く JavaScript(</body> タグの直前あたりに書くのがいいだろう。)
<SCRIPT Language="JavaScript">
<!--
document.write("<img src=\"https://yourserver.com/path_to/xlog.cgi?uri=");
document.write(document.URL);
document.write('&r=255'); // 背景が白 (R=255、G=255、B=255 の場合
document.write('&g=255');
document.write('&b=255');
document.write('&ref=');
document.write(document.referrer);
document.write("\" width=1 height=1>");
// -->
</SCRIPT>
トラックバック URL:
https://perltips.twinkle.cc/trackback/130
from PERL2javascript on 2007/12/20(木) 16:54
ワンピクセルの画像にアンカータグを付け、そこから環境変数の情報を取得するという方法らしい。
シリコンバレー在住のPerl Tipsさんのページより引用。
使用モジュールはSTRICT,CGIのほ...