我有一个小记录器函数,它可能返回两个处理程序同时登录到RotatingFileHandler和sys.stdout。
import os, logging, sys
from logging.handlers import RotatingFileHandler
from config import *
def get_logger(filename, log_level_stdout=logging.WARNING, log_level_file=logging.INFO, echo=True):
logger = logging.getLogger(__name__)
if not os.path.exists(PATH + '/Logs'):
os.mkdir(PATH + '/Logs')
logger.setLevel(logging.DEBUG)
if echo:
prn_handler = logging.StreamHandler(sys.stdout)
prn_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s'))
prn_handler.setLevel(log_level_stdout)
logger.addHandler(prn_handler)
file_handler = RotatingFileHandler(PATH + '/Logs/' + filename, maxBytes=1048576, backupCount=3)
file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s'))
file_handler.setLevel(log_level_file)
logger.addHandler(file_handler)
return logger
一般情况下,这很好,但是某些正在记录的字符串似乎是用cp1252编码的,并在试图通过记录器函数将它们打印到stdout时抛出一个(非致命的)错误。应该注意的是,在错误消息中可以很好地打印相同的字符。将它们记录到文件中也不会引起任何问题。只有控制台-- sys.stdout --才会引发此错误。
--- Logging error ---
Traceback (most recent call last):
File "C:\Program Files\Python38\lib\logging\__init__.py", line 1084, in emit
stream.write(msg + self.terminator)
File "C:\Program Files\Python38\lib\encodings\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u1ecd' in position 65: character maps to <undefined>
Call stack:
File "script.py", line 147, in <module>
logger.info(f"F-String with a name in it: '{name}'.")
Message: "F-String with a name in it: 'Heimstọð'."
Arguments: ()
解决这一问题的方法是在调用记录器函数的代码中将获得的每一条消息编码为utf8,如下所示:
logger.info((f"F-String with a name in it: '{name}'.").encode('utf8'))
然而,我觉得这既不优雅,也不高效。还应该注意的是,文件的日志记录工作得很好,我已经尝试在Windows的系统变量中将PYTHONIOENCODING设置为utf-8,没有任何明显的效果。
更新:原来我很蠢。仅仅因为控制台中打印了错误消息,并不意味着将错误打印到控制台就是错误的原因。我正在研究对这里向我提出的另一个问题的答案,过了一段时间,我意识到,我对功能的“如果回声”部分所做的任何事情都没有对结果产生任何影响。最后一次检查是注释掉整个块,我仍然得到了错误。那时,我意识到这个问题实际上是由于在写入文件时没有强制执行UTF8造成的。将简单的kwarg编码=‘utf-8’添加到RotatingFileHandler中,就像@michael建议的那样,为我解决了这个问题。我不知道如何处理这个案子,因为,虽然这个答案解决了我的问题,但并不是因为我最初误解了问题的根本原因而提出的问题。我仍然会检查它作为解决方案,并对两个答案进行表决。我也将编辑这个问题,以避免误导未来的读者相信它会回答这个问题,而不是真正的。
发布于 2021-09-23 09:44:03
你能检查sys.stdout
(sys.stdout.encoding
)的编码吗?如果不是'utf-8'
,this answer可能会帮助重新配置编码。
https://stackoverflow.com/questions/69291738
复制相似问题