diff --git a/src/structlog/stdlib.py b/src/structlog/stdlib.py index fb5fa15d..166578be 100644 --- a/src/structlog/stdlib.py +++ b/src/structlog/stdlib.py @@ -217,6 +217,12 @@ def critical(self, event: str | None = None, *args: Any, **kw: Any) -> Any: """ return self._proxy_to_logger("critical", event, *args, **kw) + def fatal(self, event: str | None = None, *args: Any, **kw: Any) -> Any: + """ + Process event and call `logging.Logger.critical` with the result. + """ + return self._proxy_to_logger("critical", event, *args, **kw) + def exception( self, event: str | None = None, *args: Any, **kw: Any ) -> Any: @@ -236,8 +242,6 @@ def log( """ return self._proxy_to_logger(LEVEL_TO_NAME[level], event, *args, **kw) - fatal = critical - def _proxy_to_logger( self, method_name: str, @@ -448,7 +452,13 @@ async def acritical(self, event: str, *args: Any, **kw: Any) -> None: """ await self._dispatch_to_sync(self.critical, event, args, kw) - afatal = acritical + async def afatal(self, event: str, *args: Any, **kw: Any) -> None: + """ + Log using `critical()`, but asynchronously in a separate thread. + + .. versionadded:: 23.1.0 + """ + await self._dispatch_to_sync(self.critical, event, args, kw) async def aexception(self, event: str, *args: Any, **kw: Any) -> None: """ @@ -625,7 +635,8 @@ async def info(self, event: str, *args: Any, **kw: Any) -> None: async def warning(self, event: str, *args: Any, **kw: Any) -> None: await self._dispatch_to_sync(self.sync_bl.warning, event, args, kw) - warn = warning + async def warn(self, event: str, *args: Any, **kw: Any) -> None: + await self._dispatch_to_sync(self.sync_bl.warning, event, args, kw) async def error(self, event: str, *args: Any, **kw: Any) -> None: await self._dispatch_to_sync(self.sync_bl.error, event, args, kw) @@ -633,7 +644,8 @@ async def error(self, event: str, *args: Any, **kw: Any) -> None: async def critical(self, event: str, *args: Any, **kw: Any) -> None: await self._dispatch_to_sync(self.sync_bl.critical, event, args, kw) - fatal = critical + async def fatal(self, event: str, *args: Any, **kw: Any) -> None: + await self._dispatch_to_sync(self.sync_bl.critical, event, args, kw) async def exception(self, event: str, *args: Any, **kw: Any) -> None: # To make `log.exception("foo") work, we have to check if the user diff --git a/tests/test_stdlib.py b/tests/test_stdlib.py index e79050f9..9bba39f9 100644 --- a/tests/test_stdlib.py +++ b/tests/test_stdlib.py @@ -206,6 +206,15 @@ def test_proxies_to_correct_method(self, method_name): assert method_name == getattr(bl, method_name)("event") + def test_proxies_to_correct_method_special_cases(self): + """ + Fatal maps to critical and warn to warning. + """ + bl = BoundLogger(ReturnLogger(), [return_method_name], {}) + + assert "warning" == bl.warn("event") + assert "critical" == bl.fatal("event") + def test_proxies_log(self): """ BoundLogger.exception.log() is proxied to the appropriate method. @@ -359,6 +368,20 @@ async def test_async_log_methods(self, meth, cl): CapturedCall(method_name=meth, args=(), kwargs={"event": "Async!"}) ] == cl.calls + async def test_async_log_methods_special_cases(self, cl): + """ + afatal maps to critical. + """ + bl = build_bl(cl, processors=[]) + + await bl.afatal("Async!") + + assert [ + CapturedCall( + method_name="critical", args=(), kwargs={"event": "Async!"} + ) + ] == cl.calls + async def test_alog(self, cl): """ Alog logs async at the correct level. @@ -1325,11 +1348,19 @@ async def test_correct_levels(self, abl, cl, stdlib_log_method): aliases = {"warn": "warning"} - alias = aliases.get(stdlib_log_method) - expect = alias if alias else stdlib_log_method + expect = aliases.get(stdlib_log_method, stdlib_log_method) assert expect == cl.calls[0].method_name + @pytest.mark.asyncio + async def test_correct_level_fatal(self, abl, cl): + """ + fatal, that I have no idea why we support, maps to critical. + """ + await abl.bind(foo="bar").fatal("42") + + assert "critical" == cl.calls[0].method_name + @pytest.mark.asyncio async def test_log_method(self, abl, cl): """