Emits each log message at most once, keyed by an explicit string. Useful for diagnostic warnings that would otherwise spam the log when the same condition recurs (per-request misconfiguration warnings, repeated fallback paths, etc.). Deduplication scope follows the lifetime of the insta
| 4 | |
| 5 | |
| 6 | class LoggerOnce: |
| 7 | """Emits each log message at most once, keyed by an explicit string. |
| 8 | |
| 9 | Useful for diagnostic warnings that would otherwise spam the log when the same condition recurs (per-request |
| 10 | misconfiguration warnings, repeated fallback paths, etc.). Deduplication scope follows the lifetime of the |
| 11 | instance — a module-level instance gives process-wide dedup; an attribute on a class gives per-instance dedup. |
| 12 | """ |
| 13 | |
| 14 | def __init__(self, logger: logging.Logger) -> None: |
| 15 | self._logger = logger |
| 16 | self._seen: set[str] = set() |
| 17 | |
| 18 | def log(self, message: str, *, key: str, level: int = logging.INFO) -> None: |
| 19 | """Log `message` at `level` the first time `key` is seen on this instance; later calls are no-ops. |
| 20 | |
| 21 | Args: |
| 22 | message: The message to log. |
| 23 | key: Deduplication key. Two calls with the same key emit at most once. |
| 24 | level: Standard `logging` level (e.g. `logging.WARNING`). Defaults to `logging.INFO`. |
| 25 | """ |
| 26 | if key in self._seen: |
| 27 | return |
| 28 | self._seen.add(key) |
| 29 | self._logger.log(level, message) |
no outgoing calls