【问题标题】:Logging null bytes via apache通过 apache 记录空字节
【发布时间】:2011-08-18 15:52:23
【问题描述】:

通过 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 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

【问题讨论】:

    标签: python apache logging


    【解决方案1】:

    你可以使用

    logging.getLogger().info('%r', binary_bytes)
    

    它应该做正确的事。

    Apache/mod_wsgi 没有任何问题 - 只是控制台输出流不应该用于二进制数据。

    【讨论】:

    • 不太可能,我不能使用它,因为我不仅要记录二进制文件。
    【解决方案2】:

    错误就在那里说明:stream.write 不能接受包含空字节的字符串参数

    也许您应该编写一个函数来转换可能包含空字节(或其他不可打印字符)的字符串并将它们替换为可打印的转义序列。所以传入像'\x31\x00' 这样的字符串会导致字符串'1\\x00' 被打印出来。

    或者,如果您正在记录的字符串都是二进制数据,只需将每个字符转换为其等效的\xDD 转义码。或者只是将字符串中的每个字符打印为一个简单的两位十六进制代码,因此 entore 字符串被记录为十六进制代码序列。

    【讨论】:

    • 我对 Python 控制台行为没意见,问题是 - Apache 出了什么问题?
    • Apache 没有什么“错误”,只是它是用 C/C++ 编写的,它遵循字符串在内部表示为字节序列的约定——每个字符一个字节,以 ASCII 结尾空 (\x00)。这是在大多数语言中表示简单字符串的标准方式,并且是(我相信)第一个 C 编译器最初处理字符串的方式的产物。
    【解决方案3】:

    当需要一个字符 (Unicode) 字符串时,您提供了一个字节字符串。请记住,在 Python 2.x 中,“字符串”类型实际上是字节字符串而不是字符串。 (这跟在 C 之后,其中“char”类型实际上是一个字节,而“A”实际上是 0x41。)如果您在记录之前直接使用 u'string' 语法或内置的 unicode(),这将确保仅记录字符串。在这种情况下,在记录之前无法使用 ASCII 编码解码为字符串的字节字符串会在此时为您提供异常,而不是在 Apache 调用中。

    要实际记录字节字符串,您似乎想要这样做,您首先需要以某种方式将它们编码为(Unicode)字符串。 base64 做起来很简单,但数据需要再次解码才能可读。我写了一个十六进制转储函数,我花了几个小时才得到我想要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 1970-01-01
      • 2017-04-29
      • 1970-01-01
      相关资源
      最近更新 更多