**Breaking changes**
- Request payload is now logged under a new nested field `request_payload` in the `jsonPayload` field of each request lifecycle parent request. Check screenshot in readme to locate the new structure in parent log when looking into Google Cloud Logging Explorer.
**New features**
- Added optional logging of request headers into the parent log. This is optional but defaults to true. The headers are placed into `request_headers` nested field in the `jsonPayload` field of parent log.
- Request payload is parsed automatically before logged in `request_payload` nested field. Parsing happens based on content type of incoming request and currently there are 3 types supported:
- `application/json`
- `application/x-www-form-urlencoded`
- `text/plain`
- User can add more parsers or override existing ones by passing extra parsers as a dict during logging initialization. Example:
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from fastapi.exceptions import HTTPException
import logging
import os
app = FastAPI()
async def custom_payload_parser_plain_text(request: Request):
try:
body_bytes = await request.body()
incoming_payload = body_bytes.decode('utf-8')
return f"This was the original request payload: {incoming_payload}"
except Exception as e:
return f"Failed to read request payload as plain text: {e} | {traceback.format_exc()}"
if os.getenv('GAE_ENV', '').startswith('standard'):
import google.cloud.logging
from google.cloud.logging_v2.handlers import setup_logging
from fastapi_gae_logging import FastAPIGAELoggingHandler
client = google.cloud.logging.Client()
overriding default parsing for payload when content type is 'text/plain'
gae_log_handler = FastAPIGAELoggingHandler(
app=app,
client=client,
custom_payload_parsers={
"text/plain": custom_payload_parser_plain_text
}
)
use the log_payload parameter if you want to opt-out from payload logging
gae_log_handler = FastAPIGAELoggingHandler(app=app, client=client, log_payload=False)
setup_logging(handler=gae_log_handler)