在使用Python的logging
模块进行日志记录时,为每个类定义一个记录器是最佳实践吗?
考虑到某些内容可能会重复,例如文件日志位置,我正在考虑将日志记录抽象成自己的类,并将一个实例导入到需要记录日志的每个类中。但是我不确定这是否是最佳实践?
在使用Python的logging
模块进行日志记录时,为每个类定义一个记录器是最佳实践吗?
考虑到某些内容可能会重复,例如文件日志位置,我正在考虑将日志记录抽象成自己的类,并将一个实例导入到需要记录日志的每个类中。但是我不确定这是否是最佳实践?
最佳实践是遵循Python软件(解)构成规则 - 模块是Python软件的单位,而不是类。因此,建议的方法是使用
logger = logging.getLogger(__name__)
在每个模块中,可以使用basicConfig()
或dictConfig()
配置记录日志。
记录器是单例的——没有必要将它们传递或存储在类的实例中。
使用JSON或YAML作为日志配置 - 在Python 2.7之后,您可以从字典中加载日志配置。这意味着您可以从JSON或YAML文件中加载日志配置。
YAML示例 -
version: 1
disable_existing_loggers: False
formatters:
simple:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
stream: ext://sys.stdout
info_file_handler:
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: simple
filename: info.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
error_file_handler:
class: logging.handlers.RotatingFileHandler
level: ERROR
formatter: simple
filename: errors.log
maxBytes: 10485760 # 10MB
backupCount: 20
encoding: utf8
loggers:
my_module:
level: ERROR
handlers: [console]
propagate: no
root:
level: INFO
handlers: [console, info_file_handler, error_file_handler]
参考文献 - Python中的良好日志记录实践
使用结构化日志。两个非常好的工具:
大多数日志记录系统告诉你应用程序中发生了什么, 而 eliot 还告诉你为什么会发生这种情况。
eliot 是一个 Python 日志记录系统,它输出行动的因果链: 行动可以产生其他行动,最终它们要么成功要么失败。 由此产生的日志记录告诉您软件做了什么:发生了什么以及是什么原因导致的。
结构化日志意味着您不会在日志中编写难以解析和难以保持一致的语句, 而是记录发生在上下文中的事件。
logger = logging.getLogger(__name__)
应该放在模块的顶部,而不是放在需要记录日志的每个函数/方法内部。 - industryworker3595112import
语句后面)。 - Vinay Sajip