#!/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 " \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 " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print "\n"; } print "
時刻番号リモートホストブラウザ、OSリファレンス
$date$count$host$agent$ref
\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"; print " \n"; print "\n"; print "
\n"; &ViewTimeOneDay(@yesterdayTimeData, $yesterdayDate, $max); print " \n"; &ViewTimeOneDay(@todayTimeData, $todayDate, $max); print "
\n"; print "
\n"; } ## 1日分を表示 sub ViewTimeOneDay { local($total) = 0; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; for (local($ii) = 0; $ii < 24; $ii++) { print " \n"; print " \n"; &ViewCountAndGraph($_[$ii], $_[25]); $total += $_[$ii]; print " \n"; } print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print "
$_[24]
時刻アクセス数グラフ
$ii
$total
\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 " \n"; &ViewCountAndGraph($count[$ii], $max); print "\n"; } print "\n"; print "
日付アクセス数グラフ
$date[$ii]
\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 " \n"; &ViewCountAndGraph($count[$ii], $max); print "\n"; } print "\n"; print "
年月アクセス数グラフ
$date[$ii]
\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 " \n"; } else { print " \n"; } &ViewCountAndGraph($data{$newkey[$ii]}, $max); print "\n"; } print "
リンク元アクセス数グラフ
$viewkey
\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 " \n"; } else { print " \n"; } &ViewCountAndGraph($data{$newkey[$ii]}, $max); print "\n"; } print "
リモートホストアクセス数グラフ
$newkey[$ii]
\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 " \n"; } else { print " \n"; } &ViewCountAndGraph($data{$newkey[$ii]}, $max); print "\n"; } print "
マシン環境アクセス数グラフ
$newkey[$ii]
\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; }