Lev*_*wan 6 python logging subclass python-3.x python-logging
我向记录器添加了两个具有不同格式化程序的处理程序。第一个需要子类化logging.Formatter来进行自定义格式化。默认格式化程序足以满足第二个处理程序的需要。
假设第一个格式化程序只是从消息中删除换行符。以下脚本说明了看似奇怪的行为:
import logging
logger = logging.getLogger(__name__)
class CustomFormatter(logging.Formatter):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def format(self, record):
record.msg = record.msg.strip().replace('\n', ' ')
return super().format(record)
h1 = logging.StreamHandler()
formatter1 = CustomFormatter(fmt=None, datefmt=None)
h1.setFormatter(formatter1)
logger.addHandler(h1)
h2 = logging.StreamHandler()
formatter2 = logging.Formatter(fmt=None, datefmt=None)
h2.setFormatter(formatter2)
logger.addHandler(h2)
logger.warning('string with\nmultiple lines')
Run Code Online (Sandbox Code Playgroud)
输出如下:
string with multiple lines
string with multiple lines
Run Code Online (Sandbox Code Playgroud)
我期望的是这个:
string with multiple lines
string with
multiple lines
Run Code Online (Sandbox Code Playgroud)
第二个格式化程序不应实现 的行为CustomFormatter,但它确实实现了。当我反转处理程序添加到记录器的顺序时,这种情况不会发生。
除非我误解了子类化,否则不应通过重写子类中的方法来更改基类的行为。当我重写除 之外的类的方法时,这似乎不是问题logging.Formatter。
这是日志记录模块中的错误,还是我在这里遗漏了一些东西?
This line was your down fall:
record.msg = record.msg.strip().replace('\n', ' ')
Run Code Online (Sandbox Code Playgroud)
You reassigned the scrubbed string to the record which is used by all remaining handlers/formatters attached to the logger. Copy the record and it works:
import logging
from copy import copy
logger = logging.getLogger(__name__)
class CustomFormatter(logging.Formatter):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def format(self, record):
record = copy(record)
record.msg = record.msg.strip().replace('\n', ' ')
return super().format(record)
h1 = logging.StreamHandler()
formatter1 = CustomFormatter(fmt=None, datefmt=None)
h1.setFormatter(formatter1)
logger.addHandler(h1)
h2 = logging.StreamHandler()
formatter2 = logging.Formatter(fmt=None, datefmt=None)
h2.setFormatter(formatter2)
logger.addHandler(h2)
logger.warning('string with\nmultiple lines')
Run Code Online (Sandbox Code Playgroud)
Outputs
string with multiple lines
string with
multiple lines
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2389 次 |
| 最近记录: |