Skip to content

Commit 0d83d6c

Browse files
author
Dmytro Trotsko
committed
Updated request logger middleware to use structured logger
1 parent 0cc6be7 commit 0d83d6c

File tree

1 file changed

+4
-40
lines changed

1 file changed

+4
-40
lines changed

src/epiportal/middleware.py

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
Request logging middleware that captures comprehensive data from all HTTP requests.
33
"""
44

5-
import logging
65
import time
76
import uuid
87
from typing import Any
98

9+
from delphi_utils import get_structured_logger
1010
from django.utils.deprecation import MiddlewareMixin
1111

1212
from epiportal.utils import get_client_ip
1313

14-
logger = logging.getLogger("epiportal.requests")
14+
logger = get_structured_logger("epiportal.requests")
1515

1616
# Headers that may contain sensitive data - values will be redacted
1717
SENSITIVE_HEADERS = frozenset(
@@ -27,9 +27,6 @@
2727
)
2828
)
2929

30-
# Maximum bytes of request/response body to log (prevents log bloat)
31-
MAX_BODY_LOG_SIZE = 4096
32-
3330
# Path segments to exclude from request logging (matched anywhere in path)
3431
LOG_EXCLUDE_PATH_PATTERNS = (
3532
# "get_table_stats_info",
@@ -57,19 +54,6 @@ def _sanitize_headers(meta: dict) -> dict[str, str]:
5754
return headers
5855

5956

60-
def _safe_body_preview(body: bytes | None, max_size: int = MAX_BODY_LOG_SIZE) -> str | None:
61-
"""Return a safe preview of request/response body, truncated if large."""
62-
if body is None or len(body) == 0:
63-
return None
64-
try:
65-
decoded = body.decode("utf-8", errors="replace")
66-
if len(decoded) > max_size:
67-
return decoded[:max_size] + f"... [truncated, total {len(body)} bytes]"
68-
return decoded
69-
except Exception:
70-
return f"[binary, {len(body)} bytes]"
71-
72-
7357
class RequestLoggingMiddleware(MiddlewareMixin):
7458
"""
7559
Middleware that logs every HTTP request with comprehensive request and response data.
@@ -120,31 +104,11 @@ def process_response(self, request, response):
120104
else:
121105
log_data["user"] = "anonymous"
122106

123-
# Request body (for methods that typically have one)
124-
if request.method in ("POST", "PUT", "PATCH"):
125-
try:
126-
body = getattr(request, "_body", None) or request.body
127-
log_data["request_body_preview"] = _safe_body_preview(body)
128-
except Exception as e:
129-
log_data["request_body_error"] = str(e)
130-
131-
# Response body (for API responses, avoid huge HTML)
132-
if (
133-
"application/json" in (response.get("Content-Type") or "")
134-
and hasattr(response, "content")
135-
):
136-
log_data["response_body_preview"] = _safe_body_preview(response.content)
137-
138107
if duration_ms is not None:
139108
log_data["duration_ms"] = round(duration_ms, 2)
140109

141-
logger.info(
142-
"%s %s %s",
143-
request.method,
144-
request.path,
145-
response.status_code,
146-
extra=log_data,
147-
)
110+
log_data["message"] = f"{request.method} {request.path} {response.status_code}"
111+
logger.info("request", **log_data)
148112

149113
except Exception as e:
150114
logger.exception("Error in request logging middleware: %s", e)

0 commit comments

Comments
 (0)