ロギング—フラスコのドキュメント

提供:Dev Guides
< FlaskFlask/docs/1.0.x/logging
移動先:案内検索

ロギング

Flaskは標準のPython loggingを使用します。 すべてのFlask関連のメッセージは、'flask'ロガー名前空間に記録されます。 Flask.loggerは、'flask.app'という名前のロガーを返し、アプリケーションのメッセージをログに記録するために使用できます。

@app.route('/login', methods=['POST'])
def login():
    user = get_user(request.form['username'])

    if user.check_password(request.form['password']):
        login_user(user)
        app.logger.info('%s logged in successfully', user.username)
        return redirect(url_for('index'))
    else:
        app.logger.info('%s failed to log in', user.username)
        abort(401)

基本設定

プロジェクトのロギングを構成する場合は、プログラムの起動時にできるだけ早く構成する必要があります。 ロギングを構成する前にapp.loggerにアクセスすると、デフォルトのハンドラーが追加されます。 可能であれば、アプリケーションオブジェクトを作成する前にロギングを設定してください。

この例では、dictConfig()を使用して、すべてのログを除いて、Flaskのデフォルトと同様のログ構成を作成します。

from logging.config import dictConfig

dictConfig({
    'version': 1,
    'formatters': {'default': {
        'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
    }},
    'handlers': {'wsgi': {
        'class': 'logging.StreamHandler',
        'stream': 'ext://flask.logging.wsgi_errors_stream',
        'formatter': 'default'
    }},
    'root': {
        'level': 'INFO',
        'handlers': ['wsgi']
    }
})

app = Flask(__name__)

デフォルト設定

自分でログを設定しない場合、FlaskはStreamHandlerapp.loggerに自動的に追加します。 リクエスト中に、WSGIサーバーによって指定されたenviron['wsgi.errors'](通常はsys.stderr)のストリームに書き込みます。 リクエストの外部では、sys.stderrにログを記録します。


デフォルトハンドラーの削除

app.loggerにアクセスした後にロギングを構成し、デフォルトのハンドラーを削除する必要がある場合は、それをインポートして削除できます。

from flask.logging import default_handler

app.logger.removeHandler(default_handler)

管理者への電子メールエラー

本番用のリモートサーバーでアプリケーションを実行する場合、ログメッセージを頻繁に確認することはおそらくないでしょう。 WSGIサーバーはおそらくログメッセージをファイルに送信します。ユーザーが何か問題が発生したと言った場合にのみ、そのファイルをチェックします。

バグの発見と修正に積極的に取り組むために、エラー以上がログに記録されたときに電子メールを送信するようにlogging.handlers.SMTPHandlerを構成できます。

import logging
from logging.handlers import SMTPHandler

mail_handler = SMTPHandler(
    mailhost='127.0.0.1',
    fromaddr='[email protected]',
    toaddrs=['[email protected]'],
    subject='Application Error'
)
mail_handler.setLevel(logging.ERROR)
mail_handler.setFormatter(logging.Formatter(
    '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
))

if not app.debug:
    app.logger.addHandler(mail_handler)

これには、同じサーバー上にSMTPサーバーが設定されている必要があります。 ハンドラーの構成の詳細については、Pythonのドキュメントを参照してください。


リクエスト情報の挿入

IPアドレスなど、リクエストに関する詳細情報を確認すると、一部のエラーのデバッグに役立つ場合があります。 logging.Formatterをサブクラス化して、メッセージで使用できる独自のフィールドを挿入できます。 Flaskのデフォルトハンドラー、上記で定義されたメールハンドラー、またはその他のハンドラーのフォーマッターを変更できます。

from flask import has_request_context, request
from flask.logging import default_handler

class RequestFormatter(logging.Formatter):
    def format(self, record):
        if has_request_context():
            record.url = request.url
            record.remote_addr = request.remote_addr
        else:
            record.url = None
            record.remote_addr = None

        return super().format(record)

formatter = RequestFormatter(
    '[%(asctime)s] %(remote_addr)s requested %(url)s\n'
    '%(levelname)s in %(module)s: %(message)s'
)
default_handler.setFormatter(formatter)
mail_handler.setFormatter(formatter)

その他のライブラリ

他のライブラリはロギングを広範囲に使用する可能性があり、それらのログからの関連メッセージも表示したい場合があります。 これを行う最も簡単な方法は、アプリロガーだけでなくルートロガーにハンドラーを追加することです。

from flask.logging import default_handler

root = logging.getLogger()
root.addHandler(default_handler)
root.addHandler(mail_handler)

プロジェクトによっては、ルートロガーだけを構成するのではなく、関心のある各ロガーを個別に構成する方が便利な場合があります。

for logger in (
    app.logger,
    logging.getLogger('sqlalchemy'),
    logging.getLogger('other_package'),
):
    logger.addHandler(default_handler)
    logger.addHandler(mail_handler)

Werkzeug

Werkzeugは、基本的な要求/応答情報を'werkzeug'ロガーに記録します。 ルートロガーにハンドラーが構成されていない場合、WerkzeugはそのロガーにStreamHandlerを追加します。


フラスコ拡張

状況に応じて、拡張機能はapp.loggerまたは独自の名前付きロガーにログを記録することを選択する場合があります。 詳細については、各拡張機能のドキュメントを参照してください。