首页 > 文章列表 > Django日志logging的配置和自定义添加方式

Django日志logging的配置和自定义添加方式

Python
500 2023-05-15

一、日志的概念

日志是一种可以追踪某些软件运行时所发生事件的方法。开发者可以在代码中调用日志记录相关的方法来表明发生了某些事情。

一个事件可以用一个可包含可选变量数据的消息来描述,事件有严重性级别(level)。

二、Django日志

Django使用python内建的logging模块打印日志,logging配置由:记录器(Logger)、处理器(Handler)、过滤器(Filter)、格式化(Formatter)。

1.logging模块默认定义了以下几个日志等级

级别

描述

CRITICAL/FATAL

50

关键错误/消息

ERROR

40

错误

WARNING

30

警告消息

INFO

20

通知消息

DEBUG

10

调试

NOTSET

0

无级别

日志等级:DEBUG < INFO < WARNING < ERROR < CRITICAL,而日志的信息量是依次减少的。

当为某个应用程序指定一个日志级别后,应用程序会记录所有日志级别大于或等于指定日志级别的日志信息,而不是仅仅记录指定级别的日志信息。

2. logging模块的使用方式介绍

logging模块提供了两种记录日志的方式:

第一种方式是使用logging提供的模块级别的函数

第二种方式是使用Logging日志系统的四大组件

logging所提供的模块级别的日志记录函数也是对logging日志系统相关类的封装而已。

三、Logging提供的模块级别的函数

函数

说明

logging.debug(msg, args, *kwargs)

创建一条严重级别为DEBUG的日志记录

logging.info(msg, args, *kwargs)

创建一条严重级别为INFO的日志记录

logging.warning(msg, args, *kwargs)

创建一条严重级别为WARNING的日志记录

logging.error(msg, args, *kwargs)

创建一条严重级别为ERROR的日志记录

logging.critical(msg, args, *kwargs)

创建一条严重级别为CRITICAL的日志记录

logging.log(level, args, *kwargs)

创建一条严重级别为level的日志记录

logging.basicConfig(**kwargs)

对root logger进行一次性配置

四、Logging日志模块四大组件

组件名称

对应类名

功能描述

记录器

Logger

提供了应用程序可一直使用的接口

处理器

Handler

将logger创建的日志记录发送到合适的目的输出

过滤器

Filter

提供了更细粒度的控制工具来决定输出哪条日志记录,丢弃哪条日志记录

格式器

Formatter

决定日志记录的最终输出格式

logging模块就是通过这些组件来完成日志处理的,logging模块级别的函数也是通过这些组件对应的类来实现的。这些组件之间的关系描述:

记录器(logger)需要通过处理器(handler)将日志信息输出到目标位置,如:文件、sys.stdout、网络等;

不同的处理器(handler)可以将日志输出到不同的位置;

记录器(logger)可以设置多个处理器(handler)将同一条日志记录输出到不同的位置;

每个处理器(handler)都可以设置自己的过滤器(filter)实现日志过滤,从而只保留感兴趣的日志;

每个处理器(handler)都可以设置自己的格式器(formatter)实现同一条日志以不同的格式输出到不同的地方。

简单点说就是:记录器(logger)是入口,真正干活儿的是处理器(handler),处理器(handler)还可以通过过滤器(filter)和格式器(formatter)对要输出的日志内容做过滤和格式化等处理操作。

1.Logger日志记录器

Logger 是日志系统的入口。每个 logger 都是命名了的 bucket, 消息写入 bucket 以便进一步处理。每一条写入 logger 的消息都是一条日志记录。

每一条日志记录也包含日志级别,代表对应消息的严重程度。日志记录还包含有用的元数据,来描述被记录的事件细节。当 logger 处理一条消息时,会将自己的日志级别和这条消息的日志级别做对比。

如果消息的日志级别匹配或者高于 logger 的日志级别,它就会被进一步处理。否则这条消息就会被忽略掉。

当 logger 确定了一条消息需要处理之后,会把它传给 Handler。

Django内置记录器

类功能描述
django.request 请求处理相关的日志消息。5xx响应被提升为错误消息;4xx响应被提升为警告消息。
django.server由RunServer命令调用的服务器所接收的请求的处理相关的日志消息。HTTP 5XX响应被记录为错误消息,4XX响应被记录为警告消息,其他一切都被记录为INFO。
django.template与模板呈现相关的日志消息
django.db.backends有关代码与数据库交互的消息。例如,请求执行的每个应用程序级SQL语句都在调试级别记录到此记录器

2.logging处理器

