# ApacheのCustomLogとTransferLogの違い

2019/06/14

この二つの違いがあんまりわかっていなかった上に、適当にApacheを設定していたせいで両方とも有効になっていて気持ち悪かったので、調べたことをメモしておきます。結論から言うと私はCustomLogだけでログを定義することにしました。

# それぞれのディレクティブでできること/できないこと

どちらもログの出力先、フォーマットを指定するディレクティブですが、細かい部分が違います。CunstomLogの方が新しいんだと思う。以下、Apache2.4について記載します。

CustomLog TransferLog
ファイルへのログ出力
プログラムへのログ出力
直前のLogFormatディレクティブによるログフォーマットの指定
LogFormatのニックネームでのログフォーマットの指定 ×
デフォルトのログフォーマット デフォルト値なし Common Log Format
ロギングする条件の指定 ×

参考:

Apache HTTP サーバ バージョン 2.4 CustomLog ディレクティブ

Apache HTTP サーバ バージョン 2.4 TransferLog ディレクティブ

いずれもパスを指定してログを書き込んだり、loggerコマンドを通してSyslogにログを送り込んだりはできます。ログのフォーマットに関する指定とロギングする条件を指定できるかできないかに違いがあります。

# LogFormatディレクティブとCustomLog/TransferLog

LogFormatディレクティブはその名の通りログのフォーマットを規定するディレクティブです。このディレクティブは二つの書き方があります。

# ニックネームをつけないLogFormat

ログフォーマットの書き方は置いておいて、ただ単にログフォーマットを規定するだけなのがこちら。

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""
1

この書き方をすると、このLogFormatディレクティブより下にあるTransferLogのログフォーマットを規定できます。上だとだめです。

# ニックネーム付きのLogFormat

ログフォーマットを規定した後に、ニックネームをつけることもできます。

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" ncsa_extended_combined
1

この書き方をすると、ニックネーム「ncsa_extended_combined」を使ってCustomLogのログフォーマットを定義することができます。

CustomLog /var/log/httpd/customed_log ncsa_extended_combined
1

CustomLogは、フォーマットをニックネームで呼び出せるため、設定をどの順で書くか気にする必要がありません。この点でCustomLogの方が使いやすいです。

参考: Apache HTTP サーバ バージョン 2.4 LogFormat ディレクティブ

余談ですがCustomLogはLogFormatディレクティブを指定せず直接フォーマットを書くこともできます。

CustomLog logs/access_log "%h %l %u %t \"%r\" %>s %b"
1

# ロギングする条件

CustomLogでは環境変数を利用してロギングする条件を指定することができます。以下はアクセス元のIPアドレスやホスト名を読み、条件に当てはまったらそのアクセスに環境変数「no_log」を設定する方法。

SetEnvIf Remote_Addr 127.0.0.1 no_log
SetEnvIf Remote_Host localhost no_log
1
2

参考: Apache HTTP サーバ バージョン 2.4 SetEnvIf ディレクティブ

CustomLogではアクセス時の環境変数を読み、ロギングするかしないかを指定することができます。びっくりマークで否定なので、以下の設定で環境変数no_logが指定されていないときのみロギングを行う、という設定ができます。

CustomLog /var/log/filtered_access_log ncsa_extended_combined env=!no_log
1

監視サーバからのポーリングアクセスはロギングしない(もしくは別のCustomLogディレクティブで別ログファイルにのみ書き出す)、という設定ができるので便利です。この点でもCustomLogの方が優れているので、TransferLogを使う理由はあまりありません。

# CentOS7のconf.d/ssl.confではなぜかTransferLogがデフォルト設定になっている

CentOS7でyumで入るApacheでしか確認していませんが、CustomLogはconf/httpd.confで定義されています。これは別に良いです。

<IfModule log_config_module>
  (~snip~)
  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
  (~snip~)
  CustomLog "logs/access_log" combined
</IfModule>
1
2
3
4
5
6

んで、 CentOS7 デフォルトのApacheのSSLの設定ファイルはconf.d/ssl.confなのですが、こちらのデフォルト設定では、SSLを有効にしたバーチャルホストの設定内でTransferLogが有効化されています。

<VirtualHost _default_:443>
  (~snip~)
  TransferLog logs/ssl_access_log
  (~snip~)
</VirtualHost>
1
2
3
4
5

この設定ファイル内では、TransferLogより上でニックネームなしのLogFormatディレクティブの設定はなされていないので、logs/ssl_access_logはデフォルトのCommon Log Formatで記録されます。こうして、combinedなフォーマットのlogs/access_logと、 Common Log Formatなフォーマットのlogs/ssl_access_logがそれぞれ生成されます。

私はlogs/ssl_access_logもロギングの条件を指定したかったので、TransferlogをやめてCustomLogに直しました。ログフォーマットもcommonやめてcombinedにしました。ついでにログファイル名も変えてます。SetEnvIfは上のコンテキストで設定しておけば下に継承されるので、httpd.confにてサーバレベルで設定しました。

  • conf/httpd.conf
<IfModule log_config_module>
 (~snip~)
  SetEnvIf Remote_Addr 127.0.0.1 no_log
  SetEnvIf Remote_Host localhost no_log
  SetEnvIf Remote_Host some\.domain\.com no_log
  SetEnvIf Remote_Host \.sub\.some\.domain\.com no_log
  CustomLog "logs/access_log" combined env=!no_log
  (~snip~)
</IfModule>
1
2
3
4
5
6
7
8
9
  • conf.d/ssl.conf
<VirtualHost _default_:443>
  (~snip~)
  CustomLog logs/wordpress_ssl_access_log combined env=!no_log
  (~snip~)
</VirtualHost>
1
2
3
4
5

これで、80番ポートへのアクセスはlogs/access_logへ、443番ポートへのアクセスはlogs/wordpress_ssl_access_logへ、それぞれ!no_log条件付きでcombined形式でロギングできるようになりました。おわり。

# おまけ1: commonとcombinedのフォーマットの違い

定義上はこうなってます。

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
1
2

combinedの方はリファラとユーザーエージェントが入ります。

# おまけ2: logs/ssl_request_logってなんやねん

conf.d/ssl.confでは、デフォルトで以下のような設定も入っています。

<VirtualHost *:443>
 (~snip~)
  #  Per-Server Logging:
  #   The home of a custom SSL log file. Use this when you want a
  #   compact non-error SSL logfile on a virtual host basis.
  CustomLog logs/ssl_request_log \
            "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
1
2
3
4
5
6
7
8

バーチャルホスト切るときは、各バーチャルホストで詳細にロギングすることにして、大元ではこんなコンパクトなログだけ残しとけばいいんじゃないということが書いてあります。複数のバーチャルホスト切ってないなら不要なのでコメントアウトしてます。