python - 防止Python日志库的双重输出

标签 python python-3.x logging

对。我正在运行一个相当复杂的(对我来说)基于对象的模型,并且我希望让我的输出按顺序排列。以前,我只是使用 print() 将输出转储到控制台,如果我想打开和关闭不同的输出,则将 if 函数附加到它们。虽然这在基本代码上工作得很好,但我对这个项目有点不感兴趣(这比我之前尝试过的事情大一个数量级)。我知道 python 日志库允许我更整洁地执行此操作并将其输出到日志文件等。

就目前情况而言,代码在运行时运行此函数,这会按照我想要的方式设置所有内容(我认为)。我已将其设置在模型内,因为我将进行整体运行,并且我想每次新运行时都重命名日志文件。

def set_logger(file_name):
    '''sets up output via loggers and a output file.'''
    output = ('%(asctime)-20s %(filename)-15s %(funcName)-15s %(levelname)-8s %(message)s')
    logging.basicConfig(level=logging.DEBUG,
                        format=output,
                        filename=file_name,
                        filemode='w')
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    formatter = logging.Formatter('%(message)s')
    console.setFormatter(formatter)
    logging.getLogger('').addHandler(console)
    return

此代码输出从 DEBUG 级别到日志文件的所有内容,同时显示 INFO 到控制台。

我的问题是,执行完成后记录器似乎保持事件状态,因此我第一次运行时会得到双行控制台输出(尽管不在日志文件中),下次运行时会得到三行,所以on...我认为这与此行有关: logging.getLogger('').addHandler(console),因为每次运行代码时我都会添加一个新的处理程序。

有没有既定的方法可以避免这种情况?我希望能够正常运行代码并让它检测是否存在 console 的现有实例,如果存在则不复制它,但是文档很难理解这个,把我难住了。

有什么建议吗?谢谢!

最佳答案

只需检查您的 RootLogger (logging.getLogger('')) 是否具有处理程序:

def set_logger(file_name):
    '''sets up output via loggers and a output file.'''
    output = ('%(asctime)-20s %(filename)-15s %(funcName)-15s %(levelname)-8s %(message)s')
    logging.basicConfig(level=logging.DEBUG,
                        format=output,
                        filename=file_name,
                        filemode='w')
    root_logger = logging.getLogger('')
    if len(root_logger.handlers) > 0: # verifies if it has already a handler
        console = logging.StreamHandler()
        console.setLevel(logging.INFO)
        formatter = logging.Formatter('%(message)s')
        console.setFormatter(formatter)
        root_logger.addHandler(console)

但是,如果将来您有多个处理程序,并且您想要检查记录器中是否有一个特定的处理程序,您可以更精确地命名您的处理程序:

def set_logger(file_name):
    '''sets up output via loggers and a output file.'''
    output = ('%(asctime)-20s %(filename)-15s %(funcName)-15s %(levelname)-8s %(message)s')
    logging.basicConfig(level=logging.DEBUG,
                        format=output,
                        filename=file_name,
                        filemode='w')
    root_logger = logging.getLogger('')
    # Verify if there is already a handler named "console"
    if any((handler.name == "console" for handler in root_logger.handlers)):
        console = logging.StreamHandler()
        console.name = "console"
        console.setLevel(logging.INFO)
        formatter = logging.Formatter('%(message)s')
        console.setFormatter(formatter)
    root_logger.addHandler(console)

关于python - 防止Python日志库的双重输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50414473/

相关文章:

ruby-on-rails - 如何测试 Rack 中间件?

java - java Logger中的日志计数器

python - 使用 read_xml 将数据从两个 XML 父节点导入到 Pandas DataFrame

python - 氟奋乃静读作\xef\xac\x82uphenazine

python - 为什么 mypy 在 MonkeyType 自动注释的模块上失败?

python-3.x - 如何在管道中使用适当的 FunctionTransformer 制作 GridSearchCV?

python - Python 中的信号处理程序和日志记录

Python 的引用传递

python - 在 Multiindex Pandas 系列中获取每个组中最大的一个

python - 带有 tkinter 的很长的 list 框