简介
在开发大型系统的时候,往往是进行微服务化,变成了多个系统之间的交互。快速迭代你会发现线上的系统很多很复杂,这时候一个用户请求过来会经过很多内部系统,如果这时候发生错误,我们去查看日志的时候,根本不知道,哪个错误来自哪一个用户,这时候我们给每一个请求加上一个Request ID就可以很好的区分了。
django-log-request-id
这个项目为我们提供了轮子,直接使用即可
github: https://github.com/dabapps/django-log-request-id
安装
1
|
pip install django-log-request- id |
添加middleware
需要加在其它middleware前面
1
2
3
4
|
MIDDLEWARE_CLASSES = ( 'log_request_id.middleware.RequestIDMiddleware' , # ... other middleware goes here ) |
header中添加RequestID
1
2
3
|
LOG_REQUEST_ID_HEADER = "HTTP_X_REQUEST_ID" GENERATE_REQUEST_ID_IF_NOT_IN_HEADER = True REQUEST_ID_RESPONSE_HEADER = "RESPONSE_HEADER_NAME" |
日志中添加RequestID
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
|
LOGGING = { 'version' : 1 , 'disable_existing_loggers' : False , 'filters' : { 'request_id' : { '()' : 'log_request_id.filters.RequestIDFilter' } }, 'formatters' : { 'standard' : { 'format' : '%(levelname)-8s [%(asctime)s] [%(request_id)s] %(name)s: %(message)s' }, }, 'handlers' : { 'console' : { 'level' : 'DEBUG' , 'class' : 'logging.StreamHandler' , 'filters' : [ 'request_id' ], 'formatter' : 'standard' , }, }, 'loggers' : { 'myapp' : { 'handlers' : [ 'console' ], 'level' : 'DEBUG' , 'propagate' : False , }, } } |
给Django日志加上request_id
用来标识同一个请求的日志,方便检索和分析。
request_id用uuid自动生成。如果请求头有X-Request-ID,就用请求头的,这样一个请求涉及多个服务调用的时候可以把request_id带过去,标识为同一个请求的request_id.
下面是代码示例。
在一个文件中自定义Middleware和Logging Filter.
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
|
import logging import threading import uuid from django.utils.deprecation import MiddlewareMixin local = threading.local() class RequestIDFilter(logging. Filter ): def filter ( self , record): record.request_id = getattr (local, 'request_id' , "none" ) return True class RequestIDMiddleware(MiddlewareMixin): def process_request( self , request): local.request_id = request.META.get( 'HTTP_X_REQUEST_ID' , uuid.uuid4(). hex ) def process_response( self , request, response): if hasattr (request, 'request_id' ): response[ 'X-Request-ID' ] = local.request_id try : del local.request_id except AttributeError: pass return response |
然后在settings.py中引用.
LOGGING配置示例
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
|
LOGGING = { 'filters' : { 'request_id' : { # 自定义的filter '()' : 'xxx.middlewares.RequestIDFilter' } }, 'formatters' : { 'standard' : { 'format' : '%(levelname)s [%(asctime)s] [%(request_id)s] %(name)s: %(message)s' # 这里使用filter request_id里的request_id字段 }, }, 'handlers' : { 'console' : { 'level' : 'DEBUG' , 'class' : 'logging.StreamHandler' , 'filters' : [ 'request_id' ], # 这里使用上面的filter: request_id 'formatter' : 'standard' , # 这里使用上面的formatter: standard }, }, 'loggers' : { 'xxx' : { 'handlers' : [ 'console' ], # 这里使用上面的handler: console 'level' : 'DEBUG' , 'propagate' : False , }, } } |
ok, 现在代码里用logging打的日志就会带上request_id了.
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:http://carey.akhack.com/2018/08/24/django使用request-id便于定位问题