【问题标题】:Read from a log file as it's being written using python在使用 python 写入时从日志文件中读取
【发布时间】:2011-03-18 10:41:37
【问题描述】:

我正在尝试找到一种使用 python 实时读取日志文件的好方法。我想在写入时一次处理一个日志文件中的行。不知何故,我需要继续尝试读取文件,直到它被创建,然后继续处理行,直到我终止进程。有没有合适的方法来做到这一点?谢谢。

【问题讨论】:

标签: python file logging file-io monitoring


【解决方案1】:

也许你可以做一个系统调用

tail -f

使用 os.system()

【讨论】:

    【解决方案2】:

    查看this PDF,从第 38 页开始,~幻灯片 I-77,您会找到所需的所有信息。当然,其他幻灯片也很棒,但这些幻灯片专门针对您的问题:

    import time
    def follow(thefile):
        thefile.seek(0,2) # Go to the end of the file
        while True:
            line = thefile.readline()
            if not line:
                time.sleep(0.1) # Sleep briefly
                continue
            yield line
    

    【讨论】:

    • 值得注意的是,这将跳过日志文件中已有的任何内容,仅打印在创建此迭代器后创建的“新”条目。而且那个 PDF 真的是一座金矿;)
    • 如果我看到旋转的日志文件该怎么办? stackoverflow.com/questions/44407834/…
    • @HarisGodil 为什么你认为这在 Python2 中不起作用?
    • 为什么用 thefile.seek(0,2) 替换 thefile.seek(0,OS.SEEK_END) ?编辑:何,实际上是the same
    • 在一个短文件上测试过,它一直在不停地运行。我做错什么了吗 ? with open(myfile, "r") as f : x = follow(f) for l in x: print(l)
    【解决方案3】:

    你可以试试这样的:

    import time
    
    while 1:
        where = file.tell()
        line = file.readline()
        if not line:
            time.sleep(1)
            file.seek(where)
        else:
            print line, # already has newline
    

    示例摘自here

    【讨论】:

    • 这似乎有效,但它不允许我在我的 django 应用程序中同时创建对象或写入数据库。我看不出有什么明显的原因。有简单的解决方法吗?
    • 我不知道。我猜你应该在一个单独的问题中发布一些代码以获得这个问题的答案。如果您将该代码放在此代码中,我看不出有任何理由不更新数据库...
    • 让它工作了,但我不得不把字符串弄乱了很多,然后才能让它写入我的数据库。谢谢。
    • file 在此上下文中似乎未定义,仅供参考。
    • 这似乎一次获得一个字节或取决于速度部分行
    【解决方案4】:

    由于这是 Python 和日志标记,还有另一种可能性。

    我假设这是基于 Python 记录器,基于 logging.Handler。

    您可以创建一个获取(命名)记录器实例的类并覆盖 emit 函数以将其放到 GUI 上(如果您需要控制台,只需将控制台处理程序添加到文件处理程序)

    例子:

    import logging
    
    class log_viewer(logging.Handler):
        """ Class to redistribute python logging data """
    
        # have a class member to store the existing logger
        logger_instance = logging.getLogger("SomeNameOfYourExistingLogger")
    
        def __init__(self, *args, **kwargs):
             # Initialize the Handler
             logging.Handler.__init__(self, *args)
    
             # optional take format
             # setFormatter function is derived from logging.Handler 
             for key, value in kwargs.items():
                 if "{}".format(key) == "format":
                     self.setFormatter(value)
    
             # make the logger send data to this class
             self.logger_instance.addHandler(self)
    
        def emit(self, record):
            """ Overload of logging.Handler method """
    
            record = self.format(record)
    
            # ---------------------------------------
            # Now you can send it to a GUI or similar
            # "Do work" starts here.
            # ---------------------------------------
    
            # just as an example what e.g. a console
            # handler would do:
            print(record)
    

    我目前正在使用类似的代码来添加一个 TkinterTreectrl.Multilistbox 用于在运行时查看记录器输出。

    Off-Side:记录器仅在初始化后立即获取数据,因此如果您希望所有数据可用,则需要从一开始就对其进行初始化。 (我知道这是预期的结果,但我认为值得一提。)

    【讨论】:

      猜你喜欢
      • 2020-06-24
      • 2021-06-22
      • 1970-01-01
      • 2017-02-20
      • 1970-01-01
      • 2019-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多