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.
You need to acknowledge two things:
- You want to send an email using Python's builtin logging system and
- 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)
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.
来源:https://stackoverflow.com/questions/10022288/simple-error-log-message-in-django