UTF-8 在 Python 日志记录中,如何?

2024-05-08

我正在尝试使用 Python 的日志记录包将 UTF-8 编码的字符串记录到文件中。作为一个玩具示例:

import logging

def logging_test():
    handler = logging.FileHandler("/home/ted/logfile.txt", "w",
                                  encoding = "UTF-8")
    formatter = logging.Formatter("%(message)s")
    handler.setFormatter(formatter)
    root_logger = logging.getLogger()
    root_logger.addHandler(handler)
    root_logger.setLevel(logging.INFO)

    # This is an o with a hat on it.
    byte_string = '\xc3\xb4'
    unicode_string = unicode("\xc3\xb4", "utf-8")

    print "printed unicode object: %s" % unicode_string

    # Explode
    root_logger.info(unicode_string)

if __name__ == "__main__":
    logging_test()

这会在logging.info()调用上引发UnicodeDecodeError。

在较低级别,Python 的日志记录包使用 codecs 包打开日志文件,并传入“UTF-8”参数作为编码。这一切都很好,但它试图将字节字符串而不是 unicode 对象写入文件,这会导致爆炸。本质上,Python 正在这样做:

file_handler.write(unicode_string.encode("UTF-8"))

什么时候应该这样做:

file_handler.write(unicode_string)

这是 Python 中的错误,还是我服用了疯狂的药丸? FWIW,这是一个普通的 Python 2.6 安装。


有这样的代码:

raise Exception(u'щ')

Caused:

  File "/usr/lib/python2.7/logging/__init__.py", line 467, in format
    s = self._fmt % record.__dict__
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

发生这种情况是因为格式字符串是字节字符串,而某些格式字符串参数是带有非 ASCII 字符的 unicode 字符串:

>>> "%(message)s" % {'message': Exception(u'\u0449')}
*** UnicodeEncodeError: 'ascii' codec can't encode character u'\u0449' in position 0: ordinal not in range(128)

使格式字符串 unicode 可以解决该问题:

>>> u"%(message)s" % {'message': Exception(u'\u0449')}
u'\u0449'

因此,在您的日志记录配置中,将所有格式字符串设置为 unicode:

'formatters': {
    'simple': {
        'format': u'%(asctime)-s %(levelname)s [%(name)s]: %(message)s',
        'datefmt': '%Y-%m-%d %H:%M:%S',
    },
 ...

并修补默认值logging使用 unicode 格式字符串的格式化程序:

logging._defaultFormatter = logging.Formatter(u"%(message)s")
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UTF-8 在 Python 日志记录中,如何? 的相关文章

随机推荐