#!/usr/local/bin/perl
###================================================================###
## ##
$scriptname = "かぞえまShow!"; #
$version = "Ver.1.00"; #
# create by セイヤ #
# E-mail: osada@tk.xaxon.ne.jp #
# HP: http://stnight.pekori.to #
## ##
###================================================================###
##==========##
# 特徴 #
##==========##
#
# カウンタの解析を行います。
# ・今日、昨日の一覧
# ・今日、昨日の時間別アクセス数
# ・今日、昨日のOS、ブラウザ名、リモートホスト別の集計
# ・最近数日間の日付別アクセス数
# ・設置してからの月別アクセス数
##==========##
# 設置例 #
##==========##
#
####([ ] 内の数字はパーミッションです)
#
# pulic_html /
# |
# +-- index.html トップページ
# |
# +-- cgi-bin / CGI 設置ディレクトリ
# |
# +-- counter / カウンタ 設置ディレクトリ [777]
# |
# +-- kzshow.cgi プログラム本体 [755]
# +-- anashow.cgi 解析プログラム本体 [755]
# +-- kzshow.txt ログファイル [666]
# +-- day.txt 日付別のデータファイル [666]
# +-- month.txt 月別のデータファイル [666]
# +-- error.txt エラーメッセージファイル [666]
##==========##
# 設定 #
##==========##
$t_title = "かいせき"; # タイトル名
$t_color = "#000000"; # タイトル文字の色
$t_size = "4"; # タイトル文字の大きさ
# タイトル画像を使う場合
$t_gif = ""; # ファイル名(使わない時は "" とする)
$t_wid = ''; # 画像の横サイズ
$t_hgt = ''; # 画像の縦サイズ
$script = "anashow.cgi"; # このスクリプトのファイル名
$datadir = "."; # データファイルを置くディレクトリ
$logfile = "kzshow.txt"; # ログファイル
$dayfile = "day.txt"; # 日付別のデータファイル
$monthfile = "month.txt"; # 月別のデータファイル
$home = "../"; # 戻り先 (絶対パスなら http://から)
$top = "1"; # $home に戻る時の target="_top" の指定
# --> 0 : 指定しない
# --> 1 : 指定する
$graphfile = "./graph.gif"; # グラフのための画像ファイル
# (絶対パスなら http://から)
# 色、背景画像の指定
$bground = ""; # 背景画像(使わない時は "" とする)
$bgcolor = "#f9fff9"; # 背景色
$text = "#000000"; # 文字色
$link = "#0000ff"; # リンク色(未訪問)
$vlink = "#ff0000"; # リンク色(既訪問)
$alink = "#00ff00"; # リンク色(訪問中)
$tblhead = "#ccffcc"; # 表の見出しの背景色
##==========##
# 設定完了 #
##==========##
# 曜日表示の設定
@week = ('日','月','火','水','木','金','土');
# データファイルのパスつきファイル名
$logfile = "$datadir/$logfile";
$dayfile = "$datadir/$dayfile";
$monthfile = "$datadir/$monthfile";
##==========##
# メイン処理 #
##==========##
# 引数を解釈
$mode = $ENV{'QUERY_STRING'};
if ($mode eq 'listtoday') {
local(@data) = &ReadData(1);
&List(@data);
}
elsif ($mode eq 'listyesterday') {
local(@data) = &ReadData(0);
&List(@data);
}
elsif ($mode eq 'anaaccess') {
@todayData = &ReadData(1);
@yesterdayData = &ReadData(0);
@dayData = &ReadDayData;
@monthData = &ReadMonthData;
&AnaAccess;
}
elsif ($mode eq 'anatoday') {
local(@data) = &ReadData(1);
&Analyze(@data);
}
elsif ($mode eq 'anayesterday') {
local(@data) = &ReadData(0);
&Analyze(@data);
}
else {
&Menu;
}
exit;
### メニュー
sub Menu {
&Header; # ヘッダを表示
print "
\n";
&Title; # タイトルを表示
print "
\n";
print "\n";
print "
\n";
print "\n";
print " メニュー | \n";
print "
\n";
print "\n";
print " 今日のアクセス内容 | \n";
print " 昨日のアクセス内容 | \n";
print "
\n";
print "\n";
print " 今日のアクセス一覧 | \n";
print " 昨日のアクセス一覧 | \n";
print "
\n";
print "\n";
print " アクセス数の推移 | \n";
print "
\n";
print "
\n";
print "
\n";
&ReturnHome; # ホームに戻るを表示
print "
\n";
&Footer; # フッタを表示
}
### リスト表示をする
sub List {
local($count, $time, $agent, $host, $ref) = split(/\t/, $_[0]);
local($sec, $min, $hour, $mday, $month, $year, $wday) = localtime($time);
local($date) = &GetDate($_[0]);
local($num) = $#_ + 1;
&Header; # ヘッダを表示
print "
\n";
&Title; # タイトルを表示
print "$date
\n";
print "アクセス数:$num
\n";
&ReturnMenu;
print "
\n";
&ViewList(@_);
print "
\n";
&Footer; # フッタを表示
}
## データの中身を表示
sub ViewList {
local($count, $time, $agent, $host, $ref) = "";
local($sec, $min, $hour, $mday, $month, $year, $wday) = "";
local($date) = "";
$ENV{'TZ'} = "JST-9";
local($ii) = 0;
print "\n";
print "
\n";
print "\n";
print " 時刻 | \n";
print " 番号 | \n";
print " リモートホスト | \n";
print " ブラウザ、OS | \n";
print " リファレンス | \n";
print "
\n";
for ($ii = 0; $ii <= $#_; $ii++) {
$data[$ii] =~ s/\r\n//g;
$data[$ii] =~ s/\r//g;
$data[$ii] =~ s/\n//g;
($count, $time, $agent, $host, $ref) = split(/\t/, $_[$ii]);
($sec, $min, $hour) = localtime($time);
$date = sprintf("%02d:%02d:%02d", $hour, $min, $sec);
if (!$agent) {
$agent = "
";
}
if (!$host) {
$host = "
";
}
if (!$ref) {
$ref = "
";
}
print "\n";
print " $date | \n";
print " $count | \n";
print " $host | \n";
print " $agent | \n";
print " $ref | \n";
print "
\n";
}
print "
\n";
print "
\n";
}
### アクセス数の解析
sub AnaAccess {
&Header; # ヘッダを表示
print "
\n";
&Title; # タイトルを表示
&ReturnMenu;
print "
\n";
print "時間別表\示
\n";
&ViewTime;
print "
\n
\n
\n";
print "日付別表\示
\n";
&ViewDay;
print "
\n
\n
\n";
print "月別表\示
\n";
&ViewMonth;
print "
\n";
&Footer; # フッタを表示
}
### 時間別表示
sub ViewTime {
local(@todayTimeData) = &MakeTimeData(@todayData);
local(@yesterdayTimeData) = &MakeTimeData(@yesterdayData);
local($todayDate) = &GetDate($todayData[0]);
local($yesterdayDate) = &GetDate($yesterdayData[0]);
local($max) = 0;
local($ii) = 0;
for ($ii = 0; $ii < 24; $ii++) {
if ($max < $todayTimeData[$ii]) {
$max = $todayTimeData[$ii];
}
if ($max < $yesterdayTimeData[$ii]) {
$max = $yesterdayTimeData[$ii];
}
}
print "\n";
print "
\n";
print "\n";
print " \n";
&ViewTimeOneDay(@yesterdayTimeData, $yesterdayDate, $max);
print " | \n";
print " \n";
&ViewTimeOneDay(@todayTimeData, $todayDate, $max);
print " | \n";
print "
\n";
print "
\n";
print "
\n";
}
## 1日分を表示
sub ViewTimeOneDay {
local($total) = 0;
print " \n";
print " \n";
print " $_[24] | \n";
print "
\n";
print " \n";
print " 時刻 | \n";
print " アクセス数 | \n";
print " グラフ | \n";
print "
\n";
for (local($ii) = 0; $ii < 24; $ii++) {
print " \n";
print " $ii | \n";
&ViewCountAndGraph($_[$ii], $_[25]);
$total += $_[$ii];
print "
\n";
}
print " \n";
print " 計 | \n";
print " $total | \n";
print "
| \n";
print "
\n";
print "
\n";
}
## アクセス数とグラフ部分を表示
sub ViewCountAndGraph {
local($length) = 0;
if ($_[0]) {
print " $_[0] | \n";
}
else {
print "
| \n";
}
# 最大値が 0 のときは長さ0
if ($_[1] == 0) {
$length = 0;
}
else {
$length = int($_[0] * 100 / $_[1]);
}
if ($length) {
print " | \n";
}
else {
print "
| \n";
}
}
## 時間ごとのデータ作成
sub MakeTimeData {
local(@timeData) = ();
local($count, $time, $agent, $host, $ref, $sec, $min, $hour) = "";
for (local($jj) = 0; $jj < 24; $jj++) {
$timeData[$jj] = 0;
}
for (local($ii) = 0; $ii <= $#_; $ii++) {
($count, $time, $agent, $host, $ref) = split(/\t/, $_[$ii]);
($sec, $min, $hour) = localtime($time);
$timeData[$hour]++;
}
return @timeData;
}
## ログ1行から日付を取得
sub GetDate {
local($count, $time, $agent, $host, $ref) = split(/\t/, $_[0]);
local($sec, $min, $hour, $mday, $month, $year, $wday) = localtime($time);
local($date) = sprintf("%d年%d月%d日(%s)", $year + 1900, $month + 1, $mday, $week[$wday]);
return $date;
}
## ログ1行から日付を取得
sub GetDate2 {
local($count, $time, $agent, $host, $ref) = split(/\t/, $_[0]);
local($sec, $min, $hour, $mday, $month, $year, $wday) = localtime($time);
local($date) = sprintf("%02d/%02d(%s)", $month + 1, $mday, $week[$wday]);
return $date;
}
## 日付別表示
sub ViewDay {
local($ii) = 0;
local($max) = 0;
local($year, $month, $day) = 0;
local(@count) = ();
local(@date) = ();
@dayData = reverse(@dayData);
for ($ii = 0; $ii <= $#dayData; $ii++) {
$dayData[$ii] =~ s/\r\n//g;
$dayData[$ii] =~ s/\r//g;
$dayData[$ii] =~ s/\n//g;
($year, $month, $day, $count[$ii]) = split(/\t/, $dayData[$ii]);
# 日付部分を作成
$date[$ii] = sprintf("%02d/%02d(%s)", $month, $day, $week[&Zeller($year, $month, $day)]);
# 最大値を求める
if ($max < $count[$ii]) {
$max = $count[$ii];
}
}
# 今日の分を追加
$date[$ii] = &GetDate2($todayData[0]);
$count[$ii] = $#todayData + 1;
if ($max < $count[$ii]) {
$max = $count[$ii];
}
print "\n";
print "
\n";
print "\n";
print " 日付 | \n";
print " アクセス数 | \n";
print " グラフ | \n";
print "
\n";
for ($ii = 0; $ii <= $#count; $ii++) {
print "\n";
print " $date[$ii] | \n";
&ViewCountAndGraph($count[$ii], $max);
print "
\n";
}
print "\n";
print "
\n";
print "
\n";
}
## 月別表示
sub ViewMonth {
local($ii) = 0;
local($max) = 0;
local($year, $month) = 0;
local(@count) = ();
local(@date) = ();
@monthData = reverse(@monthData);
for ($ii = 0; $ii <= $#monthData; $ii++) {
$monthData[$ii] =~ s/\r\n//g;
$monthData[$ii] =~ s/\r//g;
$monthData[$ii] =~ s/\n//g;
($year, $month, $count[$ii]) = split(/\t/, $monthData[$ii]);
# 月部分を作成
$date[$ii] = sprintf("%04d.%02d", $year, $month);
# 最大値を求める
if ($max < $count[$ii]) {
$max = $count[$ii];
}
}
# 今日の分を追加
local($tmp, $time, $agent, $host, $ref) = split(/\t/, $todayData[0]);
local($sec, $min, $hour, $mday, $monthToday, $yearToday) = localtime($time);
if ($yearToday + 1900 == $year && $monthToday + 1 == $month) {
$count[$ii - 1] += ($#todayData + 1);
if ($max < $count[$ii - 1]) {
$max = $count[$ii - 1];
}
}
else {
$date[$ii] = sprintf("%04d.%02d", $yearToday + 1900, $monthToday + 1);
$count[$ii] = $#todayData + 1;
if ($max < $count[$ii]) {
$max = $count[$ii];
}
}
print "\n";
print "
\n";
print "\n";
print " 年月 | \n";
print " アクセス数 | \n";
print " グラフ | \n";
print "
\n";
for ($ii = 0; $ii <= $#count; $ii++) {
print "\n";
print " $date[$ii] | \n";
&ViewCountAndGraph($count[$ii], $max);
print "
\n";
}
print "\n";
print "
\n";
print "
\n";
}
### 今日、昨日の解析
sub Analyze {
&MakeData(@_);
local($num) = $#_ + 1;
local($date) = &GetDate($_[0]);
&Header; # ヘッダを表示
print "
\n";
&Title; # タイトルを表示
print "$date
\n";
print "アクセス数:$num
\n";
&ReturnMenu;
print "
\n";
print "リンク元別表\示
\n";
&ViewRefData(%refData);
print "
\n
\n
\n";
print "リモートホスト別表\示
\n";
&ViewHostData(%hostData);
print "
\n
\n
\n";
print "マシン環境別表\示
\n";
&ViewAgentData(%agentData);
print "
\n";
&Footer; # フッタを表示
}
## 解析データ作成
sub MakeData {
for (local($ii) = 0; $ii <= $#_; $ii++) {
$data[$ii] =~ s/\r\n//g;
$data[$ii] =~ s/\r//g;
$data[$ii] =~ s/\n//g;
($count, $time, $agent, $host, $ref) = split(/\t/, $_[$ii]);
$agentData{$agent}++;
# IP表記以外はリモートホストの先頭部分をマージ
if ($host !~ /^[0-9]+\./) {
$host =~ s/^[^\.]+\./*./;
}
$hostData{$host}++;
$refData{$ref}++;
}
}
## リンク元データ表示
sub ViewRefData {
local(%data) = @_;
local(@key) = keys(%data);
local($ii) = 0;
local($max) = 0;
# アクセス数の最大値を取得
for ($ii = 0; $ii <= $#key; $ii++) {
if ($max < $data{$key[$ii]}) {
$max = $data{$key[$ii]};
}
}
print "\n";
print "
\n";
print "\n";
print " リンク元 | \n";
print " アクセス数 | \n";
print " グラフ | \n";
print "
\n";
local(@newkey) = sort { ($data{$b} <=> $data{$a}) || ($a cmp $b) } @key;
local($viewkey) = "";
for ($ii = 0; $ii <= $#newkey; $ii++) {
$viewkey = $newkey[$ii];
$viewkey =~ s/cgi\?(.)*/cgi?.../;
if (length($viewkey) > 80) {
$viewkey = substr($viewkey, 0, 70) . "...";
}
print "\n";
if ($newkey[$ii]) {
print " $viewkey | \n";
}
else {
print "
| \n";
}
&ViewCountAndGraph($data{$newkey[$ii]}, $max);
print "
\n";
}
print "
\n";
print "
\n";
}
## リモートホストデータ表示
sub ViewHostData {
local(%data) = @_;
local(@key) = keys(%data);
local($ii) = 0;
local($max) = 0;
# アクセス数の最大値を取得
for ($ii = 0; $ii <= $#key; $ii++) {
if ($max < $data{$key[$ii]}) {
$max = $data{$key[$ii]};
}
}
print "\n";
print "
\n";
print "\n";
print " リモートホスト | \n";
print " アクセス数 | \n";
print " グラフ | \n";
print "
\n";
local(@newkey) = sort { ($data{$b} <=> $data{$a}) || ($a cmp $b) } @key;
for ($ii = 0; $ii <= $#newkey; $ii++) {
print "\n";
if ($newkey[$ii]) {
print " $newkey[$ii] | \n";
}
else {
print "
| \n";
}
&ViewCountAndGraph($data{$newkey[$ii]}, $max);
print "
\n";
}
print "
\n";
print "
\n";
}
## マシン環境データ表示
sub ViewAgentData {
local(%data) = @_;
local(@key) = keys(%data);
local($ii) = 0;
local($max) = 0;
# アクセス数の最大値を取得
for ($ii = 0; $ii <= $#key; $ii++) {
if ($max < $data{$key[$ii]}) {
$max = $data{$key[$ii]};
}
}
print "\n";
print "
\n";
print "\n";
print " マシン環境 | \n";
print " アクセス数 | \n";
print " グラフ | \n";
print "
\n";
local(@newkey) = sort { ($data{$b} <=> $data{$a}) || ($a cmp $b) } @key;
for ($ii = 0; $ii <= $#newkey; $ii++) {
print "\n";
if ($newkey[$ii]) {
print " $newkey[$ii] | \n";
}
else {
print "
| \n";
}
&ViewCountAndGraph($data{$newkey[$ii]}, $max);
print "
\n";
}
print "
\n";
print "
\n";
}
## HTMLのヘッダ
sub Header {
print "Content-type: text/html\n\n";
print "\n";
print "\n";
print "\n";
print " \n";
print " $t_title\n";
print "\n";
if ($bground) {
print "\n";
}
else {
print "\n";
}
}
## HTMLのフッタ
sub Footer {
# 著作権表示(絶対に削除しないでください)
print "";
print "$scriptname $version
";
print " - St. Night Moon -";
print "
\n";
print "\n";
print "\n";
}
## タイトルを表示
sub Title {
if ($t_gif) {
print "\n";
}
else {
print "$t_title
\n";
}
}
sub ReturnHome {
print "";
if ($top) {
print "";
}
else {
print "";
}
print "ホームに戻る";
print "
";
}
sub ReturnMenu {
print "";
if ($top) {
print "";
}
else {
print "";
}
print "ホームに戻る ";
print "メニューに戻る";
print "
";
}
### ツェラーの公式
sub Zeller{
local($year, $month, $day) = ($_[0], $_[1], $_[2]);
if ($month == 1 || $month == 2){
$year--;
$month += 12;
}
return ($year + int($year / 4) - int($year / 100) + int($year / 400) + int(2.6 * $month + 1.6) + $day) % 7;
}
### データの読み込み
sub ReadData {
if (!open(IN, $logfile)) {
&Error("Can't open $logfile");
}
local(@data) = ;
close(IN);
local(@newdata) = ();
if ($_[0]) { # 今日のログを読み込み
for (local($ii) = 0; $ii <= $#data; $ii++) {
if ($data[$ii] eq "\n") {
last;
}
else {
$newdata[$ii] = $data[$ii];
}
}
}
else { # 昨日のログを読み込み
local($flag) = 0;
local($jj) = 0;
for (local($ii) = 0; $ii <= $#data; $ii++) {
if ($data[$ii] eq "\n") {
$flag = 1;
$jj = 0;
}
else {
if ($flag) {
$newdata[$jj] = $data[$ii];
$jj++;
}
}
}
}
return @newdata;
}
## 日付別データを読み込み
sub ReadDayData {
if (!open(IN, "$dayfile")) {
&Error("Can't open $dayfile");
}
local(@data) = ;
close(IN);
return @data;
}
## 月別データを読み込み
sub ReadMonthData {
if (!open(IN, "$monthfile")) {
&Error("Can't open $monthfile");
}
local(@data) = ;
close(IN);
return @data;
}
## エラー処理
sub Error {
&Header;
print "
\n";
print "エラー!
\n";
print "$_[0]
\n";
print "
\n";
&Footer;
exit;
}