114 HTTP scopes are intercepted and logged. All other scope types
115 (``"websocket"``, ``"lifespan"``) are passed through unchanged.
120 if scope[
"type"] !=
"http":
121 await self.
_app(scope, receive, send)
128 method = scope.get(
"method",
"?")
129 path = scope.get(
"path",
"/")
130 query = scope.get(
"query_string", b
"").decode(
"utf-8", errors=
"replace")
131 full_path = f
"{path}?{query}" if query
else path
132 client = scope.get(
"client")
133 client_ip = f
"{client[0]}:{client[1]}" if client
else "unknown"
139 f
"START {method} {full_path} client={client_ip}",
145 headers_raw = scope.get(
"headers", [])
146 header_map = {k.lower(): v
for k, v
in headers_raw}
147 user_agent = header_map.get(b
"user-agent", b
"").decode(
"utf-8", errors=
"replace")
149 _dbg(self.
_domain, func, f
"User-Agent: {user_agent}", level=3)
155 for key, value
in scope.get(
"headers", []):
156 header_name = key.decode(
"utf-8", errors=
"replace").lower()
159 if header_name
in _ud.HTTP_REDACT_HEADERS
160 else value.decode(
"utf-8", errors=
"replace")
165 f
"req-header {header_name}: {display_value}",
174 start = time.perf_counter()
175 status_holder = [
None]
177 async def _send_with_capture(message):
178 if message[
"type"] ==
"http.response.start":
179 status_holder[0] = message.get(
"status")
182 for key, value
in message.get(
"headers", []):
183 header_name = key.decode(
"utf-8", errors=
"replace").lower()
186 if header_name
in _ud.HTTP_REDACT_HEADERS
187 else value.decode(
"utf-8", errors=
"replace")
192 f
"resp-header {header_name}: {display_value}",
203 await self.
_app(scope, receive, _send_with_capture)
204 except Exception
as exc:
205 elapsed_ms = (time.perf_counter() - start) * 1000
209 f
"ERROR {method} {full_path} [{elapsed_ms:.1f}ms] "
210 f
"{type(exc).__name__}: {exc}",
218 elapsed_ms = (time.perf_counter() - start) * 1000
219 status = status_holder[0]
if status_holder[0]
is not None else "?"
223 f
"END {method} {full_path} -> {status} [{elapsed_ms:.1f}ms]",
229 if isinstance(status, int):
231 _dbg(self.
_domain, func, f
"5xx server error: {status}", level=3)
233 _dbg(self.
_domain, func, f
"4xx client error: {status}", level=3)