2012-11-01 7 views
16

Google App EngineでDjango-nonrelを使っているので、print()の代わりにlogging.debug()を使用する必要があります。Python-ログをフラッシュする方法は? (django)

"logging"モジュールはDjangoによって提供されていますが、print()の代わりに使用しています。

たとえば、変数xに保持されている内容を確認する必要がある場合は、
logging.debug('x is: %s' % x)と入力します。しかし、プログラムが(ストリームをフラッシュすることなく)すぐにクラッシュすると、決して印刷されません。

デバッグのために、プログラムがエラーで終了する前にデバッグ()をフラッシュする必要がありますが、これは起こっていません。私は、これはあなたが唯一の1つ(またはデフォルト)を使用していると仮定すると、あなたのために働くかもしれないと思う

+0

あなたの質問には答えられませんが、どうして 'print'を使用するのですか? – aschmid00

+1

ログを「フラッシュする」という正確な意味は? –

+0

リストされている例が理解に役立つことを願っています。 – Rucent88

答えて

9

ハンドラ:

>>> 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

そして、それはパフォーマンスのドレインかもしれないが、あなたが本当に立ち往生している場合、これはあなたのデバッグに役立つことがあります。

+1

唯一の方法は、あなたがアクセスするはずのハンドラを経由している場合に、どうやってログをフラッシュする必要がありますか?それは壊れて聞こえる。 –

+1

いいえ、それはまったくドキュメントが言っていることではありません。上の見積もりは、Handlerの代わりにHandlerの*サブクラス*のみをインスタンス化して使用する必要があることを意味します。あなたのコードは、他の誰かがすでにインスタンス化しているハンドラクラスだけを使用するので、問題はありません。 – Hjulle

+3

本当に役に立ちます。私はまだ、私が愚かなロガーにその設定でそれが常にフラッシュされていると言うことができないということは、非常に奇妙であることがわかります。私のクライアントコードがそれを強制しなければならないことを意味します。 – GhostCat

5

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

このモジュールは、モジュールレベルの方法がありますlogging.shutdown()ハンドラの全てをフラッシュし、ロギング・システムをシャットダウンする(それが呼び出された後、すなわちロギングを長く使用することができない)

この機能ショーのコードを検査しますその現在(のpython 2.7)ロギングモジュールは、このソリューションを使用しているため、そのハンドラのすべてが

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

ような何かを行うことによって洗い流すことができる_handlerListと呼ばれるモジュールレベルの変数内のすべてのハンドラに弱い参照のリストを保持しています上記の@Mikesモジュールの内部構造は優れていますが、relユースケースは、あなたが終了時にそのログをフラッシュする必要があるのpythonプログラムを持っているということです

[h.flush() for h in my_logger.handlerList] 
1

場合は、logging.shutdown()を使用して次のようにロガーへのアクセス権を持つ上のIEは、それが一般化することができます。 Pythonドキュメントから

logging.shutdownは()

は紅潮し、全てのハンドラを閉じることで順次 シャットダウンを実行するためのロギングシステムに通知します。これは、アプリケーション終了時に と呼ばれるべきであり、この呼び出しの後でログシステムのそれ以上の使用は でなければなりません。

4

私は同様の問題で苦労しましたが、ここで私はそれを解決しました。

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の代わりに使用:代わりに直接出力にログをloggingモジュールを使用するのでは、次のように独自のロガーを初期化する結果

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

、あなたは」勝ちましたもうログのフラッシュに問題があります。

関連する問題