@@ -98,6 +98,46 @@ def init_non_web(*args, **kw):
9898 __init (* args , ** kw )
9999
100100
101+ class RequestResponseDataExtractorBase (dict ):
102+ """
103+ class that keep HTTP request information for request instrumentation logging
104+ """
105+
106+ def __init__ (self , request , ** kwargs ):
107+ super (RequestResponseDataExtractorBase , self ).__init__ (** kwargs )
108+
109+ def update_response_status (self , response ):
110+ pass
111+
112+
113+ class RequestResponseDataExtractor (RequestResponseDataExtractorBase ):
114+ """
115+ default implementation
116+ """
117+
118+ def __init__ (self , request , ** kwargs ):
119+ super (RequestResponseDataExtractor , self ).__init__ (request , ** kwargs )
120+ utcnow = datetime .utcnow ()
121+ self .request_start = utcnow
122+ self .request = request
123+ self .request_received_at = util .iso_time_format (utcnow )
124+
125+ # 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
132+ 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 )
139+
140+
101141def __init (framework_name = None , custom_formatter = None , enable_json = False ):
102142 """
103143 Initialize JSON logging support, if no **framework_name** passed, logging will be initialized in non-web context.
@@ -153,14 +193,16 @@ def __init(framework_name=None, custom_formatter=None, enable_json=False):
153193 util .update_formatter_for_loggers (existing_loggers , _default_formatter )
154194
155195
156- def init_request_instrument (app = None , custom_formatter = None , exclude_url_patterns = []):
196+ def init_request_instrument (app = None , custom_formatter = None , exclude_url_patterns = [],
197+ request_response_data_extractor_class = RequestResponseDataExtractor ):
157198 """
158199 Configure the request instrumentation logging configuration for given web app. Must be called after init method
159200
160201 If **custom_formatter** is passed, it will use this formatter over the default.
161202
162203 :param app: current web application instance
163204 :param custom_formatter: formatter to override default JSONRequestLogFormatter.
205+ :param request_response_data_extractor_class: requestinfo to override default json_logging.RequestInfo.
164206 """
165207
166208 if _current_framework is None or _current_framework == '-' :
@@ -170,8 +212,11 @@ def init_request_instrument(app=None, custom_formatter=None, exclude_url_pattern
170212 if not issubclass (custom_formatter , logging .Formatter ):
171213 raise ValueError ('custom_formatter is not subclass of logging.Formatter' , custom_formatter )
172214
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+
173218 configurator = _current_framework ['app_request_instrumentation_configurator' ]()
174- configurator .config (app , exclude_url_patterns = exclude_url_patterns )
219+ configurator .config (app , request_response_data_extractor_class , exclude_url_patterns = exclude_url_patterns )
175220
176221 formatter = custom_formatter if custom_formatter else JSONRequestLogFormatter
177222 request_logger = configurator .request_logger
@@ -182,8 +227,6 @@ def init_request_instrument(app=None, custom_formatter=None, exclude_url_pattern
182227
183228
184229def get_request_logger ():
185- global _request_logger
186-
187230 if _current_framework is None or _current_framework == '-' :
188231 raise RuntimeError (
189232 "request_logger is only available if json_logging is inited with a web app, "
@@ -196,34 +239,6 @@ def get_request_logger():
196239 return instance .request_logger
197240
198241
199- class RequestInfo (dict ):
200- """
201- class that keep HTTP request information for request instrumentation logging
202- """
203-
204- def __init__ (self , request , ** kwargs ):
205- super (RequestInfo , self ).__init__ (** kwargs )
206- utcnow = datetime .utcnow ()
207- self .request_start = utcnow
208- self .request = request
209- self .request_received_at = util .iso_time_format (utcnow )
210-
211- # noinspection PyAttributeOutsideInit
212- def update_response_status (self , response ):
213- """
214- update response information into this object, must be called before invoke request logging statement
215- :param response:
216- """
217- response_adapter = _request_util .response_adapter
218- utcnow = datetime .utcnow ()
219- time_delta = utcnow - self .request_start
220- self .response_time_ms = int (time_delta .total_seconds ()) * 1000 + int (time_delta .microseconds / 1000 )
221- self .response_status = response_adapter .get_status_code (response )
222- self .response_size_b = response_adapter .get_response_size (response )
223- self .response_content_type = response_adapter .get_content_type (response )
224- self .response_sent_at = util .iso_time_format (utcnow )
225-
226-
227242class BaseJSONFormatter (logging .Formatter ):
228243 """
229244 Base class for JSON formatters
@@ -406,5 +421,6 @@ def init_connexion(custom_formatter=None, enable_json=False):
406421 request_adapter_class = fastapi_support .FastAPIRequestAdapter ,
407422 response_adapter_class = fastapi_support .FastAPIResponseAdapter )
408423
424+
409425def init_fastapi (custom_formatter = None , enable_json = False ):
410426 __init (framework_name = 'fastapi' , custom_formatter = custom_formatter , enable_json = enable_json )
0 commit comments