2013-03-15 8 views
13

私はいくつかのシミュレーションを実行する必要があるアプリケーションがあります。私は、すべてのログレコードがgeneral.logに記録され、シミュレーション実行のためのすべてのログがrun00001.logに移動するようなロギングメカニズムを設定したいと思います。 __init__()では、ランログに新しいファイルハンドルが追加されています。pythonはファイルハンドルをログファイルに解放しません

問題は、実行ファイルのログファイルが解放されないことです。実行回数を増やすと、使用可能なハンドルがなくなり、実行がクラッシュします。

私は

メインルーチン

import Model 
try: 
    myrun = Model.Run('20130315150340_run_49295') 
    ha = raw_input('enter') 
    myrun.log.info("some info") 
except: 
    traceback.print_exc(file=sys.stdout) 

ha = raw_input('enter3') 

クラス

import logging 
class Run(object): 

    """ Implements the functionality of a single run. """ 
    def __init__(self, runid): 
     self.logdir="." 
     self.runid   = runid 
     self.logFile  = os.path.join(self.logdir , self.runid + '.log') 
     self.log   = logging.getLogger('Run'+self.runid) 
     myformatter   = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s') 
     myhandler  = logging.FileHandler(self.logFile) 
     myhandler.setLevel(logging.INFO) 
     myhandler.setFormatter(myformatter) 
     self.log.addHandler(myhandler) 

その後、私は使用を以下のように実行しますが、モジュールのモデルで定義されているが、次のようにこれをテストするために、いくつかのルーチンを設定した

プログラムプロセスエクスプローラはファイルハンドラに従います。ランログが現れているのが見えますが、決して消えません。

これを強制する方法はありますか?

+1

実行が完了したときに、なぜ再びハンドラを削除しませんか?おそらくあなたはそのイベントにフックできますか? –

+0

これを行う方法に関するアドバイスはありますか?明示的にデストラクタ(myrun .__ del __())を呼び出しても、__del __()でself.log.removeHandler(myhandler)を指定しようとしました。私は__exit __()を指定し、with文を使用することで、オープンしたファイルハンドルを開くときに示唆したように試みました。しかし、これまでのところ成功はありません。 –

+1

ファイルハンドラでも '.close()'を呼び出す必要があります。 'self.log.handlers [0] .close()'で十分です。 –

答えて

32

.close()をファイルハンドラに呼び出す必要があります。あなたのRunクラスが完了すると、

呼び出す:

handlers = self.log.handlers[:] 
for handler in handlers: 
    handler.close() 
    self.log.removeHandler(handler) 
+0

'[:]'ハンドラリストのコピーを作成しませんか? –

+0

@VasilisLemonidis:はい、それがポイントです。リストを反復して要素を削除しないでください。要素をスキップすることになります。 –

+0

@VasilisLemonidis:代わりに、逆順で要素を処理することができます: 'ハンドラの逆順で(self.log.handlers):...'。 –

関連する問題