CUBE SUGAR CONTAINER

技術系のこと書きます。

Apache httpd のログを rsyslog と logrotate でローテーションする

今回は Apache httpd のログを syslog 経由で rsyslog に送った上で、そのログを logrotate でローテーションさせてみる。 このやり方であればログをローテートする際に httpd を再起動する必要がないためサービス停止が発生しない。

環境には CentOS7 を使った。

$ cat /etc/redhat-release
CentOS Linux release 7.1.1503 (Core)
$ uname -r
3.10.0-229.11.1.el7.x86_64

必要なパッケージをインストールする

今回使うパッケージをひと通りインストールしておく。 おそらく rsyslog と logrotate に関しては最初から入っている。

$ sudo yum -y install httpd rsyslog logrotate

コンテンツを用意する

正常系の確認をするためにダミーのコンテンツを用意しておく。

$ cat << EOF | sudo tee /var/www/html/index.html > /dev/null
Hello, World!
EOF

Apache httpd を設定する

Apache httpd でログを syslog に出すには、設定ファイルで ErrorLog と CustomLog で logger コマンドを使うようにすれば良いみたい。 ファシリティでログの種類を分けるのでエラーログは local5 を、アクセスログには local6 を使ってみる。

$ sudo sed -i.back -e "
  s:ErrorLog \"logs/error_log\":ErrorLog \"|/usr/bin/logger -p local5.info --\":
  s:CustomLog \"logs/access_log\" combined:CustomLog \"|/usr/bin/logger -p local6.info --\" combined:
" /etc/httpd/conf/httpd.conf

rsyslog を設定する

先ほど設定したファシリティ local5 と local6 のログを rsyslog で受け取って所定の場所に書き残すようにする。

$ cat << EOF | sudo tee /etc/rsyslog.d/httpd.conf > /dev/null
local5.* /var/log/httpd/error_log
local6.* /var/log/httpd/access_log
EOF

Apache httpd は UDP を使って syslog を転送してくるので rsyslog 側も UDP で受信できるように設定する。

$ sudo sed -i.back -e "
  s:^#\(\$ModLoad imudp\)$:\1:
  s:^#\(\$UDPServerRun 514\)$:\1:
" /etc/rsyslog.conf

logrotate を設定する

logrotate では rsyslog が書き出すログファイルをローテーションする設定を入れる。

$ cat << EOF | sudo tee /etc/logrotate.d/httpd > /dev/null
/var/log/httpd/*log {
    dateext
    hourly
    missingok
    rotate 3
    notifempty
    nocompress
    sharedscripts
    delaycompress
    postrotate
        /bin/kill -HUP \`cat /var/run/syslogd.pid 2> /dev/null\` 2> /dev/null || true
        /bin/kill -HUP \`cat /var/run/rsyslogd.pid 2> /dev/null\` 2> /dev/null || true
    endscript
}
EOF

動作を確認する

ここまででひと通りの設定が終わったので rsyslog と httpd を (再) 起動する。

$ sudo systemctl restart rsyslog
$ sudo systemctl start httpd

正常系の動作を確認するためにトップページに HTTP リクエストを飛ばす。

$ wget -qO - http://localhost
Hello, World!

rsyslog で設定したログを書き出す先のディレクトリを見ると、ログが作られている。

$ sudo ls /var/log/httpd/
access_log  error_log

試しに logrotate コマンドで強制的にログをローテーションさせてみる。

$ sudo logrotate -fv /etc/logrotate.d/httpd

既存のログが日付付きでローテーションされた。

$ sudo ls /var/log/httpd/
access_log-2015090713  error_log-2015090713

この状態でまたリクエストを飛ばしたり httpd を再起動したりすると新しいログファイルができて書き込まれていることが確認できる。

$ wget -qO - http://localhost
Hello, World!
$ sudo systemctl restart httpd
$ sudo ls /var/log/httpd/
access_log  access_log-2015090722  error_log  error_log-2015090722

いじょう。

まとめ

今回は Apache httpd のログを syslog で rsyslog に飛ばした上で、できたログファイルを logrotate でローテートさせる方法について書いた。 アプリケーションのログを syslog で飛ばすようにしておけば、アプリケーション側でローテーションの細かいことを考える必要がなくなるので便利っぽい。