Apache httpdでリクエストURI毎にログの出力先を分ける

AWS運用自動化サービス「Cloud Automator」

最近ではNginx等のWEBサーバを利用するケースも増えていますがまだまだApache httpdを利用しているケースもあると思います。

今回はApache httpdを利用した環境で画像へのリクエストはログに残したくないや、
特定のディレクトリへのアクセスはログファイルを分けたいなどと行った要件が出てきた場合の設定方法についてご紹介します。

アクセスログの設定はCustomLogディレクティブ

ご存じかと思いますがアクセスログを出力させる場合CustomLogディレクティブについて振り返ります。
CustomLogディレクティブはログの出力先やフォーマットを指定します。

デフォルトの設定ではhttpd.confに以下のような設定が入っています。

CustomLogディレクティブはVirtualHostディレクティブの中でも設定でき、
以下のようなバーチャルホスト毎にアクセスログを分けるということは
おそらくほとんどの人がやったことがあるのではないでしょうか。

そして今回のテーマである、リクエスト毎にログの出力先を変更する場合、
VirtualHostディレクティブ内にCustomLogディレクティブを複数書くことで実現します。

また、CustomLogは環境変数を引数に渡し出力させるログをコントロールすることができます。

リクエストの属性に基づいて環境変数を設定するSetEnvIfディレクティブ

画像や、特定のディレクトリへのアクセスがあった場合はログを記録しないやログファイルを
分けるといった条件分岐する場合にSetEnvIfディレクティブを利用することが可能です。

例えばfaviconへのアクセスがあった場合no_logという環境変数をセットしたい場合は以下のように書きます。

また、testのディレクトリにアクセスがあった場合にtest_log環境変数をセットしたい場合は以下のように書きます。

CustomLog、SetEnvIfを利用してログの出力先を分ける

これまで説明してきたCustomLog、SetEnvIfの2つのディレクティブを利用して本題であるログの出力停止や
リクエストURI毎にファイルを分ける設定を行います。

今回の例ではhost.example.comのドメインを利用したバーチャルホストに
test01ディレクトリ、test02ディレクトリ、test03ディレクトリがあり、
このディレクトリへのアクセスはそれぞれ分けたいという要件があるとします。

また、favicon.icoへのアクセスはログに出力させない、ファイルを分けたログファイルは
分ける前のログファイルには出力させないという要件があったとします。

これらの要件を満たす設定は以下の通りになります。

SetEnvIfディレクティブの解説

SetEnvIfディレクティブの四行については前項の設定とほぼ変わりません。
環境変数については空白区切りで複数設定することが可能です。

今回なぜ2つの環境変数を設定しているのかは後ほど解説します。

また、以下のような書き方をすることも可能です。
この場合後勝ちでの上書きとならず複数の環境変数がセットされます。

CustomLogディレクティブの解説

次のログの出力設定です。
環境変数を引数に設定できるCustomLogディレクティブを使います。
そこにログファイルのパス、ログフォーマットの名前、環境変数を指定し以下のようになっています。

env={環境変数}だとその環境変数にマッチしたリクエストのログが出力されます。
最後のアクセスログの出力設定は特定のディレクトリ以外へのアクセスログを出力させる設定です。

no_logを全てのSetEnvIfで設定した意味

CustomLogは原則全てのアクセスログを指定したファイルに出力します。
そのため以下の設定だとどうなるでしょうか。

答えはtest01ディレクトリにアクセスがあった場合はhost.example.com-test01-access_log のファイルと host.example.com-access_log の両方に同じログが出力されてしまいます。

これでは分けた意味が無いので今回はno_logの環境変数をつけてログが重複して出力されないよう設定してます。

まとめ

SenenvIfを利用して環境変数をセットし、その環境変数に合わせてログの出力先を変えることが可能です。
多すぎるログファイルは分析する際大変なこともあるので必要に応じてうまく分割してログを有効活用したいですね。

AWS運用自動化サービス「Cloud Automator」