Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way how to configure SMTPHandler in Python to do more advanced stuff?

I am using standard SMTPHandler logger to catch my Python exceptions. Is there a way how to put exception name into the subject of the mail? It would be much better than with static subject, because Gmail (and not only Gmail) can group conversations according to subject and so it could group it according to the type of error.

E.g., if 50 completely the same errors occure + 1 different, I'd see two conversations in my inbox instead of 1 group consisting 51 emails, where I can very easily overlook the single different one.

Also, is there a way how to prevent sending still the same errors? E. g. somehow define my own function deciding if email is to be sent or not. The function would take some basic info in params so it could decide (e.g. cache & see if such an issue was already sent).

I browsed the docs, but I can't find anything like that. It seems to be very simple. If SMTPHandler can't do this, what would be the best and still simple alternative? Any neat libraries?

Thank you!

like image 647
Honza Javorek Avatar asked Feb 10 '12 22:02

Honza Javorek


People also ask

What is a logging handler Python?

Python Logging Handler The log handler is the component that effectively writes/displays a log: Display it in the console (via StreamHandler), in a file (via FileHandler), or even by sending you an email via SMTPHandler, etc. Each log handler has 2 important fields: A formatter which adds context information to a log.


Video Answer


2 Answers

You simply need to create your own subclass of SMTPHandler.

For your first request: You just need to override the getSubject(record) method. As to what you can put in the subject, look at help(Formatter) after importing Formatter from logging.

For your second request: You must override the emit(record) method. Inspect the record and make your own decision about whether it should be send. If so then just call the super(SMTPHandler,self).emit(record) method.

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)
like image 192
Phil Cooper Avatar answered Sep 29 '22 09:09

Phil Cooper


The easy and flexible way is to format not only email content, but also email subject. This require subclassing logging.handlers.SMTPHandler.

This way if there are any variable references in the subject you configured, it would be expanded on demand. Here is the implementation including test code:

    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 protected]', '[email protected]', 
        '%(asctime)s Error: %(message)s', 
        ('SMTP login', 'SMTP password'), ()
    ))

    logging.error("TestError")

Replace the SMTP configuration with yours, run the code and you should receive an email where the error message is in subject (also in email body).

If you define the handler in a logging configration file, remember to escape the parameter references. e.g. %(asctime)s should become %%(asctime)s, to prevent configparser's premature interpolation -- however the %% escape is not hornored in and before python 3.1.


Please, if you ask one question at a time, you will help other Googlers a lot. You should start two topics, one is called "Is there a way how to put exception name into the subject of the mail?" and the other "is there a way how to prevent sending still the same errors?"

I will only answer your first question in order to focus on one topic. Perhaps you thought the two questions may be depending on each other hence must be asked together, while they merely came to your mind together. I think it is still feasiable to suggest you to change the title of your question to emphasize one issue, instead of saying "advanced stuff".

I also like to suggest visiting comp.lang.python if the question is an open topic and/or cannot be well defined (e.g. "I want advanced stuff, what everybody else use?")

like image 34
Tankman六四 Avatar answered Sep 29 '22 07:09

Tankman六四