Apacheモジュールを作る「postgresでロギングする(1)」

経緯

  • ずっと前からモジュール開発の本をバイト先の会社から借りていて、作ろう作ろうと思っていたが、なかなかいざとなると面倒で(爆)後回しにしていたが、久々に返して逆に「やろう」と思ったのがキッカケ。WEBを探しても全然情報ないし、まぁ残しておこう、ということ。

作るものは、postgresによるロガーである。ご存知のとおり、apacheのログは、apache_dirのconfとかvarの下にファイルとしてたまるがこれの管理は大変。また見づらい。様々なビューワも出ているが、DBに入れてしまえばいろいろと応用が効くし、CSE経由で見れてよかろう、ということで作ることにした。

尚、対象Apacheは1.3である。2.0以降はモジュール開発の方法が若干異なる。

モジュールテンプレート生成

  • apacheにはapxs(perlスクリプト)でモジュールに関していろんなこと(適当な表現だ!)ができる。PHPのインストールなんかに--with-apxsを指定したりしるが、あれはapacheにPHPのモジュールを動的に組み込むためだ(CGI PHPの場合はいらない、ということ)。それはともかく、apxsにはモジュールのテンプレートを生成する機能があるので、まずは雛形を生成する。
# apxs -n pg_logger -g 
Creating [DIR]  pg_logger
Creating [FILE] pg_logger/Makefile
Creating [FILE] pg_logger/mod_pg_logger.c

引数の意味は-nでモジュール名指定、-gはサンプルを生成(SAMPLE MODULE SOURCE GENERATION)である。(apxsスクリプトの中身を見れば分かる。)何はともあれ、これで動く雛形ができている。これでカレントディレクトリに「pg_logger」というディレクトリができ、その中にMakefileとソースができる。で、「pg_logger」に移動。

まず雛形の動作テストを行う。これが動かなきゃどうにもならない。

# make

これで

make: apxs: コマンドが見つかりませんでした

とかいわれたら、apxs(とapachectl)にパスを通す。bashrcに記述するとか。手っ取り早くは、(bashの場合)

# vi ~/.bashrc

PATH=$PATH:.:/sbin/:/usr/sbin/:/usr/local/apache/bin/

とか修正する。人により異なる。

# source ~/.bashrc

修正したら読み込む。 これでコンパイルできる。

そしたら [apache_dir]/conf/httpd.confに

LoadModule pg_logger_module /hogehoge/umauma/pg_logger/mod_pg_logger.so
<Location /pg_logger>
 SetHandler pg_logger
</Location>

等と記述する。「pg_logger以下にアクセスされたら、ハンドラpg_loggerを呼び出す」ということである。 これでhttpd.confの検査をして

# apachectl configtest
Syntax OK

となれば、再起動して

# apachectl restart

ブラウザで「http://localhost/pg_logger」にアクセスしてみて

The sample page from mod_pg_logger.c

と表示されればとりあえずOK

RefererとUser-Agent取得の確認

作るロガーは、combineフォーマットに準じたものにしたいので、Referer,User-Agentの取得が必要だ。

  • combineフォーマット
    "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""

これらの値は、ユーザが送ったリクエストのヘッダに含まれる。そこで先のテンプレソース(mod_pg_logger.c)をちょこっと修正して確認する。 コンテンツハンドラである関数「pg_logger_handler」内の記述を以下のように修正する。

/* The sample content handler */
static int pg_logger_handler(request_rec *r)
{
    r->content_type = "text/html";
    ap_send_http_header(r);
    if (!r->header_only){
        // ヘッダのみのリクエストでないとき
        ap_rputs("The sample page from mod_pg_logger.c\n", r);
        // (クライアントの送った)ヘッダーのRefererとUser-Agentを表示する。
        // 本当はNULLチェックをするが暫定。
        ap_rprintf(r,"%s<BR>\n",ap_table_get(r->headers_in, "Referer"));
        ap_rprintf(r,"%s<BR>\n",ap_table_get(r->headers_in, "User-Agent"));
    }   
    return OK;
}
  

makeして、restartしてブラウザで確認。 ブラウザの種類、ファイアウォールによってUser-Agentはでないかもしれない。 また、Refererはリンクから飛んでこないと入ってこないので注意。 ひとまず前提はここまで。

参考


トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-11-28 (日) 21:47:37 (2456d)