1

我正在尝试设置一个邮件日志解析器,它将特定行提取到另一个文件中,然后将 rsync'd 到远程服务器。我遇到的问题是,当 rsync 读取正在写入的文件时,它似乎导致解析器停止运行。我相信这是因为解析器正在模拟 tail -f ,因为邮件日志的编写是一致的。

所以:我如何允许 rsync 触摸我正在使用此代码(result_file)编写的文件,同时仍然允许它跟随邮件日志的末尾寻找新文件:

#! /usr/bin/python

import time, re, sys

result_file = open('/var/log/mrp_mail_parsed.log', 'a+')


def tail(logfile):
    logfile.seek(0,2)
    while True:
        line = logfile.readline()
        if not line:
            time.sleep(0.1)
            continue
        yield line

if __name__ == '__main__':
    logfile = open('/var/log/maillog', 'r')
    logline = tail(logfile)
    for line in logline:
        match = re.search(r'.+postfix-mrp.+', line)
        if match:
            result_file.write(line,)
            result_file.flush()
4

2 回答 2

1

我不知道谁在写文件,或者如何写,所以我不能确定,但​​我会给出比你的问题更好的概率:

如果文件没有被就地附加,而是被重写,您的代码将停止跟踪文件。要对此进行测试:

import sys
import time

def tail(logfile):
    logfile.seek(0,2)
    while True:
        line = logfile.readline()
        if not line:
            time.sleep(0.1)
            continue
        yield line

with open(sys.argv[1]) as f:
    for line in tail(f):
        print(line.rstrip())

现在:

$ touch foo
$ python tailf.py foo &
$ echo "hey" >> foo
foo
$ echo "hey" > foo

要查看发生了什么更好的情况,请尝试通过检查 inode 和大小stat。一旦路径指向与您的脚本打开的文件不同的文件,您的脚本现在正在监视一个其他人不会再接触的文件。

也有可能有人正在原地截断和重写文件。这不会改变 inode,但它仍然意味着您不会读取任何内容,因为您正在尝试从文件末尾之后的位置读取。

我不知道被 rsync'd 的文件是否导致了这种情况,或者这是否只是一个巧合。在不知道rsync您正在运行什么命令,或者查看该命令运行时文件是否被替换或文件是否被截断和重写的情况下,我们所能做的就是猜测。

于 2013-05-23T23:22:09.733 回答
0

我不相信 rsync 会导致您的问题:读取文件的单独进程不应影响编写器。您可以通过暂停 rsync 轻松测试这一点。

我猜问题出在当你到达文件末尾时 python 对文件读取的处理。一种保证有效的粗略方法是阅读以记住最后一个 EOF 的节日(使用tell())。对于每个新的读取,重新打开文件并寻找记住的偏移量。

于 2013-05-23T23:20:55.007 回答