如何在python脚本遇到错误或停止时通知自己?

时间:2011-09-08 16:45:45

标签: python ubuntu notifications

我有一个在Ubuntu上运行的python脚本并处理MySQL数据库的内容。当脚本遇到未处理的exception或处理完毕后,我希望收到通知。

实现这一目标的恰当方法是什么?

我想使用this SO-Answer中显示的方法从python中发送自己的电子邮件,但为了能够做到这一点,我必须硬编码我的logindata - 我不熟悉(脚本运行在公司内的公共服务器。)

有什么建议可以绕过这个或使用更合适的方式实现它?

8 个答案:

答案 0 :(得分:1)

通过SMTP发送电子邮件时,通常不需要提供登录数据。如果我是你,我会尝试使用您链接的答案中给出的代码,并使用您公司的SMTP服务器进行试用。

答案 1 :(得分: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()

答案 2 :(得分:0)

如果你用cron运行它,我建议在bash中查看python之外的脚本的返回值。例如,如果脚本引发异常,则返回值为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,可以将返回值写入某个文件。然后,当文件包含0以外的值或monit时,使用when the timestamp is older than how often your cron is supposed to run通知您。

答案 3 :(得分:0)

该机器是否安装了sendmail,我只是使用sendmail发送电子邮件而不是直接与smtp服务器通信,例如试试这个

echo -e "To: auniyal@example.com\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()

答案 4 :(得分:0)

您的一些选择是 -

如果您可以访问公司网络上的计算机/服务器,则可以将简单的SMTP服务器设置为邮件中继。然后,您可以在那里更安全地配置GMail的登录详细信息,具体取决于所有人都可以访问该计算机。它甚至可能作为另一台服务器上的简单VM运行。只有您有权访问的VM。然后使用此服务器从python脚本发送邮件。

如果您无法访问公司网络上的服务器,则可以查找不需要身份验证的SMTP服务器。

或者另一种选择是创建一个GMail用户,仅用于发送电子邮件和使用其凭据。

答案 5 :(得分:0)

您可以使用GMail API。它在脚本中不需要您的密码。 This answer可能有帮助。

答案 6 :(得分:0)

这很吸引人:https://www.quora.com/How-can-I-send-a-push-notification-to-my-Android-phone-with-a-Python-script

在PC上:安装notify-me

pip install notify-run

然后将其注册为:notify-run register

现在在您的手机上扫描代码,并允许来自此站点的通知。

然后您的脚本可以像这样通知您:

from notify_run import Notify
notify = Notify()
notify.send('any message you want')

答案 7 :(得分:0)

我遇到了类似的问题,我想在脚本中发生事件时发送通知。因此,我决定构建一个软件包Notif,以根据需要发送通知。我还添加了一个装饰器,以在脚本失败时发送通知。

以下是我的软件包notif发送电子邮件通知的示例:

sender_email = "my_email"
sender_login_credential = "my_password"
destination_email = sender_email
smtp_server = smtplib.SMTP('smtp.gmail.com',587)    
notif = EmailNotificator(sender_email, sender_login_credential,
                               destination_email, smtp_server)
notif.send_notification(subject="subject", text="text")

在此处查看doc