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

news2024/12/26 22:17:42

目录

一、使用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过来的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1537930.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python食品安全信息管理系统flask-django-nodejs-php

。 食品安全信息管理系统是在安卓操作系统下的应用平台。为防止出现兼容性及稳定性问题,编辑器选择的是Hbuildex,安卓APP与后台服务端之间的数据存储主要通过MySQL。用户在使用应用时产生的数据通过 python等语言传递给数据库。通过此方式促进食品安全信…

VMware 15 中 Ubuntu与windows 10共享文件夹设置

wmware 15.5.7中安装ubuntu 22.04 物理机为windows 10 1.选中ubuntu中想要共享的文件夹右击,点属性 2.在Local network share中勾选share this folder,第一次会提示你安装samba,安装即可 3.window10的资源管理器中使用 虚拟机计算机名即可…

无人机采集图像的相关知识

1.飞行任务规划 一般使用飞行任务规划软件进行飞行任务的设计,软件可以自动计算相机覆盖和图像重叠情况。比如ArduPilot (ArduPilot - Versatile, Trusted, Open) 和UgCS (http://www.ugcs.com)是两个飞行任务规划软件,可以适用大多数无人机系统。 2.图…

如何减少pdf的文件大小?pdf压缩工具介绍

文件发不出去,有时就会耽误工作进度,文件太大无法发送,这应该是大家在发送PDF时,常常会碰到的问题吧,那么PDF文档压缩大小怎么做呢?因此我们需要对pdf压缩后再发送,那么有没有好用的pdf压缩工具…

解决IE11报错:CSS 因 Mime 类型不匹配而被忽略

简要概述: 本人用springboot开发网站,手动处理js和css文件请求,报错:CSS 因 Mime 类型不匹配而被忽略 后台代码: 如下三个代码块 GetMapping("/Guest/ASN1/{FileName}")public void GetFiles(PathVariab…

阿里云 EMR Serverless Spark 版免费邀测中

随着大数据应用的广泛推广,企业对于数据处理的需求日益增长。为了进一步优化大数据开发流程,减少企业的运维成本,并提升数据处理的灵活性和效率,阿里云开源大数据平台 E-MapReduce (简称“EMR”)正式推出 E…

SQL中条件放在on后与where后的区别

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。 在使用left jion时,on和where条件的区别如下: on条件是在生成临时表时使用的条件,不管on中的条件是否为真&…

深度学习Top10算法之深度神经网络DNN

深度神经网络(Deep Neural Networks,DNN)是人工神经网络(Artificial Neural Networks,ANN)的一种扩展。它们通过模仿人脑的工作原理来处理数据和创建模式,广泛应用于图像识别、语音识别、自然语…

Dell戴尔XPS 12 9250二合一笔记本电脑原装出厂Windows10系统包下载

链接:https://pan.baidu.com/s/1rqUEM_q5DznF0om6eevcwg?pwdvij0 提取码:vij0 戴尔原厂WIN10系统自带所有驱动、出厂主题壁纸、系统属性专属联机支持标志、系统属性专属LOGO标志、Office办公软件、MyDell等预装程序 文件格式:esd/wim/sw…

Spring Cloud Alibaba Sentinel 使用详解

一、Sentinel 介绍 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 Sentinel 具有以下特征: 丰富的应用场景: Sentinel 承接了阿里巴…

【BUG】java.nio.charset.MalformedInputException: Input length = 1

springboot maven 项目启动 编码异常 修改 ERROR org.springframework.boot.SpringApplication - Application run failed java.nio.charset.MalformedInputException: Input length 1 … 修改编码为UTF-8maven : clean -> compile

深度学习:复杂工业场景下的复杂缺陷检测方法

摘要:在复杂的工业场景中,缺陷检测一直是一个重要而具有挑战性的任务。近年来,深度学习技术的快速发展为复杂工业场景下的缺陷检测提供了新的解决方案。本文将介绍深度学习在复杂工业场景下的复杂缺陷检测中的应用,并探讨其技术进…

cool-admin-node.js 中redis缓存的使用

1. 在做cool 后端的时候 用户登录 时的token 需要鉴权的value 以及发送验证码 这些 需要存到缓存里面 ,进行逻辑鉴权 所以我们需要用到redis 缓存 或者数据库缓存 我这里介绍一下redis 的缓存 在cool-admin 中 使用的一般都是宝塔面板 首先得有服务器 需要有自己的…

如何屏蔽来自一些可疑IP对网站的访问

前段时间我们的网站遭受到黑客的攻击,导致网站出现乱码以及丢失了一些网站文件。在我们将网站全部迁移至Hostease虚拟主机后,为了再次避免这种情况发生,我们对网站做了一些安全防护,除了安装一些安全插件之外,我们还屏…

计算机组成原理 数据通路组成实验

一、实验目的 (1)将双端口通用寄存器堆和双端口存储器模块联机; (2)进一步熟悉计算机的数据通路; (3)掌握数字逻辑电路中故障的一般规律,以及排除故障的一般原则和方法; (4)锻炼分析问题与解决问题的能力,在出现故障的情况下,独立分析故障…

基于CSS3制作专属可自由旋转的立方体

一、代码区域 1.1 css3代码区域 <style>* {padding: 0;margin: 0;list-style: none;}/* 1) 定义动画 */keyframes loop {0% {transform: rotateX(348deg) rotateY(67deg) rotateZ(95deg);}50% {transform: rotateX(0deg) rotateY(0deg) rotateZ(0deg);}100% {transform:…

【C++】1597. 买文具

问题&#xff1a;1597. 买文具 类型&#xff1a;基本运算、整数运算 题目描述&#xff1a; 花花去文具店买了 1 支笔和 1块橡皮&#xff0c;已知笔 x 元/ 支&#xff0c;橡皮 y元 / 块&#xff0c;花花付给了老板 n 元&#xff0c;请问老板应该找给花花多少钱&#xff1f; 输…

SQLiteC/C++接口详细介绍sqlite3_stmt类(十三)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;十二&#xff09; 下一篇&#xff1a; 待续 51、sqlite3_stmt_scanstatus_reset sqlite3_stmt_scanstatus_reset 函数用于重置指定语句对象最近一次执行的 WHER…

基于python+vue的OA公文发文管理系统flask-django-php-nodejs

系统根据现有的管理模块进行开发和扩展&#xff0c;采用面向对象的开发的思想和结构化的开发方法对OA公文发文管理的现状进行系统调查。采用结构化的分析设计&#xff0c;该方法要求结合一定的图表&#xff0c;在模块化的基础上进行系统的开发工作。在设计中采用“自下而上”的…

大模型分布式推理ray

一、目录 1 框架 2. 入门 3. 安装教程 4. 相关文档、案例阅读 二、实现 1 框架&#xff1a;Ray&#xff1a;将一个模型拆分到多个显卡中&#xff0c;实现分布式预测、训练等功能。 2. 入门 &#xff1a; 案例&#xff1a;通过ray 实现分布式部署&#xff0c;分布式推理服务。…