从日志文件中提取新错误并通过电子邮件发送结果

时间:2013-03-01 19:06:17

标签: python python-2.5

以下python 2.5脚本可以正常工作,但由于我是初学者,我想知道是否有任何明显的错误,或者更好的方法可以做我想要实现的目标?

目的是打开当天的日志 - '/ Library / Application Support / Perceptive Automation / Indigo 5 / Logs /'并提取包含单词error和仅发送新错误的行。 提取错误行后,prenumLines计算行数(tmp.txt)。然后将提取的行写入tmp.txt文件和行 再次计算(postnumLines)。大于prenumLines的行号将打印到“theBody”并通过电子邮件发送。

from datetime import date
import linecache

fileDate = str(date.today())

theBody = []

tmpFile = open('/Library/Application Support/Perceptive Automation/Indigo 5/Logs/tmp.txt')

prenumLines = sum(1 for line in tmpFile)

log= open( '/Library/Application Support/Perceptive Automation/Indigo 5/Logs/' + fileDate + ' Events.txt', 'r' )

tmpFile = open('/Library/Application Support/Perceptive Automation/Indigo 5/Logs/tmp.txt', 'w')

for line in log:
    if 'Error' in line: 
    tmpFile.write(line )
log.close()
tmpFile.close() 

postnumLines = sum(1 for line in open('/Library/Application Support/Perceptive Automation/Indigo 5/Logs/tmp.txt'))

lineNum  = prenumLines

while lineNum < postnumLines:
    theBody.append(linecache.getline( '/Library/Application Support/Perceptive Automation/Indigo 5/Logs/tmp.txt', lineNum + 1) )
    lineNum = lineNum + 1
tmpFile.close() 

theBody =  "".join(theBody)  

#theBody is the body of  an email which is sent next
#print theBody

2 个答案:

答案 0 :(得分:0)

根据我的经验,你应该考虑制作(我使用必须,但它仍然只是一个推荐),还有一些其他更符合我个人风格的变化我用应该)。

在元级别上:您的问题最初只标记为,这可能是为什么它没有得到任何关注,您必须使用,其中有更多关注者在SO。

必须不在文件中使用TAB和空格字符。由于这个原因,你的源实际上在这里输入错误。行tmpFile.write(line)应在其上方的if语句下缩进一级。

必须不使用文件名相同的字符串四次,将其替换为变量。 并使用os.path.join()

从公共基目录创建该变量

应该考虑遵循PEP8 Python的样式指南。

如果你第一次尝试这个,你的程序将无法运行,因为'tmp.txt'不存在。 prenumLines为0时优雅地失败(但我不再使用它了,见下文):

try:
    # open the file
    # count the lines
except:
    prenumLines = 0

我实际上想知道您说明您的代码是有效的,因为您覆盖tmp.txt并且只在那里写入错误行来自最后一个日志。您再次分配给tmpFile的那一刻,第一个打开阅读的时间将被关闭。然后关闭打开的tmpFile两次写入(Python不会抛出错误)。如果昨天的日志有一个错误,今天三个,你的电子邮件只会显示两行。要附加到文件,请使用open(filename,'a')

考虑在读取/写入文件时使用with语句(Python 2.5中的新增功能),这样就省去了(错误的.close()语句)。

应该考虑将theBody创建为字符串并附加行。首先使用列表并加入它们可能会更快,但此脚本每天只运行一次。

无需计算行数,只需附加错误行,然后重新读取它们并将其存储在theBody中,免除第一和第三部分并执行此操作一气呵成:

from __future__ import with_statement

import os
from datetime import date

baseDir = '/Library/Application Support/Perceptive Automation/Indigo 5/Logs'
tmpFileName = os.path.join(baseDir, 'tmp.txt')

fileDate = str(date.today())
eventFileName = os.path.join(baseDir, fileDate + ' Events.txt')

theBody = ''

with open(tmpFileName, 'a') as tmpFile:
    with open( eventFileName, 'r' ) as log:
        for line in log:
            if 'Error' in line:
                tmpFile.write(line)
                theBody += line

# theBody is the body of  an email which is sent next
print theBody

答案 1 :(得分:0)

Anthon - 再次感谢您抽出宝贵时间作出回应。生成日志的软件是Perceptive Automation Indigo,一种家庭自动化程序。它每天都会生成一个新日志,不断写入日志。我设置python脚本每10分钟解析一次日志并查找错误然后通过电子邮件发送给我。我遇到的挑战是只通过电子邮件向我发送新错误,并避免之前发送的错误。我这样做是为了计算tmp.text中的行数,然后添加新的错误,如果之前已经写过任何错误,那么它们会被覆盖。因此,如果tmp.txt中有5行,另外3行,则只发送3行。我做了一些你建议使用with语句的更改,这些更改缩短了脚本并删除了close语句。我还用变量替换了文件名。执行此操作后,脚本运行正常,但出于设计软件的原因,我无法使用包含'with statements'的脚本。我现在必须重写脚本以删除with语句。你是一个很大的帮助,我非常感谢你。