From ea676a56b93205b02d0a2fc3b7dbf75a298466a7 Mon Sep 17 00:00:00 2001 From: Daniel Fernandes Date: Fri, 26 Jun 2026 13:16:11 +0000 Subject: [PATCH 1/4] Only log PUT and POST requests as info --- src/blueapi/service/main.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/blueapi/service/main.py b/src/blueapi/service/main.py index 432cc54550..631b62a4ae 100644 --- a/src/blueapi/service/main.py +++ b/src/blueapi/service/main.py @@ -594,9 +594,15 @@ def start(config: ApplicationConfig): async def log_request_details( request: Request, call_next: Callable[[Request], Awaitable[StreamingResponse]] ) -> Response: - """Middleware to log all request's host, method, path, status and request and - body""" - log = LOGGER.debug if request.url.path == "/healthz" else LOGGER.info + """Middleware to log request's host, method, path, status and request and + body + + Logs POST and PUT as info, all else as debug.""" + log = ( + LOGGER.info + if request.method == "POST" or request.method == "PUT" + else LOGGER.debug + ) request_body = await request.body() client = request.client or Address("Unknown", -1) log_message = f"{client.host}:{client.port} {request.method} {request.url.path}" From 0d76cbba360815332821f500ae6f4d0a1d92f5c5 Mon Sep 17 00:00:00 2001 From: Daniel Fernandes Date: Fri, 26 Jun 2026 13:48:45 +0000 Subject: [PATCH 2/4] Remove duplicate logs for GET requests --- src/blueapi/service/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/blueapi/service/main.py b/src/blueapi/service/main.py index 631b62a4ae..0215c12dd0 100644 --- a/src/blueapi/service/main.py +++ b/src/blueapi/service/main.py @@ -609,7 +609,8 @@ async def log_request_details( extra = { "request_body": request_body, } - log(log_message, extra=extra) + if request.method != "GET": + log(log_message, extra=extra) response = await call_next(request) log_message += f" {response.status_code}" From a1d0ddcf4f8d7c20c04568b8768e3f9d7235c2b9 Mon Sep 17 00:00:00 2001 From: Daniel Fernandes Date: Fri, 26 Jun 2026 14:11:45 +0000 Subject: [PATCH 3/4] Only log GET requests as debug, all else as info --- src/blueapi/service/main.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/blueapi/service/main.py b/src/blueapi/service/main.py index 0215c12dd0..1296bec584 100644 --- a/src/blueapi/service/main.py +++ b/src/blueapi/service/main.py @@ -597,12 +597,8 @@ async def log_request_details( """Middleware to log request's host, method, path, status and request and body - Logs POST and PUT as info, all else as debug.""" - log = ( - LOGGER.info - if request.method == "POST" or request.method == "PUT" - else LOGGER.debug - ) + Logs GET as debug, all else as info.""" + log = LOGGER.debug if request.method == "GET" else LOGGER.info request_body = await request.body() client = request.client or Address("Unknown", -1) log_message = f"{client.host}:{client.port} {request.method} {request.url.path}" From b0486cc39bc9a6cc7fb412918f3172fe3ef12277 Mon Sep 17 00:00:00 2001 From: Daniel Fernandes Date: Tue, 30 Jun 2026 08:12:01 +0000 Subject: [PATCH 4/4] Rework request logging unit tests --- tests/unit_tests/service/test_main.py | 49 +++++++++++++++++++-------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/tests/unit_tests/service/test_main.py b/tests/unit_tests/service/test_main.py index 5a48a9dd0d..93df362669 100644 --- a/tests/unit_tests/service/test_main.py +++ b/tests/unit_tests/service/test_main.py @@ -30,31 +30,37 @@ async def root(): assert response.headers["X-BlueAPI-VERSION"] == __version__ -@pytest.mark.parametrize("path,level", [("/", "info"), ("/healthz", "debug")]) -async def test_log_request_details(path: str, level: str): - with mock.patch("blueapi.service.main.LOGGER") as logger: - app = FastAPI() - app.middleware("http")(log_request_details) +@pytest.fixture +def logging_server(): + app = FastAPI() + app.middleware("http")(log_request_details) + + @app.post("/") + async def root(): + return {"message": "Hello World"} - @app.post(path) - async def root(): - return {"message": "Hello World"} + @app.get("/healthz") + async def health(): + return {"health": "good"} - client = TestClient(app) - response = client.post(path, content="foo") + return TestClient(app) + + +async def test_post_request_logs_at_info(logging_server: TestClient): + with mock.patch("blueapi.service.main.LOGGER") as logger: + response = logging_server.post("/", content="foo") assert response.status_code == 200 - log_level = getattr(logger, level) - log_level.assert_has_calls( + logger.info.assert_has_calls( [ call( - f"testclient:50000 POST {path}", + "testclient:50000 POST /", extra={ "request_body": b"foo", }, ), call( - f"testclient:50000 POST {path} 200", + "testclient:50000 POST / 200", extra={ "request_body": b"foo", }, @@ -63,6 +69,21 @@ async def root(): ) +async def test_get_request_logs_at_debug(logging_server: TestClient): + with mock.patch("blueapi.service.main.LOGGER") as logger: + response = logging_server.get("/healthz") + + assert response.status_code == 200 + logger.debug.assert_has_calls( + [ + call( + "testclient:50000 GET /healthz 200", + extra={"request_body": b""}, + ), + ] + ) + + @pytest.mark.parametrize( "headers, expected_headers", [