Coverage for extra_codeowners/logging.py: 85%
11 statements
« prev ^ index » next coverage.py v7.15.1, created at 2026-07-13 09:46 +0000
« prev ^ index » next coverage.py v7.15.1, created at 2026-07-13 09:46 +0000
1"""Structured logging configuration with secret-safe defaults."""
3from __future__ import annotations
5import logging
6import sys
8import structlog
11def configure_logging(level: str, *, json_logs: bool) -> None:
12 """Configure stdlib and structlog for either development or production."""
13 logging.basicConfig(format="%(message)s", level=level, stream=sys.stdout, force=True)
14 processors: list[structlog.types.Processor] = [
15 structlog.contextvars.merge_contextvars,
16 structlog.processors.add_log_level,
17 structlog.processors.TimeStamper(fmt="iso", utc=True),
18 structlog.processors.StackInfoRenderer(),
19 ]
20 if json_logs: 20 ↛ 21line 20 didn't jump to line 21 because the condition on line 20 was never true
21 processors.append(structlog.processors.format_exc_info)
22 processors.append(
23 structlog.processors.JSONRenderer()
24 if json_logs
25 else structlog.dev.ConsoleRenderer(colors=sys.stdout.isatty())
26 )
27 structlog.configure(
28 processors=processors,
29 wrapper_class=structlog.make_filtering_bound_logger(logging.getLevelName(level)),
30 logger_factory=structlog.PrintLoggerFactory(),
31 cache_logger_on_first_use=True,
32 )