2011-09-08 12 views
5

我有一個在Ubuntu上運行並處理MySQL數據庫內容的python腳本。我希望在腳本遇到未處理的exception或完成處理時收到通知。如何通知我自己,當一個python腳本遇到錯誤或只是停止?

實現此目的的適當方法是什麼?

我想從使用this SO-Answer所示的方法蟒蛇內發送自己的電子郵件,但要能做到這一點我有硬編碼我logindata - 這我不舒服(腳本公共服務器上運行在公司內)。

任何建議,以繞過這一點,或使其更合適的方式發生?

+0

此登錄數據是否與您的SMTP服務器或MySQL或兩者進行身份驗證? – arunkumar

+0

使用SMTP-Sever。我想用我的GMail帳戶。 – Aufwind

回答

1

通過SMTP發送電子郵件時,通常不需要提供登錄數據。如果我是你,我會試試你已經鏈接到的答案中給出的代碼,並使用你公司的SMTP服務器進行試用。

+0

您能解釋一下您的意思嗎?您不需要在通過SMTP發送電子郵件時提供登錄數據。 ... *? – Aufwind

+0

@Aufwind:我要說的是,如果你發送一封郵件到'abc @ xyz.com',並連接到'xyz.com'的SMTP服務器(即MX記錄中列出的那個),在大多數情況下,它會接受您的電子郵件,而無需提供任何登錄信息。 – NPE

1

這是我編寫的一個異常處理程序,並在腳本死亡時使用該電子郵件異常。與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() 
0

如果你使用的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時通知您。

0

該機器是否安裝了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() 
0

一些你的選擇是 -

如果你有機會獲得一臺機器/服務器公司網絡,在那裏你可以設置一個簡單的SMTP服務器作爲郵件中繼上。然後,您可以在那裏更安全地配置GMail的登錄詳細信息,具體取決於誰可以訪問本機。它甚至可以作爲另一臺服務器上的簡單VM運行。只有你有權訪問的虛擬機。然後使用這個服務器從你的python腳本發送郵件。

如果您無法訪問公司網絡上的服務器,則可以查找不需要身份驗證的SMTP服務器。

或者另一種選擇是創建一個GMail用戶,僅用於發送電子郵件和使用其憑證。

相關問題