Django中间件与python日志模块 介绍

一、Django中间件

1.1 介绍

Django中的中间件是一个轻量级、底层的插件系统,介于request与response处理之间的一道处理过程(用来处理特定业务的请求和响应)。中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。

我们可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预。

请求—中间件—响应:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SiFAbf47-1597452018811)(E:\07-notes\picture\01-请求_中间件_响应.png)]

1.1.1 中间件配置

定义好中间件后,需要在settings.py 文件中添加注册中间件

MIDDLEWARE = ['django.middleware.security.SecurityMiddleware',  # 安全中间件'django.contrib.sessions.middleware.SessionMiddleware', # 会话中间件'corsheaders.middleware.CorsMiddleware',  # 跨域请求中间件'django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware', # 防伪造跨域请求中间件'django.contrib.auth.middleware.AuthenticationMiddleware', # 授权中间件'django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]

【拓展】HTTP请求方法:

  1. GET: 查询

  2. POST: 添加或修改数据

  3. PUT : 修改数据

  4. DELETE: 删除数据

  5. OPTIONS: 探测服务器是否支持跨域

    Access-Control-Allow[-Origin|Headers|Methods|Credentials]

    访问-控制-允许-[源|头|方法|认证]

1.1.2 中间件的钩子函数(生命周期):

process_request:  请求到达时,未到路由
process_view:     转到view处理函数之前
process_exception:  在view处理函数中抛出异常时
process_response:   在View响应之后,向客户返回(输出)之前
process_template_response:  响应之前,渲染模板之后

1.1.3 自定义中间件类

from django.utils.deprecation import MiddlewareMixinclass AuthUserMiddleware(MiddlewareMixin):def process_request(self, request):passdef process_view(self, request, view, *args, **kwargs):passdef process_exception(self, request, exception):passdef process_response(self, request, response):return response

1.1.4 通过中间件实现的功能

- 请求黑名单: 1秒内允许2次请求(正常),非正常,则在process_request()方法直接返回
- 提取授权用户的信息和权限验证:  提前配置请求路径和用户权限 
- 异常的友好提示
- 缓存数据(减少数据库的交互次数): process_response() 对response对象进行序列化和缓存。
- 记录日志(logging 模块)

1.2 线程方式实现缓存

import time
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
import threadingcached = {}# 过期缓存监控的线程
class ExpireThread(threading.Thread):def clear(self, path, max_age):time.sleep(max_age)print('--checked--', path, cached.keys())if path in cached:cached.pop(path)def run(self):while True:time.sleep(1)print('--check--', cached.keys())for path, resp_max_age in cached.items():threading.Thread(target=self.clear,args=(path, resp_max_age[-1])).start()class MyMiddleware(MiddlewareMixin):def process_request(self, request):print('--process_request---', request.path)# 判断当前请求路径是否在缓存中# 如果存在则,直接返回响应if request.path in cached:return cached[request.path][0]def process_view(self, request, view, *args, **kwargs):# args 表示 view函数的位置参数# kwargs 表示 view函数的关键参数print('---process_view---', args)def process_exception(self, request, exception):print(request.path, dir(exception))print('----process_exception----', exception)return HttpResponse('<h3>Error Page 500: %s</h3>' % str(exception))def process_response(self, request, response):print('---process_response---')if request.path not in cached:# 存入缓存(内存)print('---存入缓存---')cached[request.path] = (response, 3)print('---缓存---', cached)return responseExpireThread().start()

注册中间件, 在settings.py文件中,修改MIDDLEWARE,如下所示:

MIDDLEWARE = [...'apiapp.middleware.MyMiddleware','django.middleware.common.CommonMiddleware',...
]

1.3 基于Redis实现缓存页面

from utils.caches import save_response, get_response, has_response
import pickle
import base64class RedisCacheMiddleware(MiddlewareMixin):def process_request(self, request):print('--process_request---', request.path)# 判断当前请求路径是否在缓存中# 如果存在则,直接返回响应if has_response(request.path):resp_base_str = get_response(request.path)resp_bytes = base64.b32decode(resp_base_str.encode())response = pickle.loads(resp_bytes)return responsedef process_response(self, request, response):print('---process_response---')# 存入缓存(内存)if not has_response(request.path):resp_bytes = pickle.dumps(response) # 将python的任意对象序列化字段码# b'QABWGZDKMFXGO3ZONB2HI4BOOJSXG4DPNZZWKCSIOR2HAUTFONYG63TTMUFHCABJQFYQC7LRAIUFQCAAAAAF'resp_base64_str = base64.b32encode(resp_bytes).decode()save_response(request.path, resp_base64_str, 3)return response

二、日志模块

Python的日志模块是: logging

import logging

2.1 日志的四大部分

日志是用于记录(Logger)程序中的一些重要信息的,记录的信息按等级(Level)交给特定的处理器Handler按一定的格式(Formatter)进行处理(打印、文件保存、上传网络和发送邮件等)。

2.1.1 日志记录器 Logger

  • 记录日志信息的唯一对象, 根据不同的信息等级使用不同的记录方法
    • x.debug() 记录调试信息,logging.DEBUG (10)
    • x.info() 记录普通信息, logging.INFO (20)
    • x.warning() 记录警告信息, loggin.WARNING (30)
    • x.error() 记录错误信息, logging.ERROR (40)
    • x.critical() 记录严重错误的信息, loggin.CRITICAL (50)
  • 创建或获取记录器: logging.getLogger(name) 如果name为空,则默认为root
  • 记录器可以添加处理器和过滤器: x.addHandler(Handler())、 x.addFilter(Filter() )

2.1.2 日志处理器 Handler

作用: 将记录器记录的相关日志信息,进行特定业务的处理,如写入文件的FileHandler、发送邮件的 SMTPHandler、上传远程服务器的HTTPHandler等。

【注意】处理器可以设置日志格式化 Formatter: h.setFormatter(Formatter())

  • StreamHandler 流处理器, 控制台打印的
  • FileHandler 文件处理器,将日志消息写入到文件中
  • HTTPHandler 网络处理器,将日志消息上传到服务器
  • SMTPHandler 邮件处理器,将日志消息发送到指定邮件中。

日志记录器和处理器的关系

一个记录器可以添加多个处理器。

logger.addHandler(handler1)
logger.addHandler(handler2)
logger = logging.getLogger("network")
logger.setLevel(logging.INFO) handler1 = StreamHandler()
handler1.setLevel(logging.INFO)handler2 = FileHandler("network.log")
handler1.setLevel(logging.WARNING)logger.addHandler(handler1)
logger.addHandler(handler2)

2.1.3 日志格式化 Formatter

作用: 将记录日志信息进行格式化(可以选择重要的信息、或者自定义格式的信息)

经典的日志格式:

[ %(asctime)s - %(levelname)s < line %(lineno)s at %(pathname)s  > ] %(message)s

如果给定的日志格式中变量不能完成业务需求时,可以自定义:

[ %(asctime)s - %(username)s: %(ip)s < %(action)s > ] %(message)s

以上username、ip和action都属于自定义的格式变量,在记录器记录信息时指定extra 参数, 它是一个字典类型,key即为扩展的变量名,value即是它的值。

日志的格式:

     |  %(name)s            Name of the logger (logging channel) 记录器的名称|  %(levelno)s         Numeric logging level for the message (DEBUG, INFO,|                      WARNING, ERROR, CRITICAL) 数字形式的日志记录级别|  %(levelname)s       Text logging level for the message ("DEBUG", "INFO",|                      "WARNING", "ERROR", "CRITICAL") 日志记录级别的文本名称|  %(pathname)s        Full pathname of the source file where the logging|                      call was issued (if available) 执行日志记录调用的源文件的路径名称|  %(filename)s        Filename portion of pathname 执行日志记录调用的源文件的文件名称|  %(module)s          Module (name portion of filename) 执行日志记录调用的模块名称|  %(lineno)d          Source line number where the logging call was issued|                      (if available) 执行日志记录调用的行号|  %(funcName)s        Function name 执行日志记录调用的函数名称|  %(created)f         Time when the LogRecord was created (time.time()|                      return value) 执行日志记录的时间|  %(asctime)s         Textual time when the LogRecord was created 日期和时间|  %(msecs)d           Millisecond portion of the creation time 毫秒部分|  %(relativeCreated)d Time in milliseconds when the LogRecord was created,|                      relative to the time the logging module was loaded|                      (typically at application startup time)|  %(thread)d          Thread ID (if available) 线程ID|  %(threadName)s      Thread name (if available) 线程名称|  %(process)d         Process ID (if available) 进程ID|  %(message)s         The result of record.getMessage(), computed just as|                      the record is emitted 记录的消息

2.1.4 日志过滤器 Filter

作用: 过滤一些敏感的记录日志信息。

2.2 日志的应用

2.2.1 标准使用

#!/usr/bin/python3
import logging
from logging import StreamHandler, FileHandler, Formatter, Filterclass MsgFilter(Filter):def filter(self, record): # record记录对象# print(dir(record)) # 查看记录器里面的方法return record.msg.find('混沌') == -1logger = logging.getLogger('middleware')
# 设置记录器的信息等级:DEBUG -> INFO -> WARNING -> ERROR -> CRITICAL
logger.setLevel(logging.INFO) # 记录器可以记录INFO及以上等级信息# 添加日志过滤器
logger.addFilter(MsgFilter())# 创建日志处理器
handler1 = StreamHandler() # 流处理器,标准输出
handler1.setLevel(logging.INFO)
handler1.setFormatter(Formatter(fmt='[ %(asctime)s - %(levelname)s] %(message)s',datefmt='%Y-%m-%d %H:%M:%S'
))# 向记录器添加处理器
logger.addHandler(handler1)handler2 = FileHandler('error.log', encoding='utf-8')
handler2.setLevel(logging.ERROR)
handler2.setFormatter(Formatter(fmt="[ %(asctime)s - %(levelname)s < line %(lineno)s at %(pathname)s  > ] %(message)s",datefmt='%Y-%m-%d %H:%M:%S'
))
logger.addHandler(handler2)if __name__ == '__main__':# x = logging.getLogger('middleware')  # 获取middleware的记录器logging.getLogger('middleware').debug('中午吃拉面')logging.getLogger('middleware').info('中午吃木桶饭')logging.getLogger('middleware').warning('中午吃凉皮')logging.getLogger('middleware').error('中午吃粥和夹馍')logging.getLogger('middleware').critical('下午吃混沌')

2.2.2 扩展格式化的使用

mylogger = logging.getLogger('sys_action')
mylogger.setLevel(logging.INFO)myhandler = StreamHandler()
myhandler.setLevel(logging.INFO)
myhandler.setFormatter(Formatter(fmt="[ %(asctime)s - %(username)s: %(ip)s < %(action)s > ] %(message)s",datefmt='%Y-%m-%d %H:%M:%S'
))mylogger.addHandler(myhandler)if __name__ == '__main__':extra_info = {'username': 'admin','ip': '10.36.172.110','action': 'del category'}logging.getLogger('sys_action').debug('中午吃拉面', extra=extra_info)logging.getLogger('sys_action').info('中午吃木桶饭', extra=extra_info)logging.getLogger('sys_action').warning('中午吃凉皮',extra=extra_info)logging.getLogger('sys_action').error('中午吃粥和夹馍', extra=extra_info)logging.getLogger('sys_action').critical('下午吃混沌', extra=extra_info)

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

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

相关文章

无人系统自主性研究综述

来源&#xff1a;人机与认知实验室一、引言2012年7月&#xff0c;美国国防科学委员会发布了《自主性在国防部无人系统中的地位》&#xff0c;进一步指出自主能力是美军无人系统中的核心能力&#xff0c;分析了自主能力给无人机(UAV)、无人地面系统(UGS)、无人海上平台(UMV)和无…

一文看尽微软开发者大会 让AI和云驱动一切

来源 | 网易智能一年一度的微软开发者大会Build 2019在美国华盛顿州雷德蒙德拉开帷幕&#xff0c;微软公司CEO萨提亚纳德拉&#xff08;Satya Nadella&#xff09;介绍和发布了一系列全新技术&#xff0c;并在现场展示了以客户为中心的智能体验全新解决方案。微软此次发布的新功…

爬虫文档学习 xpath bs4 selenium scrapy...

爬虫 一、介绍 1、什么是爬虫 1.1 爬虫(Spider)的概念 爬虫用于爬取数据&#xff0c; 又称之为数据采集程序。 爬取的数据来源于网络&#xff0c;网络中的数据可以是由Web服务器&#xff08;Nginx/Apache&#xff09;、数据库服务器(MySQL、Redis)、索引库&#xff08;Ela…

用人工神经网络控制真实大脑,MIT的科学家做到了

来源&#xff1a;网络大数据三位研究者分别是 MIT 大脑与行为科学系主任 James DiCarlo、MIT 博士后 Pouya Bashivan 和 Kohitij Kar。相关论文发表在 5 月 2 日 Science 的网络版上。论文链接&#xff1a; http s://www.biorxiv.org/content/10.1101/461525v1研究人员表示&…

学习卫星菜单

学会坚持的自己写的底部中间菜单 转自http://www.cnblogs.com/persist-confident/p/4487386.html 看了hyman老师的视频&#xff0c;听起来有点迷糊&#xff0c;所以就想把实现卫星菜单的实现总结一下。长话短说&#xff0c;下面总结一下&#xff1a; 一、自定义ViewGroup1&…

Python 的垃圾回收回收机制(源码)

python内存管理及垃圾回收 1. 引用计数器 1.1 环状双向连表 refchain 在python程序中创建的任何对象都会放在refchain链表中&#xff0c;并且可以通过这个对象访问到上一个和下一个对象。 name 张三 age 18 hobby [美女,吃饭]内部会建立一些数据 -打包 C语言叫做结构体-…

未来五年人工智能将实现的五大突破

来源&#xff1a;资本实验室不论是可以和你对话的智能音箱&#xff0c;还是能够自己作画的虚拟艺术家&#xff1b;不论是能够帮助农民准确判断种植和施肥时间的农场管理系统&#xff0c;又或者是能够在演唱会现场快速识别罪犯的人脸识别程序&#xff0c;人工智能已经开始在各行…

python面试常问

一、Python基础部分 1. 数据类型 数字类型(Numbers)&#xff1a; 整数(int), 浮点数(float), 复数(complex) 布尔(Booleans)&#xff1a; True和False 字符串(Str)&#xff1a;Uniconde字符序列, 在引号内包含 列表(list)&#xff1a; 有序的值的序列 元组(Tuples)&#x…

springJDBC一对多关系,以及Java递归,jsp递归的实现

maven编译&#xff0c;springMVCspringspringJDBC框架。 要实现的功能是一个文件夹下&#xff0c;可能显示n个文件夹&#xff0c;每个文件夹下又可能显示n个文件夹。。。。 前台效果&#xff1a; controller中的方法如下&#xff1a; RequestMapping(value"/index",m…

未来全球15大热门研究方向出炉!

转自&#xff1a;科学网&#xff08;sciencenet-cas&#xff09;要点速览伦敦、纽约、新加坡、香港、巴黎、北京、东京、迪拜、上海、柏林、波士顿&#xff0c;这些国际性大都市在科技创新方面的表现如何&#xff1f;它们主要关注哪些研究方向&#xff1f;15大科技创新策源点&a…

Django-rest framework

Django-rest Framework 1. FBV CBV 1.1 开发模式 普通开发方式&#xff08;前后端放在一起写&#xff09;前后端分离 1.2 后端开发 为前端提供URL&#xff08;API/接口的开发&#xff09; 注&#xff1a;永远返回HttpResponse 1.3 Django FBV、CBV # FBV(function base …

常用的网络营销方法有哪些

索引擎营销 电子邮件营销 即时通讯营销 病毒式营销 BBS营销 博客营销 播客营销 RSS营销 SN营销 创意广告营销 知识型营销 事件营销 口碑营销 转载于:https://www.cnblogs.com/happyday56/p/4739488.html

AI产业链分布图曝光:1040个玩家,BAT率先步入应用

来源&#xff1a;网络大数据5月9日&#xff0c;在苏州举办的全球人工智能产品应用博览会上&#xff0c;《新一代人工智能发展年度报告(2018)》重磅发布。发布方是中国经济信息社与新一代人工智能产业技术创新战略联盟。报告相当于对2018年以来全球AI领域融资、国内AI企业分布、…

什么是混合云?

来源&#xff1a;光联集团混合云是使那些正常的进化措施看起来更酷&#xff0c;是IT前沿术语之一。亚马逊&#xff0c;谷歌和微软等云供应商倡导企业关闭内部数据中心并将所有基础架构迁移到云端&#xff0c;这就是“超融合”数据中心战略。1转移基础设施对于刚刚起步的公司而言…

Shell—grep、sed、awk

Shell学习 Shell 是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。 Shell 是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问操作系统内核的服务。 She…

【科普】AI的分类与演进

来源&#xff1a;物联网智库摘要&#xff1a;AI是人工通过高强度的计算能力&#xff0c;并基于大量的环境数据、行为数据、历史数据等大数据支持&#xff0c;或是一定规则的自学习机制&#xff0c;来分析特定输入的情况下&#xff0c;事物的相关性、影响和可能处理方法&#xf…

AngularJs入门学习

http://www.ituring.com.cn/article/13471 安装并配置好所有依赖环境之后&#xff0c;只需要在cmd进入angular-phonecat目录。接着指令操作npm start&#xff1b;开启服务器。如下图&#xff1a; 打开angular-phonecat的gitbash&#xff1b; 接下来就是用编译器打开angular-pho…

nginx+uWSGI + django部署项目

项目部署 nginxuWSGI django 1. WSGI WSGI是Web服务器网关接口。它是一个规范&#xff0c;描述了Web服务器(返回静态资源的就是web服务器&#xff0c;Nginx)如何与Web应用程序(django、Flask)通信&#xff0c;以及Web应用程序如何链接在一起以处理一个请求&#xff0c;&…

71页《乌镇智库:全球人工智能发展报告(2018)》PDF下载

来源&#xff1a;专知【导读】人工智能热潮之下&#xff0c;斯坦福、阿里等纷纷出台人工智能报告。乌镇智库已连续发布三年《全球人工智能发展报告》&#xff0c;以宏观视角纵览全球人工智能发展&#xff0c;从产业、融资、技术、教育和应用等多个角度展现人工智能在全球的发展…

Windows实用技巧

Windows常用命令&#xff0c;亲测可用 创建文件夹Test&#xff0c;命令为&#xff1a;mkdir Test 盘符&#xff1a; 进入系统中的某个盘&#xff0c;例如E&#xff1a;进入E盘cd 文件夹位置 进入某个文件夹&#xff0c;需要先进入盘符&#xff0c;即完成第一步&#xff0c;例如…