複数のDjangoプロセスを起動している状態で、共通の設定でログを取りたいと思ったので、失敗も含めてメモ

※ Ubuntuのバージョンは14.04LTS

TimedRotatingFileHandlerを使ってみた(失敗)

ログはファイルに書き出してログローテーションをしたかったので、TimedRotatingFileHandlerを使ってみた。

'handlers': {
    'accesslog': {
        'level': 'INFO',
        'class': 'logging.handlers.TimedRotatingFileHandler',
        'filename': 'access.log',
        'when': 'MIDNIGHT',
        'formatter': 'verbose',
    },
 },
 'loggers': {
    'accesslog': {
        'handlers': ['accesslog'],
        'level': 'INFO',
        'propagate': True  
     },
  }

これでログは取れるんだけど、しばらく放っておいてもほんの一部しかログが取れない。whenを「D」にしたりしてみたんだけど、変わらない。よくわからんなと思ったら、「PythonのFileHandlerを複数プロセスで同時に使ってはいけない」という情報が出てきた。まじか。

SocketHandlerを使ってみた(実装失敗)

そこで、上記参照ページで対策として書かれていたSocketHandlerを使ってログを取れないか試してみた。Python logging 各種出力ハンドラーの使い方についてを見ながら、socketの受け側は該当コードをとりあえずコピペ、送信側は設定を

'handlers': {
    'accesslog': {
        'level': 'INFO',
        'class': 'logging.handlers.SocketHandler',
        'ip': 'localhost',
        'port': '12345',
        'formatter': 'verbose',
    },
 },
 'loggers': {
    'accesslog': {
        'handlers': ['accesslog'],
        'level': 'INFO',
        'propagate': True  
     },
  }

として、動かしてみた。でも結局うまくいかなかった。うんともすんとも言わなかったのと、なんかエラーが出るらしい?という情報も見たので(あれ?これパッチがちゃんと当たってる?)、あまり深く調べずに採用をやめた。

SysLogHandlerを使ってみた(失敗のち成功)

SocketHandlerは早々にあきらめて、SysLogHandlerを使ってみた。

from logging.handlers import SysLogHandler
'handlers': {
    'accesslog': {
        'level': 'INFO',
        'class': 'logging.handlers.SysLogHandler',
        'facilyty': 'SysLogHandler.LOG_LOCAL0,
        'formatter': 'verbose',
    },
 },
 'loggers': {
    'accesslog': {
        'handlers': ['accesslog'],
        'level': 'INFO',
        'propagate': True  
     },
  }

django以外にrsyslogの設定も必要

$ cat /etc/rsyslog.d/hoge.conf
local0.*                         /var/log/hoge.log
$ sudo service rsyslogd restart

としてみたが動かない・・・。色々調べてみると

Logging django apps to syslogなどのソースを見ると、

handlersの項目に

'address': '/dev/log',

とあったので、それを加えるとうまくいった。/dev/logはシステムロギングのデフォルトエントリなのでそこをログの書き出し先として指定しないといけないのね。なるほど。