Django2.1 日志 中文文档

Django2.1 日志 中文文档

: Django2.1 Python


当你凝望深渊的时候,深渊也在凝望你。
作者: zhanghaoli12345@163.com

NOTE: 此文档为参照官方技术文档翻译得出,其中如有错误望可以指正。


内容源网址


##快速入门
Django使用Python的内置日志(logging)模块构建自己的日志系统。在Python的文档中由该模块的详细说明。由此,如果您从未使用过Python的日志框架(或者即使您已经使用过),您可以阅读快速入门的内容。

###球队阵容
Python日志配置由四个部分组成:

####Loggers 记录器
日志记录器是进入日志系统的入口点。每个日志记录器都是一个有名的‘桶’,将消息写入其中进行处理。
记录器具有日志级别属性(log level)。这个日志级别描述日志记录器所处理消息的严重程度。Python定义的以下日志级别:

  • DEBUG:用于调试目的的低等级系统信息
  • INFO:一般的系统信息。
  • WARNING:描述发生的一个小问题的信息
  • ERROR:描述发生的一个大问题的信息
  • CRITICAL:描述已发生的关键问题的信息。

写入日志记录器的每个消息都是日志记录。每个日志记录都有一个日志级别,指示特定消息的严重程度。日志记录还可以包含描述正在记录的事件的有用元数据。这可能包括详细信息,例如堆栈跟踪或错误代码。
当消息被提供给记录器时,将消息的日志级别与记录器的日志级别进行比较。如果消息的日志级别满足或超过记录器本身的日志级别,则消息将进行进一步处理。如果没有,消息将被忽略。
一旦日志记录器确定需要处理消息,就会将其传递给处理程序。


####Handlers 处理器
处理程序是决定日志记录器中每个消息处理行为的引擎。它描述特定的日志记录行为,例如向屏幕、文件或网络套接字写入消息。
与日志记录器一样,处理程序也具有日志级别。如果日志记录的日志级别不满足或超过处理程序的级别,处理程序将忽略消息。
日志记录器可以有多个处理程序,每个处理程序可以有不同的日志级别。通过这种方式,可以根据消息的重要性提供不同形式的通知。例如,您可以安装一个将错误和关键消息转发到分页服务的处理程序,而第二个处理程序将所有消息(包括错误和关键消息)记录到一个文件中,以便稍后进行分析。


####Filters 过滤器
过滤器用于提供对日志记录从日志记录器传递到处理程序过程中的额外控制。
默认情况下,满足日志级别要求的任何日志消息都将被处理。但是,通过安装过滤器,您可以在日志记录过程中添加额外的条件。例如,您可以安装一个过滤器,该过滤器只允许发出来自特定源的错误消息。
过滤器还可以用于在发出日志记录之前修改日志记录。例如,您可以编写一个过滤器,如果满足特定的一组条件,则将错误日志记录降级为警告记录。
过滤器可以安装在记录器或处理器上;可以在一个链中使用多个过滤器来执行多个过滤操作。


####Formatters 格式化器
最终,需要将日志记录呈现为文本。格式化器描述了文本的精确格式。格式化程序通常由包含日志记录属性(LogRecord attributes)的Python格式化字符串组成;但是,您也可以编写自定义格式化程序来实现特定的格式化行为。


##使用日志
一旦配置了日志记录器、处理程序、过滤器和格式化程序,就需要将日志调用放到代码中。使用日志框架非常简单。这里有一个例子:

# import the logging library
import logging

# Get an instance of a logger
logger = logging.getLogger(__name__)

def my_view(request, arg1, arg):
    ...
    if bad_mojo:
        # Log an error message
        logger.error('Something went wrong!')

就是这样!每次符合bad_mojo条件时,都会写入错误日志记录。

##命名记录器

调用logging.getlogger()可以获取(有必要的话会新建)一个记录器(logger)的实例。记录器由名称标识。这个名称标识被配置的记录器(logger)。
按照惯例,日志记录器的名称通常是**name**,即包含日志记录器的python模块的名称。这允许您根据每个模块过滤和处理日志调用。但是,如果您有其他方式来组织日志消息,您可以提供任何以点分隔的名称来标识您的日志记录器:

