A lightweight request logger middleware for ASGI applications
Project description
asgi-request-logger
The asgi-request-logger package provides JsonRequestLoggerMiddleware that logs incoming HTTP requests in JSON format. It captures useful metadata such as timestamp, event ID, HTTP method, path, client IP (using configurable header names), user agent, processing time, and error information (if available). This middleware is designed to be integrated into a FastAPI application.
Note:
Due to FastAPI/Starlette’s internal exception handling, when a 500 error occurs the error information may not be captured by the logger because the built-in ServerErrorMiddleware intercepts exceptions and raiseException. In such cases, it’s recommended to log error details directly within your exception handlers.
Features
- JSON Logging: Logs request details in a structured JSON format.
- Configurable Options:
- Event ID: Optionally extract an event ID from a specified header; if absent, a new UUID is generated.
- Client IP: Extract client IP from headers like X-Forwarded-For or X-Real-IP (configurable).
- Error Info Mapping: Define which keys from the error info (set by exception handlers) should be logged.
- Custom Logger: Optionally supply your own logging.Logger instance.
Installation
pip install asgi-request-logger
Usage
Basic Integration
You can add the middleware to your FastAPI/Starlette app using app.add_middleware():
from fastapi import FastAPI
from asgi_request_logger import JsonRequestLoggerMiddleware
app = FastAPI()
# Add JSON Request Logger Middleware with custom configuration.
app.add_middleware(
JsonRequestLoggerMiddleware,
event_id_header="X-Event-ID", # Use this header for the event ID; if absent, a new UUID is generated.
client_ip_headers=["x-forwarded-for", "x-real-ip"], # List of headers to determine the client IP.
error_info_name="error_info", # The key in the scope where error information is stored.
error_info_mapping={
"code": "error_code",
"message": "error_message",
"stack_trace": "stack_trace"
} # The expected dictionary format for the error information. This value will be logged under the "error" key.
)
For detailed error information, you should pass error-related info to the scope. In a FastAPI application, you can do this in your exception handlers. For example:
async def http_exception_handler(request: Request, exc: HTTPException):
my_exception = MyCustomException(http_exception=exc)
await _pass_error_info(
request=request,
my_exception=my_exception,
stack_trace=traceback.format_exc().splitlines()
)
return await _to_response(my_exception=my_exception)
async def _pass_error_info(
request: Request,
my_exception: MyCustomException,
stack_trace: list[str]
):
request.state.error_info = {
"code": my_exception.code,
"message": my_exception.reason,
"http_status": my_exception.http_status,
"stack_trace": stack_trace,
}
async def _to_response(my_exception: MyCustomException):
return Response(
status_code=my_exception.http_status,
content=json.dumps(
{"code": my_exception.code, "message": my_exception.reason}, ensure_ascii=False
)
)
Example JSON Log Output
A typical log entry might look like this:
{
"timestamp": "2025-03-02T08:17:40.123456Z",
"event_id": "ab427b0c-629b-4792-891e-bce4c94d1084",
"method": "GET",
"path": "/items/3fa85f64-5717-4562-b3fc-2c963f66afa4",
"client_ip": "203.0.113.195",
"user_agent": "Mozilla/5.0 (Macintosh; ...)",
"time_taken_ms": 12,
"status_code": 200,
"log_type": "access",
"level": "INFO"
}
If error information is present (set by your exception handlers), the log entry will also include keys like "error_code", "error_message", and "stack_trace".
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file asgi_request_logger-0.1.1.tar.gz.
File metadata
- Download URL: asgi_request_logger-0.1.1.tar.gz
- Upload date:
- Size: 4.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.1 CPython/3.12.9 Linux/6.8.0-1021-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aae3c428ea7fc2f942d3b95e8b6a8c67e95b2b10fb4485fc1638974044466fe8
|
|
| MD5 |
d37aa2778523d601ebf6a7e481a56c65
|
|
| BLAKE2b-256 |
7ac2d9da834c0c9186f9da47ca76ff233caf8c34c7ef28af89328915e82ed22f
|
File details
Details for the file asgi_request_logger-0.1.1-py3-none-any.whl.
File metadata
- Download URL: asgi_request_logger-0.1.1-py3-none-any.whl
- Upload date:
- Size: 6.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.1 CPython/3.12.9 Linux/6.8.0-1021-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2e8ac8ab024bc21cdf575899b5aeaa0865cd6fa134231e1a528d8727fc58a5f
|
|
| MD5 |
1bbc22169b98df0435c02f2e3a625c25
|
|
| BLAKE2b-256 |
03112ebba4ca38acc29c741d9a3659fe4675dc9b4b4611f6cc5644eb7cda8afa
|