如何从使用Python上次修改的日志文件中获取信息?

时间:2013-02-04 14:41:17

标签: python information-retrieval last-modified

我是Python新手,我正在尝试创建一个脚本来浏览所有日常日志文件以检查错误。

我可以打开文件,打印上次修改日志文件的时间,并打印出日志文件中的任何错误。

但是,这些日志包含过去三年的日常信息。我希望只能从日志的上次修改日期读取日志部分(而不是从过去三年中获取所有错误,我只想要从最后一天开始的错误。)

到目前为止,我的脚本是以下内容:

import sys, string, os, time

from stat import *

from datetime import datetime

now = datetime.now()

f3 = 'C:\Path\filename.txt'

seconds = os.path.getmtime(f3)
print "Last Date Ran: ", time.strftime('%m/%d/%Y %H:%M:%S' , time.localtime(seconds))

for line in open(f3 , 'r'):
    if 'error' in line:
        print ">>> " , line
    elif 'Error' in line:
        print ">>> " , line
    elif 'ERROR' in line:
        print ">>> " , line

有没有办法做到这一点?我搜索了高低,没有找到我的问题的答案。请帮忙。

5 个答案:

答案 0 :(得分:1)

简短的回答,没有。更长的答案是,您必须要么进行大量浪费的解析,要么在文件外部跟踪一些数据。您可以遍历整个文件,解析日志消息的时间戳,然后只在给定时间后打印它们。虽然对于具有3年数据的文件,您可能最好跟踪脚本读取的最后一行,然后每次打开文件以每天解析它时寻找该行。如果您可以访问流程中的相关部分,另一种方法是修改日志记录机制;您可以将消息复制到每次运行脚本时刷新的第二个文件,或者基本上通过第二个文件缓冲日志记录,并使脚本负责将日志存档到历史文件。

答案 1 :(得分:0)

如果您提供更多信息,例如您的日志文件格式,那将是可能的。

查看方法datetime.datetime.strptime。你会找到所需的一切。

E.g。

import os.path
from datetime import datetime

filename = "my.log"

def log_entry_is_interesting(line, reference_time):
    date_str = line.split()[0]
    date = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
    return timedelta(current_datetime, date).days > reference_time:


last_time_opened = os.path.getmtime(filename)
with open(filename) as f:
    for line in filter(lambda x: log_entry_is_interesting(x, last_time_opened), f):
        do_something()

我使用filter() - 方法。这在Python 3中实现为生成器,但在Python 2.x中不实现。如果您使用2.x,我肯定会使用ifilter模块中的itertools

答案 2 :(得分:0)

如果您想从上次运行脚本时获取错误,请尝试将日志文件的最后读取位置存储在另一个文件中,并在下次读取日志文件时寻找该位置。

答案 3 :(得分:0)

如果文件中的行按日期排序(对于仅附加日志是合理的)那么你可以以相反的顺序读取文件(tac utility - 如果是,则查找或实现Python版本在您的系统上不可用)并且如果过去的日期太远则停止阅读:

# ..
if 'error' in line.lower():
   if getdate(line) < today:
      break # stop processing

答案 4 :(得分:0)

您可以使用搜索功能到达文件末尾,并通过搜索新行字符或其他方式查找最后日期。找到后,您可以进行相应的操作。我写了下面的脚本来找出每个文件的最后日期。这个功能首先 此函数查找给定日志文件中最后一个条目的日期。要找到它从文件末尾开始并继续返回2个字符并检查下一个字符是否为新行字符。当有新行字符时,它会读取前10个字符。但是,如果日志中存在其他服务的例外,则行的开头可能不包含日期戳。因此,我们使用try except循环进一步迭代,以防最后一行不包含日期戳。

list= glob.glob("DebugLogFile.log*")

start_time = time.time()


def end_date(file):
count=0;
with open(file, "rb") as f:
    first = f.readline()
    # Read the first line.
    `enter code here`f.seek(-2, os.SEEK_END)
    #print f.tell()  # Jump to the second last byte.
    #print f.read(1)
    flag=True;
    while (flag) :
        try :
            #print f.tell()
            f.seek(-2, os.SEEK_CUR)
            while f.read(1) != b"\n": # Until EOL is found...
                try:
                    f.seek(-2, os.SEEK_CUR)
                    #print f.tell()             
                except:
                    f.seek(0,os.SEEK_SET)
                    print "test"
                    break

            #Remembering the current pointer in case we have to re-evaluate the date in case of exception
            last_pos = f.tell()
            last = f.readline() 
            date=last[:10]
            datetime.datetime.strptime(date, '%Y-%m-%d').date()
            flag=False
            return datetime.datetime.strptime(date, '%Y-%m-%d').date()

        except Exception, err_msg:

            f.seek(last_pos)





def threshold(file):
base_date=end_date(file)
print("Base date is ", base_date)
print("Computing the threshold.......")
#convert the string to date object
#base_date_ob=datetime.datetime.strptime(base_date, '%Y-%m-%d').date()
threshold=base_date-timedelta(days=14)
return threshold

if __name__ == "__main__":
thresh=threshold("DebugLogFile.log")
print thresh

#list =['DebugLogFile.log.100']
#print list
for file in list :
    tmp=end_date(file)
    if(tmp>=thresh):

        print ("Process file :", file, "Which has end date as ", tmp)
    else:
        print ("Do Not Process file :", file, "Which has end date as ", tmp)
time=time.time()