Home > Apacheについて | 研究について > Apache2.4.1のmod_luaをいきなり弄ってフックできる箇所を増やしてみたよ

Apache2.4.1のmod_luaをいきなり弄ってフックできる箇所を増やしてみたよ


mod_lua、色々触ってみた所、すごい簡単にモジュールっぽい動きが実装できて、可読性も良くて便利。

しかし、個人的にモジュール実装する時に良く使うのは、アクセスログ出力時のフック箇所(ap_hook_log_transaction)である。例えば、リクエスト毎にレスポンス処理前の最終段階であるap_hook_fixupsの段階でrusage()等でリソースの計測始めて、ap_hook_log_transactionの段階で差分を算出し、動的コンテンツ実行に利用したCPU使用時間等を計測する、といった使い方ができる。また、処理始めでカウンターを上げておいて、処理終わってログ書き込む段階でカウンター下げるといった使い方にもap_hook_log_transactionでのフックは便利だったりする。細かい話、コンテンツ処理するhandlerの前後で計ってもいいんだけど、hookに関数登録した方が分かりやすい。

しかし、mod_luaはそこでフックすることができない。これは面白くない。

だったら追加してやろう。ということで実装した。以下パッチ。

--- mod_lua.c.orig      2011-12-19 03:02:21.000000000 +0900
+++ mod_lua.c   2012-03-28 13:56:08.000000000 +0900
@@ -618,6 +618,10 @@
 {
     /* ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "LuaHookInsertFilter not yet implemented"); */
 }
+static int lua_log_transaction_harness(request_rec *r)
+{
+    return lua_request_rec_hook_harness(r, "log_transaction", APR_HOOK_MIDDLE);
+}

 static int lua_quick_harness(request_rec *r, int lookup)
 {
@@ -957,6 +961,14 @@
     return lua_ssl_is_https ? lua_ssl_is_https(c) : 0;
 }

+static const char *register_log_transaction_hook(cmd_parms *cmd, void *_cfg,
+                                               const char *file,
+                                               const char *function)
+{
+    return register_named_file_function_hook("log_transaction", cmd, _cfg, file,
+                                             function, APR_HOOK_MIDDLE);
+}
+
 /*******************************/

 command_rec lua_commands[] = {
@@ -1049,6 +1061,9 @@
     AP_INIT_RAW_ARGS("Lua_____ByteCodeHack", hack_section_handler, NULL,
                      OR_ALL,
                      "(internal) Byte code handler"),
+    AP_INIT_TAKE2("LuaLogTransaction", register_log_transaction_hook, NULL,
+                  OR_ALL,
+                  "Provide a hook for the log_transaction phase of request processing"),
     {NULL}
 };

@@ -1197,6 +1212,8 @@

     ap_hook_post_config(lua_post_config, NULL, NULL, APR_HOOK_MIDDLE);

+    ap_hook_log_transaction(lua_log_transaction_harness, NULL, NULL, APR_HOOK_MIDDLE);
+
     APR_OPTIONAL_HOOK(ap_lua, lua_open, lua_open_hook, NULL, NULL,
                       APR_HOOK_REALLY_FIRST);

やった事

好きに追加してねー、と言わんばかりの実装になっていたので、やったことをまとめておく。

  • command_recにAP_INIT_TAKE2でApacheのconf用のLuaLogTransactionを登録
  • LuaLogTransactionがconfに書かれた場合にParseする関数register_log_transaction_hookを登録
  • 実際にmod_luaがap_hook_log_transactionで呼び出すための関数lua_log_transaction_harnessを登録

register_log_transaction_hookの中のregister_named_file_function_hookは設定をApacheに登録するためのラッパー関数のようなもので、lua_log_transaction_harnessの中のlua_request_rec_hook_harnessは、LuaをCから呼び出すための組み込みラッパー関数のような役目をしているので、弄る必要はない。結構考えられて実装してある。

こういう風にやれば、フックしたい場所をすぐ追加できるんじゃないかなと思う。ApacheモジュールをCで書いたことなくても、こういうところから始めればすぐ動くので楽しくなってくるかも。

これで、以下のような設定をすると、レスポンス処理の終わった後のアクセスログを書き込む段階でフックすることができる。例えば、apache_class.luaというスクリプトのtimerファンクションを呼び出したい場合は、以下のよう新しい設定「LuaLogTransaction」を書く。

LuaLogTransaction /usr/local/apache2.4/conf/extra/lua/apache_class.lua timer

よしよし、これでレスポンス処理の前後でフックすることができるようになったから、luaでプロセス間通信とかしてやれば楽しいことができそうだ。

フックできているか確認

以下のような設定でフックできているか確認した。

  • luaの内容
function timer(r)
    hook = APACHE.new(r)
    r:debug(hook:clock())
    return apache2.DECLINED
end
  • Apacheの設定
LuaHookTranslateName /usr/local/apache2.4/conf/extra/lua/apache_class.lua timer
LuaLogTransaction /usr/local/apache2.4/conf/extra/lua/apache_class.lua timer

レスポンス生成前後で時間を表示するtimerをセットして、アクセスするCGIで10秒sleepしてみる。

  • ログ出力結果
[Wed Mar 28 15:11:07.253606 2012] [lua:debug] [pid 13417:tid 3069717392] @/usr/local/apache2.4/conf/extra/lua/apache_class.lua(78): [client himitsu:62591] Wed Mar 28 15:11:07 2012
-- 省略 --
[Wed Mar 28 15:11:17.611706 2012] [lua:debug] [pid 13417:tid 3069717392] @/usr/local/apache2.4/conf/extra/lua/apache_class.lua(78): [client himitsu:61812] Wed Mar 28 15:11:17 2012

というような感じで、きちんとlog_transactionのタイミングでフックできていることが分かる。

コメント:0

コメントフォーム
Remember personal info

CAPTCHA


トラックバック:2

このエントリーのトラックバックURL
http://blog.matsumoto-r.jp/wp-trackback.php?p=2128
Listed below are links to weblogs that reference
Apache2.4.1のmod_luaをいきなり弄ってフックできる箇所を増やしてみたよ from 人間とウェブの未来
pingback from 人間とウェブの未来 - mod_luaを使い倒すためにリソース取得するLuaのライブラリを作った 12-03-30 (金) 21:07

[…] Older […]

pingback from 人間とウェブの未来 - なぜApacheにmrubyを組み込もうと思ったか 12-05-08 (火) 23:55

[…] Apacheの内部処理においてフックできるポイントが少ない(自分でフック箇所を増やしたりしていた) […]

Home > Apacheについて | 研究について > Apache2.4.1のmod_luaをいきなり弄ってフックできる箇所を増やしてみたよ

検索
フィード
メタ情報

Return to page top