69 lines
2.2 KiB
Python
69 lines
2.2 KiB
Python
"""HTTP middleware helpers (Flask request hooks)."""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
import time
|
|
|
|
from flask import Flask, g, request
|
|
|
|
from . import settings
|
|
from .metrics import observe_request
|
|
from .utils import generate_request_id
|
|
|
|
|
|
def register_request_hooks(app: Flask) -> None:
|
|
"""Attach before/after request handlers for logging and correlation."""
|
|
|
|
@app.before_request
|
|
def attach_request_id_and_log(): # type: ignore[unused-ignore]
|
|
rid = request.headers.get("X-Request-Id")
|
|
if not rid:
|
|
rid = generate_request_id()
|
|
request.environ["HTTP_X_REQUEST_ID"] = rid
|
|
request.request_id = rid # type: ignore[attr-defined]
|
|
|
|
if settings.ENABLE_REQUEST_LOGS:
|
|
try:
|
|
logging.info(
|
|
"request.start",
|
|
extra={
|
|
"request_id": rid,
|
|
"method": request.method,
|
|
"path": request.path,
|
|
"remote_addr": request.remote_addr,
|
|
},
|
|
)
|
|
except Exception:
|
|
pass
|
|
|
|
try:
|
|
g._start_time = time.time()
|
|
except Exception:
|
|
g._start_time = None # type: ignore[attr-defined]
|
|
|
|
@app.after_request
|
|
def add_request_id_header(response): # type: ignore[unused-ignore]
|
|
try:
|
|
rid = getattr(request, "request_id", None) or request.environ.get("HTTP_X_REQUEST_ID")
|
|
if rid:
|
|
response.headers["X-Request-Id"] = rid
|
|
|
|
if settings.ENABLE_REQUEST_LOGS:
|
|
try:
|
|
logging.info(
|
|
"request.end",
|
|
extra={
|
|
"request_id": rid,
|
|
"status": response.status_code,
|
|
"path": request.path,
|
|
},
|
|
)
|
|
except Exception:
|
|
pass
|
|
|
|
start_time = getattr(g, "_start_time", None)
|
|
observe_request(request.method, request.path, start_time, response.status_code)
|
|
except Exception:
|
|
pass
|
|
return response
|