【问题标题】:python monitor a log file non blockingpython监控日志文件非阻塞
【发布时间】:2015-02-05 15:59:55
【问题描述】:

我有一个测试存根,它会将几条日志消息写入系统日志。

但是,许多其他应用程序也会更新此系统日志。所以,基本上,我想做一个tail -f system.log | grep "application name" 来只获取适当的日志消息。

我正在研究 dbaez 生成器技巧,我正在尝试将 http://www.dabeaz.com/generators/follow.pyhttp://www.dabeaz.com/generators/apachelog.py 结合起来

所以,在我的__main__() 中,我有这样的内容:

try:
   dosomeprocessing()     #outputs stuff to the log file

在 dosomeprocessing() 中,我运行一个循环,对于每个循环,我想查看是否有由我的应用程序引起的任何新日志消息,不一定将其打印出来,而是将它们存储在某个地方进行验证.

    logfile = open("/var/adm/messages","r")
    loglines = follow(logfile)
    logpats = r'I2G(JV)'
    logpat = re.compile(logpats)
    groups = (logpat.match(line) for line in loglines)
    for g in groups:
        if g:
            print g.groups()

日志看起来像:

Feb  4 12:55:27 Someprocessname.py I2G(JV)-300[20448]: [ID 702911   local2.error] [MSG-70047] xxxxxxxxxxxxxxxxxxxxxxx 
 Feb  4 12:55:27 Someprocessname.py I2G(JV)-300[20448]: [ID 702911  local2.error] [MSG-70055] xxxxxxxxxxxxxxxxxxxxxxx

除了很多其他的gobblygook。

现在,它卡在了for g in groups:

我对 python 和异步编程比较陌生。理想情况下,我希望能够让尾部与主进程并行运行,并在每个循环中读取新数据。

如果我需要添加更多信息,请告诉我。

【问题讨论】:

  • 日志文件轮换了吗?您的 follow.py 无法处理将 messages 重命名为 messages.1 然后为其他日志创建新文件的记录器。
  • 它几乎从不旋转,文件名保持不变。

标签: python logging generator tail


【解决方案1】:

我建议您使用watchdogpyinotify 来监控日志文件的更改。

另外,我建议记住您上次阅读的位置。收到 IN_MODIFY 通知后,您可以从最后一个位置读取到文件末尾并再次应用循环。另外,如果文件被截断,当文件大于文件大小时,将最后位置重置为 0。

示例如下:

import pyinotify
import re
import os


wm = pyinotify.WatchManager()
mask = pyinotify.IN_MODIFY


class EventHandler (pyinotify.ProcessEvent):

    def __init__(self, file_path, *args, **kwargs):
        super(EventHandler, self).__init__(*args, **kwargs)
        self.file_path = file_path
        self._last_position = 0
        logpats = r'I2G\(JV\)'
        self._logpat = re.compile(logpats)

    def process_IN_MODIFY(self, event):
        print "File changed: ", event.pathname
        if self._last_position > os.path.getsize(self.file_path):
            self._last_position = 0
        with open(self.file_path) as f:
            f.seek(self._last_position)
            loglines = f.readlines()
            self._last_position = f.tell()
            groups = (self._logpat.search(line.strip()) for line in loglines)
            for g in groups:
                if g:
                    print g.string


handler = EventHandler('some_log.log')
notifier = pyinotify.Notifier(wm, handler)

wm.add_watch(handler.file_path, mask)        
notifier.loop()

【讨论】:

  • 我没有使用pyinotify,而是使用了你上面定义的文件读取、文件查找方法来做到这一点。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
  • 2011-11-29
  • 1970-01-01
相关资源
最近更新 更多