19

私はしばらくの間、マルチプロセッシングのロギングに苦労してきましたが、それには多くの理由があります。

私の理由の 1 つは、なぜ別の get_logger.

もちろん、私はこの質問を見てきましたが、 multiprocessing.get_logger が返すロガーは、ロギング処理をスムーズにするために「プロセス共有ロック」の魔​​法を行っているようです。

そこで、今日、Python 2.7 のマルチプロセッシング コード (/multiprocessing/util.py) を調べたところ、このロガーは単純な logging.Logger であり、魔法のようなものはほとんどないことがわかりました。

get_logger 関数の直前の Python ドキュメントの説明は次のとおりです。

ロギングの一部のサポートが利用可能です。ただし、logging パッケージはプロセス共有ロックを使用しないため、(ハンドラのタイプによっては) 異なるプロセスからのメッセージが混同される可能性があることに注意してください。

では、間違ったロギング ハンドラーを使用すると、get_logger ロガーでさえ問題が発生する可能性があります。しばらくの間、ログに get_logger を使用するプログラムを使用しました。ログを StreamHandler に出力し、(どうやら) 混同されることはありません。

今私の理論は:

  1. multiprocessing.get_logger はプロセス共有ロックをまったく行いません
  2. StreamHandler はマルチプロセッシングで機能しますが、FileHandler は機能しません
  3. この get_logger ロガーの主な目的は、プロセスのライフサイクルを追跡することであり、プロセスの名前/ID の種類を既にログに記録する、入手が簡単ですぐに使用できるロガーを提供することです。

質問は次のとおりです。

私の理論は正しいですか?

この get_logger をどのように/なぜ/いつ使用しますか?

4

2 に答える 2

7

はい、 multiprocessing.get_logger() がプロセス共有ロックを行わないことは正しいと思います-あなたが言うように、ドキュメントにもこれが記載されています。すべての賛成票にもかかわらず、あなたがリンクしている質問は、そうであると述べていることに欠陥があるようです(疑いの利益を得るために、それは10年以上前に書かれたので、おそらくそれはある時点でそうでした)。

なぜ multiprocessing.get_logger() が存在するのですか? ドキュメントはそれを言う:

マルチプロセッシングで使用されるロガーを返します。必要に応じて、新しいものを作成します。

最初に作成されたとき、ロガーにはレベル logging.NOTSET があり、デフォルト ハンドラーはありません。このロガーに送信されたメッセージは、デフォルトではルート ロガーに伝達されません。

つまり、ロガーのロギング レベルが NOTSET に設定されているため、ログ メッセージが生成されないため、デフォルトではマルチプロセッシング モジュールはログ出力を生成しません。

マルチプロセッシングの問題であると思われるコードに問題が発生した場合、ログ出力の欠如はデバッグには役立ちません。それが multiprocessing.get_logger() の目的です-デフォルトのログ設定を上書きしてログを取得し、それが何をしているかを確認できるように、マルチプロセッシング モジュール自体。

multiprocessing.get_logger() の使用方法を尋ねたので、そのように呼び出して、通常の方法でロガーを構成します。次に例を示します。

logger = multiprocessing.get_logger()
formatter = logging.Formatter('[%(levelname)s/%(processName)s] %(message)s')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)

# now run your multiprocessing code

そうは言っても、ドキュメントに従って、実際には便宜上、代わりに multiprocessing.log_to_stderr() を使用することをお勧めします。

この関数は get_logger() の呼び出しを実行しますが、get_logger によって作成されたロガーを返すことに加えて、format を使用して出力を sys.stderr に送信するハンドラーを追加します。'[%(levelname)s/%(processName)s] %(message)s'

つまり、非常に多くのロギング構成を自分で設定する必要がなくなり、代わりに次のようにしてマルチプロセッシングの問題のデバッグを開始できます。

logger = multiprocessing.log_to_stderr()
logger.setLevel(logging.INFO)

# now run your multiprocessing code

繰り返しますが、これは構成されて使用されている通常のモジュール ロガーにすぎません。つまり、特別なことやプロセスセーフなことは何もありません。multiprocessing モジュール自体の内部で何が起こっているかを確認できます。

于 2020-05-28T22:15:55.157 に答える
3

この回答はget_logger具体的なものではありませんが、おそらくこの投稿で提案されているアプローチを使用できますか? QueueHandler/クラスは、パッケージQueueListenerを介して以前の Python バージョンで使用できることに注意してください( PyPIでも使用できます)。logutils

于 2012-11-23T11:33:38.307 に答える