SSブログ

アクセス解析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/<>/&lt;&gt;/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});
}


いろいろと考えてみた結果、データは送られてきたものを単純に積み上げていくだけの方がよいのかもしれません。
で、データを表示するときに集計をする、と。
次からはその方向で行こうと思います。


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。