gnuplot / webplot / access_cgi

集計結果のプロット

CGIを使って毎回集計する方法

前の方法では,リアルタイムな集計は
できません.ここでは,CGIからperlのスクリプトを起動してaccess_logの集
計をする方法を紹介します.前節で作った
webplot.plに,htmlを出力する機能を追加しましょう.

まず,前節と同様に最初に画像の場所のPATHを定義します.サーバ内での絶
対PATHと,httpdがアクセスする領域でのPATHが異なるので,これらを分け
ておきます.

 $abspath='/absolute/path/to/parent_of_image/'; $webpath='/relative/path/to/parent_of_image/'; $imgfile="access.png"; $logfile='/home/www/httpd/logs/access_log'; $gnuplot='/path/to/gnuplot'; 

$abspathは,イメージファイルを置くディレクトリで,サーバ
上での絶対PATHで表します.$webpathはhttpdのルートから見たPATH
で,URLの一部になります.このCGIが呼ばれた時点でのイメージファイルを作
成しますので,このイメージファイル及びこのファイルを置くディレクトリ
は,httpdに書き込みの許可を与えておく必要があります.

全体の流れは,前節のスクリプトと同じです.

 open(LOG,$logfile); while(<LOG>){ if(/.html/){ split; $day = substr($_[3],1,2); $mon = substr($_[3],4,3); $year= substr($_[3],8,4); $count[$day]++; } } close(LOG);  $day=$#count; $count[$day+1]=$count[$day];  & make_gnuplot; open(GNUPLOT,"| ".$gnuplot); foreach $i (0..$#plot){ print GNUPLOT $plot[$i]; } for($i=1;$i<=$#count;$i++){ printf(GNUPLOT "%10d%10dn",$i,$count[$i]); } print GNUPLOT "endn"; close(GNUPLOT);  & generate_html; exit 0;  sub make_gnuplot{ $i=0; $plot[$i++]=sprintf("set term png colorn"); $plot[$i++]=sprintf("set output '%s'n",$abspath.$imgfile); $plot[$i++]=sprintf("set size 0.7,0.7n"); $plot[$i++]=sprintf("set xrange [0:32]n"); $plot[$i++]=sprintf("set yrange [0:*]n"); $plot[$i++]=sprintf("set xtics 1,7,31n"); $plot[$i++]=sprintf("set mxtics 7n"); $plot[$i++]=sprintf("set nokeyn"); $plot[$i++]=sprintf("set gridn"); $plot[$i++]=sprintf("set title '%s %s'n",$mon,$year); $plot[$i++]=sprintf("plot '-' with stepn"); } 

gnuplotでイメージを作った後,そのURLをHTMLにしてブラウザに返す部分
が新たに追加されます.ここをsubroutine generate_htmlとしています.

  sub generate_html{ print << "EOF"; Content-Type: text/html   <html> <head><title> access_log stat </title></head> <body bgcolor="white"> <center><img src="$webpath$imgfile"></center> </body> </html> EOF 

できあがったperlのスクリプトをcgi-binの中に置いておき,htmlドキュメ
ントの中に次の様なリンクを作れば完成です.

< a href=”/cgi-bin/webplot_cgi.pl/”> Web Plot </a>

一般に,イメージファイルはブラウザにキャッシュされるため,何度も続
けてブラウザからリクエストがあっても,イメージファイルの名前(上の例な
らaccess.png)が同じなら,このイメージの中身が更新されてもブラウザはキャッ
シュの内容を表示してしまい,毎回同じグラフが表示されます.これを避ける
簡単な方法は,毎回異なる名前でイメージを作成することです.perlはPIDを
変数$$に保持していますので,例えばこれを使って “access$$.png” とすれば
毎回異なるグラフを表示するようになります.但し,この方法だと次第にゴミ
ファイルが溜って行く欠点がありますが.(ブラウザにキャッシュさせないように
するheaderを送る方法もありますが,ここでは解説しません)

up