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

目录

一、使用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.mfbz.cn/a/480260.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

V2X技术与智能传感器的完美融合:提升城市道路安全

在科技不断创新的今天,城市交通领域涌现了大量新技术。有时候我们不仅仅需要独立应用这些新技术来实现交通的变革,更需要将它们巧妙地结合连接起来,以获取更高效更安全的交通环境。本文将探讨V2X技术与智能传感器的结合,如何在城市…

uni-app打包证书android

Android平台打包发布apk应用,需要使用数字证书(.keystore文件)进行签名,用于表明开发者身份。 Android证书的生成是自助和免费的,不需要审批或付费。 可以使用JRE环境中的keytool命令生成。 以下是windows平台生成证…

1升级powershell后才能安装WSL2--最后安装linux--Ubuntu 22.04.3 LTS

视频 https://www.bilibili.com/video/BV1uH4y1W7UX特殊开启–Hyper-V虚拟机 把一下代码保存到【a.bat】的执行文件中,进行Hyper-V虚拟机的安装开启【Windows 批处理文件 (.bat)】 pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mu…

elasticsearch的数据搜索

DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括: 查询所有:查询出所有数据,一般测试用。例如:match_all 全文检索(full text)查询:利用分词器对用户…

鸿蒙Harmony应用开发—ArkTS(@Styles装饰器:定义组件重用样式)

如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,但为了代码简洁性和后续方便维护,我们推出了可以提炼公共样式进行复用的装饰器Styles。 Styles装饰器可以将多条样式设置提炼…

学点儿Java_Day9_String、包装类

1 String 详解“”和equals的区别 Testpublic void test1() {//"abc"双引号括起来的字符串:字符串常量,它也是一个对象// 1.8之后常量池放到堆,在常量池里面找有没有这个"abc"对象,// 如果常量池里面没有这…

是德科技keysight N1912A双通道功率计

181/2461/8938产品概述: Keysight(原Agilent) N1912A P系列双通道功率计可提供峰值、峰均比、平均功率、上升时间、下降时间、最大功率值、最小功率值以及宽带信号的统计数据。 Keysight(原Agilent) N1912A P系列双通道功率计, 可提供峰值、峰均比、平均功率、上升…

nodejs各版本下载

https://registry.npmmirror.com/binary.html 然后进入nodejs各个版本,然后按需选择

JAVA 栈和队列总结

除了最底层下面三个是实现类,其他都是接口。 双端队列(队头队尾都可以插入和删除元素)的方法: 普通队列方法: 常用的是add(),poll(), element() 我们用Deque(双端队列)实现栈 Deque当栈用的时候的方法。 deque.push…

百度小程序入口在哪里找到怎么打开百度词令关键词口令直达小程序?

百度小程序入口在哪里找到怎么打开百度词令关键词口令直达小程序? 一、百度搜索找到百度词令小程序 打开手机百度搜索「词令」即可找到百度词令关键词口令直达小程序; 二、百度小程序中心找到百度小程序 2.1、打开手机百度,点击底部我的&a…

解决用POI库生成的word文件中的表格在python-docx无法解析的问题

问题背景 用apache-poi生成word文件中表格&#xff0c;在使用python-docx库解析时报错&#xff1a; 问题分析 1. word文档本质上是一个rar压缩包&#xff0c;用winrar解析后如下&#xff1a; 2. 查看document.xml&#xff0c;可以看到table元素下面是没有<w:tblGrid>这…

Carla 自动驾驶挑战赛 搭建环境

1. 系统设置 1.1 下载CARLA排行榜包 下载打包的CARLA 排行榜版本。 将包解压到一个文件夹中&#xff0c;例如 CARLA。 在以下命令中&#xff0c;更改${CARLA_ROOT}变量以对应于您的 CARLA 根文件夹。 为了使用 CARLA Python API&#xff0c;您需要在您喜欢的环境中安装一些…

ARM-Linux 开发板下安装编译 OpenCV 和 Dlib

安装 OpenCV 和 Dlib 不像在 x86 平台下那样简单&#xff0c;用一句命令就可以自动安装完。而在 ARM 平台中许多软件都需要自行下载编译&#xff0c;且还有许多问题&#xff0c;本篇文章就是记录在 ARM 平台下载 OpenCV 踩过的坑。 硬件环境&#xff1a; RK3568 Ubuntu20.04…

一文读懂I2C协议

一.硬件连接 I2C必须使用开漏&#xff08;或集电极开路&#xff09;的引脚&#xff0c;其引脚框图如下所示。 SCL0对应78K0的P6.0引脚&#xff0c;SDA0对应78K0的P6.1引脚。 在使用开漏引脚通信时&#xff0c;需注意如下事项&#xff1a; 1&#xff09;两条总线须外接…

jvm提供的远程调试 简单使用

JVM自带远程调试功能 JVM远程调试&#xff0c;其实是两个虚拟机之间&#xff0c;通过socket通信&#xff0c;达到远程调试的目的&#xff1b; 前提 确保本地和远程的网络是开通的&#xff1b; 本地操作 远程操作 在启动命令参数中 把上面的内容复制进去

基于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:…

list.sort()Collections.sort()深入理解

list.sort()&&Collections.sort() 文章目录 list.sort()&&Collections.sort()背景相关代码代码一代码二 原理举一反三 业务场景考虑 背景 业务中经常用到List的sort()方法&#xff0c;但是对于其中return的-1&#xff0c;0&#xff0c;1理解不到位&#xff0c…

(附源码)基于Spring Boot与Vue的宠物用品销售系统设计与实现

前言 &#x1f497;博主介绍&#xff1a;✌专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅&#x1f447;&#x1f3fb; 2024年Java精品实战案例《100套》 &#x1f345;文末获取源码联系&#x1f345; &#x1f31…

用BSP优化3D渲染

3D渲染引擎设计者面临的最大问题之一是可见性计算&#xff1a;只必须绘制可见的墙壁和物体&#xff0c;并且必须以正确的顺序绘制它们&#xff08;应该在远处的墙壁前面绘制近墙&#xff09; 。 更重要的是&#xff0c;对于游戏等应用程序来说&#xff0c;开发能够快速渲染场景…

vue的优缺点有那些 组件常用的有那些?

优点&#xff1a; 组件化开发&#xff0c;提升效率&#xff0c;方便复用&#xff0c;便于协同开发单页面路由易于结合其他的第三方库丰富的api方法轻量高效,虚拟DOMMVVM&#xff0c;数据驱动视图轻量级的框架 缺点&#xff1a; 缺少高阶教程和文档生态环境不如angular和re…