Python:从不同模块登录到同一文件的正确方法
随着时间的推移,我已经编写了一系列脚本,我正在重构脚本以保留代码。我目前在各种脚本中使用了以下内容:Python:从不同模块登录到同一文件的正确方法,python,logging,Python,Logging,随着时间的推移,我已经编写了一系列脚本,我正在重构脚本以保留代码。我目前在各种脚本中使用了以下内容: if __name__ == '__main__': logger = logging.getLogger('dbinit') hdlr = logging.FileHandler('/var/logs/tmp/foo.log') formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
if __name__ == '__main__':
logger = logging.getLogger('dbinit')
hdlr = logging.FileHandler('/var/logs/tmp/foo.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.WARNING)
与其在每个脚本(即“模块”)中重复这一点,我希望在某个地方对记录器进行初始化,并通过各种脚本进行访问(嗯,可能封装在一个单例类中?)
如果我不能做到这一点(即将记录器初始化代码放在一个核心模块中),我假设通过在logging.FileHandler()调用中使用相同的日志文件名,各种脚本将写入相同的文件
这个假设正确吗
最后但并非最不重要的一点是,解决此问题的最佳实践(即Pythonic)方法是什么?因此,在许多地方使用此类init代码不会有什么坏处
如果我不能这样做(即,将记录器初始化代码放在一个
核心模块)
如果您想确保初始化代码只运行一次,您可以这样做,并且应该这样做。鉴于您使用的是
如果
,我假设这些脚本将作为不同的进程运行。如果是这种情况,那么应该使用单独的配置文件
此配置可以以文档中指定的格式存储在文件中。然后,可以使用logging.config.fileConfig
加载文件。您还可以将配置存储为JSON/YAML格式,将其转换为字典,并使用logging.config.dictConfig
加载它。后者是目前推荐的方法,尽管我认为前者更直接。阅读了解更多信息
使用配置文件方法的优点有很多:
在python模块中创建一个函数,如下所示:
def createLogHandler(job_name,log_file):
logger = logging.getLogger(job_name)
## create a file handler ##
handler = logging.FileHandler(log_file)
## create a logging format ##
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
现在按如下方式调用程序中的函数:
job_name = 'dbinit'
log_file = '/var/logs/tmp/foo.log'
logger = createLogHandler(job_name ,log_file )
logger.info('Logger has been created')
Related:Related:我认为您是在引用“如果处理程序已经存在,addHandler()将不会添加处理程序”。只有当它是同一个处理程序对象时(该答案中的hdlrhdlr
),你说的才是真的。如果每次都创建处理程序,你说的就不是真的。(请参阅同一问题。)在这个问题中,如果每个文件都可以创建一个新的处理程序(logging.FileHandler(…)
),您的答案是不正确的。