# 获取一个特定名称记录器的实例
logger = logging.getLogger('project.interesting.stuff'

日志记录器名称的点路径定义了一个层次结构。pproject.interesting记录器被认为是project.interesting.stuff记录器的父类; project记录器被认为是project.interesting记录器的父类。

为什么等级制度很重要?因为日志记录器可以被设置为将日志调用传递给它们的父类。通过这种方式,您可以在日志记录器树的根上定义一组处理程序,并捕获日志记录器树中的所有日志调用。在project命名空间中定义的日志处理程序将捕获在project.interestingprojects.interest.stuff日志记录器上发出的所有日志消息。

这种传播可以在每个记录器的基础上进行控制。如果您不想让一个特定的记录器传播给它的父类,您可以关闭这种行为。


##调用记录器

日志记录器实例包含输入默认日志级别条目的方法:

  • logger.debug()
  • logger.info()
  • logger.warning()
  • logger.error()
  • logger.critical()

还有其两条可用的日志调用:

  • logger.log():手动发出带有特定日志级别的日志消息。
  • logger.exception():创建一个ERRORR级别的日志消息,用于包装当前异常堆栈框架。

##配置记录器

当然,仅仅在代码中添加日志调用是不够的。您还需要配置日志记录器、处理器、过滤器和格式化器,以确保日志输出以一种有用的方式输出。

Python的日志库提供了一些配置日志从编程接口到配置文件技巧。默认情况下,Django使用dictConfig格式。

为了配置日志记录,您可以使用LOGGING来定义日志记录设置的字典。这些设置描述了日志设置中需要的日志记录器、处理器、过滤器和格式化器,以及希望这些组件具有的日志级别和其他属性。

默认情况下,LOGGING设置与Django的默认日志配置合并采用如下方案。

如果LOGGINGdictConfig中的disable_existing_loggers键设置为True(这是默认设置),那么默认配置中的所有记录器都将被禁用。禁用的日志记录器与删除的日志记录器不同;日志记录器将仍然存在,但会自动丢弃所有登录到日志记录器的内容,甚至不会将条目传播到父日志记录器。因此,您应该非常小心地使用disable_existing_loggers:True;这可能不是你想要的。相反,您可以将disable_existing_loggers设置为False并重新定义一些或所有默认的loggers;或者您可以将LOGGING_CONFIG设置为None自己处理日志配置

日志记录被配置为Django **setup()**函数的一部分。因此,您可以确定日志记录器可以随时在项目代码中使用。

例如

dictConfig格式的完整文档是关于日志配置字典的最佳说明。但是,为了让您有个大概的了解,这里有几个例子。

首先,这里有一个简单的配置,它将django日志记录器的所有日志写入本地文件:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': '/path/to/django/debug.log',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

如果使用这个示例,请确保将“filename”路径更改为可由运行Django应用程序的用户写入的位置。

其次,这里有一个如何让日志系统将Django的日志打印到控制台的示例。它可能在本地开发中有用。

默认情况下,该配置只向控制台发送INFO级别或更高的消息(与Django的默认日志配置相同,只是默认值仅在DEBUG=True时显示日志记录)。Django没有记录很多这样的消息。但是,使用这个配置,您可以设置环境变量DJANGO_LOG_LEVEL=DEBUG,以查看Django的包含所有数据库查询的详细调试日志:

import os

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
        },
    },
}

最后,这里有一个相当复杂的日志设置示例:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
            'style': '{',
        },
        'simple': {
            'format': '{levelname} {message}',
            'style': '{',
        },
    },
    'filters': {
        'special': {
            '()': 'project.logging.SpecialFilter',
            'foo': 'bar',
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'filters': ['special']
        }
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'propagate': True,
        },
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': False,
        },
        'myproject.custom': {
            'handlers': ['console', 'mail_admins'],
            'level': 'INFO',
            'filters': ['special']
        }
    }
}

