SPB Git forge
1commits 1branches 0releases
189.0 KBsize
maindefault branch
4 h agolast push
Python 54.7% TypeScript 42.5% SQL 1.9%
1.9 KB · 60 lines python
Raw Blame History
1"""Structured logging with correlation ids (structlog → JSON lines or console)."""23from __future__ import annotations45import contextvars6import logging7import sys8import uuid9from typing import Any1011import structlog1213correlation_id: contextvars.ContextVar[str] = contextvars.ContextVar("correlation_id", default="-")1415SECRET_KEYS = {"api_key", "api_secret", "secret", "password", "token", "api-sign", "api-key", "authorization"}161718def _redact(_, __, event_dict):  # noqa: ANN00119    for k in list(event_dict):20        if k.lower() in SECRET_KEYS:21            event_dict[k] = "***"22    return event_dict232425def _add_correlation(_, __, event_dict):  # noqa: ANN00126    event_dict["cid"] = correlation_id.get()27    return event_dict282930def new_correlation_id() -> str:31    cid = uuid.uuid4().hex[:12]32    correlation_id.set(cid)33    return cid343536def configure_logging(level: str = "INFO", json_output: bool = True) -> None:37    logging.basicConfig(level=level.upper(), stream=sys.stdout, format="%(message)s")38    for noisy in ("httpx", "httpcore", "websockets", "uvicorn.access"):39        logging.getLogger(noisy).setLevel(logging.WARNING)40    processors: list[Any] = [41        structlog.contextvars.merge_contextvars,42        structlog.processors.add_log_level,43        structlog.processors.TimeStamper(fmt="iso", utc=True),44        _add_correlation,45        _redact,46        structlog.processors.StackInfoRenderer(),47        structlog.processors.format_exc_info,48    ]49    renderer = structlog.processors.JSONRenderer() if json_output else structlog.dev.ConsoleRenderer()50    structlog.configure(51        processors=[*processors, renderer],52        wrapper_class=structlog.make_filtering_bound_logger(logging.getLevelName(level.upper())),53        logger_factory=structlog.PrintLoggerFactory(sys.stdout),54        cache_logger_on_first_use=False,55    )565758def get_logger(name: str) -> structlog.stdlib.BoundLogger:59    return structlog.get_logger(name)60