Python实时分析日志文件,在日志旋转时重新加载



我有这样的代码,它可以连续跟踪access.log并解析事件。但是在日志循环期间,access.log将被移动到access.log.timestamp,并且java进程将创建一个新的access.log。当这种重新调整发生时,python解析器不会解析新的access.log。请提供一些线索,我如何在程序文件更改后重新加载程序。

with open('/var/log/app/access.log') as f:
   while True:
     line = f.readline()
     if line:
      process(line)

所以问题似乎是python文件指针在日志更改时保持其位置引用。因此,当文件大小小于之前的值时,我们将检查文件大小。我们将重置python文件指针以启动,即使用seek(0)"0"。我还没有厌倦这个代码,但你可以得到结果,所以我们可以修改同样的代码。

import os
file_path = '/var/log/app/access.log'
with open(file_path) as f:
    file_size = 0
    while True:
        line = f.readline()
        if line:
            print line
        file_status_obj = os.stat(file_path)
        if file_size < file_status_obj.st_size:
            f.seek(0)
        file_size = file_status_obj.st_size

希望这有帮助:)

  • 当日志文件稍后可能有更多行时,您应该处理EOF的追赶
  • 您可以添加一个信号处理程序,使代码关闭并再次打开文件,例如由logrotate(在RHEL上)执行
  • 如果不能向该日志处理器发出信号,则可以检查文件的inode。如果你的日志轮换不是复制&截断

类似的事情,请检查所有必要的异常处理。这是我的工作系统的部分副本:

def iNodeOf(file):
  if os.path.exists(file):
    s = os.stat(file)
    return s.st_ino
  else:
    return -1
while True:
  iReload = False
  fileInode = iNodeOf(conf.LOGFILE)
  f = open(conf.LOGFILE, 'r')
  countDown = 15
  while (not iReload) and (countDown > 0):
    # seek to current position again
    f.seek(0,1)
    while countDown > 0:
      filePos = f.tell()
      line = f.readline()
      if line:
          process(line)
          countDown = 15
      else:
          countDown -= 1
          time.sleep(1)
    newInode = iNodeOf(conf.LOGFILE)
    if (fileInode == newInode):
      # file not changed, sleep, seek from BOF, and try again
      time.sleep(5)
      f.seek(filePos,0)
      countDown = 15
    else:
      # file changed
      f.close()
      iReload = True

最新更新