web-dev-qa-db-ja.com

なぜFlaskフロントでUWSGIを使用しているときにロガーがdockerにログインしないのですか?

Flaskの内部にDockerアプリケーションがあります。これは、UWSGIなしで実行しているときに_docker logs_にログインしていました。これで、以下の設定でUWSGIを使用して、Docker内でアプリケーションを実行しました。

_[uwsgi]

master = true

processes = 5
threads = 2

socket = 127.0.0.1:3031
chmod-socket = 664
stats=0.0.0.0:30310

chdir = /etc/fantas

uid = root
gid = root

wsgi-file=uwsgi_fantas.py
callable=app

vacuum = true
_

_uwsgi_fantas.py_ファイルには以下が含まれます。

_from fantas.fantas_app import FantasApp

app = FantasApp().setup()
_

setupメソッドはappを返します。

_from flask_restful import Api
from fantas import app

class FantasApp(object):
    def setup(self):
        api = Api(app)
        api.add_resource(Token, '/users')

        return app
_

最後に、Flaskフレームワークを開始する部分は、プロジェクトのルートディレクトリの___init__.py_内にあります。

_from flask import Flask
import logging

app = Flask(__name__)

s_handler = logging.StreamHandler()
s_handler.setLevel(logging.DEBUG)
app.logger.addHandler(s_handler)
_

UWSGIappオブジェクトと直接連携するため、___init__.py_内でロガーを構成しましたが、問題は、実行時にDockerに何もログインせず、単にUWSGIリクエストを記録することです。

App.loggerの構成プロセスの何が問題になっていますか?

問題は解決しましたが、ログが重複するようになりました!


EDIT-1:app.logger.setLevel(logging.DEBUG)を設定し、FlaskDockerに正常にログインしたようです。奇妙な部分は、3回ログに記録することです!すべてのロガー設定とハンドラーを削除し、使用しました:

_app.logger.setLevel(logging.DEBUG)
_

しかし、今では2回ログに記録されます。

_proj_fantas.1.huagnqqpzo1n@linuxkit-025000000001    | [2018-07-13 07:02:38,008] DEBUG in token: [Token] authenticating user...
proj_fantas.1.huagnqqpzo1n@linuxkit-025000000001    | DEBUG:flask.app:[Token] authenticating user...
_

なぜそうなのですか?


編集-2:

_app.logger.handlers_の出力は_[<logging.StreamHandler object at 0x7f0f430ca8d0>]_です。先ほど初期化したStreamHandlerを表示するだけで、それ以上のものはありません。


編集-3:

Docker内の_ps -ef_コマンドの出力:

_UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 15:26 ?        00:00:00 uwsgi uwsgi_coconuty.ini
root        10     1  0 15:26 ?        00:00:00 uwsgi uwsgi_coconuty.ini
root        12     1  0 15:26 ?        00:00:00 uwsgi uwsgi_coconuty.ini
root        13     1  0 15:26 ?        00:00:00 uwsgi uwsgi_coconuty.ini
root        15     1  0 15:26 ?        00:00:00 uwsgi uwsgi_coconuty.ini
root        16     1  0 15:26 ?        00:00:00 uwsgi uwsgi_coconuty.ini
root        20     0  0 15:27 pts/0    00:00:00 /bin/bash
root       112    20  0 15:28 pts/0    00:00:00 ps -ef
_

Dockerの内部で実行中の他のプロセスはありません。

12
ALH

まず最初に、Flaskログがバージョン0.9から現在の安定版1.0.2に初期化される方法に最近の変更があります。これを確認できます here 。あなたのdockerイメージは最新バージョンを使用していると仮定しています。

その場合、カスタムロギング設定がなくても、実際には出力ストリームのロギングが行われますが、WARNINGログ(DEBUGおよびINFO)よりも低いレベルでフィルタリングされます。これは、ログを初期化するFlaskに依存しており、-debugフラグを設定していない場合に発生します(uwsgiの場合)。

ロギングを構成するときに検討できる複数の戦略があります。 1つの提案は、アプリを定義する前に、uwsgiマスターで library自体 で示されるdictConfig初期化を使用してからフォークすることです。例に従って、__init__.pyで:

from flask import 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',
        'formatter': 'default'
    }},
    'root': {
        'level': 'DEBUG',
        'handlers': ['wsgi']
    }
})

app = Flask(__name__)

EDIT-1で言及した問題は、python ロギングの伝播の問題 のように見えます。スタンドアロンの場合があります。デバッグが簡単、 こちら

ログが示すように、ストリームハンドラを1つしか設定していなくても、おそらく親が接続されています。親をチェックすると、おそらくEDIT-2で言及したものとは異なるdifferentハンドラーがアタッチされます:

print logger.handlers
[<logging.StreamHandler object at 0x7f15669c1550>]
print logger.parent.handlers
[<logging.StreamHandler object at 0x7f15669c1610>]

これは、ログの伝播が有効になっていて、どこかでログの初期化が行われたときに発生します。 pythonのソースコードcallHandlersを見ると、伝播の仕組みを確認できます。

    ...
    hdlr.handle(record)
    if not c.propagate:
        c = None    #break out
    else:
        c = c.parent
    ...

ケース(Flask)に戻り、ログのトレースを見ると、flask.appという名前のロガーがあります。これは Flask自体 によって作成されたものです。フォーマットされたバージョンとフォーマットされていないバージョン( logging.BASIC_FORMAT )がそれぞれあります。したがって、コードまたはインポートするライブラリのいずれかで初期化されている可能性があります。

これを解決する方法は複数あります。

  • 伝播をfalseに設定する(簡単な解決策、ただし回避策)
  • 「無効な」構成を検索して削除する
  • Flaskロギングチュートリアルが示唆するように、アプリをインスタンス化する前にdictConfig初期化を使用します
3
null