佐賀人のIT技術者のブログ

IT技術、日常のブログです。たまに地元・佐賀について書きます。

【Python】マルチワーカー環境でのWebアプリログの残し方

Gunicorn と uWSGI を用いた Web アプリケーションのデプロイ

Gunicorn や uWSGI (またはそれに類するもの) を使って Web アプリケーションをデプロイする場合、クライアントのリクエストを処理するために複数のワーカープロセスが作られます。そのような環境では、 web アプリケーションに直接ファイルベースのハンドラを作ることは避けてください。 代わりに、 SocketHandler を使って別のプロセスとして動作するリスナーに web アプリケーションからログを送信するようにしてください。これは Supervisor のようなプロセス管理ツールを使うことで設定できます。

ロギングソケットのリスナーを実行する

作成中のロギングリスナーを実行するためには、 Supervisor のようなプロセス管理ツールを使う必要があるかもしれません。 [こちらの Gist] (https://gist.github.com/vsajip/4b227eeec43817465ca835ca66f75e2b)は Supervisor を使って上記の機能を実行するための必要最低限のファイルを提供しています。以下のファイルが必要になります:

ファイル 目的
prepare.sh 試験用の環境を準備する Bash スクリプト
supervisor.conf リスナーとマルチプロセスの web アプリケーションのための設定を含む Supervisor の設定ファイル
ensure_app.sh Supervisor が上記の設定で実行されていることを保証するための Bash スクリプト
log_listener.py ログイベントを受信してファイルに記録するソケットリスナープログラム
main.py リスナーに接続されたソケットを通じてロギングを実行する簡単な web アプリケーション
webapp.json web アプリケーションのための JSON 設定ファイル
client.py web アプリケーションを起動するための Python スクリプト

この web アプリケーションは、リクエストを処理する複数のワーカープロセスを起動する web アプリケーションサーバーである Gunicorn を使っています。ここに例として挙げた設定は、複数のワーカーがいかにして互いに衝突することなく同じログファイルに書き込みを行うことができるかを示しています --- ワーカーは全てソケットリスナーを通じてログを書き込むのです。

これらのファイルを試すためには、 POSIX 環境において以下を行なってください:

  1. Download ZIP ボタンを押して Gist を ZIP アーカイブとしてダウンロードしてください。

  2. アーカイブファイルをスクラッチディレクトリに展開してください。

  3. 準備のために、スクラッチディレクトリにおいて bash prepare.sh を実行してください。これにより Supervisor 関連のファイルおよびログファイルのための run サブディレクトリ、および bottle, gunicorn そして supervisor がインストールされる仮想環境を含む venv サブディレクトリが生成されます。

  4. bash ensure_app.sh を実行して Supervisor が上記の設定で実行されていることを確認してください。

  5. venv/bin/python client.py を実行して web アプリケーションを起動してください。これによりログにレコードが書き込まれるはずです。

  6. run サブディレクトリにあるログファイルを調べてください。最新のログは、パターン app.log* に一致する名前のファイルにあるはずです。ログは異なるワーカープロセスによって非決定論的な形で並行に処理されるため、特定の決まった順番にはなりません。

  7. リスナーと web アプリケーションは venv/bin/supervisorctl -c supervisor.conf shutdown を実行することでシャットダウンできます。

ありそうもないことですが、テスト環境で設定したポートが別の設定と衝突してしまった場合、設定ファイルを修正する必要があるかもしれません。

参考

Logging クックブック — Python 3.13.1 ドキュメント