Django搭建适用于自己项目的logging系统

django的日志系统是基于python的Logging模块来搭建的

日志系统分为4个部分

① loggers:用户使用的一个日志接口,将日志传递给handlers进行处理

② handlers:用于处理loggers的程序,控制日志输出到哪里,可以是文件,也可以是console。

③ Filters:过滤日志等级的程序,控制一定等级的日志进入handlers进行处理

④ Formatters :用于格式化日志

他们的级别排序:CRITICAL > ERROR > WARNING > INFO > DEBUG


下面来分别学习下这四个部分:

一、loggers:

主要有5中基本的日志等级,当然也可以自己定义一个日志等级

1
2
3
4
5
6
7
8
9
DEBUG: Low level system information for debugging purposes

INFO: General system information

WARNING: Information describing a minor problem that has occurred.

ERROR: Information describing a major problem that has occurred.

CRITICAL: Information describing a critical problem that has occurred.

二、Handlers

它是一个处理日志的引擎,描述了日志的行为,将日志可以输出到文件或者控制台上。

注:如果日志的等级不符合(低于)处理日志程序的等级,那么处理程序将会忽略该日志。

三、Filters

它主要用来提供额外的控制条件限制,比如控制该日志只能来源于某一个源的错误消息,将该错误消息发送给Handlers,
而其他的消息将被过滤掉。同时,它也可以对满足一定条件的错误日志,过滤降级为警告日志。

四、Formatters

因为最终日志是以文本的形式展现给开发者,所以必须对日志进行格式化,精确的记录日志行为。

具体的格式化属性参考官方文档:

https://docs.python.org/3/library/logging.html


介绍完日志的四个部分,接下来就是如何使用日志

比较简单的一种使用行为:

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# 错误日志文件夹
BASE_DIR_LOG = os.path.join(BASE_DIR, 'Logs')

LOGGING = {
'version': 1, # 指明dictConfig的版本,目前就只有一个版本
'disable_existing_loggers': True, # 禁用所有的已经存在的日志配置
'formatters': { # 格式器
'verbose': { # 详细的,包括日志等级名,时间,模块,进程,线程和消息
'format': '%(levelname)s - %(asctime)s - %(module)s - %(funcName)s - %(process)d - %(thread)d - %(message)s',
},
'simple': { # 简单的格式化
'format': '%(levelname)s - %(funcName)s - %(message)s',
},
},
'filters': { # 过滤器
'require_debug_true': { # 当debug为True的时候,记录
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': { # 处理器,在这里定义了三个处理器
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple',
},
'consumer_handlers': { # 将error等级的日志写到error文件中
'level': 'ERROR',
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'verbose', # 详细记录
'filename': os.path.join(BASE_DIR_LOG, 'consumer_error.log'),
'maxBytes': 1024 * 1024 * 50, # 日志大小50M
'backupCount': 3, # 备份数量
},
'shopper_handlers': {
'level': 'ERROR',
# 'filters': ['require_debug_true'],
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'verbose',
'filename': os.path.join(BASE_DIR_LOG, 'shopper_error.log'),
'maxBytes': 1024 * 1024 * 50, # 日志大小50M,
'backupCount': 3,
},
'order_handlers': {
'level': 'ERROR',
# 'filters': ['require_debug_true'],
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'verbose',
'filename': os.path.join(BASE_DIR_LOG, 'order_error.log'),
'maxBytes': 1024 * 1024 * 50, # 日志大小50M,
'backupCount': 3,
},
'trolley_handlers': {
'level': 'ERROR',
# 'filters': ['require_debug_true'],
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'verbose',
'filename': os.path.join(BASE_DIR_LOG, 'trolley_error.log'),
'maxBytes': 1024 * 1024 * 50, # 日志大小50M,
'backupCount': 3,
},
'commodity_handlers': {
'level': 'ERROR',
# 'filters': ['require_debug_true'],
'class': 'logging.handlers.RotatingFileHandler',
'formatter': 'verbose',
'filename': os.path.join(BASE_DIR_LOG, 'commodity_error.log'),
'maxBytes': 1024 * 1024 * 50, # 日志大小50M,
'backupCount': 3,
},

},
'loggers': { # 定义了二个记录器
# 默认的logger配置,捕捉一切debug即以上的信息
'django': {
'handlers': ['console',],
'propagate': True,
'level': 'DEBUG',
},
'consumer_': {
'handlers': ['consumer_handlers',],
'propagate': False, # 是否向更高级别的logger传递
'level': 'ERROR',
},
'shopper_': {
'handlers': ['shopper_handlers',],
'level': 'ERROR',
'propagate': False,
},
'order_': {
'handlers': ['order_handlers',],
'level': 'ERROR',
'propagate': False,
},
'trolley_': {
'handlers': ['trolley_handlers',],
'level': 'ERROR',
'propagate': False,
},
'commodity_': {
'handlers': ['commodity_handlers',],
'level': 'ERROR',
'propagate': False,
},
},
}

测试日志

1
2
3
4
5
6
7
8
9
10
class test(APIView):
def post(self,request):
name = request.data.get('name')
if name == 'syz':
logger.error('eee')
return JsonResponse(response_code.server_error)

def get(self,request):
common_logger.info('rr')
return JsonResponse(response_code.server_error)

结果:

日志文件里的信息

ERROR:

1
2
ERROR - 2020-04-08 09:33:53,288 - shppoer_register_api - post - 13652 - 16904 - eee
ERROR - 2020-04-08 09:35:12,561 - shppoer_register_api - post - 10880 - 19536 - eee

控制台的信息:

DEBUG即以上

1
2
INFO - log_message - "GET /shopper/test HTTP/1.1" 301 0
INFO - log_message - "GET /shopper/test/ HTTP/1.1" 200 67