Skip to content

Commit 9fea59b

Browse files
author
harvey_xiang
committed
feat: add request log
1 parent 7d7f731 commit 9fea59b

File tree

2 files changed

+57
-6
lines changed

2 files changed

+57
-6
lines changed

src/memos/api/middleware/request_context.py

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Request context middleware for automatic trace_id injection.
33
"""
44

5+
import json
56
import time
67

78
from collections.abc import Callable
@@ -26,6 +27,43 @@ def extract_trace_id_from_headers(request: Request) -> str | None:
2627
return None
2728

2829

30+
async def get_request_params(request: Request) -> tuple[dict, bytes | None]:
31+
"""
32+
Extract request parameters (query params and body) for logging.
33+
34+
Args:
35+
request: The incoming request object
36+
37+
Returns:
38+
Tuple of (params_dict, body_bytes). body_bytes is None if body was not read.
39+
"""
40+
params_log = {}
41+
42+
# Get query parameters
43+
if request.query_params:
44+
params_log["query_params"] = dict(request.query_params)
45+
46+
# Get request body for requests with body
47+
body_bytes = None
48+
content_type = request.headers.get("content-type", "")
49+
if request.method in ("POST", "PUT", "PATCH", "DELETE") and content_type:
50+
try:
51+
body_bytes = await request.body()
52+
if body_bytes:
53+
if "application/json" in content_type.lower():
54+
try:
55+
params_log["body"] = json.loads(body_bytes)
56+
except (json.JSONDecodeError, UnicodeDecodeError) as e:
57+
params_log["body"] = f"<unable to parse JSON: {e!s}>"
58+
else:
59+
# For non-JSON requests, log body size only
60+
params_log["body_size"] = len(body_bytes)
61+
except Exception as e:
62+
logger.error(f"Failed to read request body: {e}")
63+
64+
return params_log, body_bytes
65+
66+
2967
class RequestContextMiddleware(BaseHTTPMiddleware):
3068
"""
3169
Middleware to automatically inject request context for every HTTP request.
@@ -55,14 +93,22 @@ async def dispatch(self, request: Request, call_next: Callable) -> Response:
5593
)
5694
set_request_context(context)
5795

58-
# Log request start with parameters
59-
params_log = {}
96+
# Get request parameters for logging
97+
params_log, body_bytes = await get_request_params(request)
6098

61-
# Get query parameters
62-
if request.query_params:
63-
params_log["query_params"] = dict(request.query_params)
99+
# Re-create the request receive function if body was read
100+
# This ensures downstream handlers can still read the body
101+
if body_bytes is not None:
64102

65-
logger.info(f"Request started, params: {params_log}, headers: {request.headers}")
103+
async def receive():
104+
return {"type": "http.request", "body": body_bytes, "more_body": False}
105+
106+
request._receive = receive
107+
108+
logger.info(
109+
f"Request started, method: {request.method}, path: {request.url.path}, "
110+
f"request params: {params_log}, headers: {request.headers}"
111+
)
66112

67113
# Process the request
68114
try:

src/memos/api/routers/server_router.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@ def _search_pref():
387387
memories_result, pref_formatted_memories, search_req.mem_cube_id, search_req.handle_pref_mem
388388
)
389389

390+
logger.info(f"Search memories result: {memories_result}")
391+
390392
return SearchResponse(
391393
message="Search completed successfully",
392394
data=memories_result,
@@ -538,6 +540,9 @@ def _process_pref_mem() -> list[dict[str, str]]:
538540
text_response_data = text_future.result()
539541
pref_response_data = pref_future.result()
540542

543+
logger.info(f"add_memories Text response data: {text_response_data}")
544+
logger.info(f"add_memories Pref response data: {pref_response_data}")
545+
541546
return MemoryResponse(
542547
message="Memory added successfully",
543548
data=text_response_data + pref_response_data,

0 commit comments

Comments
 (0)