web-dev-qa-db-ja.com

Python-ログをフラッシュする方法は? (ジャンゴ)

私はGoogle App EngineでDjango-nonrelを使用しているため、print()ではなくlogging.debug()を使用する必要があります。

「ロギング」モジュールはDjangoによって提供されていますが、print()の代わりにそれを使用するのはおおよその時間です。

たとえば、変数xに保持されているコンテンツを確認する必要がある場合は、
logging.debug('x is: %s' % x)。しかし、プログラムがすぐに(ストリームをフラッシュせずに)クラッシュした場合は、出力されません。

デバッグのために、プログラムがエラーで終了する前にdebug()をフラッシュする必要がありますが、これは発生していません。

26
Rucent88

私はこれがあなたのためにうまくいくと思います、あなたが1つ(またはデフォルト)のハンドラーのみを使用していると仮定すると:

>>> import logging
>>> logger = logging.getLogger()
>>> logging.debug('wat wat')
>>> logger.handlers[0].flush()

しかし、ドキュメントではそれは一種の眉をひそめています。

アプリケーションコードは、Handlerのインスタンスを直接インスタンス化して使用しないでください。代わりに、Handlerクラスは、すべてのハンドラーが持つ必要のあるインターフェースを定義し、子クラスが使用(またはオーバーライド)できるデフォルトの動作を確立する基本クラスです。 http://docs.python.org/2/howto/logging.html#handler-basic

また、パフォーマンスが低下する可能性もありますが、本当に行き詰まっている場合は、デバッグに役立つ場合があります。

15
Mike Shultz

終了時にログをフラッシュするpythonプログラムがある場合の使用例は、logging.shutdown()を使用してください。

pythonドキュメントから:

logging.shutdown()

すべてのハンドラーをフラッシュして閉じることにより、正常にシャットダウンするようにロギングシステムに通知します。これはアプリケーションの終了時に呼び出す必要があり、この呼び出しの後にロギングシステムをこれ以上使用しないでください。

10
Risadinha

私は同様の問題で苦労しました、そしてここに私がそれを解決した方法があります。 loggingモジュールを直接使用してログを出力する代わりに、次のように独自のロガーを初期化します。

import sys
import logging


def init_logger():
    logger = logging.getLogger()

    h = logging.StreamHandler(sys.stdout)
    h.flush = sys.stdout.flush
    logger.addHandler(h)

    return logger

次に、コードでloggingの代わりに使用します。

def f():
    logger = init_logger()
    logger.debug('...')

その結果、ログのフラッシュに関する問題は発生しなくなります。

9
constt

Djangoロギングは、標準のpythonロギングモジュールに依存しています。

このモジュールには、モジュールレベルのメソッドがあります:logging.shutdown()は、すべてのハンドラーをフラッシュし、ロギングシステムをシャットダウンします(つまり、ロギングを呼び出すと、ロギングを使用できなくなります)。

この関数のコードを検査すると、現在(Python 2.7)ロギングモジュールが_handlerListと呼ばれるモジュールレベルの変数にすべてのハンドラーへの弱参照のリストを保持しているため、次のようなことですべてのハンドラーをフラッシュできます

[h_weak_ref().flush() for h_weak_ref in logging._handlerList]

このソリューションは上記のモジュール@Mikesソリューションの内部を使用するので優れていますが、ロガーへのアクセス権に依存しているため、次のように一般化できます。

 [h.flush() for h in my_logger.handlerList]
5
tjb