Python 通过apache记录空字节
通过Apache将二进制数据记录到标准输出时存在问题 配置日志记录后,我尝试记录字符串Python 通过apache记录空字节,python,apache,logging,Python,Apache,Logging,通过Apache将二进制数据记录到标准输出时存在问题 配置日志记录后,我尝试记录字符串'\x31\x00': logging.getLogger().info('\x31\x00') 如果我使用python控制台,一切都很顺利-我看到了预期的结果: 2011-05-01 22:21:27,430 INFO [test_logging:9][test_logging] 1 但如果我通过Apache和mod_wsgi使用日志记录,我会得到回溯: Traceback (most recent cal
'\x31\x00'
:
logging.getLogger().info('\x31\x00')
如果我使用python控制台,一切都很顺利-我看到了预期的结果:
2011-05-01 22:21:27,430 INFO [test_logging:9][test_logging] 1
但如果我通过Apache和mod_wsgi使用日志记录,我会得到回溯:
Traceback (most recent call last):
File "/usr/local/lib/python2.6/logging/__init__.py", line 789, in emit
stream.write(fs % msg) TypeError: write() argument 1 must be string without null bytes, not str
臭虫在哪里?我应该深入到哪里
我的日志记录配置:
[loggers]
keys=root
[formatters]
keys=stdoutFormatter
[handlers]
keys=stdoutHandler
[logger_root]
level=NOTSET
handlers=stdoutHandler
[handler_stdoutHandler]
class=StreamHandler
formatter=stdoutFormatter
args=(sys.stdout,)
[formatter_stdoutFormatter]
format=%(asctime)s %(levelname)s [%(module)s:%(lineno)d][%(funcName)s] %(message)s
Apache版本2.2.16
Python版本2.6.4
Mod_wsgi 2.8错误就在这里说明:stream.write不能接受包含空字节的字符串参数 也许您应该编写一个函数来转换可能包含空字节(或其他不可打印字符)的字符串,并将其替换为可打印转义序列。因此,传入像
'\x31\x00'
这样的字符串将导致打印字符串'1\\x00'
或者,如果您记录的字符串都是二进制数据,只需将每个字符转换为其对应的
\xDD
转义码即可。或者只是将字符串中的每个字符打印为一个简单的两位数十六进制代码,这样entore字符串就被记录为一个十六进制代码序列。错误就在这里说明:stream.write不能接受包含空字节的字符串参数
也许您应该编写一个函数来转换可能包含空字节(或其他不可打印字符)的字符串,并将其替换为可打印转义序列。因此,传入像'\x31\x00'
这样的字符串将导致打印字符串'1\\x00'
或者,如果您记录的字符串都是二进制数据,只需将每个字符转换为其对应的\xDD
转义码即可。或者只需将字符串中的每个字符打印为一个简单的两位数十六进制代码,这样entore字符串就可以被记录为一系列十六进制代码。您可以使用
logging.getLogger().info('%r', binary_bytes)
它应该做正确的事情
Apache/mod_wsgi没有什么问题——只是控制台输出流不应该用于二进制数据。您可以使用
logging.getLogger().info('%r', binary_bytes)
它应该做正确的事情
Apache/mod_wsgi没有什么问题-只是控制台输出流不应该用于二进制数据。当需要字符(Unicode)字符串时,您提供了一个字节字符串。请记住,在Python2.x中,“string”类型实际上是字节字符串而不是字符串。(这跟在C后面,其中“char”类型实际上是一个字节,“a”实际上是0x41。)如果在记录之前直接使用u'string'语法或内置的unicode(),这将确保只记录字符串。在这种情况下,在日志记录之前无法使用ASCII编码解码为字符串的字节字符串将在该点而不是从Apache调用中获得异常
要实际记录字节字符串(这似乎是您想要做的),首先需要将它们以某种方式编码为(Unicode)字符串。base64操作简单,但需要再次解码数据,以使其可读。我编写了一个十六进制转储函数,花了几个小时才得到我想要的结果。当需要字符(Unicode)字符串时,您提供了一个字节字符串。请记住,在Python2.x中,“string”类型实际上是字节字符串而不是字符串。(这跟在C后面,其中“char”类型实际上是一个字节,“a”实际上是0x41。)如果在记录之前直接使用u'string'语法或内置的unicode(),这将确保只记录字符串。在这种情况下,在日志记录之前无法使用ASCII编码解码为字符串的字节字符串将在该点而不是从Apache调用中获得异常
要实际记录字节字符串(这似乎是您想要做的),首先需要将它们以某种方式编码为(Unicode)字符串。base64操作简单,但需要再次解码数据,以使其可读。我编写了一个十六进制转储函数,花了我几个小时才完全达到我想要的效果。我对Python控制台的行为没有意见,问题是-Apache有什么问题?Apache没有什么“问题”,只是它是用C/C++编写的,遵循的惯例是,字符串在内部表示为字节序列,每个字符以ASCII NUL(\x00)结尾。这是大多数语言中表示简单字符串的标准方式,也是(我相信)第一代C编译器最初处理字符串的方式的产物。我对Python控制台行为没有意见,问题是-Apache有什么问题?Apache没有什么“错”的,只是它是用C/C++编写的,遵循的惯例是,字符串在内部表示为字节序列,每个字符以ASCII NUL(\x00)结尾。这是大多数语言中表示简单字符串的标准方式,也是(我相信)第一代C编译器最初处理字符串的方式的产物。不太可能,我不能使用它,因为我要记录的不仅仅是二进制。不太可能,我不能使用它,因为我要记录的不仅仅是二进制。