We are running custom management commands periodically on the server.
Is there any way to get something like error reporting via email working for the command?
We are running custom management commands periodically on the server.
Is there any way to get something like error reporting via email working for the command?
You could use django logging handler AdminEmailHandler:
https://docs.djangoproject.com/en/dev/topics/logging/#django.utils.log.AdminEmailHandler
As the docs say:
This handler sends an email to the site admins for each log message it receives.
So you could use this to log an error on any exception raised in the management command, and the exception would be automatically send to the admins
Let us say I have this simple management command in which I want to handle exception and send mail:
test_command.py
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def handle(self, *args, **options):
x = 1 / 0
print("x: ", x)
As you can see above command will generate division by zero exception we can handle this exception in the command itself but then what if we have many such commands we will have to repeat exception handling for each one by one. A better way is to handle the exception in manage.py
as all commands are run through it like this:
manage.py
#!/usr/bin/env python
import os
import sys
from django.core.management import execute_from_command_line
from app_name.exception_reporter import AdminExceptionMailReporter
CRON_JOBS = ['test_command']
def execute_command(args):
if args and len(args) >= 2 and args[1] in CRON_JOBS:
try:
execute_from_command_line(args)
except Exception:
command_name = args[1]
# SENDING MAIL TO ADMIN INFORMING ABOUT THE EXCEPTION
AdminExceptionMailReporter(sys.exc_info(), command_name).send()
raise
else:
execute_from_command_line(args)
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
execute_command(sys.argv)
Now let us define our AdminExceptionMailReporter
:
exception_reporter.py
from django.core import mail
from django.views.debug import ExceptionReporter
DEFAULT_SUBJECT = "The '%s' cron job has failed with an exception."
DEFAULT_MESSAGE = "Please find the below reason for failure:"
class AdminExceptionMailReporter:
def __init__(self, exception, command_name, subject=None, message=None):
self.exception = exception
self.command_name = command_name
self.subject = subject
self.message = message
def set_subject(self, subject):
self.subject = subject
def set_message(self, message):
self.message = message
def _set_default_html(self):
if self.subject is None:
subject = DEFAULT_SUBJECT % self.command_name
self.set_subject(subject)
if self.message is None:
self.set_message(DEFAULT_MESSAGE)
def get_reporter(self, is_email=True):
exception_class, exception_name, traceback = self.exception
reporter = ExceptionReporter(
None, exc_type=exception_class,
exc_value=exception_name, tb=traceback,
is_email=is_email
)
return reporter
def send(self, fail_silently=False):
self._set_default_html()
mail.mail_admins(
self.subject, self.message, fail_silently=fail_silently,
html_message=self.get_reporter().get_traceback_html()
)
Now the final step is to add AdminEmailHandler in logging and adding your mail name email tuple in ADMIN setting variable.
© 2022 - 2024 — McMap. All rights reserved.