名称更改Python时生成器读取日志文件

时间:2015-12-18 01:06:14

标签: python generator filenames filenotfoundexception

目标是逐行实时读取日志文件(标准生成器的东西)但是捕获的是,文件名以不同的间隔变化。名称更改无法帮助(应用程序口述附加时间字符串),并且当日志文件大小达到~2MB(猜测)时,名称会更改。

我的方法是创建一个获取文件(或新文件)的文件获取函数,然后将其传递给生成器。我认为当文件更改名称时,我会找到一个“找不到文件”的文件。错误,但我的测试表明,文件名更改完全被阻止,因为另一个程序正在使用此文件'。必须允许更改名称,并且此读取器代码根本不会干扰应用程序日志记录过程。

import os
import time
import fnmatch

directory = '\\foo\\'

def fileGenerator(logFile):
     """ Run a line generator """
     logFile.seek(0,2)
     while True:
         line = logFile.readline()
         if not line:
             time.sleep(0.1)
             continue
         yield line

def fileGetter():
     """ Get the Logging File """
     matchedFiles = []
     for afile in os.listdir(directory):
        if fnmatch.fnmatch(afile,'amc_*.txt'):
            matchedFiles.append(afile)
     if len(matchedFiles)==1:
        #There was exactly one matching file found send it to the generator
        return os.path.join(directory,matchedFiles[0])
    else:
        #There either wasn't a file found or many matching
        #Error out and stop process... critical error

if __name__ == '__main__':
    filePath = fileGetter()
    try:
        logFile = open(filePath,"r")
    except Exception as e:
        #Catch the file not found and go back to the file path getter
        #Send the file back to the generator
        print e
    if logFile:
        loglines = fileGenerator(logFile)
        for line in loglines:
            #handle the line
            print line,

1 个答案:

答案 0 :(得分:0)

如果您在等待写入新内容时无法保持文件处于打开状态,我建议您在睡觉前保存上次文件位置并关闭文件,然后重新打开文件并寻求之后点。如果您关心发现文件添加或立即重命名,您还可以调查文件系统通知系统。

def log_reader():
    filename = "does_not_exist"
    filepos = 0

    while True:
        try:
            file = open(filename)
        except FileNotFoundError:
            filename = fileGetter()
            # if renamed files start empty, set filepos to zero here!
            continue

        file.seek(filepos)

        while True:
            line = file.readline()
            if not line:
                filepos = file.tell()
                file.close()
                sleep(0.1) # you may want to test different sleep lengths to avoid FS thrash
                break
            yield line

如果你做得太多,文件的打开和关闭可能会压缩你的文件系统,所以我建议你比以前的代码睡得更久(但是你可能想测试一下你的操作系统处理它的程度如何你关心日志阅读器的响应能力。)