django☞日志

阅读量: zyh 2020-03-08 14:12:12
Categories: > Tags:

前言

https://docs.djangoproject.com/zh-hans/3.1/topics/logging/

https://docs.python.org/3/library/logging.config.html#configuration-dictionary-schema

https://docs.python.org/3/library/logging.html

django 采用 python 的 logger 模块,配置方式选择字典方式

字典方式基本介绍

有一些必选的键值对 https://docs.python.org/3/library/logging.config.html#dictionary-schema-details

例如versionformatters等,具体看上面官方文档和下面的例子

关键对象介绍

loggers 根据消息界别接收日志,但不负责输出

LogRecord logger接收一条日志,就创建一个logrecord对象

handlers 绑定在logger,用于处理日志logrecord对象,例如输出到哪里. 可以将多个handler绑定到同一个logger

formatters 绑定在handler,用来格式化日志logrecord对象

filters 通过设定过滤条件,过滤从loggerhandler的日志logrecord对象。非必须

额外的

LoggerAdapter(logger, extra) 用来包装logger,它接收一个logger和一个字典extra,从而将extra添加到logrecord

之后,通过LoggerAdapter对象接收的日志,再经过formatterextra.key的编排,就实现了添加信息到原始日志的功能.

日志级别

流程

给接收的日志定级别:logger.<level>("log message")

logger判断接收的日志级别是否符合logger定义的级别

如果符合,logger无差别的推送消息到多个handler,如果不符合,则忽略;另外,如果logger.propagate为真,则消息会复制一份到更高级别的logger

handler判断接收的日志级别是否符合handler定义的级别

如果符合,handler通过formatter排列logrecord对象属性,并通过handler.class将日志输出,如果不符合,则忽略;另外,如果handlerfilter,则只会输出满足filter的日志

例子

写入 settings.py

# Logging
LOGGING = {
    'version': 1,  # 指明版本,目前就只有一个版本
    'disable_existing_loggers': False,  # 表示是否禁用所有的已经存在的日志配置
    # 声明两个格式化id
    'formatters': {  # 格式器
        'verbose': {  # 详细
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'standard': {  # 标准
            'format': '[%(asctime)s] [%(levelname)s] %(message)s'
        },
    },
    # 定义过滤器 special,它有一个条件函数 project.logging.SpecialFilter(foo), 函数被实例化的时候,foo='bar'
    # project.logging.SpecialFilter 需要自己实现, 判断 logrecord 对象,或者满足一些条件才输出日志
    'filters': {
        'special': {
            '()': 'project.logging.SpecialFilter',
            'foo': 'bar',
        },
    },
    # handlers:用来定义具体处理日志的方式,可以定义多种,"console"就是打印到控制台方式。file是写入到文件的方式,"mail_admins"是邮件通知
    # 这里的 console/file/mail_admins 仅仅是自定义的名称
    'handlers': { # 处理器
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'stream': 'ext://sys.stdout',   # 文件重定向的配置,将打印到控制台的信息都重定向出去
            'formatter': 'standard'   # 制定输出的格式,注意 在上面的formatters配置里面选择一个,否则会报错
        },
        'file_all': {
            'level': 'DEBUG',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.dirname(os.path.dirname(os.path.realpath(__file__)))+'/log/all.log',  
            'formatter': 'standard'
            'maxBytes': 1024
            'when': 'midnight'
            'interval': 1
            'backupCount': 3     
            'utc': False
            'encoding': 'utf-8'
            
        },
        'file_request': {
            'level': 'DEBUG',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.dirname(os.path.dirname(os.path.realpath(__file__)))+'/log/request.log',  
            'formatter': 'standard'
            'maxBytes': 1024
            'when': 'midnight'
            'interval': 1
            'backupCount': 3     
            'utc': False
            'encoding': 'utf-8'
            
        },
        'file_db': {
            'level': 'DEBUG',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.dirname(os.path.dirname(os.path.realpath(__file__)))+'/log/db.log',  
            'formatter': 'standard'
            'maxBytes': 1024
            'when': 'midnight'
            'interval': 1
            'backupCount': 3     
            'utc': False
            'encoding': 'utf-8'
            
        },
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'filters': ['special']
        },
    },
    'loggers': {  # log记录器,配置之后就会对应的输出日志
        'django': {
            'handlers': ['file_all'],
            'level': 'INFO',
            'propagate': False,
        },
        'django.request ':{
            'handlers': ['file_request','mail_admins'],
            'level': 'INFO',
            'propagate': False,
        },
         'django.server ':{
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': False,
        },       
        'django.db.backends': {
            'handlers': ['file_db'],
            'level':'INFO',
            'propagate': False,
        },
        # 根记录器
        'root': {
        'handlers': ['console'],
        'level': 'WARNING',
        },
    },
}

logger

https://docs.python.org/3/library/logging.html#logger-objects

从上面的例子可以看到,logger有一个属性是propagate,这个属性的作用是将收到的消息复制一份到更高级别的logger

关于logger的层级意思是:通过.分割的logger_name

上述列子中,层级高低排序是:

root>django>django.request=django.server

root>django>``django.db.backends`

handler

https://docs.python.org/3/library/logging.handlers.html#module-logging.handlers

在上述例子中,handlerclass都是python的内置类型

formatter

格式化logrecord对象,排版logrecord的属性

logrecord

https://docs.python.org/zh-cn/3.9/library/logging.html#logrecord-attributes

LoggerAdapter

https://docs.python.org/zh-cn/3.9/library/logging.html#loggeradapter-objects

调用

import logging, logging.config

logging.config.dictConfig(LOGGING) # django 无需此步骤,django 会自动加载
logger = logging.getLogger(__name__)  # 这里的logger名称要匹配上 dictConfig 定义的 logger, 匹配遵循名称层级规则
logger.info("message")