root: show location header in logs when redirecting

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-09-07 11:04:00 +02:00
parent 70d0dd51a5
commit eeb755ab7d
1 changed files with 16 additions and 9 deletions

View File

@ -19,22 +19,24 @@ class ASGILogger:
app: ASGIApp app: ASGIApp
status_code: int
start: float
def __init__(self, app: ASGIApp): def __init__(self, app: ASGIApp):
self.app = app self.app = app
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
content_length = 0 content_length = 0
status_code = 0
request_id = "" request_id = ""
location = ""
start = time()
async def send_hooked(message: Message) -> None: async def send_hooked(message: Message) -> None:
"""Hooked send method, which records status code and content-length, and for the final """Hooked send method, which records status code and content-length, and for the final
requests logs it""" requests logs it"""
headers = dict(message.get("headers", [])) headers = dict(message.get("headers", []))
if "status" in message: if "status" in message:
self.status_code = message["status"] nonlocal status_code
status_code = message["status"]
if b"Content-Length" in headers: if b"Content-Length" in headers:
nonlocal content_length nonlocal content_length
@ -43,14 +45,19 @@ class ASGILogger:
if message["type"] == "http.response.start": if message["type"] == "http.response.start":
response_headers = dict(message["headers"]) response_headers = dict(message["headers"])
nonlocal request_id nonlocal request_id
nonlocal location
request_id = response_headers.get(RESPONSE_HEADER_ID.encode(), b"").decode() request_id = response_headers.get(RESPONSE_HEADER_ID.encode(), b"").decode()
location = response_headers.get(b"Location", b"").decode()
if message["type"] == "http.response.body" and not message.get("more_body", True): if message["type"] == "http.response.body" and not message.get("more_body", True):
runtime = int((time() - self.start) * 1000) nonlocal start
self.log(scope, runtime, content_length, request_id=request_id) runtime = int((time() - start) * 1000)
kwargs = {"request_id": request_id}
if location != "":
kwargs["location"] = location
self.log(scope, runtime, content_length, status_code, **kwargs)
await send(message) await send(message)
self.start = time()
if scope["type"] == "lifespan": if scope["type"] == "lifespan":
# https://code.djangoproject.com/ticket/31508 # https://code.djangoproject.com/ticket/31508
# https://github.com/encode/uvicorn/issues/266 # https://github.com/encode/uvicorn/issues/266
@ -68,7 +75,7 @@ class ASGILogger:
# Check if header has multiple values, and use the first one # Check if header has multiple values, and use the first one
return client_ip.split(", ")[0] return client_ip.split(", ")[0]
def log(self, scope: Scope, content_length: int, runtime: float, **kwargs): def log(self, scope: Scope, content_length: int, runtime: float, status_code: int, **kwargs):
"""Outpot access logs in a structured format""" """Outpot access logs in a structured format"""
host = self._get_ip(scope) host = self._get_ip(scope)
query_string = "" query_string = ""
@ -79,7 +86,7 @@ class ASGILogger:
host=host, host=host,
method=scope.get("method", ""), method=scope.get("method", ""),
scheme=scope.get("scheme", ""), scheme=scope.get("scheme", ""),
status=self.status_code, status=status_code,
size=content_length / 1000 if content_length > 0 else 0, size=content_length / 1000 if content_length > 0 else 0,
runtime=runtime, runtime=runtime,
**kwargs, **kwargs,