我已经用Python实现了一个记录器。基本上,这个想法是让记录器具有多个处理程序。我通过以下yaml配置来实现
version: 1
formatters:
simple:
format: "%(name)s - %(lineno)d - %(message)s"
complex:
format: "%(asctime)s - %(name)s | %(levelname)s | %(module)s : [%(filename)s: %(lineno)d] - %(message)s"
json:
class: utils.logger.JsonFormatter
format: '%(asctime)s %(name)s %(levelname)s %(module)s %(filename)s: %(message)s'
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: json
file:
class: logging.handlers.TimedRotatingFileHandler
when: midnight
backupCount: 5
level: DEBUG
formatter: complex
filename : /tgs_workflow/logs/tgs_logs.log
cloud:
class: utils.logger.GoogleLogger
formatter: json
level: INFO
loggers:
cloud:
level: INFO
handlers: [console,file,cloud]
propagate: yes
__main__:
level: DEBUG
handlers: [console,file,cloud]
propagate: yes
在Yaml中,我创建了一个类GoogleLogger
和一个类JsonFormatter
,这些是平时唯一的事情。
为了使其正常工作,我想使用我的记录仪的任何地方(实例化):
import logging
import logging.config
import yaml
with open('/tgs_workflow/logging.yaml','rt') as f:
config=yaml.safe_load(f.read())
f.close()
logging.config.dictConfig(config)
logger = logging.getLogger(__name__)
logger.info("This info")
现在这里有两个问题
Q1。必须在每个我希望使用它的类/脚本中实例化它,这是一种不好的做法吗?这也意味着有很多冗余代码。 (相同的代码,多个位置)
Q2。我通常将其放在__main__
中,但是当我的班级没有主体但包含日志记录时会发生什么情况?我绝对知道将其放在文件顶部不是一个好主意。
例如对于第二季度:这是一个非常糟糕的例子,但我只是想强调一个类将需要一些日志记录
import logging
"""
>>>Insert Instantiator here <<<
"""
class Tools():
def __init__(self, name, age):
self.name = name
self.age = age
def who_am_i(self, name, age):
try:
if (self.name == "Adam"):
return True
logging.info("This was Adam")
else:
return False
logging.info("This was not Adam")
except Exception:
logging.error("There is an error")
我使用记录器的唯一方法是在课程顶部包含我的 Instantiator 。那一定是不正确的,或者至少不是最佳实践吗?正确的方法是什么?
答案 0 :(得分:1)
方法是坚持使用名称,而不对每个模块/文件使用不同的记录器,或者使用层次结构。如果您的工具类是通过main导入的,则__main__
和cloud
将已经配置并可以使用。您所需要做的就是将>>>Insert Instantiator here <<<
替换为logger = logging.getLogger('__main__')
,一切顺利。如果您不想直接在主记录器上使用,可以加一个点使其成为层次结构。 logger = logging.getLogger('__main__.tools')
。现在,这是一个记录器,它将其日志传播到__main__
记录器,但可以具有自己的级别,等等。