Python logging.Formatter 使用“%”格式而不是“{”,即使指定了“{”
Python logging.Formatter uses "%"-formatting instead of "{" even when "{" specified
我尝试创建一个带有自定义格式化程序的自定义记录器,相应地从 logging.Logger
和 logging.Formatter
继承它们。但是,即使我将 style
指定为 "{"
,我也会收到错误消息。据我所知,这个错误是由于格式化程序试图使用旧式 %
格式进行格式化造成的。
这是我的 logger.py
、formatter.py
和 main.py
的示例,用于重现此内容。
# logger.py
import logging
from formatter import CustomFormatter
class CustomLogger(logging.Logger):
def __init__(self, name: 'str'):
super().__init__(name)
self._console_handler = logging.StreamHandler()
format_string_for_console = '[{levelname}] {name}: {message}'
time_format_string = '%Y-%m-%d %H:%M:%S%Z'
console_formatter = CustomFormatter(
fmt=format_string_for_console,
datefmt=time_format_string,
style='{')
self._console_handler.setFormatter(console_formatter)
# formatter.py
import copy
import logging
class CustomFormatter(logging.Formatter):
def __init__(self, fmt: 'str' = None, datefmt: 'str' = None, style: 'str' = '%'):
self.__format = f'Some modification to default format {fmt}'
self.__date_format = datefmt
self.__style = style
super().__init__(fmt, datefmt, style)
def format(self, record: 'logging.LogRecord') -> str:
record_copy = copy.copy(record)
return logging.Formatter(
fmt=self.__format,
datefmt=self.__date_format,
style=self.__style
).format(record_copy)
# main.py
from logger import CustomLogger as CL
logger = CL('test_logger')
logger.warning('info_msg {}', 1)
别跟我说这个MVP可笑,它被极度缩小到尽可能少,但仍然重现错误。我得到的错误有这个堆栈跟踪:
--- Logging error ---
Traceback (most recent call last):
File "/usr/lib/python3.8/logging/__init__.py", line 1085, in emit
msg = self.format(record)
File "/usr/lib/python3.8/logging/__init__.py", line 929, in format
return fmt.format(record)
File "/usr/lib/python3.8/logging/__init__.py", line 668, in format
record.message = record.getMessage()
File "/usr/lib/python3.8/logging/__init__.py", line 373, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
File "<stdin>", line 1, in <module>
Message: 'info_msg {}'
Arguments: (1,)
我一定是做错了什么,但我不知道是什么。任何帮助将不胜感激。
有两种格式:
- 正在格式化记录调用中传递的消息和参数。为了向后兼容,这些 始终 使用
%
格式化 - 日志记录早于其他类型的格式化。
- 将上一步生成的消息与事件时间、进程 ID、线程 ID、当前函数、当前模块以及传递给日志记录调用的任何其他上下文信息等其他内容一起格式化。此级别可以使用传递给格式化程序的
style
来决定如何格式化消息。在这种更高级别的格式化中,格式化程序的格式字符串中的 message
将保存在上一步中确定的值。
我尝试创建一个带有自定义格式化程序的自定义记录器,相应地从 logging.Logger
和 logging.Formatter
继承它们。但是,即使我将 style
指定为 "{"
,我也会收到错误消息。据我所知,这个错误是由于格式化程序试图使用旧式 %
格式进行格式化造成的。
这是我的 logger.py
、formatter.py
和 main.py
的示例,用于重现此内容。
# logger.py
import logging
from formatter import CustomFormatter
class CustomLogger(logging.Logger):
def __init__(self, name: 'str'):
super().__init__(name)
self._console_handler = logging.StreamHandler()
format_string_for_console = '[{levelname}] {name}: {message}'
time_format_string = '%Y-%m-%d %H:%M:%S%Z'
console_formatter = CustomFormatter(
fmt=format_string_for_console,
datefmt=time_format_string,
style='{')
self._console_handler.setFormatter(console_formatter)
# formatter.py
import copy
import logging
class CustomFormatter(logging.Formatter):
def __init__(self, fmt: 'str' = None, datefmt: 'str' = None, style: 'str' = '%'):
self.__format = f'Some modification to default format {fmt}'
self.__date_format = datefmt
self.__style = style
super().__init__(fmt, datefmt, style)
def format(self, record: 'logging.LogRecord') -> str:
record_copy = copy.copy(record)
return logging.Formatter(
fmt=self.__format,
datefmt=self.__date_format,
style=self.__style
).format(record_copy)
# main.py
from logger import CustomLogger as CL
logger = CL('test_logger')
logger.warning('info_msg {}', 1)
别跟我说这个MVP可笑,它被极度缩小到尽可能少,但仍然重现错误。我得到的错误有这个堆栈跟踪:
--- Logging error ---
Traceback (most recent call last):
File "/usr/lib/python3.8/logging/__init__.py", line 1085, in emit
msg = self.format(record)
File "/usr/lib/python3.8/logging/__init__.py", line 929, in format
return fmt.format(record)
File "/usr/lib/python3.8/logging/__init__.py", line 668, in format
record.message = record.getMessage()
File "/usr/lib/python3.8/logging/__init__.py", line 373, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting
Call stack:
File "<stdin>", line 1, in <module>
Message: 'info_msg {}'
Arguments: (1,)
我一定是做错了什么,但我不知道是什么。任何帮助将不胜感激。
有两种格式:
- 正在格式化记录调用中传递的消息和参数。为了向后兼容,这些 始终 使用
%
格式化 - 日志记录早于其他类型的格式化。 - 将上一步生成的消息与事件时间、进程 ID、线程 ID、当前函数、当前模块以及传递给日志记录调用的任何其他上下文信息等其他内容一起格式化。此级别可以使用传递给格式化程序的
style
来决定如何格式化消息。在这种更高级别的格式化中,格式化程序的格式字符串中的message
将保存在上一步中确定的值。