Django配置日志(logging)以及详细分析

965 阅读6分钟

Django配置日志(logging)

前提:

需要了解python的logging库的一些基础知识 logging库

官方文档(不推荐看)

公众号文章

使用

settings.py

import os
import datetime
​
​
# 日志配置# 给ADMINS发送邮件需要配置
ADMINS = (
    ('admin_name', 'your@gmail.com'),
)
MANAGERS = ADMINS
# 创建log文件的文件夹
LOG_DIR = os.path.join(BASE_DIR, "logs")
​
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}},
    "formatters": {  # 定义了两种日志格式
        "verbose": {  # 标准
            "format": "%(levelname)s %(asctime)s %(module)s "
                      "%(process)d %(thread)d %(message)s"
        },
        'simple': {  # 简单
            'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s',
            "datefmt": "%Y-%m-%d %H:%M:%S"
        },
    },
    "handlers": {  # 定义了四种日志处理方式
        "mail_admins": {  # 只有debug=False且Error级别以上发邮件给admin
            "level": "ERROR",
            "filters": ["require_debug_false"],
            "class": "django.utils.log.AdminEmailHandler",
        },
​
        'time_file': {
            'level': 'DEBUG',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join(LOG_DIR, '{}.log'.format(datetime.date.today())),
            'when': "D",
            'interval': 1,
            'formatter': 'simple',
            'encoding': 'utf-8',
        },
        'file': {  # Info级别以上保存到日志文件
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,根据文件大小自动切
            'filename': os.path.join(LOG_DIR, "info.log"),  # 日志文件
            'maxBytes': 1024 * 1024 * 10,  # 日志大小 10M
            'backupCount': 2,  # 备份数为 2
            'formatter': 'simple',  # 简单格式
            'encoding': 'utf-8',
        },
        "console": {  # 打印到终端console
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "verbose",
        },
    },
    "root": {"level": "INFO", "handlers": ["console"]},
    "loggers": {
        "mylogger": {
            "level": "DEBUG",
            "handlers": ["console","time_file"]
        },
        "django.request": {  # Django的request发生error会自动记录
            "handlers": ["mail_admins"],
            "level": "ERROR",
            "propagate": False,  # 向不向更高级别的logger传递
        },
        "django.security.DisallowedHost": {  # 对于不在 ALLOWED_HOSTS 中的请求不发送报错邮件
            "level": "ERROR",
            "handlers": ["console", "mail_admins"],
            "propagate": True,
        },
    },
}

视图函数

需要使用到的视图函数中选择需要使用的日志“记录器”,这里使用的是自定义的mylogger,这个记录器实现的处理器有输出到控制台的

import logging
​
# 日志输出常量定义
logger = logging.getLogger('mylogger')
​
def user_reg(request):
    if request.method == "GET":
        logger.info('有人进入注册页面')
        return HttpResponse("有人进入注册页面")

settings.py文件解析

保存文件夹及LOGGING前三行

  • 这一句是设定日志文件的保存文件夹,这个路径主要是在FileHandler类型的处理器下使用到
# 创建log文件的文件夹
LOG_DIR = os.path.join(BASE_DIR, "logs")
  • 这里面的都是对记录器、处理器、格式化器、过滤器的设置
LOGGING = {}
  • 前两行,一个是关于版本,一个是是否禁用默认配置(无需改动)
'version': 1,
# 若此处为True:则将禁用默认配置中的所有记录器,记录器仍将存在,但会静默丢弃记录到它的所有内容,甚至不会将条目传播到父记录器
'disable_existing_loggers': False,
  • 过滤器的设置(后面没有一个处理器有用到,无需改动,不是重点)

    • DEBUGTrue 时,传递记录。
"filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}},

格式化器

  • 格式化器的设置

    • format:设置日志的输出格式[1]
    • datefmt:设置时间输出格式
"formatters": {  # 定义了两种日志格式
    "verbose": {  # 标准
        "format": "%(levelname)s %(asctime)s %(module)s "
        "%(process)d %(thread)d %(message)s"
    },
    'simple': {  # 简单
        'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s',
        "datefmt": "%Y-%m-%d %H:%M:%S"
    },
},

处理器

  • 处理器的设置(以最经典的两种处理器介绍)

    • file(保存日志处理器)

    • console(标准输出处理器)

      • level(保存或输出的级别)
      • class (指定使用何种类型的处理器)[2]
      • formatter(使用上面定义的哪个格式化器来输出日志)
    "handlers": {
        'file': {  
            'level': 'INFO',  # Info级别以上保存到日志文件
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,根据文件大小自动切
            'filename': os.path.join(LOG_DIR, "info.log"),  # 日志文件
            'maxBytes': 1024 * 1024 * 10,  # 日志大小 10M
            'backupCount': 2,  # 备份数为 2
            'formatter': 'simple',  # 使用哪个格式化器
            'encoding': 'utf-8',  # 保存的格式
        },
        "console": {  # 打印到终端console
            "level": "DEBUG",  # DEBUG级别以上输出到终端
            "class": "logging.StreamHandler",  # 生成一个向stream(数据流)输出的处理器
            "formatter": "verbose",  # 使用哪个格式化器
        },
    },

