くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Djangoでログをカスタマイズして、レスポンス時の詳細をロギングする

Djangoを利用している際に、標準のロギングだとリクエスト時のパラメタが表示されない。。
POSTだとURLしか確認できないため、拡張してみたときの備忘録。

リクエスト/レスポンスに関する拡張ポイント

Djangoでは、色々と拡張ポイントが用意されているらしく、
Middlewareを作ってその拡張ポイントを利用することができる。

今回調べたのはこんな感じ。ほかにもprocess_template_responseとかprocess_viewとかあるらしい。

# -*- coding: utf-8 -*
class LoggingRequestMiddleware(object):

  """ リクエスト時のハンドリング """
  def process_request(self, request):
  
  """ リクエスト時に例外発生時のハンドリング """
  def process_exception(self, request, exception)
  
  """ レスポンス返却時のハンドリング """
  def process_response(self, request, response):
    return response

レスポンス時のステータスとリクエスト詳細をログに表示する

ログを出力するMiddlewareを作成する

process_responseを拡張して、パラメタやログインユーザも表示する用に変更してみた。

# -*- coding: utf-8 -*
import logging
import traceback

class LoggingRequestMiddleware(object):
    logger = logging.getLogger('django.request')

    def process_response(self, request, response):
        try:
            request_info = self.__get_request_info(request)
            user_info = self.__get_user_info__(request.user)

            msg = u"{} {} \t{}".format(response.status_code, request_info, user_info)
            self.logger.info(msg)
        except:
            self.logger.error(traceback.format_exc())

        return response

    def __get_request_info(self, request):
        if request.method == u'GET':
            params = self.__format_params__(dict(request.GET))
        elif request.method == u'POST':
            params = self.__format_params__(dict(request.POST))
        else:
            params = u''

        return u'{} {}\tparam:[{}]'.format(request.method, request.get_full_path(), params)

    def __get_user_info__(self, user):
        if user is None:
            return u'user: - '

        try:
            return u'user: {}({})'.format(user, user.id)
        except:
            return u'user: - '

    def __format_params__(self, params):
        param_items = filter(lambda (k, v):k != u'csrfmiddlewaretoken',params.items())
        return u', '.join([u'{}={}'.format(key, self.__list_str__(value)) for (key, value) in param_items])

    def __list_str__(self, params):
        if params is None:
            return u''
        elif len(params) == 1:
            return u'{}'.format(params[0])
            
        return u'[' + u', '.join(u'{}'.format(item) for item in params) + u']'

作成したMiddlewareを利用するようにsettings.pyを修正する

作ったMiddlewareを有効にするには、MIDDLEWARE_CLASSESに追加すればOK!

MIDDLEWARE_CLASSES = [
   ・・・
    'app.middle.LoggingRequestMiddleware'
]

以上!!

参考にしたサイト様