diff --git a/homeassistant/util/logging.py b/homeassistant/util/logging.py index 07ee6608141..943e701a144 100644 --- a/homeassistant/util/logging.py +++ b/homeassistant/util/logging.py @@ -39,6 +39,24 @@ class HomeAssistantQueueHandler(logging.handlers.QueueHandler): except Exception: # pylint: disable=broad-except self.handleError(record) + def handle(self, record: logging.LogRecord) -> Any: + """ + Conditionally emit the specified logging record. + + Depending on which filters have been added to the handler, push the new + records onto the backing Queue. + + The default python logger Handler acquires a lock + in the parent class which we do not need as + SimpleQueue is already thread safe. + + See https://bugs.python.org/issue24645 + """ + return_value = self.filter(record) + if return_value: + self.emit(record) + return return_value + @callback def async_activate_log_queue_handler(hass: HomeAssistant) -> None: diff --git a/tests/util/test_logging.py b/tests/util/test_logging.py index a1183ee1637..04d6f133381 100644 --- a/tests/util/test_logging.py +++ b/tests/util/test_logging.py @@ -38,6 +38,17 @@ async def test_logging_with_queue_handler(): ): handler.emit(log_record) + with patch.object(handler, "emit") as emit_mock: + handler.handle(log_record) + emit_mock.assert_called_once() + + with patch.object(handler, "filter") as filter_mock, patch.object( + handler, "emit" + ) as emit_mock: + filter_mock.return_value = False + handler.handle(log_record) + emit_mock.assert_not_called() + with patch.object(handler, "enqueue", side_effect=OSError), patch.object( handler, "handleError" ) as mock_handle_error: