Anforderung:
Erfassen und speichern Sie die rohen JSON-Körper bestimmter Leiten Sie Anfragen und Antworten mit einer Datengröße von etwa 1 MB weiter, ohne die Antwortzeiten wesentlich zu beeinträchtigen.
Middleware fängt jede Anfrage ab, bevor sie Endpunkte erreicht, und antwortet, bevor sie an Clients gesendet wird, was eine Datenmanipulation ermöglicht. Das Problem bei der Verwendung des Anforderungstextstroms in der Middleware besteht jedoch darin, dass er für nachgeschaltete Endpunkte nicht mehr verfügbar ist. Daher verwenden wir die Funktion set_body(), um sie verfügbar zu machen.
Die Protokollierung kann mit BackgroundTask durchgeführt werden, wodurch sichergestellt wird, dass die Protokollierung nach der Antwort erfolgt an den Kunden gesendet, wodurch Verzögerungen bei den Antwortzeiten vermieden werden.
# Logging middleware async def some_middleware(request: Request, call_next): req_body = await request.body() await set_body(request, req_body) response = await call_next(request) # Body storage in RAM res_body = b'' async for chunk in response.body_iterator: res_body += chunk # Background logging task task = BackgroundTask(log_info, req_body, res_body) return Response(...) # Endpoint using middleware @app.post('/') async def main(payload: Dict): pass
Durch die Erstellung einer benutzerdefinierten APIRoute-Klasse können wir Anforderungs- und Antworttexte steuern und ihre Verwendung auf bestimmte Routen über einen APIRouter beschränken.
Bei großen Antworten (z. B. Streaming-Medien) kann es bei der benutzerdefinierten Route zu RAM-Problemen oder clientseitigen Verzögerungen aufgrund des Lesens kommen gesamte Antwort in den RAM. Erwägen Sie daher, solche Endpunkte von der benutzerdefinierten Route auszuschließen.
class LoggingRoute(APIRoute): async def custom_route_handler(request: Request) -> Response: req_body = await request.body() response = await original_route_handler(request) # Response handling based on type if isinstance(response, StreamingResponse): res_body = b'' async for item in response.body_iterator: res_body += item response = Response(...) else: response.body # Logging task task = BackgroundTask(log_info, req_body, response.body) response.background = task return response # Endpoint using custom APIRoute @router.post('/') async def main(payload: Dict): return payload
Beide Optionen bieten Lösungen für die Protokollierung von Anforderungs- und Antwortdaten ohne die Reaktionszeiten erheblich beeinträchtigen. Option 1 ermöglicht eine allgemeine Protokollierung, während Option 2 eine detaillierte Kontrolle über Routen bietet, die eine Protokollierung erfordern.
Das obige ist der detaillierte Inhalt vonWie kann man rohe HTTP-Anforderungs-/Antwortkörper in FastAPI effizient protokollieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!