• python-Django-Logging 用法详解


    Django Logging Settings

    Django 官方文档地址 https://docs.djangoproject.com/en/2.0/topics/logging/#examples

    Python dictConfig 的配置,参考 **Python ** 官方手册

    https://docs.python.org/3/library/logging.config.html#logging-config-dictschema

    1. 简介

    ​ 本文针对 Django 配置日志输出、控制台日志全部输出到文件、日志/控制台 console 重定向到文件。

    Django 利用的就是 Python 提供的 logging 模块,但 Django 中要用 logging,还得有一定的配置规则,需要在 settings.py 中设置。

    ​ 默认情况下,Django 使用 dictConfig 格式。为了配置日志记录,您可以使用 LOGGING 定义日志记录设置的字典。这些设置描述了您希望在日志记录设置

    中使用的日志记录器,处理程序,过滤器和格式化程序,以及希望这些组件具有的日志级别和其他属性。

    ​ 如果将 dictConfig 中的 disable_existing_loggersLOGGING 设置为 True(默认值),则将禁用默认配置中的所有记录器。禁用的记录器与已删除的记

    录器不同;记录器仍将存在,但会静默丢弃记录到它的所有内容,甚至不会将条目传播到父记录器。因此,您应该非常小心地使用;这可能不是您想要的。相反,

    您可以设置为并重新定义一些或所有默认记录器;或者您可以自定义设置。

    配置如下:

    disable_existing_loggers: True 禁用默认配置中的所有记录器

    disable_existing_loggers: False 启动默认配置中的所有记录器

    2. 文件日志示例

    2.1 日志配置

    ​ 一个简单的文件日志配置,它将所有日志记录从 Django 记录器写入本地文件。

    import os
    
    LOGGING = {
        'version': 1,                                    # 定义版本 1
        'disable_existing_loggers': False,               # 允许使用已有的默认过滤器
        'handlers': {                                    # 日志处理器
            'file': {                                    # 定义一个处理器 file
                'level': 'DEBUG',                        # 定义 handelr 的日志级别
                'class': 'logging.FileHandler',          # 使用文件类处理器,可以将日志写入文件中
                'filename': '/path/to/django/debug.log', # 定义 DEBUG 日志信息的存储路径,文件路径需要确认有可写权限
            },
        },
        'loggers': {                                     # 日志记录器
            'django': {                                  # 记录 django 项目中的信息
                'handlers': ['file'],                    # 使用处理器 file
                'level': 'DEBUG',                        # 日志的等级为 DEBUG 
                'propagate': True,                       # 允许传播至上级记录器
            },
        },
    }
    '
    运行
    2.2 配置说明

    ​ 字典中的 version 指明了配置的版本;disable_existing_loggers 指明是否禁止默认配置的记录器。(这两项通常不需要去改动)

    重点看 loggershandlers 的配置:

    ​ 如前面说,一条消息首先传递给 loggerDjango 中内置了几种记录器,比如这里用到的 Django 记录器,它会接收 Django 层次结构中的所有消息。

    然后我们定义了需要处理 DEBUG 以上级别的消息,并把这些消息传递给名叫file的处理器。

    ‘propagate’: True 可以基于每个记录器控制该传播,如果您不希望特定记录器传播到其父项,则可以关闭此行为。

    ​ 现在消息来到名叫 filehandlers 中了。这个处理器定义了消息处理级别仍然为 DEBUG,在 class 中定义将消息输出到文件中去,文件地址为项目目录的 /path/to/django/debug.log

    ​ 因为这里没有配置 filtersformatters,因此会采用默认的设置。

    ​ 需要注意的是日志的输出文件的目录 /path/to/django/ 一定要提前创建好,并且确保项目拥有此目录的写入权限。

    3. 控制台日志示例

    3.1 日志配置

    ​ 默认情况下,此配置仅将日志等级为 INFO 的日志向 console 控制台发送消息,其他级别或更高级别的消息则不发送至控制台。

    ​ 与 Django 的默认日志记录配置相同,但默认情况下仅在 DEBUG=True 时显示日志记录。

    Django 不会记录许多此类消息。但是,通过此配置,您还可以设置环境变量 DJANGO_LOG_LEVEL=DEBUG 以查看 Django 的所有调试日志记录,这非常

    冗长,因为它包含所有数据库查询。

    import os
    
    LOGGING = {
        'version': 1,                                           # 定义版本 1
        'disable_existing_loggers': False,                      # 允许使用已有的默认过滤器
        'handlers': {                                           # 日志处理器
            'console': {                                        # 定义一个处理器 console
                'class': 'logging.StreamHandler',               # 使用流处理类,可以将信息打印到控制台
            },
        },
        'loggers': {                                            # 日志记录器
            'django': {                                         # 记录 django 项目中的信息
                'handlers': ['console'],                        # 使用处理器 console
                'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'), # 日志的等级为 INFO 
            },
        },
    }
    '
    运行

    4. 复杂日志示例

    4.1 日志配置

    ​ 所有与日志有关的配置默认在 LOGGING ={} 中,distConfig 格式。如果我们没有进行特别配置,Django 会执行默认的日志配置。

    Django settings 默认配置:

    DEBUG = True

    django logger 及其(除 django.server 之外)所有下级的 INFO 以上的日志,都会被 StreamHandler 处理(输出到 console

    DEBUG = Flase

    django logger 及其(除 django.server 之外)所有下级的 ERRORCRITICAL 的日志,都会被 AdminEmailHandler 处理(发送至指定邮件)

    ​ 如果我们不想使用默认的配置,可以将 LOGGING 中的 ‘disable_existing_loggers’ 设置为 True(默认也是 True ),这样一来,默认的配置就会被禁用。

    但是设置 ‘disable_existing_loggers’: True,必须要非常小心,因为可能产生一些令人意外的结果(官网这么说的,还没试过),所以比较建议的方法

    ‘disable_existing_loggers’: False,然后重写部分或者全部的默认 logger

    LOGGING = {
        'version': 1,                                    # 定义版本 1
        'disable_existing_loggers': False,               # 允许使用已有的默认过滤器
        'formatters': {                                  # 日志格式器
            'verbose': {                                 # 定义一个格式器 verbose
                'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
                                                         # 输出日志级别名称,日志消息以及生成日志消息的时间,进程,线程和模块
            },
            'simple': {                                  # 定义一个格式器 simple
                'format': '%(levelname)s %(message)s'    # 仅输出日志级别名称(例如 DEBUG)和日志消息
            },
        },
        'filters': {                                     # 日志过滤器
            'special': {                                 # 定义一个过滤器 sepcial
                '()': 'project.logging.SpecialFilter', 
                'foo': 'bar',
            },
            'require_debug_true': {
                '()': 'django.utils.log.RequireDebugTrue',
            },
        },
        'handlers': { 									 # 日志处理器
            'console': {                                 # 定义一个处理器 console,将 INFO 级别的日志使用 stream 流处理打印到控制台
                'level': 'INFO',
                'filters': ['require_debug_true'],
                'class': 'logging.StreamHandler',
                'formatter': 'simple'                    # 过滤规则使用 simple,只输出日志等级以及 messages 信息
            },
            'mail_admins': {                             # 定义一个处理器 mail_admis,将 ERROR 级别的日志使用 AdminEmailHandler 处理器
                'level': 'ERROR',
                'class': 'django.utils.log.AdminEmailHandler',
                'filters': ['special']                   # 将错误信息发送到该网站的 admin 超级用户的邮箱,错误信息格式采用 special 格式处理
            }
        },
        'loggers': {                                     # 日志记录器
            'django': {                                  # 定义一个记录器 django,使用 console 处理器,即将记录的信息打印到控制台
                'handlers': ['console'],                 
                'propagate': True,                       # 允许传播至上级记录器
            },
            'django.request': {                          # 定义一个记录器 django.request,使用 main_admins 处理器,只处理邮件发送的错误信息
                'handlers': ['mail_admins'],
                'level': 'ERROR',
                'propagate': False,                      # 禁用传播至上级记录器 django
            },
            'myproject.custom': {                        # 定义一个记录器 myproject.custome,同时使用 console、mail_admis 处理器
                'handlers': ['console', 'mail_admins'],
                'level': 'INFO',
                'filters': ['special'] 
            }
        }
    }
    '
    运行
    4.2 配置说明
    • 将配置文件的格式标识为 “ 版本1 ” 格式。也是目前唯一的版本格式。

    • 定义两个格式化程序:

      • simple

        ​ 仅输出日志级别名称(例如 DEBUG )和日志消息。

        ​ 该 format 字符串是普通的 Python 格式化字符串,描述了将在每条记录行上输出的详细信息。

        ​ 可以输出的详细信息的完整列表可以在 Formatter Objects 中找到。

      • verbose

        ​ 输出日志级别名称,日志消息以及生成日志消息的时间,进程,线程和模块。

    • 定义两个过滤器:

      • project.logging.SpecialFilter (special)

        ​ 如果此过滤器需要其他参数,则可以在过滤器配置字典中将它们作为其他关键字提供,在这种情况下,实例化时 foo 将为参数提供值。

      • django.utils.log.RequireDebugTrue

        ​ 该记录在 DEBUG is True 时传递。

    • 定义两个处理程序:

      • console,StreamHandler

        ​ 将任何 INFO (或更高版本的)消息打印到 sys.stderr。该处理程序使用 simple 输出格式。

      • mail_admins,AdminEmailHandler

        ​ 通过电子邮件将任何 ERROR (或更高版本)消息发送到该网站 ADMINS。该处理程序使用 special 过滤器。

    • 配置三个记录器:

      • django

        ​ 将所有消息传递给 console 处理程序。

      • django.request

        ​ 将所有 ERROR 消息传递给 mail_admins 处理程序。另外,该记录器被标记为不传播消息。

        ​ 这意味着记录器 django.request 将不会处理写入日志消息至 django

      • myproject.custom

        ​ 将所有 INFO 或更高级别的消息传递给该消息,也将 special 过滤器传递给两个处理程序 consolemail_admins

        ​ 这意味着所有 INFO 级别的消息(或更高级别的消息)将被打印到控制台。ERRORCRITICAL 消息也将通过电子邮件输出。

    4.3 邮件配置

    ​ 上面的日志配置提到需要在日志中发送错误信息至 admin 的邮箱,Django 项目中需要在 settings 配置好邮件发送的相关配置

    'The email address that error messages come from, such as those sent to ADMINS and MANAGERS.'
    
    # 邮件配置
    EMAIL_HOST = 'smtp.maildomain.com'                    # SMTP地址
    EMAIL_PORT = 25                                       # SMTP端口
    EMAIL_HOST_USER = 'sender@maildomain.com'             # 发送邮件的邮箱
    EMAIL_HOST_PASSWORD = '******'                        # 我的邮箱密码
    EMAIL_SUBJECT_PREFIX = u'[prefix]'                    # 为邮件 Subject-line 前缀,默认是 '[django]'
    EMAIL_USE_TLS = True                                  # 与 SMTP 服务器通信时,是否启动 TLS 链接(安全链接),默认 false
    # 管理员站点
    SERVER_EMAIL = 'adminli@163.com'  
    ADMINS = (('receiver', 'receiver@maildomain.com'),)   # 接收邮件的邮箱(或邮件组)
    '
    运行

    5. 自定义日志配置

    ​ 如果您不想使用 PythondictConfig 格式配置记录器,则可以指定自己的配置方案。

    ​ 该 LOGGING_CONFIG 设置定义了用于配置 Django 记录器的可调用对象。默认情况下,它指向 Pythonlogging.config.dictConfig() 函数。但是,如果

    要使用其他配置过程,则可以使用带有单个参数的任何其他可调用对象。LOGGING 配置日志记录时,将提供的内容作为该参数的值。

    ​ 设置 LOGGING_CONFIGNone 仅表示禁用自动配置过程。如果禁用配置过程,Django 仍将进行日志记录调用,而回退到定义的默认日志记录行为。

    settings 配置如下:

    LOGGING_CONFIG = None
     
    import logging.config
    logging.config.dictConfig(...)
    

    6. Django 日志记录扩展

    6.1 Django 内建 logger
    1. django

    django 只是一个最上级的 logger,但实际上并不接收什么实际的信息,所有的信息都是通过下级 logger 接收。

    2. django.request
    • 处理请求处理有关的日志消息

      • 5XX 响应作为 ERROR 消息引发;出现 4XX 响应作为 WARNING 消息。
    • 发送给该记录器的消息具有以下额外的上下文:

      • status_code:与请求关联的 HTTP 响应代码。
      • request: 生成日志消息的请求对象。
    3. django.server
    • runserver 命令调用的服务器接收的请求处理相关的日志消息

      • HTTP 5XX 响应记录为 ERROR 消息,4XX 响应记录为 WARNING 消息,其他所有记录为 INFO
    • 发送给该记录器的消息具有以下额外的上下文:

      • status_code:与请求关联的 HTTP 响应代码。
      • request: 生成日志消息的请求对象。
    4. django.template
    • 记录与模板渲染有关的消息

      • 缺少的上下文变量将记录为 DEBUG 消息。

      • 在调试模式关闭时,在关闭期间引发的未捕获异常将会记录为消息(这是有用的,因为在这种情况下使异常屏蔽并返回空字符串)。

        {%include %} WARNING {% include %}

    5. django.db.backends
    • 与代码与数据库的交互有关的消息

      • 请求执行的每个应用程序级 SQL 语句都在 DEBUG 该记录器级别记录。
    • 发送给该记录器的消息具有以下额外的上下文:

      • duration:执行 SQL 语句所花费的时间。
      • sql: 执行的 SQL 语句。
      • params: 在 SQL 调用中使用的参数。
    • 出于性能方面的考虑,仅在 settings.DEBUGSQL 日志记录设置为 True 才启用 SQL 日志记录,而不考虑日志记录级别或已安装的处理程序。

    • 此日志记录不包括框架级初始化(例如:SET TIMEZONE )或事务管理查询(例如:**SET TIMEZONE BEGIN COMMIT ROLLBACK **)。

    • 如果要查看所有数据库查询,请打开数据库中的查询日志记录。

    6.2 Handlers 日志邮件处理器
    class AdminEmailHandler(include_html=False, email_backend=None)[source]
    
    • Django 除了提供 Python 日志记录 loggging 模块所提供的日志处理程序外,还提供了一个特别的日志处理程序。

    • 该处理程序 ADMINS 针对收到的每个日志消息都会向该站点 admin 用户发送一封电子邮件。

    • 如果日志记录包含 request 属性,则请求的完整详细信息将包含在电子邮件中。

    ​ 如果客户的 IP 地址在 INTERNAL_IPS 设置中,则电子邮件主题将包含短语“内部 IP” ;如果没有,它将包括 “EXTERNAL IP”。

    ​ 如果日志记录包含堆栈跟踪信息,则该堆栈跟踪将包含在电子邮件中。

    • AdminEmailHandlerinclude_html 参数用于控制回溯电子邮件是否包含 HTML 附件,该附件包含调试 Web 页面的完整内容。要在您的配置中设置此值,请将其包含在的处理程序定义中 django.utils.log.AdminEmailHandler,如下所示:
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            # 设置为 True 则包含 HTML 附件
            'include_html': True, 
        }
    },
    

    注意

    ​ 此电子邮件的 HTML 版本包含完整的追溯,在堆栈的每个级别上都包含局部变量的名称和值,以及 Django 设置的值。

    ​ 所以此信息可能非常敏感,您可能不想通过电子邮件发送它。考虑使用诸如 Sentry 之类的东西来获得两全其美的体验。既有全面的回溯的丰富信息以及不通

    过电子邮件发送信息的安全性。

    ​ 您还可以明确指定要从错误报告中过滤掉的某些敏感信息,可以了解有关过滤错误报告的更多信息 。

    ​ 通过设置 email_backend 的参数 AdminEmailHandler,可以覆盖处理程序正在使用的电子邮件后端,如下所示:

    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'email_backend': 'django.core.mail.backends.filebased.EmailBackend',
        }
    },
    

    默认情况下,EMAIL_BACKEND 将使用指定的电子邮件

    send_mail(subject,message,*args,**kwargs)[源代码]**

    ​ 向管理员用户发送电子邮件。若要自定义此行为,可以对 AdminEmailHandler 类进行子类化并重写此方法。

    6.3 Filters 过滤器扩展

    Django 除了提供 Python 日志记录模块所提供的日志过滤器外,还提供了一些特别日志过滤器。

    • classCallbackFilter(callback)source

      • 该过滤器接受一个回调函数(该函数应接受一个参数,即要记录的信息),并为通过过滤器的每条记录调用该函数。
      • 如果回调返回 False,则该记录的处理将不会继续。
    • 示例

      • UnreadablePostError 要从管理员电子邮件中过滤掉,您可以创建过滤器功能:
      from django.http import UnreadablePostError
       
      def skip_unreadable_post(record):
          if record.exc_info:
              exc_type, exc_value = record.exc_info[:2]
              if isinstance(exc_value, UnreadablePostError):
                  return False
          return True
      
      • 将其添加到您的日志记录配置中:
      'filters': {
          'skip_unreadable_posts': {
              '()': 'django.utils.log.CallbackFilter',
              'callback': skip_unreadable_post,
          }
      },
      'handlers': {
          'mail_admins': {
              'level': 'ERROR',
              'filters': ['skip_unreadable_posts'],
              'class': 'django.utils.log.AdminEmailHandler'
          }
      },
      
    • class RequireDebugFalse[source]

      仅当 settings.DEBUGFalse 时,此过滤器才会传递记录。

      该过滤器被用作在默认如下 LOGGING 配置,以确保 AdminEmailHandler 当只发送错误电子邮件到管理员:

      'filters': {
          'require_debug_false': {
              '()': 'django.utils.log.RequireDebugFalse',
          }
      },
      'handlers': {
          'mail_admins': {
              'level': 'ERROR',
              'filters': ['require_debug_false'],
              'class': 'django.utils.log.AdminEmailHandler'
          }
      },
      
    • class RequireDebugTrue[source]

      这个过滤器 filter 类似于 RequireDebugFalse ,只有当 settings.DEBUGTrue 的时候,才会被调用。

  • 相关阅读:
    音频领域的50个关键词
    【LeetCode】Day96-第一个唯一字符&赎金信&字母异位词
    React 之 forwardRef用法(十六)
    Mybatis中 list.size() = 1 但显示 All elements are null
    洛谷P2261 整除分块模板
    用ARM进行汇编语言编程(7)HelloWorld和gdb调试Arm程序
    mindspore训练retinanet时报错无法计算loss,停止训练
    error: failed to push some refs to ‘gitee.com:wavelet-aa/msb_-erp.git
    基于motoharw平台的电机控制策略模型simulink仿真实现
    OpenHarmony移植案例: build lite源码分析之hb命令__entry__.py
  • 原文地址:https://blog.csdn.net/qq_31455841/article/details/127121176