Django 5企业级Web应用开发实战-日志
【图书介绍】《Django 5企业级Web应用开发实战(视频教学版)》_django 5企业级web应用开发实战(视频教学版)-CSDN博客
《Django 5企业级Web应用开发实战(视频教学版)》(王金柱)【摘要 书评 试读】- 京东图书 (jd.com)
Django 5框架Web应用开发_夏天又到了的博客-CSDN博客
本节主要介绍关于Django框架日志方面的内容。Django使用Python的内置日志记录模块执行系统日志记录,主要包括了Logger、Handler、Filter和Formatter这4个模块。
Logger是进入日志系统的入口点,每个Logger都是一个命名的存储集合,可以将消息写入其中以进行处理。
Logger具有日志级别,日志级别描述了Logger将处理的消息的严重性。Python定义了以下日志级别:
- DEBUG:用于调试目的的底层系统信息。
- INFO:通用系统信息。
- WARNING:描述已发生的警告问题的信息。
- ERROR:描述已发生的主要问题的信息。
- CRITICAL:描述已发生的严重问题的信息。
写入Logger的每条消息都是一个日志记录。每个日志记录还具有指示该特定消息的严重性的日志级别。日志记录还可以包含有用的元数据,该元数据描述了正在记录的事件,可以包括详细信息,例如堆栈跟踪或错误代码。
将消息提供给Logger时,会将消息的日志级别与Logger的日志级别进行比较。如果消息的日志级别达到或超过Logger本身的日志级别,则将对消息进行进一步处理;如果没有,该消息将被忽略。
当Logger确定需要处理消息后,就会将消息传递给相应处理程序(Handle)。
处理程序是确定Logger中每个消息发生什么情况的引擎,描述了特定的日志记录行为。例如,将消息写到屏幕、文件或网络套接字。
如同Logger一样,处理程序也具有日志级别。如果日志记录的日志级别不满足或超过处理程序的级别,则处理程序将忽略该消息。
一个Logger可以具有多个处理程序,并且每个处理程序可以具有不同的日志级别。这样,可以根据消息的重要性提供不同形式的通知。例如,可以安装一个处理程序,将ERROR和CRITICAL消息转发到分页服务,而另一个处理程序将所有消息(包括ERROR和CRITICAL消息)记录到文件中,以供以后分析。
Filter(过滤器)用于提供额外的控制,以控制哪些日志记录从logger传递到Handle。
默认情况下,将处理所有符合日志级别要求的日志消息。但是,通过安装过滤器可以在日志记录过程中放置其他条件。例如,可以安装一个过滤器,该过滤器仅允许发出来自特定来源的ERROR消息。
过滤器还可以用于在发出之前修改日志记录。例如,可以编写一个过滤器,如果满足一组特定的条件,则将ERROR日志记录降级为WARNING记录。
过滤器可以安装在Logger或Handle上,在一个链中可以使用多个过滤器来执行多个过滤操作。
最终的日志记录需要呈现为文本,而格式器(Formatter)描述了该文本的确切格式。格式化程序通常由包含LogRecord属性的Python格式化字符串组成。不过,也可以编写自定义格式化程序,以实现特定的格式化行为。
使用日志记录的方法很简单,在Django项目的配置文件setting.py中配置好Logger、Handle、Filter和Formatters后,就可以将需要的日志记录的调用放入代码中。下面是几个比较常用的代码实例。
第一个是一个相对简单的配置,用于将Django框架的Logger中的所有日志记录写入本地文件。
【代码11-7】
01 LOGGING = {
02 'version': 1,
03 'disable_existing_loggers': False,
04 'handlers': {
05 'file': {
06 'level': 'DEBUG',
07 'class': 'logging.FileHandler',
08 'filename': 'debug.log',
09 },
10 },
11 'loggers': {
12 'django': {
13 'handlers': ['file'],
14 'level': 'DEBUG',
15 'propagate': True,
16 },
17 },
18 }
第二个是一个相对完整的配置,包括Logger、Handle、Filter和Formatter的全部配置信息。
【代码11-8】
01 LOGGING = {
02 'version': 1,
03 'disable_existing_loggers': False,
04 'formatters': {
05 'verbose': {
06 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d
%(message)s'
07 },
08 'simple': {
09 'format': '%(levelname)s %(message)s'
10 },
11 },
12 'filters': {
13 'special': {
14 '()': 'project.logging.SpecialFilter',
15 'foo': 'bar',
16 },
17 'require_debug_true': {
18 '()': 'django.utils.log.RequireDebugTrue',
19 },
20 },
21 'handlers': {
22 'console': {
23 'level': 'INFO',
24 'filters': ['require_debug_true'],
25 'class': 'logging.StreamHandler',
26 'formatter': 'simple'
27 },
28 'mail_admins': {
29 'level': 'ERROR',
30 'class': 'django.utils.log.AdminEmailHandler',
31 'filters': ['special']
32 }
33 },
34 'loggers': {
35 'django': {
36 'handlers': ['console'],
37 'propagate': True,
38 },
39 'django.request': {
40 'handlers': ['mail_admins'],
41 'level': 'ERROR',
42 'propagate': False,
43 },
44 'myproject.custom': {
45 'handlers': ['console', 'mail_admins'],
46 'level': 'INFO',
47 'filters': ['special']
48 }
49 }
50 }
这个Logger配置完成了以下工作:
(1)将配置标识为dictConfig版本(version=1)。目前,这是唯一的dictConfig格式版本。
(2)定义了两个Formatter。
- 简单信息:仅输出日志级别名称(例如DEBUG)和日志消息。格式字符串是普通的Python格式字符串,描述了将在每条记录行上输出的详细信息。可在Formatter对象中找到可以输出的详细信息的完整列表。
- 详细信息:输出日志级别名称、日志消息、生成日志消息的时间、进程、线程和模块。
(3)定义了两个Filters。
- project.logging.SpecialFilter:使用特殊别名。如果此过滤器需要其他参数,则可以在过滤器配置字典中将它们作为其他关键字提供。
- django.utils.log.RequireDebugTrue:当DEBUG为True时,会传递记录。
(4)定义了两个Handler。
- 控制台:一个StreamHandler,它将任何INFO(或更高版本)消息输出到sys.stderr。该处理程序使用简单的输出格式。
- mail_admins:一个AdminEmailHandler,通过电子邮件将任何ERROR(或更高版本)消息发送到站点ADMINS。该处理程序使用特殊的过滤器。
(5)配置了3个Logger。
- django:该Logger将所有消息传递到控制台处理程序。
- django.request:该Logger将所有错误消息传递给mail_admins处理程序。另外,该记录器被标记为不传播消息,这意味着Logger将不会处理写入django.request的日志消息。
- myproject.custom:该Logger将所有信息传递到INFO或更高级别,还将特殊过滤器传递给两个处理程序——控制台和mail_admins。这意味着所有INFO级别的消息(或更高级别)将被打印到控制台,错误和严重消息也将通过电子邮件输出。
下面通过一个代码实例演示一下Logger的用法。首先,新建一个简单Django项目MyLogSite,然后创建一个简单的视图,通过该视图输出日志信息。具体代码如下:
【代码11-9】(详见源代码MyLogSite项目中的MyLogSite/views.py文件)
01 from django.http import HttpResponse
02
03 import logging
04 logger = logging.getLogger('django')
05
06 def index(request):
07 logger.info('info')
08 logger.error('error')
09 logger.warn('warn')
10 logger.debug('debug')
11 return HttpResponse("This is homepage!")
【代码分析】
在第03行代码中,通过import关键字引入了logging对象。
在第04行代码中,通过logging对象调用getLogger('django')方法获取logger对象。
在第06~11行代码定义的视图函数中,通过logger对象分别调用info()方法、error()方法、warn()方法和debug()方法输出日志信息。
最后,在项目配置文件settings.py中配置logger信息,具体代码如下:
【代码11-10】(详见源代码MyLogSite项目中的MyLogSite/settings.py文件)
01 BASE_LOG_DIR = os.path.join(BASE_DIR, "logs")
02
03 LOGGING = {
04 'version': 1,
05 'disable_existing_loggers': False,
06 'handlers': {
07 'file': {
08 'level': 'DEBUG',
09 'class': 'logging.FileHandler',
10 'filename': os.path.join(BASE_LOG_DIR, 'opt.log'),
11 },
12 },
13 'loggers': {
14 'django': {
15 'handlers': ['file'],
16 'level': 'DEBUG',
17 'propagate': True,
18 },
19 },
20 }
【代码分析】
在第01行代码中,配置了日志文件的输出目录BASE_LOG_DIR。注意,日志输出目录(logs)一般配置在项目根目录下。
第03~20行代码定义了Logger配置信息,与【代码11-7】基本一致。需要注意第10行代码中,通过前面定义的BASE_LOG_DIR参数指定了具体的日志信息文件opt.log。
如图11.2中的箭头和标识所示,Logger日志信息文件opt.log已经生成了。下面我们打开该日志文件查看一下,如图11.4中的箭头和标识所示,虽然Logger日志信息文件opt.log中输出了很多信息,但还是可以找到【代码11-9】中通过logger对象输出的调试信息。
图11.4 MyLogSite项目的日志信息(opt.log)文件