web-dev-qa-db-ja.com

Gunicornでホストされている場合、Flaskアプリケーションがログを作成しないのはなぜですか?

Flaskを使用するWebアプリケーションにロギングを追加しようとしています。

組み込みサーバー(つまりpython3 server.py)を使用してホストされている場合、ロギングは機能します。 Gunicornを使用してホストされている場合、ログファイルは作成されません。

問題を再現する最も簡単なコードは次のとおりです。

#!/usr/bin/env python

import logging
from flask import Flask
flaskApp = Flask(__name__)


@flaskApp.route('/')
def index():
    flaskApp.logger.info('Log message')
    print('Direct output')
    return 'Hello World\n'


if __== "__main__":
    logHandler = logging.FileHandler('/var/log/demo/app.log')
    logHandler.setLevel(logging.INFO)
    flaskApp.logger.addHandler(logHandler)
    flaskApp.logger.setLevel(logging.INFO)
    flaskApp.run()

アプリケーションは次を使用して呼び出されます。

gunicorn server:flaskApp -b :80 -w 4
    --access-gfile /var/log/demo/access.log
    --error-logfile /var/log/demo/error.log

サイトのホームページにリクエストを行うと、次のことが起こります。

  1. 応答として予想されるHTTP 200 "Hello World\n"を受け取ります。

  2. /var/log/demo/access.logにはリクエストのトレースがあります。

  3. /var/log/demo/error.logは変わりません(ブートイベントのみがあります)。

  4. ターミナルには「直接出力」行があります。

  5. 「/var/log/demo/app.log」はありません。アプリケーションを起動する前にファイルを作成しても、ファイルは変更されません。

ご了承ください:

  • ディレクトリ/var/log/demoは誰でもアクセス(読み取り、書き込み、実行)できるため、これは権限の問題ではありません。

  • StreamHandlerを2番目のハンドラーとして追加しても、ターミナルにもGunicornログファイルにも「ログメッセージ」メッセージのトレースはありません。

  • Gunicornはpip3 install gunicornを使用してインストールされるため、Pythonバージョンとの不一致はないはずです。

何が起こっていますか?

37

python3 server.pyを使用すると、server3.pyスクリプトが実行されます。

gunicorn server:flaskApp ...を使用する場合、gunicorn起動スクリプトを実行します。このスクリプトはimportsモジュールserverを検索し、変数flaskAppを探しますそのモジュール。

server.pyがインポートされているため、__name__変数には"server"ではなく"__main__"が含まれ、ログハンドラーのセットアップコードは実行されていません。

ログハンドラーのセットアップコードをif __== "__main__":スタンザの外側に移動するだけで済みます。ただし、gunicornがserverをインポートするときにnotを実行したいので、flaskApp.run()を必ず保持してください。

if __== “__main__”:の機能 の詳細

32
Jeremy Allen

このアプローチは私のために機能します:Pythonロギングモジュールをインポートし、それにgunicornのエラーハンドラーを追加します。その後、ロガーはgunicornエラーログファイルにログインします。

import logging

app = Flask(__name__)

gunicorn_error_logger = logging.getLogger('gunicorn.error')
app.logger.handlers.extend(gunicorn_error_logger.handlers)
app.logger.setLevel(logging.DEBUG)
app.logger.debug('this will show in the log')

Gunicorn起動スクリプトは、ログエントリを次のようなファイルに出力するように構成されています。

gunicorn main:app \
    --workers 4 \
    --bind 0.0.0.0:9000 \
    --log-file /app/logs/gunicorn.log \
    --log-level DEBUG \
    --reload
24
pkout