Add Log method "any handler is minimum level" with tests

Checks if a given handler is set for any current active handler
This commit is contained in:
Clemens Schwaighofer
2025-12-04 14:37:55 +09:00
parent 895701da59
commit acd61e825e
3 changed files with 107 additions and 0 deletions

View File

@@ -392,6 +392,24 @@ class LogParent:
except IndexError: except IndexError:
return LoggingLevel.NOTSET return LoggingLevel.NOTSET
def any_handler_is_minimum_level(self, log_level: LoggingLevel) -> bool:
"""
if any handler is set to minimum level
Arguments:
log_level {LoggingLevel} -- _description_
Returns:
bool -- _description_
"""
for handler in self.handlers.values():
try:
if LoggingLevel.from_any(handler.level).includes(log_level):
return True
except (IndexError, AttributeError):
continue
return False
@staticmethod @staticmethod
def validate_log_level(log_level: Any) -> bool: def validate_log_level(log_level: Any) -> bool:
""" """

View File

@@ -108,6 +108,16 @@ def main():
log.set_log_level(Log.CONSOLE_HANDLER, LoggingLevel.ERROR) log.set_log_level(Log.CONSOLE_HANDLER, LoggingLevel.ERROR)
log.logger.warning('[NORMAL] Invisible Warning test: %s', log.logger.name) log.logger.warning('[NORMAL] Invisible Warning test: %s', log.logger.name)
log.logger.error('[NORMAL] Visible Error test: %s', log.logger.name) log.logger.error('[NORMAL] Visible Error test: %s', log.logger.name)
log.logger.debug('[NORMAL] Visible Debug test: %s', log.logger.name)
print(f"*** Any handler is minimum level ERROR: {log.any_handler_is_minimum_level(LoggingLevel.ERROR)}")
print(f"*** Any handler is minimum level DEBUG: {log.any_handler_is_minimum_level(LoggingLevel.DEBUG)}")
for handler in log.handlers.values():
print(
f"*** Setting handler {handler} is level {LoggingLevel.from_any(handler.level).name} -> "
f"*** INC {LoggingLevel.from_any(handler.level).includes(LoggingLevel.DEBUG)}")
print(f"*** WARNING includes ERROR: {LoggingLevel.WARNING.includes(LoggingLevel.ERROR)}")
print(f"*** ERROR includes WARNING: {LoggingLevel.ERROR.includes(LoggingLevel.WARNING)}")
log.set_log_level(Log.CONSOLE_HANDLER, LoggingLevel.DEBUG) log.set_log_level(Log.CONSOLE_HANDLER, LoggingLevel.DEBUG)
log.debug('Current logging format: %s', log.log_settings['console_format_type']) log.debug('Current logging format: %s', log.log_settings['console_format_type'])
@@ -115,6 +125,8 @@ def main():
log.info('Does hit show less') log.info('Does hit show less')
log.update_console_formatter(ConsoleFormat.TIME | ConsoleFormat.LINENO) log.update_console_formatter(ConsoleFormat.TIME | ConsoleFormat.LINENO)
log.info('Does hit show less B') log.info('Does hit show less B')
print(f"*** Any handler is minimum level ERROR: {log.any_handler_is_minimum_level(LoggingLevel.ERROR)}")
print(f"*** Any handler is minimum level DEBUG: {log.any_handler_is_minimum_level(LoggingLevel.DEBUG)}")
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -438,4 +438,81 @@ class TestLogLevelHandling:
level = log_instance.get_log_level("file_handler") level = log_instance.get_log_level("file_handler")
assert level == LoggingLevel.DEBUG assert level == LoggingLevel.DEBUG
class DummyHandler:
"""Dummy log level handler"""
def __init__(self, level: LoggingLevel):
self.level = level
@pytest.fixture
def log_instance_level() -> Log:
"""
Minimal log instance with dummy handlers
Returns:
Log -- _description_
"""
log = Log(
log_path=Path("/tmp/test.log"),
log_name="test",
log_settings={
"log_level_console": LoggingLevel.DEBUG,
"log_level_file": LoggingLevel.DEBUG,
"console_enabled": False,
"console_color_output_enabled": False,
"console_format_type": None,
"per_run_log": False,
"add_start_info": False,
"add_end_info": False,
"log_queue": None,
}
)
return log
def test_any_handler_is_minimum_level_true(log_instance_level: Log):
"""Test any_handler_is_minimum_level returns True when a handler meets the level"""
# Handler with DEBUG level, should include INFO
log_instance_level.handlers = {
"h1": DummyHandler(LoggingLevel.DEBUG)
}
assert log_instance_level.any_handler_is_minimum_level(LoggingLevel.INFO) is True
def test_any_handler_is_minimum_level_false(log_instance_level: Log):
"""Test any_handler_is_minimum_level returns False when no handler meets the level"""
# Handler with WARNING level, should include ERROR
log_instance_level.handlers = {
"h1": DummyHandler(LoggingLevel.WARNING)
}
assert log_instance_level.any_handler_is_minimum_level(LoggingLevel.ERROR) is True
def test_any_handler_is_minimum_level_multiple(log_instance_level: Log):
"""Test any_handler_is_minimum_level with multiple handlers"""
# Multiple handlers, one matches
log_instance_level.handlers = {
"h1": DummyHandler(LoggingLevel.ERROR),
"h2": DummyHandler(LoggingLevel.DEBUG)
}
assert log_instance_level.any_handler_is_minimum_level(LoggingLevel.INFO) is True
# None matches
log_instance_level.handlers = {
"h1": DummyHandler(LoggingLevel.ERROR),
"h2": DummyHandler(LoggingLevel.CRITICAL)
}
assert log_instance_level.any_handler_is_minimum_level(LoggingLevel.DEBUG) is False
def test_any_handler_is_minimum_level_handles_exceptions(log_instance_level: Log):
"""Test any_handler_is_minimum_level handles exceptions gracefully"""
# Handler with missing level attribute
class BadHandler:
pass
log_instance_level.handlers = {
"h1": BadHandler()
}
# Should not raise, just return False
assert log_instance_level.any_handler_is_minimum_level(LoggingLevel.DEBUG) is False
# __END__ # __END__