我有一個在Ubuntu上運行並處理MySQL數據庫內容的python腳本。我希望在腳本遇到未處理的exception
或完成處理時收到通知。如何通知我自己,當一個python腳本遇到錯誤或只是停止?
實現此目的的適當方法是什麼?
我想從使用this SO-Answer所示的方法蟒蛇內發送自己的電子郵件,但要能做到這一點我有硬編碼我logindata - 這我不舒服(腳本公共服務器上運行在公司內)。
任何建議,以繞過這一點,或使其更合適的方式發生?
我有一個在Ubuntu上運行並處理MySQL數據庫內容的python腳本。我希望在腳本遇到未處理的exception
或完成處理時收到通知。如何通知我自己,當一個python腳本遇到錯誤或只是停止?
實現此目的的適當方法是什麼?
我想從使用this SO-Answer所示的方法蟒蛇內發送自己的電子郵件,但要能做到這一點我有硬編碼我logindata - 這我不舒服(腳本公共服務器上運行在公司內)。
任何建議,以繞過這一點,或使其更合適的方式發生?
這是我編寫的一個異常處理程序,並在腳本死亡時使用該電子郵件異常。與sys.excepthook = ExceptHook
設置:
import os
import sys
import traceback
import re
import smtplib
import getpass
def ExceptHook(etype, value, tb):
"""Formats traceback and exception data and emails the error to me: &^&^@&^&^&.com.
Arguments:
etype -- Exception class type
value -- Exception string value
tb -- Traceback string data
"""
excType = re.sub('(<(type|class \')|\'exceptions.|\'>|__main__.)', '', str(etype)).strip()
Email = {'TO':"*****@*****.com", 'FROM':getpass.getuser() + '@blizzard.com', 'SUBJECT':'** Exception **', 'BODY':'%s: %s\n\n' % (excType, etype.__doc__)}
for line in traceback.extract_tb(tb):
Email['BODY'] += '\tFile: "%s"\n\t\t%s %s: %s\n' % (line[0], line[2], line[1], line[3])
while 1:
if not tb.tb_next: break
tb = tb.tb_next
stack = []
f = tb.tb_frame
while f:
stack.append(f)
f = f.f_back
stack.reverse()
Email['BODY'] += '\nLocals by frame, innermost last:'
for frame in stack:
Email['BODY'] += '\nFrame %s in %s at line %s' % (frame.f_code.co_name, frame.f_code.co_filename, frame.f_lineno)
for key, val in frame.f_locals.items():
Email['BODY'] += '\n\t%20s = ' % key
try:
Email['BODY'] += str(val)
except:
Email['BODY'] += '<ERROR WHILE PRINTING VALUE>'
thisHost = socket.gethostname()
thisIP = socket.gethostbyname(thisHost)
gmTime = time.gmtime()
logName = 'SomeTool_v%s_%s_%s_%s.%s.%s_%s.%s.%s.log' % (__version__, thisHost, thisIP, gmTime.tm_mon, gmTime.tm_mday, gmTime.tm_year, gmTime.tm_hour, gmTime.tm_min, gmTime.tm_sec)
if not os.path.exists(LOGS_DIR):
try:
os.mkdir(LOGS_DIR)
except:
baseLogDir = os.path.join(NET_DIR, "logs")
if not os.path.exists(baseLogDir):
try:
os.mkdir(baseLogDir)
except:
pass
else:
open(os.path.join(baseLogDir, logName), 'w').write(Email['BODY'])
else:
open(os.path.join(LOGS_DIR, logName), 'w').write(Email['BODY'])
Email['ALL'] = 'From: %s\nTo: %s\nSubject: %s\n\n%s' % (Email['FROM'], Email['TO'], Email['SUBJECT'], Email['BODY'])
server = smtplib.SMTP(MY_SMTP)
server.sendmail(Email['FROM'], Email['TO'], Email['ALL'])
server.quit()
if __name__ == '__main__':
sys.excepthook = ExceptHook
try:
1/0
except:
sys.exit()
如果你使用的cron運行此,我建議在看劇本的返回值蟒蛇之外在bash。例如,如果腳本拋出一個異常,你會得到一個返回值1:
$ python test.py
Traceback (most recent call last):
File "test.py", line 7, in <module>
raise ValueError("test")
ValueError: test
$ echo $?
1
雖然乾淨退出返回0:
$ python test.py
$ echo $?
0
要監視的cron,你可以寫回值到某個地方的文件。然後,使用monit在文件包含非0值或when the timestamp is older than how often your cron is supposed to run時通知您。
該機器是否安裝了sendmail,我只是使用sendmail發送電子郵件,而不是直接與smtp服務器通話,例如,試試這個
echo -e "To: [email protected]\nSubject: Testx\nTest\n" | sudo sendmail -bm -t -v
它會顯示的sendmail在詳細模式行動,如果它的作品你可以使用sendmail來例如發送電子郵件
ps = Popen(["/usr/lib/sendmail"]+list(your_recipents), \
stdin=PIPE)
ps.stdin.write('you msg')
ps.stdin.flush()
ps.stdin.close()
一些你的選擇是 -
如果你有機會獲得一臺機器/服務器公司網絡,在那裏你可以設置一個簡單的SMTP服務器作爲郵件中繼上。然後,您可以在那裏更安全地配置GMail的登錄詳細信息,具體取決於誰可以訪問本機。它甚至可以作爲另一臺服務器上的簡單VM運行。只有你有權訪問的虛擬機。然後使用這個服務器從你的python腳本發送郵件。
如果您無法訪問公司網絡上的服務器,則可以查找不需要身份驗證的SMTP服務器。
或者另一種選擇是創建一個GMail用戶,僅用於發送電子郵件和使用其憑證。
您可以使用GMail API。腳本中不需要密碼。 This answer可能會有所幫助。
此登錄數據是否與您的SMTP服務器或MySQL或兩者進行身份驗證? – arunkumar
使用SMTP-Sever。我想用我的GMail帳戶。 – Aufwind