我已经用Python开发了一个记录器的实现。我知道Python已经有了内置的记录器,我的目标是获得改进的反馈和建议,特别是关于代码结构的建议。
代码在这里:
from .helpers import write_txt
from enum import Enum
from datetime import datetime
# Define type formats of messages
class LogFormats(Enum):
TITLE = 'title'
SUBTITLE = 'subtitle'
ERROR = 'error'
TAB = 'tab'
DEFAULT = 'default'
# Handler functions for output messages with different formats
def format_title(message: str, time: str) -> str:
to_print = f"\n[{time}] ### ### {message.upper()} ### ###\n"
return to_print
def format_subtitle(message: str, time: str) -> str:
to_print = f"[{time}] *** *** {message.upper()} *** ***"
return to_print
def format_error(message: str, time: str) -> str:
to_print = f"[{time}]\t ERROR: {message}"
return to_print
def format_tab(message: str, time: str) -> str:
to_print = f"[{time}]\t {message}"
return to_print
def format_default(message: str, time: str) -> str:
to_print = f"[{time}] - {message}"
return to_print
# Handler functions dispatcher
FORMATTER_DISPATCH = {
LogFormats.TITLE: format_title,
LogFormats.SUBTITLE: format_subtitle,
LogFormats.ERROR: format_error,
LogFormats.TAB: format_tab,
LogFormats.DEFAULT: format_default
}
class txtFileLogger():
"""Provides functionality for logging to a txt file"""
registry: str = ''
@classmethod
def register_log(cls, msg: str) -> None:
cls.registry = cls.registry + '\n' + msg
@classmethod
def output_log_to_txt(cls, filename = 'txt_log') -> None:
write_txt(cls.registry, filename)
# ===================
# MAIN CLASS
#====================
class Logger():
"""Format log messages and outputs it to the console. Also, provide methods for dumping the log session to a txt file."""
txt_logger = txtFileLogger
silenced = False
@classmethod
def log(cls,
message: str,
format: LogFormats = LogFormats.DEFAULT,
hidden: bool = False
) -> None:
"""
Logs a log message.
This function logs a message and prints it to the console. The log type can be specified for different message formats. Also the console output can be toggled.
Args:
message (str): The message to be logged.
type (LogTypes, optional): The log type.
hidden (bool, optional): If set to True, hides the log in the console for this message. The message will be registered and dumped in txt file regardless of this option.
"""
current_time = datetime.now().strftime("%H:%M:%S")
msg = str(message)
# Format log message according to selected type format
log_type = LogFormats(format)
formatter = FORMATTER_DISPATCH[log_type]
formated_msg = formatter(msg, current_time)
# Registers log for txt file output
cls.txt_logger.register_log(formated_msg)
# Print log to console
if not hidden and not cls.silenced:
print(formated_msg)
@classmethod
def dump_log_to_txt(cls, filename: str) -> None:
"""Writes log to a txt file"""
cls.txt_logger.output_log_to_txt(filename)
@classmethod
def mute(cls) -> None:
"""Disables console output."""
cls.silenced = True
print('[Logger] - *** Output to console is currently silenced ***')
@classmethod
def unmute(cls) -> None:
"""Enables console output."""
cls.silenced = False
print('[Logger] - *** Enabling logging to console ***')我使用类作为一种“单例”来实现这一点。因此,我可以在不同的文件中调用记录器,并为注册表提供一个单一的真实来源。使用示例:
import Logger
log = Logger.log
log('message 1', format='title')
log('message 2', format='subtitle')
log('error message', format='error')
Logger.dump_log_to_txt('foo_filename')一些一般性问题:
我感谢任何反馈意见和建议。谢谢!
发布于 2023-04-08 15:41:29
您的所有format_函数都可以重构为具有命名参数的格式字符串,如
"\n[{time}] ### ### {message} ### ###\n"然后可以通过.format(time=x, message=x)在一个位置进行格式化。
LogFormats相当困惑。其中一些条目是“严厉”(ERROR),一些是格式,其中一个是DEFAULT,应该设置为与DEFAULT = PLAIN这样的不同命名格式相等。
txtFileLogger需要在TitleCase中,因为它是一个类。另外,它应该是一个包含文件名成员的非静态类,write_txt应该作为一个成员函数移到它中。每个目标文件应该有一个实例。
不继承任何东西的类不应该接收()后缀。
Logger也应该是一个非静态类。如果一个记录员被迫成为一个单身人士,那是没有帮助的。至多,让Logger成为一个普通类,既可以实例化,也可以提供默认的全局实例。
hidden很尴尬。您已经有效地对一个机制进行了硬编码,其中一个文件的最小严重性低于控制台。看看内置记录器是如何做到这一点的;您可以将控制台和文件配置成不同的严重程度,然后客户端可能会幼稚到哪个目标关心哪个严重程度,并为每个日志条目提供一个单一的严重性。
“效率”是一个很有意义的术语。使用内置记录器。如果您试图推送如此多的日志量,以致内置记录器在时间或空间上是一个限制因素,那么您可能记录太多,而不是试图优化一个主卷版本,您应该限制您的日志记录。以一种非结构化的方式有效地记录的东西是有上限的。(结构化日志是一个不同的主题。)在这方面,对效率的担忧是过早的优化。
对于实践来说,好吧,我想,但在现实生活中,不要这样做,而使用内置记录器。
https://codereview.stackexchange.com/questions/284365
复制相似问题