我正在尝试设置一个邮件日志解析器,它将特定的行拉出到另一个文件中,然后将其rsync到远程服务器。我遇到的问题是当rsync读取正在写入的文件时,它似乎导致解析器停止运行。我相信这是因为解析器正在模拟尾部-f,因为maillog被一致地写入。
所以:我如何允许rsync使用此代码(result_file)触摸我正在编写的文件,同时仍然允许它跟随maillog的末尾寻找新文件:
#! /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()
答案 0 :(得分: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
要了解更好的情况,请尝试通过stat
检查inode和大小。只要路径引用的文件与脚本打开的文件不同,您的脚本现在就会看到一个其他人无法再触摸的文件。
也有可能有人正在截断并重写文件。这不会改变inode,但它仍然意味着你不会读取任何东西,因为你试图从文件末尾的位置读取。
我不知道rsync的文件是否会导致这种情况,或者这只是巧合。在不知道您正在运行什么rsync
命令,或者查看文件是否被替换,或者文件被截断并在该命令运行时被重写时,我们所能做的就是猜测。
答案 1 :(得分:0)
我不相信rsync会导致您的问题:读取文件的单独进程不应该影响编写器。您可以通过暂停rsync来轻松测试。
我猜测问题在于当你点击文件末尾时python处理文件读取。保证工作的原始方法是阅读以记住最后一次EOF中的offest(使用tell()
)。对于每个新读取,重新打开文件并寻找记住的偏移量。