记录器

  • 这个是logging标准库默认的记录器,设置时必须加上,一般不用,都是用根据自己的需求去使用自定义的记录器

    • logger = logging.getLogger('root')  # ()中不写任何内容默认是root
      
"root": {"level": "INFO", "handlers": ["console"]},
  • 自定义记录器

    • mylogger(自定义记录器的名称)

      logger = logging.getLogger('mylogger')  
      
      • level(记录器的级别,记录器的级别一般要小于等于使用的处理器的级别)
      • handlers(指定使用上面哪个处理器)
    • django.request(官方的记录器)

      • 它将所有 ERROR 消息传递给 mail_admins 处理器。此外,这个记录器被标记为不传播消息。这意味着写给 django.request 的日志信息不会被 django 日志处理器处理。
    • django.security.DisallowedHost(官方的记录器)

      • 它将所有 ERROR 或更高等级的消息传递给两个处理程序——consolemail_admins。这意味着所有 ERROR 级别(或更高)的消息将被打印到控制台;ERRORCRITICAL 消息也将通过电子邮件输出。
"loggers": {
    "mylogger": {
        "level": "DEBUG",
        "handlers": ["console","time_file"]
    },
    "django.request": {  # Django的request发生error会自动记录
        "handlers": ["mail_admins"],
        "level": "ERROR",
        "propagate": False,  # 向不向更高级别的logger传播消息,默认为True
    },
    "django.security.DisallowedHost": {  # 对于不在 ALLOWED_HOSTS 中的请求不发送报错邮件
        "level": "ERROR",
        "handlers": ["console", "mail_admins"],
        "propagate": True,
    },
},

自定义logging组件

自定义格式化器

formatters这个key中的value的字典里新添一个键值对

"new_format" :{
    'format': '',
    "datefmt": ""
}

datefmt默认是%Y-%m-%d %H:%M:%S样式的

属性特定格式化描述
asctime%(asctime)s日志产生的时间,默认格式为msecs2003-07-0816:49:45,896
msecs%(msecs)d日志生成时间的亳秒部分
created%(created)ftime.tme)生成的日志创建时间戳
message%(message)s具体的日志信息
filename%(filename)s生成日志的程序名
name%(name)s日志调用者
funcname%( funcname)s调用日志的函数名
levelname%(levelname)s日志级別( DEBUG,INFO, WARNING, 'ERRORCRITICAL)
levene%( leveling)s日志级别对应的数值
lineno%(lineno)d日志所针对的代码行号(如果可用的话)
module%( module)s生成日志的模块名
pathname%( pathname)s生成日志的文件的完整路径
process%( (process)d生成日志的进程D(如果可用)
processname(processname)s进程名(如果可用)
thread%(thread)d生成日志的线程D(如果可用)
threadname%( threadname)s线程名(如果可用)

自定义处理器

handlers这个key中的value的字典里新添一个键值对,指定处理器后除了Streamhandler输出终端的处理器,一般还需要添加处理器所需要的参数的键值对

"new_handlers": {  # 打印到终端console
    "level": "DEBUG",  # 级别
    "class": "",  # 那种类型的处理器
    "formatter": "simple",  # 使用哪个格式化器
},
处理器名称解释使用提示
Streamhandler将日志输出在终端(控制台)上的处理器logging.StreamHandler()
Filehandler将日志保存到磁盘文件的处理器logging.FileHandler(filename="")
BaseRotatingHandler基本的日志轮转方式logging.handlers.BaseRotatingHandler() 具体的参数没有找到
RotatingHandler支持日志文件按大小轮转logging.handlers.RotatingHandler 是后面类的基础
RotatingHandler按照日志文件大小轮转,继承自RotatingHandlerlogging.handlers.RotatingHandler
TimeRotatingHandler按照时间轮转,继承自RotatingHandlerlogging.handlers.TimeRotatingHandler
SMTPHandler远程输出日志到邮件地址logging.handlers.SMTPHandler()
HTTPHandler通过GET或POST远程输出到HTTP服务器logging.handlers.HTTPHandler()

如何确定处理器里面需要的一些参数,比如要使用TimedRotatingFileHandler这个时间轮转处理器

# 直接点进去看源码
from logging.handlers import TimedRotatingFileHandler 
'time_file': {
    'level': 'DEBUG',
    'class': 'logging.handlers.TimedRotatingFileHandler',
    
    # 这些都是 TimedRotatingFileHandler 需要设定的一些参数
    'filename': os.path.join(LOG_DIR, '{}.log'.format(datetime.date.today())),
    'when': "D",
    'interval': 1,
    'encoding': 'utf-8',
    
    'formatter': 'simple',
},

或者直接百度TimedRotatingFileHandler

自定义记录器

"loggers": {
    "mylogger": {
        "level": "DEBUG",  # 记录器的级别,记录器的级别一般要小于等于使用的处理器的级别
        "handlers": ["console","time_file"]  # 指定使用上面哪个处理器
        "propagate": True,  # 向不向更高级别的logger传播消息,默认为True
    },
}

执行流程图

img