在使用 python 写入时从日志文件中读取

Posted

技术标签:

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

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

【问题讨论】:

这个也不错...我认为它非常符合您的标准,并提供了一个可以轻松扩展的类。 http://code.activestate.com/recipes/577968-log-watcher-tail-f-log/ 【参考方案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 真的是一座金矿;) 如果我看到旋转的日志文件该怎么办? ***.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:记录器仅在初始化后立即获取数据,因此如果您希望所有数据可用,则需要从一开始就对其进行初始化。 (我知道这是预期的结果,但我认为值得一提。)

【讨论】:

以上是关于在使用 python 写入时从日志文件中读取的主要内容,如果未能解决你的问题,请参考以下文章

python中使用pyspark 读取和整理日志数据并将数据写入到es中去

腾讯云Logstash实战5-读取COS中的日志文件并写入到Elasticsearch

如何使用日志记录 Python 模块写入文件?

PHP记录和读取JSON格式日志文件

python获取nginx子请求

python 监控日志