Loggerlevel dataclass

This commit is contained in:
jbannon 2022-06-06 23:21:47 +00:00
parent 1e68a785ba
commit 7b433ea1b1
4 changed files with 54 additions and 69 deletions

View file

@ -20,7 +20,7 @@ parser.add_argument(
metavar="|".join(LoggerLevels.names()), metavar="|".join(LoggerLevels.names()),
type=str, type=str,
help="level of logs to print to console, defaults to info", help="level of logs to print to console, defaults to info",
default=LoggerLevels.name_of(LoggerLevels.INFO), default=LoggerLevels.INFO.name,
choices=LoggerLevels.names(), choices=LoggerLevels.names(),
) )
################################################################################################### ###################################################################################################

View file

@ -72,7 +72,7 @@ def _main():
args, extra_args = parser.parse_known_args() args, extra_args = parser.parse_known_args()
config: ConfigFile = ConfigFile.from_file_path(args.config).initialize() 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": if args.subparser == "sub":
_download_subscriptions_from_yaml_files(config=config, args=args) _download_subscriptions_from_yaml_files(config=config, args=args)

View file

@ -4,73 +4,32 @@ import logging
import os import os
import sys import sys
import tempfile import tempfile
from dataclasses import dataclass
from typing import List from typing import List
from typing import Optional from typing import Optional
@dataclass
class LoggerLevel:
name: str
level: int
logging_level: int
class LoggerLevels: class LoggerLevels:
""" """
Custom log levels Custom log levels
""" """
# No logs whatsoever QUIET = LoggerLevel(name="quiet", level=0, logging_level=logging.NOTSET) # No logs whatsoever
QUIET = 0 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
# Only ytdl-sub info logs DEBUG = LoggerLevel(
INFO = 10 name="debug", level=30, logging_level=logging.DEBUG
) # ytdl-sub + yt-dlp debug logs
# ytdl-sub and yt-dlp info logs
VERBOSE = 20
# ytdl-sub and yt-dlp info + debug logs
DEBUG = 30
@classmethod @classmethod
def to_logging_level(cls, logger_level: int) -> int: def all(cls) -> List[LoggerLevel]:
"""
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]:
""" """
Returns Returns
------- -------
@ -78,6 +37,24 @@ class LoggerLevels:
""" """
return [cls.QUIET, cls.INFO, cls.VERBOSE, cls.DEBUG] 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 @classmethod
def names(cls) -> List[str]: def names(cls) -> List[str]:
""" """
@ -85,19 +62,25 @@ class LoggerLevels:
------- -------
All log level names 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: class Logger:
# The level set via CLI arguments # The level set via CLI arguments
_LEVEL = LoggerLevels.DEBUG _LOGGER_LEVEL: LoggerLevel = LoggerLevels.DEBUG
_DEBUG_LOGGER_FILE = None _DEBUG_LOGGER_FILE = None
@classmethod @classmethod
def set_log_level(cls, log_level: int): def set_log_level(cls, log_level_name: str):
cls._LEVEL = log_level """
Parameters
----------
log_level_name
Name of the log level to set
"""
cls._LOGGER_LEVEL = LoggerLevels.from_str(name=log_level_name)
@classmethod @classmethod
def _get_formatter(cls) -> logging.Formatter: def _get_formatter(cls) -> logging.Formatter:
@ -116,7 +99,7 @@ class Logger:
Logger handler Logger handler
""" """
handler = logging.StreamHandler(sys.stdout) 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()) handler.setFormatter(cls._get_formatter())
return handler return handler
@ -142,7 +125,7 @@ class Logger:
logger_name += f":{name}" logger_name += f":{name}"
logger = logging.Logger(name=logger_name, level=logging.DEBUG) 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()) logger.addHandler(cls._get_stdout_handler())
if debug_file: if debug_file:
logger.addHandler(cls._get_debug_file_handler()) 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:<name>]. Optional. Name of the logger which is included in the prefix like [ytdl-sub:<name>].
If None, the prefix is just [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 io.StringIO() as redirect_stream:
with contextlib.redirect_stdout(new_target=redirect_stream): with contextlib.redirect_stdout(new_target=redirect_stream):

View file

@ -22,7 +22,7 @@ class TestLogger:
], ],
) )
def test_logger_info_stdout(self, capsys, log_level, outputs_to_stdout): 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 = Logger.get(name="name_test")
logger.info("test") logger.info("test")
@ -43,7 +43,7 @@ class TestLogger:
], ],
) )
def test_logger_debug_stdout(self, capsys, log_level, outputs_to_stdout): 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 = Logger.get(name="name_test")
logger.debug("test") logger.debug("test")
@ -64,7 +64,7 @@ class TestLogger:
], ],
) )
def test_logger_always_outputs_to_debug_file(self, log_level): 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 = Logger.get(name="name_test")
logger.info("info test") logger.info("info test")
@ -85,7 +85,7 @@ class TestLogger:
], ],
) )
def test_handle_external_logs(self, capsys, log_level, expected_stdout): 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"): with Logger.handle_external_logs(name="name_test"):
print("test line 1") print("test line 1")
print("test line 2") print("test line 2")