From 7b433ea1b1b2e557521e34a797ab2e46bfb9d02f Mon Sep 17 00:00:00 2001 From: jbannon Date: Mon, 6 Jun 2022 23:21:47 +0000 Subject: [PATCH] Loggerlevel dataclass --- src/ytdl_sub/cli/main_args_parser.py | 2 +- src/ytdl_sub/main.py | 2 +- src/ytdl_sub/utils/logger.py | 111 ++++++++++++--------------- tests/unit/utils/test_logger.py | 8 +- 4 files changed, 54 insertions(+), 69 deletions(-) diff --git a/src/ytdl_sub/cli/main_args_parser.py b/src/ytdl_sub/cli/main_args_parser.py index ed90ddf0..38c7ad41 100644 --- a/src/ytdl_sub/cli/main_args_parser.py +++ b/src/ytdl_sub/cli/main_args_parser.py @@ -20,7 +20,7 @@ parser.add_argument( metavar="|".join(LoggerLevels.names()), type=str, help="level of logs to print to console, defaults to info", - default=LoggerLevels.name_of(LoggerLevels.INFO), + default=LoggerLevels.INFO.name, choices=LoggerLevels.names(), ) ################################################################################################### diff --git a/src/ytdl_sub/main.py b/src/ytdl_sub/main.py index fa83ed84..695e6ac0 100644 --- a/src/ytdl_sub/main.py +++ b/src/ytdl_sub/main.py @@ -72,7 +72,7 @@ def _main(): args, extra_args = parser.parse_known_args() config: ConfigFile = ConfigFile.from_file_path(args.config).initialize() - Logger.set_log_level(log_level=args.log_level) + Logger.set_log_level(log_level_name=args.log_level) if args.subparser == "sub": _download_subscriptions_from_yaml_files(config=config, args=args) diff --git a/src/ytdl_sub/utils/logger.py b/src/ytdl_sub/utils/logger.py index 0874449b..9919c5e7 100644 --- a/src/ytdl_sub/utils/logger.py +++ b/src/ytdl_sub/utils/logger.py @@ -4,73 +4,32 @@ import logging import os import sys import tempfile +from dataclasses import dataclass from typing import List from typing import Optional +@dataclass +class LoggerLevel: + name: str + level: int + logging_level: int + + class LoggerLevels: """ Custom log levels """ - # No logs whatsoever - QUIET = 0 - - # Only ytdl-sub info logs - INFO = 10 - - # ytdl-sub and yt-dlp info logs - VERBOSE = 20 - - # ytdl-sub and yt-dlp info + debug logs - DEBUG = 30 + QUIET = LoggerLevel(name="quiet", level=0, logging_level=logging.NOTSET) # No logs whatsoever + INFO = LoggerLevel(name="info", level=10, logging_level=logging.INFO) # ytdl-sub info logs + VERBOSE = LoggerLevel(name="verbose", level=20, logging_level=logging.INFO) # ytdl-sub + yt-dlp + DEBUG = LoggerLevel( + name="debug", level=30, logging_level=logging.DEBUG + ) # ytdl-sub + yt-dlp debug logs @classmethod - def to_logging_level(cls, logger_level: int) -> int: - """ - Parameters - ---------- - logger_level - LoggingLevels enum - - Returns - ------- - logging level - """ - match logger_level: - case cls.QUIET: - return logging.NOTSET - case cls.DEBUG: - return logging.DEBUG - case _: - return logging.INFO - - @classmethod - def name_of(cls, log_level: int): - """ - Parameters - ---------- - log_level - The log level - - Returns - ------- - Name of the log levels - """ - match log_level: - case cls.QUIET: - return "quiet" - case cls.INFO: - return "info" - case cls.VERBOSE: - return "verbose" - case cls.DEBUG: - return "debug" - case _: - raise ValueError("Invalid log level") - - @classmethod - def all(cls) -> List[int]: + def all(cls) -> List[LoggerLevel]: """ Returns ------- @@ -78,6 +37,24 @@ class LoggerLevels: """ return [cls.QUIET, cls.INFO, cls.VERBOSE, cls.DEBUG] + @classmethod + def from_str(cls, name: str) -> LoggerLevel: + """ + Parameters + ---------- + name + The log level name + + Raises + ------ + ValueError + Name is not a valid logger level + """ + for logger_level in cls.all(): + if name == logger_level.name: + return logger_level + raise ValueError("Invalid logger level name") + @classmethod def names(cls) -> List[str]: """ @@ -85,19 +62,25 @@ class LoggerLevels: ------- All log level names """ - return [cls.name_of(log_level=log_level) for log_level in cls.all()] + return [logger_level.name for logger_level in cls.all()] class Logger: # The level set via CLI arguments - _LEVEL = LoggerLevels.DEBUG + _LOGGER_LEVEL: LoggerLevel = LoggerLevels.DEBUG _DEBUG_LOGGER_FILE = None @classmethod - def set_log_level(cls, log_level: int): - cls._LEVEL = log_level + def set_log_level(cls, log_level_name: str): + """ + Parameters + ---------- + log_level_name + Name of the log level to set + """ + cls._LOGGER_LEVEL = LoggerLevels.from_str(name=log_level_name) @classmethod def _get_formatter(cls) -> logging.Formatter: @@ -116,7 +99,7 @@ class Logger: Logger handler """ handler = logging.StreamHandler(sys.stdout) - handler.setLevel(LoggerLevels.to_logging_level(cls._LEVEL)) + handler.setLevel(cls._LOGGER_LEVEL.logging_level) handler.setFormatter(cls._get_formatter()) return handler @@ -142,7 +125,7 @@ class Logger: logger_name += f":{name}" logger = logging.Logger(name=logger_name, level=logging.DEBUG) - if stdout and cls._LEVEL >= LoggerLevels.INFO: + if stdout and cls._LOGGER_LEVEL.level >= LoggerLevels.INFO.level: logger.addHandler(cls._get_stdout_handler()) if debug_file: logger.addHandler(cls._get_debug_file_handler()) @@ -177,7 +160,9 @@ class Logger: Optional. Name of the logger which is included in the prefix like [ytdl-sub:]. If None, the prefix is just [ytdl-sub] """ - logger = cls._get(name=name, stdout=cls._LEVEL >= LoggerLevels.VERBOSE, debug_file=True) + logger = cls._get( + name=name, stdout=cls._LOGGER_LEVEL.level >= LoggerLevels.VERBOSE.level, debug_file=True + ) with io.StringIO() as redirect_stream: with contextlib.redirect_stdout(new_target=redirect_stream): diff --git a/tests/unit/utils/test_logger.py b/tests/unit/utils/test_logger.py index 310fd4d8..bc06c8cc 100644 --- a/tests/unit/utils/test_logger.py +++ b/tests/unit/utils/test_logger.py @@ -22,7 +22,7 @@ class TestLogger: ], ) def test_logger_info_stdout(self, capsys, log_level, outputs_to_stdout): - Logger._LEVEL = log_level + Logger._LOGGER_LEVEL = log_level logger = Logger.get(name="name_test") logger.info("test") @@ -43,7 +43,7 @@ class TestLogger: ], ) def test_logger_debug_stdout(self, capsys, log_level, outputs_to_stdout): - Logger._LEVEL = log_level + Logger._LOGGER_LEVEL = log_level logger = Logger.get(name="name_test") logger.debug("test") @@ -64,7 +64,7 @@ class TestLogger: ], ) def test_logger_always_outputs_to_debug_file(self, log_level): - Logger._LEVEL = log_level + Logger._LOGGER_LEVEL = log_level logger = Logger.get(name="name_test") logger.info("info test") @@ -85,7 +85,7 @@ class TestLogger: ], ) def test_handle_external_logs(self, capsys, log_level, expected_stdout): - Logger._LEVEL = log_level + Logger._LOGGER_LEVEL = log_level with Logger.handle_external_logs(name="name_test"): print("test line 1") print("test line 2")