【问题标题】:Read the latest line from a file which keeps getting updated从不断更新的文件中读取最新行
【发布时间】:2021-02-14 08:05:23
【问题描述】:

我目前正在编写一个不和谐的机器人,它读取一个不断更新的本地日志文件。每次添加新行并匹配特定模式时,机器人(应该)发布包含该内容的消息。我尝试了以下或我目前的立场是以下代码。我的代码当前的问题是文件一直打开。如果自上次阅读后更新文件,有没有办法只读取文件?或者换句话说,有没有一种方法可以实现我的解决方案,该解决方案不需要一直打开文件/一直忙于读取文件?

while not BOT.is_closed():        
    for log in logs:
        file_path = config["path_to_log"]
        logfiles= []
        for filename in glob.glob(os.path.join(file_path,f'_{log}*')):
            logfiles.append(filename)
        latest_file = max(logfiles, key=os.path.getmtime)
        """ #second try doenst work if to much content gets added at the same time
        with open(latest_file,"rb") as f:
            if(len(messagelist)>1000):
                messagelist = []
            f.seek(-2, os.SEEK_END)
            while f.read(1) != b'\n':
                f.seek(-2, os.SEEK_CUR)
            last_line = f.readline().decode()
            for word in words:
                if word in last_line and last_line not in messagelist:
                    messagelist.append(last_line)
                    print(last_line)
                    await channel.send(last_line)
                else: 
                    time.sleep(1)
            """ 
        # first try it works but i dont think its the best solution
        try: 
            fp = open(latest_file, 'r')
        except:
            end_program("Error while reading the log file")

        for line in (fp.readlines() [-10:]): 
            new = line
            for word in words:
                if word in new and new not in messagelist:
                    messagelist.append(new)
                    print(new)
                    await channel.send(new)
                else: 
                    time.sleep(1)
                ###
        fp.close()

【问题讨论】:

标签: python-3.x file logging


【解决方案1】:

你可以使用生成器。

import time, os
def follow(filename):
    with open(filename) as f:
        f.seek(0, os.SEEK_END)
        while True:
            line = f.readline()
            if not line:
                time.sleep(1)
                continue
            if line.startswith('a'):
                yield line

上面的生成器将yield 行末尾留有换行符。您可能需要稍微修改yield line 以排除换行符,例如yield line[:-1]line.startswith('a') 只是一个示例,展示如何匹配模式的yield 行。你需要用你的模式更新它。

在您的代码中,您可以将生成器用作:

for line in follow('/path/to/file'):
    # do something with line

【讨论】:

    猜你喜欢
    • 2013-05-19
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多