对logging 模块的调整应用,与调整django 的默认打印

本文介绍了如何在Python的logging模块中添加额外信息,包括自定义Filter和Formatter,以在正常打印和Django后台日志中增加特定内容。通过threading.local存储线程数据,并在Django中间件中调整logging设置,确保每个请求都有唯一的request_id。
摘要由CSDN通过智能技术生成

对logging 模块的调整应用

目标需求:

​ 1、在正常的logging 中打印中默认增加其他信息

​ 2、在django后台打印中,增加对应的信息内容

实现:

​ 1、调整logging 模块的 Formatter 或 Filter 的模块,让在正常打印的内容中增加一些其他前置函数中的 信息

import threading
import logging

# 这边使用的是 threading.local() 存放线程中的数据
local = threading.local()


# 配置 filter 或 formatter
# 在filter 的 record 中增加字段
class changeLoggingFilter(logging.Filter):
    def filter(self, record):
        record.new_info = getattr(local, 'new_info', 'none')
        record.new_info2 = getattr(local, 'new_info2', 'none')
        record.new_info3 = getattr(local, 'new_info3', 'none')
        return True


# 在formatter 中 判断是否有这 几个新参数
class changeLoggingFormatter(logging.Formatter):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def format(self, record):
        if not hasattr(record, 'new_info'):
            record.new_info = getattr(local, 'new_info', 'none')
        if not hasattr(record, 'new_info2'):
            record.new_info2 = getattr(local, 'new_info2', 'none')
        if not hasattr(record, 'new_info3'):
            record.new_info3 = getattr(local, 'new_info3', 'none')
        return super().format(record)


# 使用 先把调整的 filter 或 fotmatter 放入logging 模块中
# 1、使用formatter 的方式调整打印数据信息
def change_formatter():
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    formatter = changeLoggingFormatter(fmt='%(asctime)s [%(levelname)s] [new_info=%(new_info)s] [new_info2=%(new_info2)s] [new_info3=%(new_info3)s]  %(message)s', datefmt=None)
    if logger.handlers:
        logger.handlers[0].setFormatter(formatter)
    else:
        sh = logging.StreamHandler()
        sh.setFormatter(formatter)
        logger.addHandler(sh)


# 2、调整 filter 的方式调整打印输出的信息
def change_filter():
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    f = changeLoggingFilter()
    logger.addFilter(f)
    formatter = logging.Formatter('%(asctime)s [%(levelname)s] [new_info=%(new_info)s] [new_info2=%(new_info2)s] [new_info3=%(new_info3)s]  %(message)s')
    if logger.handlers:
        logger.handlers[0].setFormatter(formatter)
    else:
        sh = logging.StreamHandler()
        sh.setFormatter(formatter)
        logger.addHandler(sh)


def check_logging_start():
    new_info = '1111111111'
    new_info2 = '2222222222'
    new_info3 = '3333333333'
    local.new_info = new_info
    local.new_info2 = new_info2
    local.new_info3 = new_info3
    logging.debug('this debug message~~')
    logging.info('this info message~~')
    logging.warning('this warn message~~')
    logging.error('this error message~~')


if __name__ == '__main__':
    change_formatter()
    # change_filter()
    check_logging_start()

2、在django中增加logging 和控制台输出的请求打印日志

说明:django 中可以使用 中间件 来提前对logging 模块做处理,测试使用的threading.local(),在 settings 中使用LOGGING 中导入filter 的方式,显示使用的不是同一个线程存储空间,就在中间件中直接调整

# 中间件的调用
# 一、Django默认的中间件:在django项目的settings模块中,有一个 MIDDLEWARE 变量,其中每一个元素就是一个中间件
# 1.在项目名或者应用名下创建一个任意名称的文件夹,如:mymiddlewear,
# 2.在该文件夹内创建一个任意名称的py文件,如:mymiddle
# 3.在该py文件内需要书写类(这个类必须继承MiddlewareMixin),在这个类里面就可以自定义五个方法了,这五个方法并不是全部都需要书写,用几个写几个
process_request(self,request)              # 请求相关
process_response(self, request, response)  # 响应相关
process_view(self, request, callback, callback_args, callback_kwargs)   # 路由层到视图层中间
process_template_response(self,request,response) # 视图层到模板层中间
process_exception(self, request, exception)      # 视图函数出现异常
# 4.需要将类的路径以字符串的形式注册到配置文件中才能生效;在应用下创建的,注册路径时有提示,项目下创建的则没有提示
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    
    'mymiddlewear.mymiddle.M1',  # 你自己写的中间件的路径
]

# 二、在创建的中间件mymiddle py文件中调整logging 模块,在中间件 M1 类中
import datetime
import logging
import time
import traceback
import threading
from django.utils.deprecation import MiddlewareMixin
import uuid

local = threading.local()
# logging.raiseExceptions = False  # 这个打开后,所有的 loggin 模块自带的 异常都不会打印


class change_formatter(logging.Formatter):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def format(self, record):
        if not hasattr(record, 'request_id'):
            record.request_id = getattr(local, 'request_id', 'none')
        return super().format(record)


# # 从local 中获取threading 中的信息
# class change_filter(logging.Filter):
#     def filter(self, record):
#         record.request_id = getattr(local, 'request_id', 'none')
#         return True


# 这边使用的 是 调整formatter 的类来替换 django 中使用的所有formatter 格式
class M1(MiddlewareMixin):
    def __init__(self, get_response=None):
        super().__init__(get_response)

        # 对两个打印信息做调整
        # 使用 调整formatter 的方式来替换所有的打印
        logger_server = logging.getLogger('django.server')  # django 的默认响应log 信息
        logger = logging.getLogger()  # django中其他 使用的 logging 模块初始化
		# 替换 django 默认打印的 formatter
        django_formatter = change_formatter(fmt='%(server_time)s [request-id=%(request_id)s] %(message)s', datefmt=None)
        logger_server.handlers[0].setFormatter(django_formatter)
		# 替换 django 中 使用的 所有 logging 模块的 打印的formatter 的前置信息
        formatter = change_formatter(fmt='%(asctime)s [%(levelname)s] [request-id=%(request_id)s] %(message)s', datefmt=None)
        logger.handlers[0].setFormatter(formatter)
        
        # 使用filter 的方式调换(这个方式有弊端,当框架中有其他新初始化的logging 模块时,也需要导入这个类进去,才不会报 keyerror 的异常)
        # logger_server = logging.getLogger('django.server')  # django 的默认响应log 信息
        # logger = logging.getLogger()  # django中其他 使用的 logging 模块初始化
        # f = UserRunningProgramFilter()  # 初始化 filter 里面增加 request_id 信息
        # logger_server.addFilter(f)
        # logger.addFilter(f)
        # formatter = logging.Formatter('%(asctime)s [%(levelname)s] [request-id=%(request_id)s] %(message)s')
        # django_formatter = logging.Formatter('%(server_time)s [request-id=%(request_id)s] %(message)s')
        
        # logger_server.handlers[0].setFormatter(django_formatter)
        # logger.handlers[0].setFormatter(formatter)
        # or 
        # sh = logging.StreamHandler()
        # sh.setFormatter(formatter)
        # logger.addHandler(sh)

    def process_request(self, request):
        self.request_id = str(uuid.uuid4())
        local.request_id = self.request_id

    def process_response(self, request, response):
        response.headers['request-id'] = self.request_id

请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值