アクセス解析CGI #00002 [プログラミング]
さて、バージョン0.002。
データファイルを1日1ファイルでやっていくことにしました。データファイル名は"ana********.dat"で********には年月日が入ります。
データの書式は前回と変わらず。
あとちょこちょこっと修正。
以下がCGIのソース。perlで書いてます。
ana.cgi - アクセス解析 ver.0.001
#!/usr/local/bin/perl $ver = "ver.0.002"; $query = $ENV{'QUERY_STRING'}; @query = split(/&/, $query); foreach (@query) { ($property, $value) = split(/=/, $_); $value =~ tr/+/ /; $value =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg; $value =~ s/\r\n//g; $value =~ s/\r//g; $value =~ s/\n//g; $value =~ s/<>/<>/g; $q{$property} = $value; } $ttl = $q{'TITLE'}; $url = $q{'URL'}; $ref = $q{'REFR'}; # 時刻取得 ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); $ymd = sprintf("%d%02d%02d", $year + 1900, $mon +1, $mday); # データファイル読み込み $t_dat = "ana${ymd}.dat"; $lfh = my_flock() or die 'Busy!'; $dirname = '.'; opendir(DIR, $dirname) or die; @files = readdir(DIR); closedir(DIR); $i = 0; $g = 0; while ($i < @files) { if ($t_dat eq $files[$i]) { $g = 1; last; } $i++; } if ($g == 1) { open(FILE, "./$t_dat") or die; @dat = <FILE>; close(FILE); } else { @dat = (); } # データ処理 $i = 0; $g = 0; while ($i < @dat) { ($durl, @dres) = split(/<>/, $dat[$i]); if ($durl eq $url) { $g = 1; last; } $i++; } if ($g == 1) { ($durl, $dcnt, @dres) = split(/<>/, $dat[$i]); $dcnt++; $dat[$i] = join('<>', ($durl, $dcnt, @dres)); } else { push(@dat, "$url<>1<>$ttl<>\n"); } # データファイル書き込み open(TFILE, ">./~$t_dat") or die; foreach (@dat) { print TFILE "$_"; } close(TFILE); rename ("./~$t_dat", "./$t_dat"); my_funlock($lfh); $prt = $#dat + 1; print "Content-type: text/javascript\n"; print "document.write(\'test"; print "$prt"; print "\')\;\n"; exit(0); # ファイルロック・アンロック # 参考:http://tech.bayashi.net/pdmemo/filelock.html sub my_flock { my %lfh = (dir => './lockdir/', basename => 'lockfile', timeout => 60, trytime => 10, @_); $lfh{path} = $lfh{dir} . $lfh{basename}; for (my $i = 0; $i < $lfh{trytime}; $i++, sleep 1) { return \%lfh if (rename($lfh{path}, $lfh{current} = $lfh{path} . time)); } opendir(LOCKDIR, $lfh{dir}); my @filelist = readdir(LOCKDIR); closedir(LOCKDIR); foreach (@filelist) { if (/^$lfh{basename}(\d+)/) { return \%lfh if (time - $1 > $lfh{timeout} and rename($lfh{dir} . $_, $lfh{current} = $lfh{path} . time)); last; } } undef; } sub my_funlock { rename($_[0]->{current}, $_[0]->{path}); }
いろいろと考えてみた結果、データは送られてきたものを単純に積み上げていくだけの方がよいのかもしれません。
で、データを表示するときに集計をする、と。
次からはその方向で行こうと思います。
コメント 0