Python 日志格式器和字符串格式不要混用
Python log formatter and string formatting don't mix
我有一个使用 Formatter 的记录器,需要记录包含变量的消息。够正常的。如果我的记录器不使用格式化程序,一切都很好。如果是这样,它突然就不知道如何进行格式字符串扩展了。这很奇怪。
所以如果我有这个:
import logging
import sys
logger = logging.getLogger("test_logger")
normal_handler = logging.StreamHandler(sys.stdout)
formatted_handler = logging.FileHandler("testlog.txt")
logger.setLevel(logging.DEBUG)
normal_handler.setLevel(logging.DEBUG)
formatted_handler.setLevel(logging.DEBUG)
record_format = "(%(asctime)s %(module)s %(funcName)s) %(msg)s"
timestamp_format = "[%Y-%m-%d %H:%M:%S]"
formatter = logging.Formatter(fmt=record_format, datefmt=timestamp_format)
formatted_handler.setFormatter(formatter)
logger.addHandler(normal_handler)
logger.addHandler(formatted_handler)
test_var = "bar"
logger.info("foo %s", test_var)
...然后在 stdout 上我得到了预期的输出:foo bar
...但是在使用格式化程序的日志文件中我得到:([2021-03-30 11:20:29] <stdin> <module>) foo %s
我知道格式化程序带有样式参数,但是 a) 我不能使用它,因为我也必须支持 python 2,并且 b) 即使我确实使用了它,python 2也有同样的问题,所以无论如何都无法解决问题。我可以在将它们发送到记录器之前预先格式化我的日志消息,但我认为这是不鼓励的(当然 pylint 抱怨它,我真的不想禁用 pylint 警告而不是解决问题)。
请问我错过了什么?
您看到这个的原因是因为在您的格式字符串中,您使用 msg
键明确要求预先格式化的原始字符串。如果您将该行中的 msg
更改为 message
,这是格式化日志字符串的键,它们都会输出“foo bar”。
record_format = "(%(asctime)s %(module)s %(funcName)s) %(message)s"
我有一个使用 Formatter 的记录器,需要记录包含变量的消息。够正常的。如果我的记录器不使用格式化程序,一切都很好。如果是这样,它突然就不知道如何进行格式字符串扩展了。这很奇怪。
所以如果我有这个:
import logging
import sys
logger = logging.getLogger("test_logger")
normal_handler = logging.StreamHandler(sys.stdout)
formatted_handler = logging.FileHandler("testlog.txt")
logger.setLevel(logging.DEBUG)
normal_handler.setLevel(logging.DEBUG)
formatted_handler.setLevel(logging.DEBUG)
record_format = "(%(asctime)s %(module)s %(funcName)s) %(msg)s"
timestamp_format = "[%Y-%m-%d %H:%M:%S]"
formatter = logging.Formatter(fmt=record_format, datefmt=timestamp_format)
formatted_handler.setFormatter(formatter)
logger.addHandler(normal_handler)
logger.addHandler(formatted_handler)
test_var = "bar"
logger.info("foo %s", test_var)
...然后在 stdout 上我得到了预期的输出:foo bar
...但是在使用格式化程序的日志文件中我得到:([2021-03-30 11:20:29] <stdin> <module>) foo %s
我知道格式化程序带有样式参数,但是 a) 我不能使用它,因为我也必须支持 python 2,并且 b) 即使我确实使用了它,python 2也有同样的问题,所以无论如何都无法解决问题。我可以在将它们发送到记录器之前预先格式化我的日志消息,但我认为这是不鼓励的(当然 pylint 抱怨它,我真的不想禁用 pylint 警告而不是解决问题)。
请问我错过了什么?
您看到这个的原因是因为在您的格式字符串中,您使用 msg
键明确要求预先格式化的原始字符串。如果您将该行中的 msg
更改为 message
,这是格式化日志字符串的键,它们都会输出“foo bar”。
record_format = "(%(asctime)s %(module)s %(funcName)s) %(message)s"