タグ「Perl」が付けられているもの
そこで無い頭を使ってちょっとだけ考えたのですが、Encodeとjcodeに被さる形でラッパーを書いて、それを利用すれば良いのでは無いかという案。
ただ、自分の手元には5.6環境なんて残って無くて、テスト環境作ったりする必要もありそうですし、面倒くさいです。
誰か作ってないかなぁ。。
日本語の扱いについては慣例的にjcode.plに頼りきりだったのですが、Encodeモジュールとやらを使ってみようかと。ところが、こいつがなかなか曲者で、jcode.plに慣れていると大変かも知れません。
今後はEncodeモジュールにするべきでしょうし、jcode.plが不要になるということもあって、少しだけ使ってみました。
ApacheをPerlスクリプト経由でデータベースに吐き出す方法だが
パフォーマンスの問題が大丈夫か?という不安があった。
実際やってみると、毎回起動している訳ではないためある程度
大丈夫そうという事が判った。
http://httpd.apache.org/docs/2.2/ja/logs.html#piped
Apacheのドキュメントにあるのだが、
>Apache はパイプ経由のログ用のプロセスをサーバの起動時に実行し、 サーバの実行中にそのプログラムがクラッシュしたときはそれを再び 実行します。(この最後の機能がこの技術が「信頼性のあるパイプ経由のロギング」 と呼ばれている理由です。)
という記述があり、Perlを利用してもパフォーマンス的には問題ないだろうと思う。
最初は行毎にスクリプトが呼び出されるのかと思い、
my line = <>
と記述していたが上手くいかず上記のドキュメントを発見して
while (my $line = <>) {
とすることでログを取得することが出来た。
別の方法としてmod_log_sqlを利用する方法もあるが、DBとしてMySQLしかサポートしていないようである。Perl+DBIで書き出す場合はDBIがサポートする他のDBを利用できることが利点となる。
勉強も兼ねてApacheのログをデータベースに出力してみる。
何で?わざわざDBに?という事だが、
メリット)
・複数Webサーバのログを集約することが出来る
・ログから条件で抜き出す事が容易かつ高速
デメリット)
・DBのメンテナンスが必要
・ログの記録に関してはパフォーマンス的にどうか?
実際に出力する方法としては
httpd.confのCustomLog行でパイプが使える(rotatelogもパイプ使いますよね・・・)ので、「標準入力から入力されたアクセスログをデータベースに書き出す」プログラムがあれば実現可能となる。
CustomLog "|/usr/local/bin/PROGRAM" common
勉強も兼ねてPerlで書いてみた。
PerlからDBを操作する方法としてはDBIを利用するのが簡単そうである。
テストで書いてみたので、置いてみる。テストで作ってみたPerlソースファイル
多分自分が一番見るんだけど。
標準入力(<>)から入力された行を区切って項目別に分けて、データを準備して、それをSQL文(INSERT)に渡すだけである。
そもそも、ApacheのログをMySQLで管理したいってのが目的。ApacheのログをMySQLに吐き出すには、mod_log_sqlを使う方法がある。それに問題は無いのだけど、どうせなら今までのログもSQLに取り込んでおきたい。という事で、Perlを使ってログをDBに吐き出す事にした。PHPでデータベースを使う例は良く見るんだけど、Perlでの例はあまり見たことがなかったので、メモしておく。
前準備として、CPANからDBIとDBD:mysqlをインストールしておく。
# perl -MCPAN -e shell
cpan[1]< install DBI
cpan[2]< install DBD:mysql
これでPerlでMySQLは簡単に使える。
前準備としてDBIを使う宣言use DBI:
データベースへの接続
$dbh=DBI->connect("DBI:mysql:データベース名:サーバ", "ユーザ名", "パスワード");
/blockquote> SQL文の準備
$sql="INSERT INTO テーブル (...) VALUE (...);"SQL文の実行
$sth=$dbh->prepare($sql);
$sth->execute;ステートメントハンドルオブジェクトを閉じる
$sth->finish;データベースハンドルオブジェクトを閉じる
$dbh->disconnect;手順はこれだけ。DBIの作者に感謝してありがたく使わせてもらいます。
えと前述の
next if(($list[1]+$list[2]+$list[3]+$list[4]) == 0);ってコードですが、文字列排除をした方が良いですね。
従って
next if("$list[1] $list[2] $list[3] $list[4]" =~ /[A-Za-z]);の方がベターでしょうね。。sarにパラメータ与えて気づきましたorz
またSolarisなんですけど、sarのレポートから、「報告用のレポート」を作成する必要があって、sarの出力結果をPerlに食わせて、CSVかHTMLに出力させることを考えた。
@buf = `LANG=C sar -f $sa_path/$filename`;
foreach (@buf) {
chomp($_);
next if($_ =~ /^$/);
$_ =~ s/\t+/ /g;
$_ =~ s/\s+/ /g;
@list = split(/ /, $_ );
next if(($list[1]+$list[2]+$list[3]+$list[4]) == 0);
next unless($list[0] =~ /[012][0-9]:[0-5][0-9]:[0-5][0-9]/);
$time = $list[0];
$usr = $list[1];
$sys = $list[2];
$wio = $list[3];
$idle = $list[4];
処理
}
とりあえず、sarの出力結果の内、頭4行と最終行は不要。
1行目:空行
2行目:「OS名 ホスト名 OSバージョン カーネルバージョン アーキテクチャ 日付」
3行目:空行
4行目:「時間 %usr %sys %wio %idle」
最終行:「Average 平均値」
headとlastを使って抜き出そうかとも思ったんですが、結局if/unlessで判断することに。もっと適切な方法もありそうなんですが...。
サーバの監視用途で、Perlでコマンドを書いたのだが、どうしてもGUIでの表示。できればWebでの表示をご希望とのこと。テキストで表示画面を作成したのだが、どうも見づらい。出来ればグラフで視覚的に表示したい。追加ソフト無しでグラフを表示したい。後々の管理を考えると、出来れば画像ファイルも置きたくない。(cgi1本で実現したい)
と言うことで、頑張ってCSSだけで、グラフを表示することにした。
結果から書くと、意外と簡単。
<style>後はHTMLの100pxと50%の部分を適時書き換えればok。
.graph {
position: relative;
width: 400px;\n";
border: 1px solid darkslateblue;
padding: 2px;
}
.graph .bar {
display: block;
position: relative;
background: hotpink;
text-align: center;
color: black;
height: 1em;
line-height: 1em;
}
.graph .bar span {
position: absolute; left: 1em;
}
</style><html>
<div class="graph">
<strong class="bar" style="width: 100px>
50%</strong>
</div>
</html>
ちなみに表示させると、こんな感じ
31% |
1% |
最近どうもPerlのプログラムに限界を感じている。
仕事柄というか Windows、MAC OS X、Solaris等を使うのだが
やはり色々な機種間で互換性を高めるにはJAVAが必要になってきた。
JAVAを使ってみると、AWTとかSwingとかGUI周りが難しい。。
何というか勉強が必要と痛感した。