类名功能描述
logging.StreamHandler类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息
logging.FileHandler将日志消息写入文件filename。
logging.handlers.DatagramHandler(host,port) 发送日志消息给位于制定host和port上的UDP服务器。使用UDP协议,将日志信息发送到网络
logging.handlers.HTTPHandler(host, url) 使用HTTP的GET或POST方法将日志消息上传到一台HTTP 服务器。
logging.handlers.RotatingFileHandler(filename)将日志消息写入文件filename。如果文件的大小超出maxBytes制定的值,那么它将被备份为filenamel。
logging.handlers.SocketHandler使用TCP协议,将日志信息发送到网络。
logging.handlers.SysLogHandler日志输出到syslog
logging.handlers.NTEventLogHandler远程输出日志到Windows NT/2000/XP的事件日志
logging.handlers.SMTPHandler远程输出日志到邮件地址
logging.handlers.MemoryHandler日志输出到内存中的制定buffer

3.Filter过滤器

在日志从 logger 传到 handler 的过程中,使用 Filter 来做额外的控制。

默认情况下,只要级别匹配,任何日志消息都会被处理。不过,也可以通过添加 filter 来给日志处理的过程增加额外条件。例如,可以添加一个 filter 只允许某个特定来源的 ERROR 消息输出。

Filter 还被用来在日志输出之前对日志记录做修改。例如,可以写一个 filter,当满足一定条件时,把日志记录从 ERROR 降到 WARNING 级别。

Filter 在 logger 和 handler 中都可以添加;多个 filter 可以链接起来使用,来做多重过滤操作。

4.Formatter格式器

日志记录最终是需要以文本来呈现的。Formatter 描述了文本的格式。

一个 formatter 通常由包含 LogRecord attributes 的 Python 格式化字符串组成,不过你也可以为特定的格式来配置自定义的 formatter。

格式描述
%(name)s记录器 logger 的名字
%(levelno)s数据形式的日志记录级别
%(levelname)s文本形式的日志记录级别
%(filename)s执行日志记录调用的源文件的文件名
%(pathname)s执行日志记录调用的源文件的 全路径+文件名
%(funcName)s执行日志记录调用的函数名称
%(module)s调用的模块名称,django是 app 的名称
%(lineno)d记录调用的行号
%(created)s执行日志记录的时间
%(asctime)s日期时间
%(msecs)s毫秒部分
%(thread)s线程ID
%(threadName)s线程名称
%(process)d进程ID
%(message)s记录的消息,自定义内容

五、Django中添加logging

1.在项目setting.py 文件中配置logginger 日志

# 日志配置
# 给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'
        },
    },
    "handlers": {  # 定义了三种日志处理方式
        "mail_admins": {  # 只有debug=False且Error级别以上发邮件给admin
            "level": "ERROR",
            "filters": ["require_debug_false"],
            "class": "django.utils.log.AdminEmailHandler",
        },
        '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": {
        "django.request": {  # Django的request发生error会自动记录
            "handlers": ["mail_admins"],
            "level": "ERROR",
            "propagate": True,  # 向不向更高级别的logger传递
        },
        "django.security.DisallowedHost": {  # 对于不在 ALLOWED_HOSTS 中的请求不发送报错邮件
            "level": "ERROR",
            "handlers": ["console", "mail_admins"],
            "propagate": True,
        },            
    },
}

2.admin.py配置后台管理操作日志

from django.contrib import admin
@admin.register(admin.models.LogEntry)
class LogEntryAdmin(admin.ModelAdmin):
    """
    该类用于显示 admin 内置的 django_admin_log 表。
    其中,content_type 是指用户修改的 Model 名
    """
    list_display = ['action_time', 'user', 'content_type', '__str__']
    list_display_links = ['action_time']
    list_filter = ['action_time', 'content_type', 'user']
    list_per_page = 50
    readonly_fields = ['action_time', 'user', 'content_type',
                       'object_id', 'object_repr', 'action_flag', 'change_message']

六、自定义日志

1.现在setting.py日志配置增加配置项

 "handlers": {
     ......
         'user': {   # 专门定义一个收集特定信息的日志
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
            'filename': os.path.join(BASE_DIR+'/logs/', "demo.log"),
            'maxBytes': 1024 * 1024 * 50,  # 日志大小 50M
            'backupCount': 5,
            'formatter': 'verbose',
            'encoding': "utf-8"
        },
     ......
    }
  "loggers": {
      ......
        'user_log': {      # 名为 'demo'的logger还单独处理
            'handlers': ['user'],
            "propagate": True,
            'level': 'INFO',
        },
       ......
       }

2.在view.py中简单添加自定义日志配置项

# 调用setting.py中创建额user_log的logger实例
logger = logging.getLogger('user_log')
def test(request):
  logger.info(request.user.username+',添加成功' )
  return Httpresponse('Success')

3.在setting.py下配置日志文件为logs/demo.log

发送请求后去对应的目录既可查看到日志

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持程序之家。