web-dev-qa-db-ja.com

Python:同じファイルにログを記録する別々のプロセス?

Pythonのloggingライブラリは、2つ(またはそれ以上)の別々のpythonプロセス同じファイルへのログ記録)のシリアル化されたログ記録を提供しますか?ドキュメント(私が読んだもの)。

もしそうなら、完全に異なるマシン(両方からアクセス可能なNFSエクスポートに共有ログファイルが存在する)ではどうでしょうか。

19
sjbx

いいえ、サポートされていません。 From python logging Cookbook

ロギングはスレッドセーフであり、単一のプロセスで複数のスレッドから単一のファイルへのロギングがサポートされていますが、複数のプロセスから単一のファイルへのロギングはサポートされていません、Pythonの複数のプロセス間で単一のファイルへのアクセスをシリアル化する標準的な方法がないため。

その後、クックブックは、ログを処理する単一のソケットサーバープロセスと、ログメッセージを送信する他のプロセスを使用することを提案しています。このアプローチの実用的な例は、セクション ネットワークを介したログイベントの送信と受信 にあります。

15
Hayden Crocker

この問題の厄介な解決策の1つは、単一のスレッドでソケットをリッスンするロギングプロセスを作成することです。このプロセスは、受信したものをすべて出力するだけです。

重要なのは、調停メカニズムとしてソケットキューをハイジャックすることです。

#! /usr/bin/env python

import sys
import socket
import argparse

p = argparse.ArgumentParser()
p.add_argument("-p", "--port", help="which port to listen on", type=int)
p.add_argument("-b", "--backlog", help="accept backlog size", type=int)
p.add_argument("-s", "--buffersize", help="recv buffer size", type=int)
args = p.parse_args()

port = args.port if args.port else 1339
backlog = args.backlog if args.backlog else 5
size = args.buffersize if args.buffersize else 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', port))
s.listen(backlog)
print "Listening on port ", port, 'backlog size', backlog, 'buffer size', size, '\n'
while 1:
    try:
        (client, address) = s.accept()
        data = client.recv(size)
        print data
    except:
        client.close()

そしてそれをテストするには:

#! /usr/bin/env python

import sys
import socket
import argparse

p = argparse.ArgumentParser()
p.add_argument("-p", "--port", help="send port", action='store', default=1339, type=int)
p.add_argument("text", help="text to send")
args = p.parse_args()

if not args.quit and not args.text:
    p.print_help()
else:
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('', args.port))
        s.send(args.text)
    except:
        s.close()

次に、次のように使用します。

stdbuf -o L ./logger.py -b 10 -s 4096 >>logger.log 2>&1 &

最近のアクティビティを次のように監視します。

tail -f logger.log

特定のプロセスからの各ロギングエントリは、アトミックに発行されます。これを標準のロギングシステムに追加するのはそれほど難しいことではありません。ソケットを使用すると、複数のマシンが専用マシンでホストされている単一のログをターゲットにすることもできます。

1
user5135927

最も簡単な方法は、ログにカスタムハンドラーを使用することです。これにより、キューを持つすべてのログが子プロセスからメインに渡され、そこでログに記録されます。このような方法で、たとえば、メインUIスレッドとワーカースレッドがあるクライアントアプリケーションでログを処理します。

また、POSIXシステムでは、追加モードでロギングを使用できます。最大4kbはアトミックです。

0