1
- # coding=utf-8
2
- import logging
3
-
4
- from starlette .middleware .base import BaseHTTPMiddleware , RequestResponseEndpoint
5
- from starlette .requests import Request
6
- from starlette .responses import Response
7
- from starlette .types import ASGIApp
8
-
9
- import json_logging
10
- import json_logging .framework
11
- from json_logging .framework_base import AppRequestInstrumentationConfigurator , RequestAdapter , ResponseAdapter
12
-
13
- from json_logging .util import is_not_match_any_pattern
14
-
15
1
16
2
def is_fastapi_present ():
17
3
# noinspection PyPep8,PyBroadException
@@ -24,114 +10,4 @@ def is_fastapi_present():
24
10
25
11
26
12
if is_fastapi_present ():
27
- import fastapi
28
- import starlette .requests
29
- import starlette .responses
30
-
31
-
32
- class JSONLoggingASGIMiddleware (BaseHTTPMiddleware ):
33
- def __init__ (self , app : ASGIApp , exclude_url_patterns = tuple ()) -> None :
34
- super ().__init__ (app )
35
- self .request_logger = logging .getLogger ('fastapi-request-logger' )
36
- self .exclude_url_patterns = exclude_url_patterns
37
- logging .getLogger ("uvicorn.access" ).propagate = False
38
-
39
- async def dispatch (self , request : Request , call_next : RequestResponseEndpoint ) -> Response :
40
- log_request = is_not_match_any_pattern (request .url .path , self .exclude_url_patterns )
41
-
42
- if not log_request :
43
- return await call_next (request )
44
-
45
- request_info = json_logging .RequestInfo (request )
46
- response = await call_next (request )
47
- request_info .update_response_status (response )
48
- self .request_logger .info (
49
- "" , extra = {"request_info" : request_info , "type" : "request" }
50
- )
51
- return response
52
-
53
-
54
- class FastAPIAppRequestInstrumentationConfigurator (AppRequestInstrumentationConfigurator ):
55
- def config (self , app , exclude_url_patterns = tuple ()):
56
- if not is_fastapi_present ():
57
- raise RuntimeError ("fastapi is not available in system runtime" )
58
- if not isinstance (app , fastapi .FastAPI ):
59
- raise RuntimeError ("app is not a valid fastapi.FastAPI instance" )
60
-
61
- # Disable standard logging
62
- logging .getLogger ('uvicorn.access' ).disabled = True
63
-
64
- # noinspection PyAttributeOutsideInit
65
- self .request_logger = logging .getLogger ('fastapi-request-logger' )
66
-
67
- app .add_middleware (JSONLoggingASGIMiddleware , exclude_url_patterns = exclude_url_patterns )
68
-
69
-
70
- class FastAPIRequestAdapter (RequestAdapter ):
71
- @staticmethod
72
- def get_request_class_type ():
73
- return starlette .requests .Request
74
-
75
- @staticmethod
76
- def support_global_request_object ():
77
- return False
78
-
79
- @staticmethod
80
- def get_current_request ():
81
- raise NotImplementedError
82
-
83
- def get_remote_user (self , request : starlette .requests .Request ):
84
- try :
85
- return request .user
86
- except AssertionError :
87
- return json_logging .EMPTY_VALUE
88
-
89
- def get_http_header (self , request : starlette .requests .Request , header_name , default = None ):
90
- try :
91
- if header_name in request .headers :
92
- return request .headers .get (header_name )
93
- except :
94
- pass
95
- return default
96
-
97
- def set_correlation_id (self , request_ , value ):
98
- request_ .state .correlation_id = value
99
-
100
- def get_correlation_id_in_request_context (self , request : starlette .requests .Request ):
101
- try :
102
- return request .state .correlation_id
103
- except AttributeError :
104
- return None
105
-
106
- def get_protocol (self , request : starlette .requests .Request ):
107
- protocol = str (request .scope .get ('type' , '' ))
108
- http_version = str (request .scope .get ('http_version' , '' ))
109
- if protocol .lower () == 'http' and http_version :
110
- return protocol .upper () + "/" + http_version
111
- return json_logging .EMPTY_VALUE
112
-
113
- def get_path (self , request : starlette .requests .Request ):
114
- return request .url .path
115
-
116
- def get_content_length (self , request : starlette .requests .Request ):
117
- return request .headers .get ('content-length' , json_logging .EMPTY_VALUE )
118
-
119
- def get_method (self , request : starlette .requests .Request ):
120
- return request .method
121
-
122
- def get_remote_ip (self , request : starlette .requests .Request ):
123
- return request .client .host
124
-
125
- def get_remote_port (self , request : starlette .requests .Request ):
126
- return request .client .port
127
-
128
-
129
- class FastAPIResponseAdapter (ResponseAdapter ):
130
- def get_status_code (self , response : starlette .responses .Response ):
131
- return response .status_code
132
-
133
- def get_response_size (self , response : starlette .responses .Response ):
134
- return response .headers .get ('content-length' , json_logging .EMPTY_VALUE )
135
-
136
- def get_content_type (self , response : starlette .responses .Response ):
137
- return response .headers .get ('content-type' , json_logging .EMPTY_VALUE )
13
+ from .implementation import FastAPIAppRequestInstrumentationConfigurator , FastAPIRequestAdapter , FastAPIResponseAdapter
0 commit comments