简介
在开发大型系统的时候,往往是进行微服务化,变成了多个系统之间的交互。快速迭代你会发现线上的系统很多很复杂,这时候一个用户请求过来会经过很多内部系统,如果这时候发生错误,我们去查看日志的时候,根本不知道,哪个错误来自哪一个用户,这时候我们给每一个请求加上一个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便于定位问题