python 监控日志文件非阻塞
python monitor a log file non blocking
我有一个测试存根,可以将几条日志消息写入系统日志。
但是,这个系统日志也会被许多其他应用程序更新。所以,基本上,我想做一个 tail -f system.log | grep "application name"
来只获取适当的日志消息。
我正在研究 dbaez 生成器技巧,我正在尝试将两者结合起来 http://www.dabeaz.com/generators/follow.py and http://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 和异步编程比较陌生。理想情况下,我希望能够使 tail 运行ning 与主进程并行,并在每个循环中读取新数据。
如果我需要添加更多信息,请告诉我。
我建议您使用 watchdog or pyinotify 来监控日志文件的更改。
此外,我建议记住您阅读的最后位置。收到 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()
我有一个测试存根,可以将几条日志消息写入系统日志。
但是,这个系统日志也会被许多其他应用程序更新。所以,基本上,我想做一个 tail -f system.log | grep "application name"
来只获取适当的日志消息。
我正在研究 dbaez 生成器技巧,我正在尝试将两者结合起来 http://www.dabeaz.com/generators/follow.py and http://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 和异步编程比较陌生。理想情况下,我希望能够使 tail 运行ning 与主进程并行,并在每个循环中读取新数据。
如果我需要添加更多信息,请告诉我。
我建议您使用 watchdog or pyinotify 来监控日志文件的更改。
此外,我建议记住您阅读的最后位置。收到 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()