spb/crypto-trade-bot
Public
Python 54.7%
TypeScript 42.5%
SQL 1.9%
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