今回は mod_wsgi で動作させた WSGI アプリケーションのログを syslog で飛ばして、それを rsyslog で受信して logrotate でローテーションさせてみる。 尚、Apache httpd 本体のログを syslog で飛ばす方法は以下を参照のこと。
検証用の環境には CentOS7 を使った。
$ cat /etc/redhat-release CentOS Linux release 7.1.1503 (Core) $ uname -r 3.10.0-229.11.1.el7.x86_64
必要なパッケージをインストールする
mod_wsgi など必要なパッケージをインストールする。 rsyslog と logrotate は最初から入っていると思う。
$ sudo yum -y install mod_wsgi rsyslog logrotate
WSGI アプリケーションを用意する
次に WSGI に対応したアプリケーションを用意する。 mod_wsgi の場合、application という名前のシンボルを自動的に読み込むようになっている。 ログの設定は設定ファイルから読み込むようにした。
$ cat << EOF | sudo tee /var/www/cgi-bin/myapp.wsgi > /dev/null # -*- coding: utf-8 -*- import os import logging from logging import config logging.config.fileConfig( '/var/www/cgi-bin/logging.conf', disable_existing_loggers=False, ) LOG = logging.getLogger(__name__) def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) LOG.info('Hello, World!') return ['Hello, World!\n'] EOF
WSGI アプリケーションを動作させるために mod_wsgi の設定ファイルを用意する。 先ほど作成した WSGI アプリケーションの場所を指定することになる。 また、動作させる場合はデーモンモードにすると良い。
$ cat << EOF | sudo tee /etc/httpd/conf.d/wsgi.conf > /dev/null WSGISocketPrefix /var/run/wsgi WSGIDaemonProcess myapp-process WSGIScriptAlias /myapp /var/www/cgi-bin/myapp.wsgi <Location /myapp> WSGIProcessGroup myapp-process </Location> EOF
mod_wsgi の動作モードについては以下の記事に書いた。
WSGI アプリケーションが参照する、ロギングの設定ファイルを用意する。 ここで syslog でログを飛ばすように設定している。 ファシリティには local2 (SysLogHandler.LOG_LOCAL2) を使った。
$ cat << EOF | sudo tee /var/www/cgi-bin/logging.conf > /dev/null [loggers] keys=root [handlers] keys=syslogHandler [formatters] keys=simpleFormatter [logger_root] level=DEBUG handlers=syslogHandler [handler_syslogHandler] class=logging.handlers.SysLogHandler level=DEBUG formatter=simpleFormatter args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_LOCAL2) [formatter_simpleFormatter] format=%(asctime)s - %(process)d - %(threadName)s - %(name)s - %(levelname)s - %(message)s @ %(pathname)s:%(lineno)d EOF
ロギングの設定ファイルの詳細については以下を参照する。
16.6. logging — Python 用ロギング機能 — Python 3.5.2 ドキュメント
rsyslog を設定する
今度は syslog を受ける側の rsyslog を設定する。 まずは、syslog が UDP で転送されてくるので、それを受信できるようにする。
$ sudo sed -i.back -e " s:^#\(\$ModLoad imudp\)$:\1: s:^#\(\$UDPServerRun 514\)$:\1: " /etc/rsyslog.conf
ファシリティ local2 のログを保存する先を指定する。
$ cat << EOF | sudo tee /etc/rsyslog.d/mod_wsgi.conf > /dev/null local2.* /var/log/mod_wsgi/mod_wsgi.log EOF
logrotate を設定する
rsyslog で保存したログを logrotate でローテーションする設定を用意する。
$ cat << EOF | sudo tee /etc/logrotate.d/mod_wsgi > /dev/null /var/log/mod_wsgi/mod_wsgi.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
wget で WSGI アプリケーションにアクセスしてみる。
$ wget -qO - http://localhost/myapp
Hello, World!
すると、ログファイルが作られたことが確認できる。
$ sudo cat /var/log/mod_wsgi/mod_wsgi.log Sep 12 23:49:16 2015-09-12 23: 49:16,399 - 4227 - MainThread - _mod_wsgi_18cb3436d24acb6e50a4d2521dd7445a - INFO - Hello, World! @ /var/www/cgi-bin/myapp.wsgi:16
動作確認のために、できたログファイルを強制的にローテーションさせてみよう。
$ sudo logrotate -fv /etc/logrotate.d/mod_wsgi reading config file /etc/logrotate.d/mod_wsgi Handling 1 logs rotating pattern: /var/log/mod_wsgi/mod_wsgi.log forced from command line (3 rotations) empty log files are not rotated, old logs are removed considering log /var/log/mod_wsgi/mod_wsgi.log log needs rotating rotating log /var/log/mod_wsgi/mod_wsgi.log, log->rotateCount is 3 dateext suffix '-2015091223' glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' glob finding old rotated logs failed renaming /var/log/mod_wsgi/mod_wsgi.log to /var/log/mod_wsgi/mod_wsgi.log-2015091223 running postrotate script
みるとちゃんとログファイルがローテーションされている。
$ sudo ls /var/log/mod_wsgi
mod_wsgi.log-2015091223
もちろん、再度アクセスすると新しいログファイルの方に書き込みが行われる。
$ wget -qO - http://localhost/myapp Hello, World! $ sudo ls /var/log/mod_wsgi mod_wsgi.log mod_wsgi.log-2015091223
めでたしめでたし。
まとめ
今回は mod_wsgi のログを rsyslog に飛ばして logrotate でローテーションするところを確認してみた。 尚、今回使った Python のロギング設定ファイルは、mod_wsgi に限らず使うことができる。 通常のアプリケーションのログを syslog で転送する場合にも有効なので、覚えておきたい。
スマートPythonプログラミング: Pythonのより良い書き方を学ぶ
- 作者: もみじあめ
- 発売日: 2016/03/12
- メディア: Kindle版
- この商品を含むブログを見る