タグ「Perl」が付けられているもの

Win32::ODBCを弄ってみる

  • 投稿日:
  • by
  • カテゴリ:
ActivePerlからMySQLを使いたかったんですが・・・以前Linux/UNIX環境ではDBIとDBD::MySQL使ってやったのですが、今回は別の方法を採ることにしました。ActivePerl用のDBD::MySQLのPPMパッケージも存在するのですが、今回は既存の環境があってその上で動かさなきゃならないという制約もあったし、インターネットへの接続も出来ない。その上、インストール作業自体も出来るだけ簡単に行えるようにする必要があったので、Windowsへインストールするものはインストーラが用意されているものを中心に選ぶことにしました。幸いMySQLのODBCコネクタならmsi形式のインストーラも準備されているし、ActivePerlの配布パッケージにもWin32::ODBCが含まれているので、ODBCコネクタ、MySQLとActivePerlをGUIからインストールするだけで環境を整える事が出来そうです。そんな訳でMySQLのODBCコネクタをインストールして、PerlからWin32::ODBC経由でMySQLを使うことにしました。使いかた自体にさほど差はないのですが、データベースとの接続部分はODBC側の設定になるのでPerl上で設定すべき項目が少ないのは便利かも知れません。

Perlで日本語の件

確かにPerl5.8からはマルチバイトもサポートされたのですが、実際のところ、現場レベルではまだまだPerl5.6環境も残っていて簡単に移行することもできません。
そこで無い頭を使ってちょっとだけ考えたのですが、Encodeとjcodeに被さる形でラッパーを書いて、それを利用すれば良いのでは無いかという案。

ただ、自分の手元には5.6環境なんて残って無くて、テスト環境作ったりする必要もありそうですし、面倒くさいです。

誰か作ってないかなぁ。。

Perl5.8の日本語処理

Perlも5.8でマルチバイト文字への対応がされてます。Encodeモジュールが実装されたり、UTF-8に対応したり・・・。
日本語の扱いについては慣例的に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)に渡すだけである。

PerlからMySQLを使う。

そもそも、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:データベース名:サーバ", "ユーザ名", "パスワード");

SQL文の準備
$sql="INSERT INTO テーブル (...) VALUE (...);"
$sth=$dbh->prepare($sql);
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

sarからデータを・・・

また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で判断することに。もっと適切な方法もありそうなんですが...。

CSSでグラフ表示

サーバの監視用途で、Perlでコマンドを書いたのだが、どうしてもGUIでの表示。できればWebでの表示をご希望とのこと。テキストで表示画面を作成したのだが、どうも見づらい。出来ればグラフで視覚的に表示したい。追加ソフト無しでグラフを表示したい。後々の管理を考えると、出来れば画像ファイルも置きたくない。(cgi1本で実現したい)
と言うことで、頑張ってCSSだけで、グラフを表示することにした。
結果から書くと、意外と簡単。

<style>
.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>

後はHTMLの100pxと50%の部分を適時書き換えればok。

ちなみに表示させると、こんな感じ

31%
1%
取りあえずはシンプルにグラフ化できたので、満足。

勉強か?

最近どうもPerlのプログラムに限界を感じている。

仕事柄というか Windows、MAC OS X、Solaris等を使うのだが
やはり色々な機種間で互換性を高めるにはJAVAが必要になってきた。

JAVAを使ってみると、AWTとかSwingとかGUI周りが難しい。。


何というか勉強が必要と痛感した。