Immutable context carrier. Doesn't do any actual logging; examples for useful subclasses are: - the generic `BoundLogger` that can wrap anything, - `structlog.stdlib.BoundLogger`. - `structlog.twisted.BoundLogger`, See also `custom-wrappers`.
| 26 | |
| 27 | |
| 28 | class BoundLoggerBase: |
| 29 | """ |
| 30 | Immutable context carrier. |
| 31 | |
| 32 | Doesn't do any actual logging; examples for useful subclasses are: |
| 33 | |
| 34 | - the generic `BoundLogger` that can wrap anything, |
| 35 | - `structlog.stdlib.BoundLogger`. |
| 36 | - `structlog.twisted.BoundLogger`, |
| 37 | |
| 38 | See also `custom-wrappers`. |
| 39 | """ |
| 40 | |
| 41 | _logger: WrappedLogger |
| 42 | """ |
| 43 | Wrapped logger. |
| 44 | |
| 45 | .. note:: |
| 46 | |
| 47 | Despite underscore available **read-only** to custom wrapper classes. |
| 48 | |
| 49 | See also `custom-wrappers`. |
| 50 | """ |
| 51 | |
| 52 | def __init__( |
| 53 | self, |
| 54 | logger: WrappedLogger, |
| 55 | processors: Iterable[Processor], |
| 56 | context: Context, |
| 57 | ): |
| 58 | self._logger = logger |
| 59 | self._processors = processors |
| 60 | self._context = context |
| 61 | |
| 62 | def __repr__(self) -> str: |
| 63 | return f"<{self.__class__.__name__}(context={self._context!r}, processors={self._processors!r})>" |
| 64 | |
| 65 | def __eq__(self, other: object) -> bool: |
| 66 | try: |
| 67 | return self._context == other._context # type: ignore[attr-defined] |
| 68 | except AttributeError: |
| 69 | return False |
| 70 | |
| 71 | def __ne__(self, other: object) -> bool: |
| 72 | return not self.__eq__(other) |
| 73 | |
| 74 | def bind(self, **new_values: Any) -> Self: |
| 75 | """ |
| 76 | Return a new logger with *new_values* added to the existing ones. |
| 77 | """ |
| 78 | return self.__class__( |
| 79 | self._logger, |
| 80 | self._processors, |
| 81 | self._context.__class__(self._context, **new_values), |
| 82 | ) |
| 83 | |
| 84 | def unbind(self, *keys: str) -> Self: |
| 85 | """ |