Python:管理日志处理程序的最佳实践

ih99xse1  于 2023-06-28  发布在  Python
关注(0)|答案(1)|浏览(107)

日志记录器示例化的最佳实践是什么?目前,我正在使用它来创建一个logger:

def create_logger(logger_name='default_logger_name', tags={"application": "default-app", "environment": "development"}):
    handler = logging_loki.LokiQueueHandler(
        Queue(-1),
        url="https://somewhere",
        tags=tags,
        auth=("some", "thing="),
        version="1",
    )

    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.DEBUG)
    logger.addHandler(handler)
    logger.addHandler(get_console_handler())
    return logger

def get_console_handler():
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.DEBUG)
    log_format = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    console_handler.setFormatter(log_format)

    return console_handler

然后打电话

self.logger = create_logger(__name__)

在任何我想写日志的课上。这有两个问题。第一个是我的班级突然和loki结合在一起这显然是不好的。第二个问题是,即使我没有使用任何使用额外模块的处理程序,我注意到在单元测试期间,我必须在不同的测试之间显式删除处理程序,否则我将获得第二次运行的测试的输出的2倍,第三次运行的输出的3倍等等,因为重复的处理程序一直在添加而没有被删除。我应该使用什么样的模式来避免这些问题?我想到的第一件事是在类构造函数中传递日志记录器创建方法。这解决了第一个问题,但没有解决必须移除处理程序的问题。第二种方法是传递一个日志记录器示例,并处理类外部的所有内容(比如在测试之间删除处理程序)。然而,这仍然会让我不得不做一个显式的处理程序删除,这感觉有点奇怪。

w8ntj3qf

w8ntj3qf1#

推荐的做法是只向根日志记录器添加处理程序,并且只使用配置API(如logging.config.dictConfig)执行一次,从main()函数或if __name__ == '__main__'子句调用它。您可能需要一个工厂函数来示例化自定义处理程序,如

def loki_hander_factory(url, tags, auth, version):
    return logging_loki.LokiQueueHandler(
        Queue(-1),
        url=url,
        tags=tags,
        auth=auth,
        version=version,
    )

然后你可以通过如下配置来使用它:

handlers:
  loki:
    '()' : mypkg.util.loki_handler_factory
    level   : INFO
    url: https://somewhere
    tags:
        application: 'default-app'
        environment: development
    auth: [some, 'thing=']
    version: '1'

而配置可以是

import logging.config
import yaml

if __name__ == '__main__':
    with open('logging_conf.yaml') as f:
        d = yaml.safe_load(f)
    logging.config.dictConfig(d)

以上只是配置的部分YAML代码段;您可以参考链接文档以获取更多信息。当然,您也可以使用JSON或Python代码作为配置字典。

相关问题