simple error log message in django

2019-02-07 15:23发布

I've got error emails setup via Django's logging mechanism in 1.3. It sends me a nice email when an error happens. However, when I log a simple error message it's being formatted oddly and I'm not sure why.

For example, there's a condition in my app where if something doesn't exist in the DB I want to know about, but I have a suitable default value that will work fine. Thus, I want an email sent to me with some info; it's not necessarily happening on an Exception.

If I do something like this:

logger.error("fee did not exist in the database for action %s", "actionX")

The information in the logfile is fine, but the email is really lacking some information. Here's the subject line:

[Django] ERROR: Test this jazz %s

And then the body:

None

Request repr() unavailable

My question is, how do I get A) the value to show up in the subject and B) get some actual, relevant information in the body....like line number or something like that.

2条回答
Animai°情兽
2楼-- · 2019-02-07 16:03

You need to acknowledge two things:

  1. You want to send an email using Python's builtin logging system and
  2. You are not logging a regular exception so the builtin mechanism for sending emails won't work since it's depending on an exception type-like object to be passed and stuff to be stored in a traceback.

Anyways, not impossible!

LOGGING = {
   ...
   'handlers': {
        ...
        'my_special_mail_handler': {
            'level': 'ERROR',
            'filters': [],
            'class': 'myapp.loggers.MyEmailHandler',
            'include_html': False,
        },
    },
    'loggers': {
        ...
        'my_special_logger': {
            'handlers': ['console', 'my_special_mail_handler'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}

MY_RECIPIENTS = (("Name of person", "email@example.com"),)

...that stuff is merged into your settings.

Then, there's your special logging class, MyEmailHandler:

from django.utils.log import AdminEmailHandler
from django.core.mail.message import EmailMultiAlternatives
from django.conf import settings

class MyEmailHandler(AdminEmailHandler):

    def emit(self, record):
        if not getattr(settings, "MY_RECIPIENTS", None):
            return
        subject = self.format_subject(record.getMessage())
        message = getattr(record, "email_body", record.getMessage())
        mail = EmailMultiAlternatives(u'%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
                    message, settings.SERVER_EMAIL, [a[1] for a in settings.MY_RECIPIENTS],)
        mail.send(fail_silently=False)

Now you're able to create a special logging entry that's both emailed and output to the terminal this way:

import logging
logger = logging.getLogger("my_special_logger")
error = logger.makeRecord(
    logger.name, logging.ERROR, 0, 0,
    u"Subject: Some error occured",
    None, None, "", None,
)
error.email_body = msg
logger.handle(error)

and to make stuff easy, use a utility function:

import logging
def my_log(msg, body, level=logging.ERROR):
    logger = logging.getLogger("my_special_logger")
    error = logger.makeRecord(
        logger.name, level, 0, 0,
        u"Subject: Some error occured",
        None, None, "", None,
    )
    error.email_body = msg
    logger.handle(error)
查看更多
叼着烟拽天下
3楼-- · 2019-02-07 16:09

The Django Logging docs state:

Of course, it isn't enough to just put logging calls into your code. You also need to configure the loggers, handlers, filters and formatters to ensure that logging output is output in a useful way.

You need to tweak your settings in your logging.config() dictionary. That allows you to set out exactly what information you want and how to format.

Cutting a small bit from the docs:

'formatters': {
    'verbose': {
        'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
    },

Gives you a bit of an idea how you can influence the output, and the logging.config docs for python will fill out the available options.

查看更多
登录 后发表回答