Django在日志中使用AdminEmailHandler发送邮件(同步),及celery异步发送日志邮件的实现

发布于:2024-03-22 ⋅ 阅读:(89) ⋅ 点赞:(0)

目录

一、使用AdminEmailHandler实现发送日志通知邮件

1,配置日志项

2,配置邮件项

3,在视图里使用日志

二、继承AdminEmailHandler使用celery实现异步发送邮件

1,安装配置celery

2,继承AdminEmailHandler类,重写方法

3,编写异步任务

4,配置日志项

5,在视图里使用日志

6,启动celery并测试


在django的项目配置日志功能后,响应发送日志邮件到邮箱进行通知

一、使用AdminEmailHandler实现发送日志通知邮件

1,配置日志项

# settings.py

# 日志配置
LOGGING = {
    "version": 1,
    "formatters": {
        "simple": {
            "format": '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
        },
        "standard": {
            "format": '%(levelname)s:%(asctime)s:%(filename)s:%(lineno)d:%(message)s'
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "simple"
        },
        "file": {
            "class": "logging.FileHandler",
            "formatter": "simple",
            "filename": "monitoring.log",  # 将日志信息写入本地文件中
            "encoding": "utf-8"
        },
        'mail_admins': {  # 新增mail_admins的handler,class为AdminEmailHandler
            'level': 'INFO',  # 发送邮件的级别,INFO及以上的级别会发送邮件
            'class': 'django.utils.log.AdminEmailHandler',  # 
            'formatter': "simple"
        }
    },
    "loggers": {
        "simple": {
            "level": "DEBUG",
            "handlers": ["file", "mail_admins"],  # 添加mail_admins项
            "propagate": True
        },
        "standard": {
            "level": "ERROR",
            "handlers": ["console", "file"],
            "propagate": True
        }
    }
}

2,配置邮件项

# 邮件配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.qq.com'  # 如果是 163 改成 smtp.163.com
EMAIL_PORT = 587
EMAIL_HOST_USER = 'xxxx@qq.com'  # 登录邮箱的账号
EMAIL_HOST_PASSWORD = 'yxamfessnijaie'  # 授权码,各邮箱的设置中启用smtp服务时获取


SERVER_EMAIL = 'xxxx@qq.com'  # 日志邮件的发送方
ADMINS = [('admin', 'xxxxx@qq.com')]  # 日志邮件的接收方

3,在视图里使用日志

import logging

logger = logging.getLogger('simple')  # 使用配置的simple项
logging.basicConfig(level=logging.INFO)  # 配置级别



class MessageView(View):
    def get(self, request):
        # 查询的逻辑
        logger.info("查询成功")
        return JsonResponse({"status": 200})

为MessageView视图配置url后使用postman请求测试

可以看到视图请求成功返回了,邮件也收到了

但是存在一个问题:如此配置的发送日志邮件的功能是同步的,也就是说是阻塞的,需要邮件发送成功后视图才能返回结果,所以下面使用celery自定义一个异步的

二、继承AdminEmailHandler使用celery实现异步发送邮件

在项目根目录下创建celery_tasks文件夹,以下是目录结构:

1,安装配置celery

pip install celery django-redis
# settings.py


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'celery',  # 添加celery
]

在celery_tasks目录 下创建celery.py文件,定入下面的内容:

import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MediaManager.settings')

app = Celery('MediaManager')  # 项目的名
app.config_from_object('celery_tasks.config', namespace='CELERY')  # 配置文件
app.autodiscover_tasks()  # 任务

在celery_tasks目录 下创建config.py文件,写入下面的内容:

CELERY_BROKER_URL = 'redis://127.0.0.1:6379/4'  # 存储celery任务队列的数据库
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/5'  # 存储结果的数据库
CELERY_TASK_SERIALIZER = 'json'
# celery时区
CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_ENABLE_UTC = False

 在与settings.py同级的__init__.py文件里写入以下内容:

from celery_tasks.celery import app as celery_app
__all__ = ['celery_app']

2,继承AdminEmailHandler类,重写方法

在celery_tasks目录下创建handlers.py,写入下面的内容:

from django.utils.log import AdminEmailHandler
from celery_tasks.sms.tasks import send_email_async


class CeleryAdminEmailHandler(AdminEmailHandler):
    def emit(self, record):
        message = self.format(record)  # 邮件正文内容
        subject = super(CeleryAdminEmailHandler, self).format_subject(message)  # 邮件标题
        send_email_async.delay(subject, message)

重写AdminEmailHandler类里的emit方法

CeleryAdminEmailHandler的emit方法调用send_mail_async.delay()方法异步执行任务

3,编写异步任务

在在celery_tasks/sms目录下创建tasks.py,写入下面的内容:

from celery import shared_task
from django.core import mail
from django.core.mail import get_connection
from django.conf import settings



def connection():
    return get_connection(backend=settings.EMAIL_BACKEND, fail_silently=True)


@shared_task
def send_email_async(subject, message, *args, **kwargs):
    try:
        mail.mail_admins(
            subject, message, *args, connection=connection(), **kwargs
        )
        return "success"
    except Exception as e:
        print("发生错误:" + str(e))
        return "fail"

4,配置日志项

将日志配置中的mail_admins的class项替换为handlers.py里写的CeleryAdminEmailHandler类

# settings.py

# 日志配置
LOGGING = {
    "version": 1,
    "formatters": {
        "simple": {
            "format": '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
        },
        "standard": {
            "format": '%(levelname)s:%(asctime)s:%(filename)s:%(lineno)d:%(message)s'
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "simple"
        },
        "file": {
            "class": "logging.FileHandler",
            "formatter": "simple",
            "filename": "monitoring.log",  # 将日志信息写入本地文件中
            "encoding": "utf-8"
        },
        'mail_admins': {  # 新增mail_admins的handler,class为AdminEmailHandler
            'level': 'INFO',  # 发送邮件的级别,INFO及以上的级别会发送邮件
            'class': 'celery_tasks.handlers.CeleryAdminEmailHandler',  # 替换为自己写的类
            'formatter': "simple"
        }
    },
    "loggers": {
        "simple": {
            "level": "DEBUG",
            "handlers": ["file", "mail_admins"],  # 添加mail_admins项
            "propagate": True
        },
        "standard": {
            "level": "ERROR",
            "handlers": ["console", "file"],
            "propagate": True
        }
    }
}

5,在视图里使用日志

import logging

logger = logging.getLogger('simple')  # 使用配置的simple项
logging.basicConfig(level=logging.INFO)  # 配置级别



class MessageView(View):
    def get(self, request):
        # 查询的逻辑
        logger.info("查询成功")
        return JsonResponse({"status": 200})

6,启动celery并测试

先启动django项目,然后在项目根目录下启动celery

celery -A MediaManager  worker -l INFO -P eventlet

 

为MessageView视图配置url后使用postman请求测试

 可以发现postman返回的很快,因为这时发送邮件的耗时任务交由celery执行了,邮件也异步收到了

 redis查看任务返回的结果,result参数为success也提示成功了,这个success是在tasks.py里return过来的

本文含有隐藏内容,请 开通VIP 后查看

微信公众号

今日签到

点亮在社区的每一天
去签到