Как заставить обработчик файлов удалять escape-последовательности терминала (цвета) из сообщения журнала?

#python #python-3.x #django #logging #terminal

#python #python-3.x #django #ведение журнала #терминал

Вопрос:

У меня есть один, Logger с двумя Handler символами: StreamHandler и FileHandler .

Я хочу записать цветной вывод на терминал, используя escape-последовательности (см. Использование регистратора) через StreamHandler . Однако я не хочу регистрировать такие escape-последовательности через FileHandler :

 Log to StreamHandler: 33[39m{}33[0m33[91m{}33[0m33[39m{}33[0m
Log to FileHandler: {}{}{}
  

Другими словами, FileHandler следует удалить управляющие последовательности терминала.

Есть ли какое-либо решение, кроме создания двух Logger файлов, сконфигурированных с помощью StreamHandler и FileHandler соответственно?

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

Использование регистратора:

 fmt = 'Match: {} ({}/v{}): 33[39m{}33[0m33[91m{}33[0m33[39m{}33[0m ({}) {}'

self.logger.info(
    fmt,
    o.type.lower(),
    o.id,
    o.version,
    remove_control_chars(match.left),
    remove_control_chars(match.text),
    remove_control_chars(match.right),
    match.regex,
    suffix
)
  

Конфигурация регистратора:

 def init(log, level, no_console):
    formatter = logging.Formatter(
        '{asctime:s} -- {levelname:<5s} -- {name:s} -- {process:d} -- {funcName:s} -- {message:s}',
        datefmt='%m/%d/%Y %I:%M:%S %p',
        style='{'
    )

    logger = logging.getLogger('watchdog')

    if getattr(logging, level.upper()) is None:
        raise common.exc.WatchdogException(f'Failed to set level for logger: {level.upper()}')

    logger.setLevel(getattr(logging, level.upper()))

    if not no_console:
        handler = logging.StreamHandler()
        handler.setFormatter(formatter)
        logger.addHandler(handler)

    try:
        handler = logging.FileHandler(log, mode='w ')
        handler.setFormatter(formatter)
        logger.addHandler(handler)
    except Exception as exc:
        raise common.exc.WatchdogException(f'Failed to initialize file handler: {log}') from exc
  

Ответ №1:

Можно удалить дополнительные символы в FileHandler , Filter добавив к нему, но есть гораздо лучшее решение. У каждого обработчика могут быть свои Formatter . Таким образом, идеальным способом было бы добавить Formatter только к StreamHandler , который добавляет escape-последовательности терминала в журнал.

Комментарии:

1. Спасибо. В моем случае сообщение журнала содержит произвольный текст, поэтому может быть трудно определить, куда именно поместить экранирование терминала. У вас есть решение для этого? Я принял решение удалить экранирование терминала вместо этого в FileHandler : record.msg = re.sub('33[91m(.*)33[0m', '\1', record.msg) , но я беспокоюсь, повлияет ли такое сопоставление регулярных выражений на производительность приложения, когда есть МНОГО сообщений журнала?