DRFでdjango-requestを使ってみた話です
できること
- APIリクエスト履歴の保存
- 保存できる項目
- ステータスコード
- メソッド
- パス
- リクエスト日時
- SSLかどうか
- ajax通信かどうか
- ipアドレス(問題あり、後述)
- リファラ
- ユーザーエージェント
- 言語
- ユーザーID
- 保存できる項目
- django-adminで見れて、GoogleAnalyticsのようにグラフィカルに表示もできる
- ただしあまり複雑なフィルターは無いようなので、その場合はクエリで対応する必要がありそう
できないこと
- POSTパラメータなどリクエストbodyの内容の履歴
- セキュリティ的な観点もあるので、POSTパラメータの保存はリスキーではありますね
手順
1 pip等でインストール
pip install django-request
2 INSTALLED_APPS
にrequest
追加
3 MIDDLEWARE
にrequest.middleware.RequestMiddleware
追加
4 マイグレーション実行
manage.py migrate
以上で、request_request
テーブルにAPIリクエストが保存されるようになります
カスタマイズ
除外パス
django-adminのリクエストまで保存されてしまうので除外設定した方がいいと思います
自分はこんな感じにしました(healthはヘルスチェック用のパス)
REQUEST_IGNORE_PATHS = (
r'^admin/', r'^docs/', r'^health$', r'\.ico$', r'^static/'
)
IPアドレスについて
IPアドレスはREMOTE_ADDR
を使ってるため、ロードバランサがあると正しく取れません
苦肉の策でこんな感じにしました(もっといいやり方があれば教えて欲しい)
from request.middleware import RequestMiddleware
class XRequestMiddleware(RequestMiddleware):
def process_response(self, request, response):
# django-requestの中でREMOTE_ADDRをIPとして保存してしまっているので、無理やりだけどHTTP_X_FORWARDED_FORに変更する
http_x_forwarded_for_ip = request.META.get('HTTP_X_FORWARDED_FOR')
remote_addr_ip = request.META.get('REMOTE_ADDR')
if http_x_forwarded_for_ip:
request.META['REMOTE_ADDR'] = http_x_forwarded_for_ip
response = super().process_response(request, response)
if http_x_forwarded_for_ip:
request.META['REMOTE_ADDR'] = remote_addr_ip
return response
ちなみにHTTP_X_FORWARDED_FOR
はIPアドレスがカンマ区切りで入ってくることがあるので、REQUEST_IGNORE_IP
を使うなら以下のようにしたほうがいいですね
http_x_forwarded_for_ip = request.META.get('HTTP_X_FORWARDED_FOR').split(',')[0]
所感
簡単に組み込めますし、データドリブンには必須じゃないでしょうか
あとは、データが溜まった時のバックアップが課題ですね
しかし、IPアドレスのところはアップデートして欲しいな・・・