2013-03-01 55 views
0

下面的python 2.5腳本可以工作,但由於我是初學者,我不知道是否存在任何明顯的錯誤或者更好的方法來實現我想實現的目標?從日誌文件和電子郵件結果中提取新錯誤

目標是打開當天的日誌 - '/ Library/Application Support/Perceptive Automation/Indigo 5/Logs /',並提取包含單詞錯誤的行並僅發送新錯誤。 提取錯誤行後,在tmp.txt中計數行數(prenumLines)。然後將提取的行寫入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 

回答

0

有你,從我的經驗來說,真的應該考慮做(我用必須,但它仍然只是一個建議)的變化,以及一些其他更爲我的個人風格(在那裏我使用應該是)。

在元級別:你的問題,本來只是標記這可能是爲什麼它沒有得到任何關注,您必須使用其中有那麼多的追隨者。

必須不使用文件中的製表符和空格字符。因此,您的來源實際上在SO上進行了不正確的縮進。該行:tmpFile.write(line)應該在其上面的if聲明下縮進一級。

必須不使用相同的字符串四次是一個文件名,用一個變量替換它。 並創建使用os.path.join()

應該考慮以下PEP8風格指南Python中常見的基本目錄變量。

如果您第一次嘗試此操作,「tmp.txt」不存在,您的程序將無法運行。爲0的prenumLines優雅地失敗(但我沒有使用這個可言了,見下文):

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

其實我想知道的是你的國家,你的代碼的工作,因爲你覆蓋tmp.txt和只寫錯誤線來自最近的日誌。您再次分配給tmpFile的那一刻,第一次開放閱讀已關閉。然後關閉用於寫入兩次的tmpFile(爲此,Python不會引發錯誤)。如果昨天的日誌有一個錯誤和今天三,你的電子郵件將只顯示兩行。要附加到文件使用open(文件名,「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 
+0

非常感謝您的詳細回覆。我目前正在通過它來試圖瞭解您的意見和更改。我不知道它是否會改變您的某些回覆,但我想要做的是將該身體作爲電子郵件發送,但僅適用於自上一封電子郵件以來發生的任何新錯誤。包含錯誤的日誌以當前日期命名約會它只是當前的日誌,我想從中獲取錯誤。再次感謝! – 2013-03-24 21:26:41

+0

我試着用一行'tmp.txt'測試你的原始腳本,並在每日日誌中做了5行中的3行。 'tmp.txt'沒有被追加,而是被覆蓋。你沒有看到這種行爲嗎?如果在經過這個之後有任何問題,請讓我知道。 – Anthon 2013-03-25 04:33:18

+0

生成日誌的軟件是Indigo,一個自動化程序。它每天寫入一個新日誌。我設置了腳本,每10分鐘解析一次日誌,查找錯誤併發送郵件。我想要新的新錯誤,而不是以前發送的錯誤。我在tmp.text中統計了這些行,並添加了新的錯誤,以前寫入的任何錯誤都被覆蓋。因此,如果tmp.txt中有5行,並且添加了3行,則只會發送3行新行。我做了一些你所建議的修改,但是我發現我不能在軟件中使用包含'with statements'的腳本。再次感謝你的幫助。 – 2013-03-26 12:56:42

0

Anthon - 非常感謝您花時間回覆。生成日誌的軟件是Perceptive Automation Indigo,一個家庭自動化程序。它不斷地向日志寫入每日生成的新日誌。我設置了python腳本,每隔10分鐘解析一次日誌,查找錯誤,然後通過電子郵件發送給我。我面臨的挑戰是隻有通過電子郵件發送新錯誤並避免以前發送的錯誤。我是如何計算tmp.text中的行數,然後添加新的錯誤,如果以前寫過任何錯誤,他們會被覆蓋,如你所說。因此,如果tmp.txt中有5行,並且添加了3行,則只會向我發送3行新行。我做了一些改變,你建議使用with語句縮短腳本並擺脫結束語。我也用一個變量替換了文件名。這樣做後,腳本運行良好,但由於設計軟件的原因,我無法使用包含'with statements'的腳本。我現在必須重寫腳本以刪除with語句。你一直很大的幫助,我非常感謝你。

+0

即使包含'from __future__ import with_statement'行,您也不能使用with語句嗎?這應該在Python2.5中起作用 – Anthon 2013-03-26 14:48:10

相關問題