Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:从不同模块登录到同一文件的正确方法_Python_Logging - Fatal编程技术网

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()将不会添加处理程序”。只有当它是同一个处理程序对象时(该答案中的hdlr
    hdlr
    ),你说的才是真的。如果每次都创建处理程序,你说的就不是真的。(请参阅同一问题。)在这个问题中,如果每个文件都可以创建一个新的处理程序(
    logging.FileHandler(…)
    ),您的答案是不正确的。