Coverage for faststream / _internal / logger / logging.py: 97%
29 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-08 01:48 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-08 01:48 +0000
1import logging
2import sys
3from collections.abc import Mapping
4from logging import LogRecord
5from typing import TYPE_CHECKING, TextIO
7from .formatter import ColourizedFormatter
9if TYPE_CHECKING:
10 from faststream._internal.context.repository import ContextRepo
13class ExtendedFilter(logging.Filter):
14 def __init__(
15 self,
16 default_context: Mapping[str, str],
17 message_id_ln: int,
18 context: "ContextRepo",
19 name: str = "",
20 ) -> None:
21 self.default_context = default_context
22 self.message_id_ln = message_id_ln
23 self.context = context
24 super().__init__(name)
26 def filter(self, record: LogRecord) -> bool:
27 if is_suitable := super().filter(record): 27 ↛ 39line 27 didn't jump to line 39 because the condition on line 27 was always true
28 log_context: Mapping[str, str] = self.context.get_local(
29 "log_context",
30 self.default_context,
31 )
33 for k, v in log_context.items():
34 value = getattr(record, k, v)
35 setattr(record, k, value)
37 record.message_id = getattr(record, "message_id", "")[: self.message_id_ln]
39 return is_suitable
42def get_broker_logger(
43 name: str,
44 default_context: Mapping[str, str],
45 message_id_ln: int,
46 fmt: str,
47 context: "ContextRepo",
48 log_level: int,
49) -> logging.Logger:
50 logger = get_logger(
51 name=f"faststream.access.{name}",
52 log_level=log_level,
53 stream=sys.stdout,
54 fmt=fmt,
55 )
56 logger.addFilter(ExtendedFilter(default_context, message_id_ln, context=context))
57 return logger
60def get_logger(name: str, log_level: int, stream: "TextIO", fmt: str) -> logging.Logger:
61 logger = logging.getLogger(name)
62 logger.setLevel(log_level)
63 logger.propagate = False
64 set_logger_fmt(logger, stream=stream, fmt=fmt)
65 return logger
68def set_logger_fmt(
69 logger: logging.Logger,
70 stream: "TextIO",
71 fmt: str,
72) -> None:
73 if _handler_exists(logger):
74 return
76 handler = logging.StreamHandler(stream=stream)
77 handler.setFormatter(
78 ColourizedFormatter(
79 fmt=fmt,
80 use_colors=True,
81 ),
82 )
83 logger.addHandler(handler)
86def _handler_exists(logger: logging.Logger) -> bool:
87 # Check if a StreamHandler for sys.stdout already exists in the logger.
88 for handler in logger.handlers:
89 if isinstance(handler, logging.StreamHandler) and handler.stream == sys.stdout:
90 return True
91 return False
94logger = get_logger(
95 name="faststream",
96 log_level=logging.INFO,
97 stream=sys.stderr,
98 fmt="%(asctime)s %(levelname)8s - %(message)s",
99)