Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/edge_proxy/middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import time
from typing import Any, Callable

import structlog
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware

logger = structlog.get_logger("edge_proxy.request")


class RequestLoggingMiddleware(BaseHTTPMiddleware):
"""
Log all incoming HTTP requests and responses with timing information.
"""

async def dispatch(
self, request: Request, call_next: Callable[[Request], Any]
) -> Any:
start_time = time.time()

logger.debug(
"request",
method=request.method,
url=request.url.path,
client_host=request.client.host if request.client else None,
)

response = await call_next(request)

duration = time.time() - start_time

logger.debug(
"response",
method=request.method,
url=request.url.path,
status_code=response.status_code,
size=int(response.headers.get("content-length", 0)),
duration_ms=round(duration * 1000),
)

return response
2 changes: 2 additions & 0 deletions src/edge_proxy/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from edge_proxy.environments import EnvironmentService
from edge_proxy.exceptions import FeatureNotFoundError, FlagsmithUnknownKeyError
from edge_proxy.logging import setup_logging
from edge_proxy.middleware import RequestLoggingMiddleware
from edge_proxy.models import IdentityWithTraits
from edge_proxy.settings import get_settings

Expand Down Expand Up @@ -113,6 +114,7 @@ async def refresh_cache():
await environment_service.refresh_environment_caches()


app.add_middleware(RequestLoggingMiddleware)
app.add_middleware(
CORSMiddleware,
allow_origins=settings.allow_origins,
Expand Down
41 changes: 41 additions & 0 deletions tests/test_middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import json

from fastapi import FastAPI
from fastapi.testclient import TestClient
from pytest_mock import MockerFixture

from edge_proxy.middleware import RequestLoggingMiddleware


def test_request_logging_middleware(mocker: MockerFixture) -> None:
# Given
mock_logger = mocker.patch("edge_proxy.middleware.logger")

app = FastAPI()
app.add_middleware(RequestLoggingMiddleware)
response = "ok"

@app.get("/test")
async def test_endpoint():
return response

client = TestClient(app)

# When
client.get("/test")

# Then
mock_logger.debug.assert_any_call(
"request",
method="GET",
url="/test",
client_host="testclient",
)
mock_logger.debug.assert_any_call(
"response",
method="GET",
url="/test",
status_code=200,
size=len(json.dumps(response)),
duration_ms=mocker.ANY,
)