1+ import importlib
12import json
23import time
3- import re
4+ import uuid
5+
46from django .conf import settings
57from django .urls import resolve
68from django .utils import timezone
@@ -57,6 +59,19 @@ def __init__(self, get_response):
5759 settings .DRF_API_LOGGER_STATUS_CODES ) is list :
5860 self .DRF_API_LOGGER_STATUS_CODES = settings .DRF_API_LOGGER_STATUS_CODES
5961
62+ self .DRF_API_LOGGER_ENABLE_TRACING = False
63+ self .DRF_API_LOGGER_TRACING_ID_HEADER_NAME = None
64+ if hasattr (settings , 'DRF_API_LOGGER_ENABLE_TRACING' ):
65+ self .DRF_API_LOGGER_ENABLE_TRACING = settings .DRF_API_LOGGER_ENABLE_TRACING
66+ if self .DRF_API_LOGGER_ENABLE_TRACING and hasattr (settings , 'DRF_API_LOGGER_TRACING_ID_HEADER_NAME' ):
67+ self .DRF_API_LOGGER_TRACING_ID_HEADER_NAME = settings .DRF_API_LOGGER_TRACING_ID_HEADER_NAME
68+
69+ self .tracing_func_name = None
70+ if hasattr (settings , 'DRF_API_LOGGER_TRACING_FUNC' ):
71+ mod_name , func_name = settings .DRF_API_LOGGER_TRACING_FUNC .rsplit ('.' , 1 )
72+ mod = importlib .import_module (mod_name )
73+ self .tracing_func_name = getattr (mod , func_name )
74+
6075 def __call__ (self , request ):
6176
6277 # Run only if logger is enabled.
@@ -77,13 +92,31 @@ def __call__(self, request):
7792 if namespace in self .DRF_API_LOGGER_SKIP_NAMESPACE :
7893 return self .get_response (request )
7994
95+ # Code to be executed for each request/response after
96+ # the view is called.
97+
8098 start_time = time .time ()
99+
100+ headers = get_headers (request = request )
101+ method = request .method
102+
81103 request_data = ''
82104 try :
83105 request_data = json .loads (request .body ) if request .body else ''
84106 except :
85107 pass
86108
109+ tracing_id = None
110+ if self .DRF_API_LOGGER_ENABLE_TRACING :
111+ if self .DRF_API_LOGGER_TRACING_ID_HEADER_NAME :
112+ tracing_id = headers .get (self .DRF_API_LOGGER_TRACING_ID_HEADER_NAME )
113+ else :
114+ if self .tracing_func_name :
115+ tracing_id = self .tracing_func_name ()
116+ else :
117+ tracing_id = str (uuid .uuid4 ())
118+ request .tracing_id = tracing_id
119+
87120 # Code to be executed for each request before
88121 # the view (and later middleware) are called.
89122 response = self .get_response (request )
@@ -92,18 +125,13 @@ def __call__(self, request):
92125 if self .DRF_API_LOGGER_STATUS_CODES and response .status_code not in self .DRF_API_LOGGER_STATUS_CODES :
93126 return response
94127
95- # Code to be executed for each request/response after
96- # the view is called.
97-
98- headers = get_headers (request = request )
99- method = request .method
100-
101128 # Log only registered methods if available.
102129 if len (self .DRF_API_LOGGER_METHODS ) > 0 and method not in self .DRF_API_LOGGER_METHODS :
103130 return response
104131
105- if response .get ('content-type' ) in ('application/json' , 'application/vnd.api+json' , 'application/gzip' , 'application/octet-stream' ):
106-
132+ if response .get ('content-type' ) in (
133+ 'application/json' , 'application/vnd.api+json' , 'application/gzip' , 'application/octet-stream' ):
134+
107135 if response .get ('content-type' ) == 'application/gzip' :
108136 response_body = '** GZIP Archive **'
109137 elif response .get ('content-type' ) == 'application/octet-stream' :
@@ -144,6 +172,10 @@ def __call__(self, request):
144172 d ['response' ] = json .dumps (d ['response' ], indent = 4 , ensure_ascii = False )
145173 LOGGER_THREAD .put_log_data (data = d )
146174 if self .DRF_API_LOGGER_SIGNAL :
175+ if tracing_id :
176+ data .update ({
177+ 'tracing_id' : tracing_id
178+ })
147179 API_LOGGER_SIGNAL .listen (** data )
148180 else :
149181 return response
0 commit comments