66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
"""Central logging configuration utilities."""
|
|
from __future__ import annotations
|
|
|
|
import importlib
|
|
import logging
|
|
|
|
from . import settings
|
|
|
|
JsonFormatter = None
|
|
try:
|
|
_json_module = importlib.import_module("pythonjsonlogger.json")
|
|
JsonFormatter = getattr(_json_module, "JsonFormatter", None)
|
|
except Exception:
|
|
try:
|
|
_json_module = importlib.import_module("pythonjsonlogger.jsonlogger")
|
|
JsonFormatter = getattr(_json_module, "JsonFormatter", None)
|
|
except Exception:
|
|
JsonFormatter = None
|
|
|
|
|
|
class RequestContextFilter(logging.Filter):
|
|
"""Inject request metadata into log records when a request context exists."""
|
|
|
|
def filter(self, record: logging.LogRecord) -> bool:
|
|
try:
|
|
from flask import has_request_context, request
|
|
|
|
if has_request_context():
|
|
rid = getattr(request, "request_id", None) or request.environ.get("HTTP_X_REQUEST_ID")
|
|
record.request_id = rid
|
|
record.remote_addr = request.remote_addr
|
|
record.path = request.path
|
|
record.method = request.method
|
|
else:
|
|
record.request_id = None
|
|
record.remote_addr = None
|
|
record.path = None
|
|
record.method = None
|
|
except Exception:
|
|
record.request_id = None
|
|
record.remote_addr = None
|
|
record.path = None
|
|
record.method = None
|
|
return True
|
|
|
|
|
|
def configure_logging() -> None:
|
|
"""Configure root logging handlers and optional JSON formatting."""
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="[%(asctime)s] %(levelname)s in %(module)s: %(message)s",
|
|
)
|
|
|
|
if settings.ENABLE_JSON_LOGS and JsonFormatter is not None:
|
|
try:
|
|
handler = logging.getLogger().handlers[0]
|
|
handler.setFormatter(JsonFormatter("%(asctime)s %(levelname)s %(name)s %(message)s"))
|
|
except Exception:
|
|
logging.exception("Failed to initialize JSON log formatter")
|
|
|
|
try:
|
|
for handler in logging.getLogger().handlers:
|
|
handler.addFilter(RequestContextFilter())
|
|
except Exception:
|
|
pass
|