2020年12月1日火曜日

flask でリクエスト ID をログに埋め込む方法

概要

flask でリクエスト ID を生成しログに含める方法を紹介します
flask-log-request-id というモジュールがあるのでこれを使うと比較的簡単に実現できます

環境

  • macOS 10.15.7
  • Python 3.8.5
    • flask 1.1.2
    • flask-log-request-id 0.10.1

インストール

  • pipenv install flask-log-request-id

現在のリクエスト ID を取得する

current_request_id() を参照するだけです

  • vim app.py
import logging
from flask import Flask
from flask_log_request_id import RequestID, current_request_id

app = Flask(__name__)
RequestID(app)

@app.route('/')
def hello():
    app.logger.setLevel(logging.INFO)
    app.logger.info(current_request_id())
    return 'ok'
  • FLASK_APP=app.py pipenv run flask run 1>/dev/null

ロガーにリクエスト ID を追加する

ハンドラを作成して RequestIDLogFilter を追加します

  • vim app.py
import logging
from flask import Flask
from flask_log_request_id import RequestID, RequestIDLogFilter

app = Flask(__name__)
RequestID(app)

handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - level=%(levelname)s - request_id=%(request_id)s - %(message)s"))
handler.addFilter(RequestIDLogFilter())
logging.getLogger().addHandler(handler)

@app.route('/')
def hello():
    app.logger.setLevel(logging.INFO)
    app.logger.info("hello")
    return 'ok'
  • FLASK_APP=app.py pipenv run flask run 1>/dev/null

レスポンスのヘッダに含める

@app.after_request で response オブジェクトに追加するだけです

  • vim app.py
import logging
from flask import Flask
from flask_log_request_id import RequestID, RequestIDLogFilter, current_request_id

app = Flask(__name__)
RequestID(app)

handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - level=%(levelname)s - request_id=%(request_id)s - %(message)s"))
handler.addFilter(RequestIDLogFilter())
logging.getLogger().addHandler(handler)

@app.after_request
def append_request_id(response):
    response.headers.add('X-Request-Id', current_request_id())
    return response

@app.route('/')
def hello():
    app.logger.setLevel(logging.INFO)
    app.logger.info("hello")
    return 'ok'

おまけ: werkzeug のログを表示させない

  • vim app.py
import logging
from flask import Flask
from flask_log_request_id import RequestID, RequestIDLogFilter, current_request_id

app = Flask(__name__)
RequestID(app)

handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - level=%(levelname)s - request_id=%(request_id)s - %(message)s"))
handler.addFilter(RequestIDLogFilter())
logging.getLogger().addHandler(handler)

wlogger = logging.getLogger('werkzeug')
wlogger.setLevel(logging.ERROR)

@app.route('/')
def hello():
    app.logger.setLevel(logging.INFO)
    app.logger.info("hello")
    return 'ok'

最後に

celery とのシナジーもあるモジュールなので celery を使っている場合にはオススメです

参考サイト

0 件のコメント:

コメントを投稿