Подавить перевод строки в модуле регистрации Python - PullRequest
30 голосов
/ 24 августа 2011

Я пытаюсь заменить специальную систему регистрации модулем регистрации Python.Я использую систему ведения журнала для вывода информации о ходе выполнения длинной задачи в одну строку, чтобы вы могли tail вести журнал или просматривать его в консоли.Я сделал это, установив флажок в своей функции регистрации, которая подавляет новую строку для этого сообщения журнала и строит строку по частям.

Вся запись ведется из одного потока, поэтому проблем с сериализацией нет.

Возможно ли это сделать с помощью модуля регистрации Python?Это хорошая идея?

Ответы [ 4 ]

34 голосов
/ 14 октября 2015

Если вы хотите сделать это, вы можете изменить терминатор обработчика логов. Я использую Python 3.4. Это было введено в Python 3.2, как заявлено Ninjakannon.

handler = logging.StreamHandler()
handler.terminator = ""

Когда StreamHandler пишет, он записывает терминатор последним.

12 голосов
/ 14 ноября 2012

Новая строка, \n, вставлена ​​в класс StreamHandler.

Если вы действительно настроили на исправление такого поведения, то вот пример того, как я решил это путем исправления обезьяны метода emit(self, record) внутри класса logging.StreamHandler.

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

Вот пользовательская реализация emit(), которая пропускает разрывы строк:

def customEmit(self, record):
    # Monkey patch Emit function to avoid new lines between records
    try:
        msg = self.format(record)
        if not hasattr(types, "UnicodeType"): #if no unicode support...
            self.stream.write(msg)
        else:
            try:
                if getattr(self.stream, 'encoding', None) is not None:
                    self.stream.write(msg.encode(self.stream.encoding))
                else:
                    self.stream.write(msg)
            except UnicodeError:
                self.stream.write(msg.encode("UTF-8"))
        self.flush()
    except (KeyboardInterrupt, SystemExit):
        raise
    except:
        self.handleError(record)

Тогда вы создадите пользовательский класс ведения журнала (в данном случае подклассы от TimedRotatingFileHandler).

class SniffLogHandler(TimedRotatingFileHandler):
    def __init__(self, filename, when, interval, backupCount=0,
                 encoding=None, delay=0, utc=0):

        # Monkey patch 'emit' method
        setattr(StreamHandler, StreamHandler.emit.__name__, customEmit)

        TimedRotatingFileHandler.__init__(self, filename, when, interval,
                                          backupCount, encoding, delay, utc)

Некоторые люди могут утверждать, что этот тип решения не Pythonic , или что-то еще. Это может быть так, так что будьте осторожны.

Также имейте в виду, что это глобально исправит SteamHandler.emit(...), поэтому, если вы используете несколько классов ведения журнала, то это исправление повлияет и на другие классы ведения журнала!

Проверьте это для дальнейшего чтения:

Надеюсь, это поможет.

8 голосов
/ 24 августа 2011

Давайте начнем с вашего последнего вопроса: нет, я не верю, что это хорошая идея.ИМО, в долгосрочной перспективе это ухудшает читабельность лог-файла.

Я предлагаю придерживаться модуля logging и использовать опцию '-f' в вашей команде 'tail' для просмотра вывода с консоли.Вы, вероятно, в конечном итоге будете использовать FileHandler .Обратите внимание, что аргумент по умолчанию для 'delay' равен False, что означает, что вывод не будет буферизован.

Если вам действительно необходимо подавлять переводы строк, я бы порекомендовал создать свой собственный обработчик.*

0 голосов
/ 01 июля 2019

Я столкнулся с необходимостью записать определенный раздел в одну строку, когда я перебирал кортеж, но хотел сохранить весь регистратор.

Сначала собрал выходные данные в одну строку, а затем отправил их в логгер, как только я вышел из раздела. Пример концепции

for fld in object._fields: 
  strX = (' {} --> {} ').format(fld, formattingFunction(getattr(obj,fld)))
debugLine += strX
logger.debug('{}'.format(debugLine))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...