这个日志配置做以下事情:

  • 将配置标识为“dictConfig version 1”格式。目前,这是唯一的dictConfig格式版本。

  • 定义了两个格式化器:

    • simple:仅输出日志的级别(e.g. DEBUG)以及日志信息。

      格式字符串是一种普通的Python格式字符串,是在每个日志行上输出的详细信息。可以在Formatter Objects中找到可以输出的信息的完整列表。

    • verbose:它输出日志级别名称、日志消息以及生成日志消息的时间、进程、线程和模块。

  • 定义了两个过滤器:

    • project.logging.SpecialFilter:使用特殊的别名。如果这个筛选器需要额外的参数,它们可以作为筛选器配置字典中的附加键提供。在这种情况下,当实例化SpecialFilter时,参数foo将被赋予一个bar的值。
    • django.utils.log.RequireDebugTrue:当DEBUGTrue时,它会传递记录。
  • 定义了两个处理器:

    • console:一个StreamHandler,它会将所有INFO或更高级的消息输出到sys.stderr。这个处理器使用simple输出格式。
    • mail_admin:一个AdminEmailHandler,它将所有ERROE或更高级的消息通过电子邮件发送给ADMINS。这个处理器使用special过滤器。
  • 定义了三个记录器:

    • django:将所有消息传递给控制台处理程序
    • django.request:它将所有错误消息传递给mail_admins处理程序。此外,这个记录器被标记为不传递消息。这意味着django记录器不会处理写给django.request记录器的日志消息。
    • myproject.custom:将经过special过滤器的INFO或更高级的消息传递给consolemail_admins。也就是说所有INFO或更高级的消息将在控制台输出,ERROECRITICAL消息将通过电子邮件输出。

##自定义日志配置
如果不希望使用Python的dictConfig格式配置日志记录器,可以指定自己的配置方案。
LOGGING_CONFIG设置定义了可调用的,用于配置Django的日志记录器。默认情况下,它指向Python的logging.config.dictConfig()函数。然而,如果您想使用不同的配置过程,您可以使用任何其他可调用的,它只接受一个参数。在配置日志参数后,LOGGING的内容将作为参数的值提供。


##禁用日志配置
如果您根本不想配置日志记录(或者您想使用自己的方法手动配置日志记录),您可以将LOGGING_CONFIG设置为None。这将禁用Django默认日志记录的配置过程。下面是一个示例,它禁用Django的日志配置,然后手动配置日志记录:

LOGGING_CONFIG = None

import logging.config
logging.config.dictConfig(...)

LOGGING_CONFIG设置为None只意味着禁用了自动配置进程,而不是日志本身。如果您禁用了配置过程,Django将继续调用日志记录,返回到定义的默认日志记录行为。


##Django日志拓展
Django提供了许多实用程序来处理Web服务器环境中日志记录的独特需求。

###Loggers 记录器
Django提供了几个内置的日志记录器。

####django
django层次结构中的所有消息的捕获程序。没有消息会使用这个名称发布消息,消息使用下面其中的一个日志记录器发布。


####django.request
与处理请求相关的日志消息。5XX响应作为ERROR消息被提出;4XX响应作为WARNING信息提出。请求被记录到django的请求。被记录到django.security的日志不会被记录到django.request中。

该日志记录器的消息具有以下额外上下文:

  • status_code:与请求相关联的HTTP响应代码。
  • request:生成日志消息的请求对象。

####django.server
与处理由runserver命令调用的服务器接收到的请求相关的日志消息。HTTP 5XX响应被记录为ERROR消息,4XX响应被记录为WARNING消息,其他的都被记录为INFO

该日志记录器的消息具有以下额外上下文:

  • status_code:与请求相关联的HTTP响应代码。
  • request:生成日志消息的请求对象。

####django.template
与模板呈现相关的日志消息。

  • 遗漏的上下文变量被记录为DEBUG消息

