使用 python 日志记录包,如何将附加格式插入具有自己的格式化程序的多个记录器处理程序中?

Evg*_*gen 5 python logging formatter

我有一个带有多个处理程序的记录器,它们有自己的格式化程序。现在我想添加一个缩进功能,在运行时控制缩进级别。我希望来自所有处理程序的消息获得此缩进。我尝试将其创建为过滤器,但发现我似乎无法更改消息内容。然后我尝试将其用作格式化程序,但每个处理程序只能有一个。如何在不显式更改每个处理程序的格式化程序的情况下添加此类缩进?
我应该提到我拥有的格式化程序之一是一个为输出添加颜色的类。它不是一个简单的格式字符串。


此外,我正在使用配置文件。理想情况下,我希望能够主要从那里驾驶它。但是,我需要修改缩进格式化程序的状态(例如设置缩进级别),但我不知道如何访问该特定格式化程序,因为没有logger.getFormatter("by_name")方法。
澄清一下,我需要访问特定的格式化程序实例,主要是为了即时调整格式。该实例已通过文件中的 logging.config 创建。我没有找到任何允许我根据其名称获取特定格式化程序的访问器方法。

Lau*_*low 5

#!/usr/bin/env python

import logging
from random import randint

log = logging.getLogger("mylog")
log.setLevel(logging.DEBUG)

class MyFormatter(logging.Formatter):
    def __init__(self, fmt):
        logging.Formatter.__init__(self, fmt)

    def format(self, record):
        indent = " " * randint(0, 10) # To show that it works
        msg = logging.Formatter.format(self, record)
        return "\n".join([indent + x for x in msg.split("\n")])

# Log to file
filehandler = logging.FileHandler("indent.txt", "w")
filehandler.setLevel(logging.DEBUG)
filehandler.setFormatter(MyFormatter("%(levelname)-10s %(message)s"))
log.addHandler(filehandler)

# Log to stdout too
streamhandler = logging.StreamHandler()
streamhandler.setLevel(logging.INFO)
streamhandler.setFormatter(MyFormatter("%(message)s"))
log.addHandler(streamhandler)

# Test it
log.debug("Can you show me the dog-kennels, please")
log.info("They could grip it by the husk")
log.warning("That's no ordinary rabbit!")
log.error("Nobody expects the spanish inquisition")
try:
    crunchy_frog()
except:
    log.exception("It's a real frog")
Run Code Online (Sandbox Code Playgroud)

结果:

    他们可以抓住它的外壳
    那不是普通的兔子!
          没有人期望西班牙宗教裁判所
         这是一只真正的青蛙
         回溯(最近一次调用最后一次):
           文件“./logtest2.py”,第 36 行,在 
             crunchy_frog()
         NameError:未定义名称“crunchy_frog”

我不确定我是否理解你的第二个问题。


Evg*_*gen 1

这是另一种,虽然很老套,但很简单。我的所有处理程序的消息始终以消息级别字符串开头。只需在每次缩进更改时修改这些该死的字符串即可:

# (make a LEVELS dict out of all the logging levels first)    
def indent(self, step = 1):
        "Change the current indent level by the step (use negative to decrease)"
        self._indent_level += step
        if self._indent_level < 0:
            self._indent_level = 0
        self._indent_str = self._indent_str_base * self._indent_level
        for lvl in LEVELS:
            level_name = self._indent_str + LEVELS[lvl]
            logging.addLevelName(lvl, level_name)
Run Code Online (Sandbox Code Playgroud)

(有关缩进功能的内容,请参阅我的其他答案)
现在缩进器可以是一个独立的类,而不会弄乱日志记录过程的细节。只要消息包含级别字符串,就会出现缩进,即使在它之前有一些内容。一般来说并不理想,但可能对我有用。
有人有更多适用于任何消息格式的想法吗?