Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python日志中的UTF-8,如何实现?_Python_Logging_Unicode - Fatal编程技术网

Python日志中的UTF-8,如何实现?

Python日志中的UTF-8,如何实现?,python,logging,unicode,Python,Logging,Unicode,我正在尝试使用Python的日志记录包将UTF-8编码的字符串记录到文件中。例如: import logging def logging_test(): handler = logging.FileHandler("/home/ted/logfile.txt", "w", encoding = "UTF-8") formatter = logging.Formatter("%(message)s") h

我正在尝试使用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)
当它应该这样做时:

file_handler.write(unicode_string.encode("UTF-8"))
file_handler.write(unicode_string)
这是Python中的一个bug,还是我在服用疯狂的药丸?FWIW,这是一个普通的Python 2.6安装。

试试这个:

import logging

def logging_test():
    log = open("./logfile.txt", "w")
    handler = logging.StreamHandler(log)
    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.encode("utf8", "replace"))


if __name__ == "__main__":
    logging_test()

值得一提的是,我希望必须使用codecs.open以utf-8编码打开文件,但这是默认设置,或者这里正在进行其他操作,因为它是这样工作的。

检查您是否拥有最新的Python 2.6-自2.6发布以来,发现并修复了一些Unicode错误。例如,在我的Ubuntu Jaunty系统上,我复制并粘贴了你的脚本,只删除了日志文件名中的“/home/ted/”前缀。结果(从终端窗口复制和粘贴):

vinay@eta-jaunty:~/projects/scratch$python--版本 Python 2.6.2 vinay@eta-jaunty:~/projects/scratch$python utest.py 打印的unicode对象:0 vinay@eta-jaunty:~/projects/scratch$cat logfile.txt ô vinay@eta-洋洋得意:~/projects/scratch$ 在Windows框上:

C:\temp>python --version Python 2.6.2 C:\temp>python utest.py printed unicode object: ô C:\temp>python——版本 Python 2.6.2 C:\temp>python utest.py 打印的unicode对象:0 以及文件的内容:


这也可以解释为什么Lennart Regebro也无法复制它。

如果我正确理解了您的问题,那么当您执行以下操作时,您的系统也会出现同样的问题:

str(u'ô')
我想在Unix上自动编码到区域设置编码将不起作用,除非您在模块via中的
setencoding
函数中启用了区域设置感知
if
分支。该文件通常位于
/usr/lib/python2.x
中,无论如何都值得检查。AFAIK,默认情况下禁用了区域设置感知
setencoding
(对于我的Python 2.6安装是这样的)

这些选择包括:

  • 让系统找出将Unicode字符串编码为字节的正确方法,或者在代码中进行编码(需要在特定于站点的
    site.py
    中进行一些配置)
  • 在代码中编码Unicode字符串并仅输出字节
另请参见Ian Bicking和相关链接。

代码如下:

raise Exception(u'щ')
原因:

  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',
    },
 ...
并将默认的
日志记录
格式化程序修补为使用unicode格式字符串:

logging._defaultFormatter = logging.Formatter(u"%(message)s")

我在Python3中运行Django时也遇到了类似的问题:我的记录器在遇到一些Umlauts(äöüß)时死亡,但在其他方面情况良好。我查看了很多结果,发现没有一个有效。我试过了

import locale; 
if locale.getpreferredencoding().upper() != 'UTF-8': 
    locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') 
这是我从上面的评论中得到的。 它不起作用。看看当前的语言环境,我得到了一些疯狂的ANSI东西,结果基本上就是“ASCII”。这让我完全走错了方向

将日志格式字符串更改为Unicode不会有帮助。 在脚本的开头设置魔法编码注释没有帮助。 设置发件人消息的字符集(文本来自HTTP请求)没有帮助

工作原理是在
settings.py
中将文件处理程序上的编码设置为UTF-8。因为我没有设置任何内容,所以默认设置为
None
。这显然是ASCII码(或者我想说的是:ASS-KEY)

“处理程序”:{
“文件”:{
“级别”:“调试”,
'class':'logging.handlers.TimedRotatingFileHandler',

‘encoding’:‘UTF-8’,#我有点晚了,但我刚刚看到这篇文章,它使我能够非常轻松地设置UTF-8的登录

或者在这里输入代码:

root_logger= logging.getLogger()
root_logger.setLevel(logging.DEBUG) # or whatever
handler = logging.FileHandler('test.log', 'w', 'utf-8') # or whatever
formatter = logging.Formatter('%(name)s %(message)s') # or whatever
handler.setFormatter(formatter) # Pass handler as a parameter, not assign
root_logger.addHandler(handler)

你的代码在这里工作得非常好。我努力让它失败,但我没有成功。你是对的,python用UTF-8编码它,因为它询问outfile使用什么编码,而你指定了UTF-8,所以就这样。我不得不点击wayback机器来找到你提到的。很有趣。是的,就是这样。在在更高版本中修复的python日志记录包。我正在运行python 2.6.1(r261:675152010年2月11日00:51:29)[GCC 4.2.1(Apple Inc.build 5646)]在我的iMac上的darwin上,我仍然得到相同的错误。这个错误真的修复了吗?是的,它是-它发生在2.6.1和2.6.2之间,修订版69448:-所以你需要升级到更高的版本。Python 3.5呢?默认情况下不是所有字符串都应该是unicode吗?@Januszskoniczny你对Python 3有相同的问题吗?是的,我在docker con上有过tainer。我通过设置一组连接到操作系统编码的环境变量来解决这个问题。对于在这里遇到同样问题的任何人,请参见。@JanuszSkonieczny我在我的代码中所做的
import locale;if locale.getpreferredencoding().upper()!=“UTF-8”:locale.setlocale(locale.LC_ALL,'en_US.UTF-8')
在Windows 10上(ntdll.dll,ver:10.0.18362.1171)对于设置为cp1250(以及可能的其他版本)的系统编码,这可能会导致Python x64版本的异常(代码0xc0000374):3.8.2、3.9、3.8.6、3.7.1(以及可能的其他版本)。当心!@Gank你在使用python 3我猜谢谢@Chris它救了我:),只是想检查一下这是否在某种程度上等同于
supervisord]environment=LC\u ALL='en\u US.UTF-8',LANG='en\u US.UTF-8'
,因为我从其他线程中发现了这一点,但它似乎对我不起作用。我真的不知道。代码方面(见上文)和操作系统方面然而,我有根据的猜测是,
LC
LANG
会影响操作系统