web-dev-qa-db-ja.com

multiprocessing.Processのログ出力

Pythonでmultiprocessing.Processクラスを使用するときに、指定されたプロセスからstdout出力を記録する方法はありますか?

63
astrofrog

最も簡単な方法は、単にsys.stdoutマルチプロセッシングマニュアル の例を少し変更します:

from multiprocessing import Process
import os
import sys

def info(title):
    print title
    print 'module name:', __name__
    print 'parent process:', os.getppid()
    print 'process id:', os.getpid()

def f(name):
    sys.stdout = open(str(os.getpid()) + ".out", "w")
    info('function f')
    print 'hello', name

if __== '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    q = Process(target=f, args=('fred',))
    q.start()
    p.join()
    q.join()

そしてそれを実行する:

 $ ls 
 m.py 
 $ python m.py 
 $ ls 
 27493.out 27494 .out m.py 
 $ cat 27493.out 
 function f 
 module name:__main __ 
 parent process:27492 
 process id:27493 
 hello bob 
 $ cat 27494.out 
 function f 
 module name:__main __ 
 parent process:27492 
 process id:27494 
 hello fred 
 
50
Mark Rushakoff

@Mark Rushakoffの回答に追加するものは2つだけです。デバッグするとき、open()呼び出しのbufferingパラメーターを0に変更すると非常に便利です。

sys.stdout = open(str(os.getpid()) + ".out", "a", buffering=0)

それ以外の場合、madness、なぜならtail -f出力ファイルを実行すると、結果が非​​常に断続的になる可能性があります。 buffering=0 にとって tail -fing素晴らしい。

そして、完全を期すために、あなた自身に賛成してリダイレクトsys.stderr 同様に。

sys.stderr = open(str(os.getpid()) + "_error.out", "a", buffering=0)

また、便宜上、必要に応じて別のプロセスクラスにダンプすることもできます。

class MyProc(Process):
    def run(self):
        # Define the logging in run(), MyProc's entry function when it is .start()-ed 
        #     p = MyProc()
        #     p.start()
        self.initialize_logging()

        print 'Now output is captured.'

        # Now do stuff...

    def initialize_logging(self):
        sys.stdout = open(str(os.getpid()) + ".out", "a", buffering=0)
        sys.stderr = open(str(os.getpid()) + "_error.out", "a", buffering=0)

        print 'stdout initialized'

ここに対応する要点

15
HeyWatchThis

sys.stdout = Logger()を設定できます。ここで、Loggerは、writeメソッド(即時、または\nが検出されるまで累積)がlogging.info(またはログに記録する他の方法)。 実際の動作例

「与えられた」プロセスが誰を意味するのかわかりません(誰がそれを与えたのか、他のすべてのプロセスと区別するのか...)。それをインスタンス化すると、そのtarget関数(およびそれのみ)-またはrunサブクラスでオーバーライドしているProcessメソッドを、そのラッパーにラップできます。このsys.stdoutの「リダイレクト」を実行し、他のプロセスはそのままにします。

仕様を少し詳しく説明していただければ、もっと詳細にお手伝いできますか...?

11
Alex Martelli