私は次のような複数のPythonプロセスを実行しています:
find /path/to/logfiles/*.gz | xargs -n1 -P4 python logparser.py
そして、出力は時々スクランブルされます。
出力ストリームはバッファリングされておらず、書き込みのサイズはデフォルトのシステム(osx 10.8.2、python 2.7.2)で定義された512バイトのPIPE_BUFよりも小さいため、書き込みはアトミックである必要があると思いますが、出力がスクランブルされることがあります。私は何かが欠けているに違いありません、そしてどんな提案もいただければ幸いです。
ありがとう。
スクリプトの簡略化されたスケルトンは次のとおりです。
import argparse
import csv
import gzip
class class UnbufferedWriter(object):
"""Unbuffered Writer from
http://mail.python.org/pipermail/tutor/2003-November/026645.html
"""
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
def parse_records(infile):
if infile.name.endswith('.gz'):
lines = gzip.GzipFile(fileobj=infile)
else:
lines = infile
for line in lines:
# match lines with regex and filter out on some conditions.
yield line_as_dict
def main(infile, outfile):
fields = ['remote_addr', 'time', 'request_time', 'request', 'status']
writer = csv.DictWriter(outfile, fields, quoting=csv.QUOTE_ALL)
for record in parse_records(infile):
row_as_dict = dict(
remote_addr=record.get('remote_addr', ''),
time=record.get('time', ''),
request_time=record.get('request_time', ''),
request=record.get('request', ''),
status=record.get('status', '')
)
writer.writerow(row_as_dict)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
parser.add_argument('outfile', nargs='?', type=argparse.FileType('w', 0), default=sys.stdout)
pargs = parser.parse_args()
pargs.outfile = UnbufferedWriter(pargs.outfile)
main(pargs.infile, pargs.outfile)