読者です 読者をやめる 読者になる 読者になる

cloverrose's blog

Python, Machine learning, Emacs, CI/CD, Webアプリなど

Django on HerokuのLoggingについて

いわゆるアクセス解析をするためにロギングをすることにしました。

なお、Herokuでは以下の性質からConsoleに印字可能文字をセパレーターとしてロギングしていくのが一番簡単で相性が良さそうだと思いました。
1. Fileには保存できないっぽい(要確認)
2. ログにタイムスタンプが自動でつく
3. heroku logsコマンドでASCII制御文字が見れない

出力するもの

今回はどのURLから飛んできたか(META['HTTP_REFERER'])とブラウザID(COOKIES['sessionid'])を出力する。
Request and response objects | Django documentation | Django

ソースコード(抜粋)

# myutil/mylogging.py
import logging
logger = logging.getLogger(__name__)

def access_log(func):
    def wrapper(request, *args, **kwargs):
        messages = []
        if 'HTTP_REFERER' in request.META:
            messages.append(request.META['HTTP_REFERER'])
        else:
            messages.append('<NULL>')
        if 'sessionid' in request.COOKIES:
            messages.append(request.COOKIES['sessionid'])
        else:
            messages.append(null_str)
        if 'HTTP_USER_AGENT' in request.META:
            messages.append(request.META['HTTP_USER_AGENT'])
        else:
            messages.append(null_str)
        logger.info('/'.join(messages)))
        return func(request, *args, **kwargs)
    return wrapper

# home/views.py
from myutil.mylogging import access_log

@access_log
def home(request):
    # 略

# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'myutil.mylogging': {
            'handlers': ['console'],
            'level': 'INFO',
        },
    }
}

ASCII制御文字

ASCII文字コード : IT用語辞典
ASCII - Wikipedia
(制御文字を使いたかったのは、セパレーターやNULL用文字列としてほぼ重複しないから)

Fileにログ出力

python:django:ログ出力設定 - HiiHahWIKI - making some notes for... -
(FileHandlerやStreamHandlerはPython標準でNullHandlerやAdminEmailHandlerがDjango標準)