概要
apacheの設定で良くある、envによってヘルスチェック等のログを出さないor別ファイルに出す設定。nginxのaccess_logではif=conditionというオプションが使える。
動機は、mod_pagespeedが生成する内部アクセスのログがうっとおしいから、分けてやろう、というところから。
条件判定の設定
まずは条件判定が必要。他にも変数がいろいろ使える。
アクセス元IPアドレスで分ける
geoモジュールが使える。
僕のところでは、localhostとdocker0経由のヘルスチェック(自分も含む)のログをメインのログに出したくないので、以下の判定を「http」セクションに設定(※serverセクションではない)。
geo $internal_access {
default off;
127.0.0.1 on;
172.17.0.0/16 on;
}
User-Agentで分ける。
mapで分ける。
mod_pagespeedが生成する「Serf/1.3.8 mod_pagespeed/1.10.33.2-7599」みたいなUAからのアクセスを判定する。
map $http_user_agent $internal_access {
default off;
"~Serf.*mod_pagespeed.*" on;
}
ログ出力設定
ここが若干、apacheとは異なるところで、apacheのSetEnvIfは「!env」が使えるが、nginxのaccess_logは基本、0/1で出す・出さないの判定しかしてくれない。
なので、前述の判定を行った結果を以って、フラグ変数をもう一度定義して分ける。
map $internal_access $mainlog {
off 1;
default 0;
}
map $internal_access $internallog {
off 0;
default 1;
}
access_log logs/blog-access.log main if=$mainlog;
access_log logs/internal-access.log main if=$internallog;
これで各々のログにUAなりアクセス元IPなりで分かれてログが出力されるようになる。
まとめ
!envができないのかなぁ、というのが疑問。確かに、フィルタと考えれば今の形でも表現はできてるんだけど、やっぱり条件式は少ないほうが嬉しい。確かに、apacheでも記述レベルは同程度(!envの分だけ、1行、条件が少ない)なので、気にするレベルでは無いかな、とも思う。