@@ -98,44 +98,46 @@ def init_non_web(*args, **kw):
98
98
__init (* args , ** kw )
99
99
100
100
101
- class RequestResponseDataExtractorBase (dict ):
101
+ class RequestResponseDTOBase (dict ):
102
102
"""
103
- class that keep HTTP request information for request instrumentation logging
103
+ Data transfer object for HTTP request & response information for request instrumentation logging
104
+ Any key that is stored in this dict will be appended to final JSON log object
104
105
"""
105
106
106
107
def __init__ (self , request , ** kwargs ):
107
- super (RequestResponseDataExtractorBase , self ).__init__ (** kwargs )
108
+ """
109
+ invoked when request start, where to extract any necessary information from the request object
110
+ :param request: request object
111
+ """
112
+ super (RequestResponseDTOBase , self ).__init__ (** kwargs )
113
+ self ._request = request
108
114
109
- def update_response_status (self , response ):
110
- pass
115
+ def on_request_complete (self , response ):
116
+ """
117
+ invoked when request complete, update response information into this object, must be called before invoke request logging statement
118
+ :param response: response object
119
+ """
120
+ self ._response = response
111
121
112
122
113
- class RequestResponseDataExtractor ( RequestResponseDataExtractorBase ):
123
+ class DefaultRequestResponseDTO ( RequestResponseDTOBase ):
114
124
"""
115
125
default implementation
116
126
"""
117
127
118
128
def __init__ (self , request , ** kwargs ):
119
- super (RequestResponseDataExtractor , self ).__init__ (request , ** kwargs )
129
+ super (DefaultRequestResponseDTO , self ).__init__ (request , ** kwargs )
120
130
utcnow = datetime .utcnow ()
121
- self .request_start = utcnow
122
- self .request = request
123
- self .request_received_at = util .iso_time_format (utcnow )
131
+ self ._request_start = utcnow
132
+ self ["request_received_at" ] = util .iso_time_format (utcnow )
124
133
125
134
# noinspection PyAttributeOutsideInit
126
- def update_response_status (self , response ):
127
- """
128
- update response information into this object, must be called before invoke request logging statement
129
- :param response:
130
- """
131
- response_adapter = _request_util .response_adapter
135
+ def on_request_complete (self , response ):
136
+ super (DefaultRequestResponseDTO , self ).on_request_complete (response )
132
137
utcnow = datetime .utcnow ()
133
- time_delta = utcnow - self .request_start
134
- self .response_time_ms = int (time_delta .total_seconds ()) * 1000 + int (time_delta .microseconds / 1000 )
135
- self .response_status = response_adapter .get_status_code (response )
136
- self .response_size_b = response_adapter .get_response_size (response )
137
- self .response_content_type = response_adapter .get_content_type (response )
138
- self .response_sent_at = util .iso_time_format (utcnow )
138
+ time_delta = utcnow - self ._request_start
139
+ self ["response_time_ms" ] = int (time_delta .total_seconds ()) * 1000 + int (time_delta .microseconds / 1000 )
140
+ self ["response_sent_at" ] = util .iso_time_format (utcnow )
139
141
140
142
141
143
def __init (framework_name = None , custom_formatter = None , enable_json = False ):
@@ -194,7 +196,7 @@ def __init(framework_name=None, custom_formatter=None, enable_json=False):
194
196
195
197
196
198
def init_request_instrument (app = None , custom_formatter = None , exclude_url_patterns = [],
197
- request_response_data_extractor_class = RequestResponseDataExtractor ):
199
+ request_response_data_extractor_class = DefaultRequestResponseDTO ):
198
200
"""
199
201
Configure the request instrumentation logging configuration for given web app. Must be called after init method
200
202
@@ -212,8 +214,9 @@ def init_request_instrument(app=None, custom_formatter=None, exclude_url_pattern
212
214
if not issubclass (custom_formatter , logging .Formatter ):
213
215
raise ValueError ('custom_formatter is not subclass of logging.Formatter' , custom_formatter )
214
216
215
- if not issubclass (request_response_data_extractor_class , RequestResponseDataExtractorBase ):
216
- raise ValueError ('request_response_data_extractor_class is not subclass of json_logging.RequestInfoBase' , custom_formatter )
217
+ if not issubclass (request_response_data_extractor_class , RequestResponseDTOBase ):
218
+ raise ValueError ('request_response_data_extractor_class is not subclass of json_logging.RequestInfoBase' ,
219
+ custom_formatter )
217
220
218
221
configurator = _current_framework ['app_request_instrumentation_configurator' ]()
219
222
configurator .config (app , request_response_data_extractor_class , exclude_url_patterns = exclude_url_patterns )
@@ -275,10 +278,13 @@ class JSONRequestLogFormatter(BaseJSONFormatter):
275
278
276
279
def _format_log_object (self , record , request_util ):
277
280
json_log_object = super (JSONRequestLogFormatter , self )._format_log_object (record , request_util )
278
- request = record .request_info .request
279
281
request_adapter = request_util .request_adapter
282
+ response_adapter = _request_util .response_adapter
283
+ request = record .request_response_data ._request
284
+ response = record .request_response_data ._response
280
285
281
286
length = request_adapter .get_content_length (request )
287
+
282
288
json_log_object .update ({
283
289
"type" : "request" ,
284
290
"correlation_id" : request_util .get_correlation_id (request ),
@@ -292,13 +298,13 @@ def _format_log_object(self, record, request_util):
292
298
"request_size_b" : util .parse_int (length , - 1 ),
293
299
"remote_host" : request_adapter .get_remote_ip (request ),
294
300
"remote_port" : request_adapter .get_remote_port (request ),
295
- "request_received_at" : record .request_info .request_received_at ,
296
- "response_time_ms" : record .request_info .response_time_ms ,
297
- "response_status" : record .request_info .response_status ,
298
- "response_size_b" : record .request_info .response_size_b ,
299
- "response_content_type" : record .request_info .response_content_type ,
300
- "response_sent_at" : record .request_info .response_sent_at
301
+ "response_status" : response_adapter .get_status_code (response ),
302
+ "response_size_b" : response_adapter .get_response_size (response ),
303
+ "response_content_type" : response_adapter .get_content_type (response ),
301
304
})
305
+
306
+ json_log_object .update (record .request_response_data )
307
+
302
308
return json_log_object
303
309
304
310
0 commit comments