Как уведомить себя, когда скрипт python сталкивается с ошибкой или просто останавливается? - PullRequest
6 голосов
/ 08 сентября 2011

У меня есть скрипт на python, который работает в Ubuntu и обрабатывает содержимое базы данных MySQL. Я хочу получать информацию, когда сценарий встречается с необработанным exception или когда он завершает обработку.

Как правильно это сделать?

Я подумал о том, чтобы отправить себе электронное письмо из Python, используя метод, показанный в этого SO-ответа , но чтобы это сделать, мне нужно жестко закодировать мои logindata - что мне неудобно скрипт запускается на общедоступном сервере внутри компании).

Какие-либо предложения обойти это или сделать это более подходящим способом?

Ответы [ 7 ]

1 голос
/ 08 сентября 2011

Вот обработчик исключений, который я написал и использую, который отправляет электронное сообщение об исключении, когда скрипт умирает. Установите его с помощью 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()
1 голос
/ 08 сентября 2011

Обычно вам не нужно указывать данные для входа при отправке электронной почты через SMTP.На вашем месте я бы поэкспериментировал с кодом, приведенным в ответе, с которым вы связались, и попробовал бы его на SMTP-сервере вашей компании.

0 голосов
/ 18 июля 2019

Это сработало как шарм: https://www.quora.com/How-can-I-send-a-push-notification-to-my-Android-phone-with-a-Python-script

НА ПК: установите notify-me

pip install notify-run

затем зарегистрируйте его как: notify-run register

Теперь на вашем мобильном телефоне отсканируйте код и разрешите уведомление с этого сайта.

Тогда ваш скрипт может уведомить вас так:

from notify_run import Notify
notify = Notify()
notify.send('any message you want')
0 голосов
/ 16 января 2017

Вы можете использовать GMail API. Ему не нужен ваш пароль внутри скрипта. Этот ответ может помочь.

0 голосов
/ 08 сентября 2011

Некоторые из ваших вариантов -

Если у вас есть доступ к машине / серверу в сети компании, где вы можете настроить простой SMTP-сервер в качестве почтового ретранслятора. Затем вы можете настроить свою регистрационную информацию для GMail более надежно, в зависимости от того, у кого все есть доступ к машине. Это может потенциально даже работать как простая виртуальная машина на другом сервере. ВМ, к которой есть доступ только у вас. Затем используйте этот сервер для отправки почты из вашего скрипта Python.

Если у вас нет доступа к серверу в сети компании, вы можете искать SMTP-серверы, которые не требуют аутентификации.

Или другой вариант - создать пользователя GMail только для отправки электронных писем и использования его учетных данных.

0 голосов
/ 08 сентября 2011

Если на этой машине установлен 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()
0 голосов
/ 08 сентября 2011

Если вы запускаете это с помощью cron, я бы посоветовал взглянуть на возвращаемое значение скрипта вне python в 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, или , когда отметка времени старше, чем частота, с которой ваш cron должен запускаться .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...