Skip to content

Instantly share code, notes, and snippets.

@real666maverick
Created September 12, 2017 20:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save real666maverick/93013b69cf76d265240d8217bf93bbac to your computer and use it in GitHub Desktop.
Save real666maverick/93013b69cf76d265240d8217bf93bbac to your computer and use it in GitHub Desktop.
logger unicode vs utf8 receipe just actually for python2
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = "maverick"
def monkey_patch():
"""
Импортируем модуль logger_monkey_patch и вызываем logger_patch.monkey_patch()
Происходит подмена метода emit в StreamHandler и решается проблема:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 4-12: ordinal not in range(128)
такого типа строка корректно логируется:
import Codecs
_unicode = Codecs()._unicode
self.__logger.debug("%sKey:%s - Value:%s", ident, _unicode(str(key)), _unicode(str(value)))
Если в левой части лог строки (там где Key и Value будут русские символы),
то не забываем символ 'u' перед строкой:
self.__logger.debug(u"%sKey:%s - Value:%s", ident, _unicode(str(key)), _unicode(str(value)))
"""
def emit(self, record):
"""
Патченная версия emit метода, для решения граблем с ascii encoding/decoding
на момент логирования объектов имеющих смесь локальных и английских символов и
при этом испорльзуется оператор % для сложения строк (внутри StreamHandler)
Emit a record.
If a formatter is specified, it is used to format the record.
The record is then written to the stream with a trailing newline. If
exception information is present, it is formatted using
traceback.print_exception and appended to the stream. If the stream
has an 'encoding' attribute, it is used to determine how to do the
output to the stream.
"""
try:
msg = self.format(record)
stream = self.stream
if _unicode:
fs = u"%s\n"
else:
fs = "%s\n"
if not _unicode: #if no unicode support...
stream.write(fs % msg)
else:
try:
if (isinstance(msg, unicode) and getattr(stream, "encoding", None)):
ufs = fs.decode(stream.encoding)
try:
stream.write(ufs % msg)
except UnicodeEncodeError:
# Printing to terminals sometimes fails. For example,
# with an encoding of 'cp1251', the above write will
# work if written to a stream opened or wrapped by
# the codecs module, but fail when writing to a
# terminal even when the codepage is set to cp1251.
# An extra encoding step seems to be needed.
stream.write((ufs % msg).encode(stream.encoding))
else:
stream.write(fs % msg)
except UnicodeError:
stream.write(fs % msg.decode("UTF-8"))
self.flush()
except (KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
try:
_logging = __import__("logging")
_unicode = _logging._unicode
_logging.StreamHandler.emit = emit
except Exception:
# скрытие исключение не ошибка - фича!
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment