web-dev-qa-db-ja.com

Python withgunicornでロギングモジュールを使用する方法

フラスコベースのアプリがあります。ローカルで実行する場合はコマンドラインから実行しますが、デプロイする場合は複数のワーカーを含むgunicornで開始します。

loggingモジュールを使用してファイルにログを記録したいと思います。これについて私が見つけたドキュメントは https://docs.python.org/3/library/logging.htmlhttps://docs.python.org/3/ howto/logging-cookbook.html

アプリがgunicornで起動される可能性がある場合、ロギングを使用する正しい方法について混乱しています。ドキュメントはスレッド化に対応していますが、マスタープロセスを制御できると想定しています。混乱のポイント:

logger = logging.getLogger('myapp')は異なるgunicornワーカースレッドで同じロガーオブジェクトを返しますか?

ファイルにログを記録するためにログFileHandlerをロガーに添付している場合、異なるワーカーでこれを複数回実行しないようにするにはどうすればよいですか?

私の理解(間違っているかもしれません)は、logger.setLevel(logging.DEBUG)を呼び出すだけで、デフォルトのログレベルが高く、デバッグメッセージを無視する可能性があるルートロガーを介してメッセージを送信するため、alsoデバッグメッセージを通過させるには、logging.basicConfig(logging.DEBUG)を呼び出す必要があります。しかし、ドキュメントには、スレッドからlogging.basicConfig()を呼び出さないように書かれています。 gunicornを使用するときにルートログレベルを正しく設定するにはどうすればよいですか?または私はする必要はありませんか?

5
user2428107

各ワーカーは独自のメモリを備えた分離されたプロセスであるため、異なるワーカー間で同じロガーを実際に共有することはできません。

マスタープロセスはワーカーの管理のみを考慮しているため、コードはこれらのワーカー内で実行されます。

マスタープロセスは、さまざまなプロセス信号をリッスンし、それに応じて反応する単純なループです。 TTIN、TTOU、CHLDなどのシグナルをリッスンすることにより、実行中のワーカーのリストを管理します。 TTINとTTOUは、実行中のワーカーの数を増減するようにマスターに指示します。

Gunicorn自体には、2つの主要な実行モードがあります

  • 同期
  • 非同期

したがって、これはスレッド化とは異なり、マルチプロセッシングです。

ただし、Gunicorn 19以降、スレッドオプションを使用して複数のスレッドでリクエストを処理できます。スレッドの使用は、gthreadワーカーの使用を前提としています。

これを念頭に置いて、ロギングコードは一度記述され、新しいワーカーが作成されるたびに複数回呼び出されます。 Singeltonパターンを使用して、同じロガーインスタンスが同じワーカー内で使用されていることを確認できます。


ロガー自体を構成するには、ルートロガーレベルとさまざまなロガーレベルを設定する通常のプロセスに従う必要があります。

basicConfig() すでに設定されている場合、ルートハンドラーには影響しません。

ルートロガーにハンドラーが既に構成されている場合、この関数は何もしません。

ルートにレベルを明示的に設定するには、

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(name)

次に、レベルをハンドラーまたはロガーレベルで設定できます。

handler = logging.handlers.TimedRotatingFileHandler(log_path, when='midnight', backupCount=30)                                                                                                             
handler.setLevel(min_level)

ロギング関連の詳細については、この同様の回答を確認できます ロギングレベルの設定

その他のリソース:

http://docs.gunicorn.org/en/stable/design.html

1
Ahmed Kamal