Регистрация нулевых байтов через apache - PullRequest
1 голос
/ 04 мая 2011

Существует проблема с записью двоичных данных в стандартный вывод через 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

Ответы [ 3 ]

1 голос
/ 04 мая 2011

Вы можете просто использовать

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

и все должно работать правильно.

В Apache / mod_wsgi нет ничего плохого - просто консольные выходные потоки не должны использоватьсядля двоичных данных.

0 голосов
/ 04 мая 2011

Вы указали байтовую строку, когда ожидается символьная (Unicode) строка.Помните, что в Python 2.x тип "string" действительно является строкой байтов, а не символьной строкой.(Это следует за C, где тип «char» на самом деле является байтом, а «A» на самом деле 0x41.) Если вы используете либо синтаксис u'string ', либо встроенный unicode () непосредственно перед регистрацией, это обеспечитрегистрируются только строки символов.В этом случае байтовые строки, которые не могут быть декодированы в символьные строки с использованием кодировки ASCII перед регистрацией, получат исключение в этой точке, а не из вызовов Apache.

Для фактической записи байтовых строк, которыекажется, что вы хотите сделать, вам сначала нужно как-то кодировать их в (Unicode) символьные строки.С base64 это просто сделать, но данные нужно будет снова декодировать, чтобы они были удобочитаемыми.Я написал функцию hex-dump, которая заняла у меня несколько часов, чтобы получить именно то, что я хотел.

0 голосов
/ 04 мая 2011

Ошибка тут же указана: stream.write не может принимать строковый аргумент, содержащий нулевые байты .

Возможно, вам следует написать функцию, которая преобразует строку, которая может содержать нулевые байты (или другие непечатаемые символы), и заменяет их печатными escape-последовательностями. Таким образом, передача строки типа '\x31\x00' приведет к печати строки '1\\x00'.

Или, если строка, которую вы регистрируете, - это все двоичные данные, просто преобразуйте каждый символ в его эквивалентный код \xDD. Или просто распечатайте каждый символ в строке в виде простого двузначного шестнадцатеричного кода, чтобы строка восстановления была записана в виде последовательности шестнадцатеричных кодов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...