Есть ли способ, как настроить SMTPHandler в Python для более сложных вещей? - PullRequest
6 голосов
/ 11 февраля 2012

Я использую стандартный SMTPHandler logger для перехвата моих исключений Python. Есть ли способ, как поместить имя исключения в тему письма? Это было бы намного лучше, чем со статической темой, потому что Gmail (и не только Gmail) может группировать разговоры по теме и поэтому может сгруппируйте его по типу ошибки.

Например, если 50 абсолютно одинаковых ошибок + 1 разные, я бы увидел два разговора в моей папке входящих вместо 1 группы, состоящей из 51 электронного письма, где я очень легко мог пропустить один другой.

Также, есть ли способ, как предотвратить отправку еще тех же ошибок? Например. каким-то образом определить мою собственную функцию, решая, будет ли отправлено письмо или нет. Функция будет принимать некоторую базовую информацию в параметрах, чтобы она могла решить (например, кэшировать и посмотреть, была ли уже отправлена ​​такая проблема).

Я просмотрел документы, но ничего подобного не могу найти. Кажется, все очень просто. Если SMTPHandler не может этого сделать, что будет лучшей и все же простой альтернативой? Любые аккуратные библиотеки?

Спасибо!

Ответы [ 3 ]

7 голосов
/ 11 февраля 2012

Вам просто нужно создать свой собственный подкласс SMTPHandler .

Для вашего первого запроса: вам просто нужно переопределить метод getSubject(record).Что касается того, что вы можете указать в теме, посмотрите на help(Formatter) после импорта Formatter из журнала.

Для вашего второго запроса: вы должны переопределить метод emit(record).Проверьте запись и примите решение о том, следует ли ее отправлять.Если это так, то просто вызовите метод super(SMTPHandler,self).emit(record).

class MySMTPHandler(SMTPHandler):

    def getSubject(self, record):
        return "My Error Format from the record dict"

    def emit(self, record):
        #check for record in self.already_send or something
        if sendit:
           super(MySMTPHandler,self).emit(record)
1 голос
/ 27 декабря 2013

Простой и гибкий способ - отформатировать не только содержимое электронной почты, но и тему электронной почты. Это требует подклассов logging.handlers.SMTPHandler.

Таким образом, если в настроенной вами теме есть ссылки на переменные, она будет расширена по требованию. Вот реализация, включающая тестовый код:

    import logging, logging.handlers
    class TitledSMTPHandler(logging.handlers.SMTPHandler):
        def getSubject(self, record):
            formatter = logging.Formatter(fmt=self.subject)
            return formatter.format(record)

    # below is to test
    logging.getLogger().addHandler(TitledSMTPHandler(
        ('your.smtp.server',587), 
        'email@from.address', 'email@to.address', 
        '%(asctime)s Error: %(message)s', 
        ('SMTP login', 'SMTP password'), ()
    ))

    logging.error("TestError")

Замените конфигурацию SMTP на вашу, запустите код, и вы получите электронное письмо с сообщением об ошибке в теме (также в теле письма).

Если вы определяете обработчик в файле конфигурации регистрации, не забудьте экранировать ссылки на параметры. например %(asctime)s должно стать %%(asctime)s, чтобы предотвратить преждевременную интерполяцию configparser - однако экранирование %% не поддерживается в Python 3.1 и до него.


Пожалуйста, если вы будете задавать один вопрос за раз, вы сильно поможете другим пользователям Google. Вы должны начать две темы, одна называется "Есть ли способ, как поместить имя исключения в тему письма?" а другой "есть ли способ, как предотвратить отправку все тех же ошибок?"

Я отвечу только на ваш первый вопрос, чтобы сосредоточиться на одной теме. Возможно, вы подумали, что эти два вопроса могут зависеть друг от друга, поэтому их нужно задавать вместе, а они просто приходили вам в голову вместе. Я думаю, что все еще целесообразно предложить вам изменить название вашего вопроса, чтобы подчеркнуть одну проблему, вместо того, чтобы говорить «продвинутый материал».

Я также хотел бы предложить посетить comp.lang.python, если вопрос является открытой темой и / или не может быть четко определен (например, «Я хочу продвинутые вещи, что все остальные используют?»)

0 голосов
/ 11 февраля 2012

Вы можете унаследовать класс SMTPHandler и расширить или заменить его функциональные возможности, например

class A(object):
    def __init__(self):
        self.email = "jjj@jjj.com"

    def send_error(self, error):
        send_mail(self.email, error)

class B(A):
    def __init__(self):
        A.__init__(self)

    def send_error(self, error):
        if not error.sent:
            A.send_mail(self, error)
        else:
            #do nothing
            pass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...