How to notify myself when a python script runs into an error or just stops?
I have a python script which runs on Ubuntu and processes the content of a MySQL Database. I want to be informed when the script开发者_如何转开发 runs into an unhandled exception or when it is done processing.
What is the appropriate way to make this happen?
I thought of sending myself an email from within python using the method shown in this SO-Answer, but to be able to do that I have to hardcode my logindata - which I am not comfortable with (the script runs on a public server within the company).
Any suggestions to bypass that or to make it happen using a more appropriate way?
This worked as charm: https://www.quora.com/How-can-I-send-a-push-notification-to-my-Android-phone-with-a-Python-script
ON PC: install notify-me
pip install notify-run
then register it as: notify-run register
now on your mobile scan the code and allow notification from this site.
Then your script can notify you like this:
from notify_run import Notify
notify = Notify()
notify.send('any message you want')
You typically don't need to supply login data when sending an email over SMTP. If I were you, I'd experiment with the code given in the answer you've linked to and try it out with your company's SMTP server.
Here is an exception handler I wrote and use that emails the exception when the script dies.  Set it with 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()
If you're running this with cron, I would suggest looking at the return value of the script outside of python in bash. For example, if the script raises an exception, you will get a return value of 1:
$ python test.py 
Traceback (most recent call last):
  File "test.py", line 7, in <module>
    raise ValueError("test")
ValueError: test
$ echo $?
1
While a clean exit returns 0:
$ python test.py 
$ echo $?
0
To monitor the cron, you can write the return value to a file somewhere. Then, use monit to notify you when the file contains a value other than 0, or when the timestamp is older than how often your cron is supposed to run.
Does that machine have sendmail installed, I would just use sendmail to send emails instead of directly talking to smtp server e.g. try this
echo -e "To: auniyal@example.com\nSubject: Testx\nTest\n" | sudo sendmail -bm -t -v
It will show sendmail in action in verbose mode and if it works you can just use sendmail to send email e.g.
    ps = Popen(["/usr/lib/sendmail"]+list(your_recipents), \
               stdin=PIPE)
    ps.stdin.write('you msg')
    ps.stdin.flush()
    ps.stdin.close()
Some of your options are -
If you have access to a machine/server on the company network, where you can setup a simple SMTP server as a mail relay. You can then configure your login details for GMail a bit more securely there, depending on who all has access to the machine. It could potentially even be run as a simple VM on another server. A VM that only you have access to. Then use this server for sending mail from your python script.
If you don't have access to a server on the company network, you could look for SMTP servers which don't require authentication.
Or another option is to create a GMail user just for sending out emails and using its credentials.
You may use GMail API. It doesn't need your password inside the script. This answer might help.
 
         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论