####django.db.backends
与代码与数据库交互有关的消息。例如,请求执行的每个应用程序级SQL语句都以DEBUG级别记录到这个日志记录器中。

该日志记录器的消息具有以下额外上下文:

  • duration:执行SQL语句所花费的时间。
  • sql:执行的SQL语句。
  • params:SQL调用中使用的参数。

出于性能原因,SQL日志记录只有在设置时才启用。调试设置为True,而不管日志级别或安装的处理程序如何。

这种日志记录不包括框架级初始化(e.g. SET TIMEZONE)或事务管理查询(e.g. BEGIN,COMMIT,ROLLBACK)。如果希望查看所有数据库查询,请打开数据库中的查询日志。


####diango.security.*
安全日志记录器将收到任何SuspiciousOperation和其他安全相关错误信息(errors)。对于每个安全错误的子类型,包括所的有SuspiciousOperation,都有一个子日志记录器。日志事件的级别取决于异常处理的位置。大多数事件都被记录为warning,而到达WSGI处理程序的任何SuspiciousOperation都将被记录为erro。例如,请求中包含HTTP主机头来自不匹配ALLOWED_HOSTS的客户机,Django将返回400响应,并将一条错误消息记录到django.security。DisallowedHost记录器。

默认情况下,这些日志事件将到达django记录器,当DEBUG=False时,django记录器将向管理员发送错误事件。由于SuspiciousOperation而导致400响应的请求将不会被记录到django.request记录器,只会记录到django.security记录器。

为了使特定类型的SuspiciousOperation保持沉默,您可以在下面的示例中重写特定的日志记录器:

'handlers': {
    'null': {
        'class': 'logging.NullHandler',
    },
},
'loggers': {
    'django.security.DisallowedHost': {
        'handlers': ['null'],
        'propagate': False,
    },
},

其余不基于SuspiciousOperationdjango.security记录器有:


####django.db.backends.schema
记录在迁移框架migrations framework对数据库进行模式更改期间执行的SQL查询。注意,它不会记录RunPython执行的查询。这个日志记录器的消息在额外的上下文中有paramssql(但与django.db.backends不同,非持续)。这些值具有与django.db.backends中解释的相同的含义。


处理器

除了这些Python提供的日志模块,Django还提供了一个日志处理器。

类 AdminEmailHandler(include_html=False,email_backend=None) source

这个处理器将会把接收到的每一条日志消息发送给当前的站点ADMINS

如果日志记录包含一个request属性,其所有细节都将被包含在邮件中。如果登录的IP地址在INTENAL_IPS设置中,邮件中将会包含“internal IP”字段。否则,邮件将会包含“EXTERNAL IP”

如果日志记录中包含堆栈追踪的信息,邮件将会包含堆栈追踪的信息。

AdminEmailHandler incldue_html 参数用于控制DEBUG模式下回溯信息邮件中是否会存在一个包含完整环境信息的调试网页的HTML附件。

通过包含如下 django.utils.log.AdminEmailHandler 处理器定义可以在你的配置中启动该项内容:

'handlers':{
	'mail_admin':{
		'level':'ERROR',
		'class':'django.utils.log.AdminEmailHandler',
		'include_html':True,
	}
},

值得注意的是,这个 HTML 版本的电子邮件包含完整的回溯信息,包含堆栈每一层中局部变量的名称和值,加上您的Django设置的值。

这些信息可能是非常敏感的,你可能不希望发送电子邮件。

因此,您可以考虑使用 Sentry 一类的东西兼顾两者的优点,完整丰富的信息回溯 + 不通过电子邮件发送信息。

你也可以显示的指定将敏感信息从错误报告中剔除,为此,您需要学习更多过滤器的内容

通过设置 AdminEmailHandleremail_backend 参数可以覆盖处理器所使用的email backend,例如:

'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) **source

发送邮件给管理员用户,您可以通过定义 AdminEmailHandler 子类重写其方法的方式定制行为。


过滤器

未完待续!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值