python logger: изменить формат [дубликат]

В последних версиях Android Studio, по крайней мере для меня, следующие работы:

«Инструменты» -> «Android» -> «Sync Project with Gradle Files»

В последней версии Android Studio 3.1.3 (июль 2018 г.) в главном меню доступен «Sync Project with Gradle Files».

53
задан dreftymac 2 May 2017 в 02:12
поделиться

8 ответов

Да, вы можете сделать это с помощью специального класса Formatter:

class MyFormatter(logging.Formatter):
    def format(self, record):
        #compute s according to record.levelno
        #for example, by setting self._fmt
        #according to the levelno, then calling
        #the superclass to do the actual formatting
        return s

Затем присоедините экземпляр MyFormatter к вашим обработчикам.

29
ответ дан Vinay Sajip 18 August 2018 в 17:27
поделиться
  • 1
    Выдающийся - отлично работал. Я изменил метод format (), чтобы проверить levelno, и при необходимости измените сообщение. В противном случае он сбрасывает его обратно к исходной строке, в которую я прошел. Спасибо! – bedwyr 27 August 2009 в 21:10
  • 2
  • 3
    Удалите галочку из этого ответа. Тот, что находится ниже этого, завершен. В этом ответе есть пробелы кода, в которых есть только комментарии, описывающие, что вы должны делать. – Utkonos 4 June 2017 в 08:19

Это адаптация ответа estani на новую реализацию logging.Formatter, которая теперь опирается на стили форматирования. Шахта опирается на формат стиля '{', но его можно адаптировать. Может быть уточнено, чтобы быть более общим и разрешить выбор стиля форматирования и пользовательских сообщений в качестве аргументов __init__.

class SpecialFormatter(logging.Formatter):
    FORMATS = {logging.DEBUG : logging._STYLES['{']("{module} DEBUG: {lineno}: {message}"),
           logging.ERROR : logging._STYLES['{']("{module} ERROR: {message}"),
           logging.INFO : logging._STYLES['{']("{module}: {message}"),
           'DEFAULT' : logging._STYLES['{']("{module}: {message}")}

    def format(self, record):
        # Ugly. Should be better
        self._style = self.FORMATS.get(record.levelno, self.FORMATS['DEFAULT'])
        return logging.Formatter.format(self, record)

hdlr = logging.StreamHandler(sys.stderr)
hdlr.setFormatter(SpecialFormatter())
logging.root.addHandler(hdlr)
logging.root.setLevel(logging.INFO)
51
ответ дан Community 18 August 2018 в 17:27
поделиться
  • 1
    Это отлично работает! Я изменил ссылки на MyFormatter по имени на self для большей согласованности. – halloleo 6 September 2012 в 05:22
  • 2
    И здесь я могу добавить способ использования класса MyFormatter в вашей программе (заменить каждый & lt; CR & gt; на возврат каретки): fmt = MyFormatter() & lt; CR & gt; hdlr = logging.StreamHandler(sys.stdout) & Lt; CR & GT; <CR> hdlr.setFormatter (FMT) <CR> logging.root.addHandler (hdlr) <CR> logging.root.setLevel (ОТЛАДКА) `& л; CR & GT; – halloleo 6 September 2012 в 05:25
  • 3
    Этот ответ не будет работать после 3.2 из-за изменений во внутреннем механизме каротажа. logging.Formatter.format теперь зависит от параметра style в __init__. – Evpok 21 May 2013 в 01:32
  • 4
    Спасибо за обновление этого для работы с Python3. Я столкнулся с той же проблемой в Python3 и придумал аналогичное решение. Пожалуйста, будьте так любезны, чтобы опубликовать этот ответ там. [Д0] stackoverflow.com/questions/14844970/… – JS. 21 May 2013 в 20:20
  • 5
    {{Сделано}} – Evpok 21 May 2013 в 21:20
  • 6
    Используя новый стиль '{' в ваших комментариях? :-) – JS. 21 May 2013 в 21:34
  • 7
    @JS. Просто Википедия: p – Evpok 21 May 2013 в 21:36
  • 8
    Евпок прав. Добавьте это после того, как вы присвойте self._fmt: self._style = logging.PercentStyle(self._fmt) – Ross R 11 October 2014 в 13:55
  • 9
    Может ли это быть улучшено с помощью super() вместо вызова logging.Formatter? – phoenix 16 November 2015 в 17:31

И снова, как ответ JS, но более компактный.

class SpecialFormatter(logging.Formatter):
    FORMATS = {logging.DEBUG :"DBG: %(module)s: %(lineno)d: %(message)s",
               logging.ERROR : "ERROR: %(message)s",
               logging.INFO : "%(message)s",
               'DEFAULT' : "%(levelname)s: %(message)s"}

    def format(self, record):
        self._fmt = self.FORMATS.get(record.levelno, self.FORMATS['DEFAULT'])
        return logging.Formatter.format(self, record)

hdlr = logging.StreamHandler(sys.stderr)
hdlr.setFormatter(SpecialFormatter())
logging.root.addHandler(hdlr)
logging.root.setLevel(logging.INFO)
14
ответ дан estani 18 August 2018 в 17:27
поделиться
  • 1
    Этот ответ не будет работать после 3.2 из-за изменений во внутреннем механизме каротажа. logging.Formatter.format теперь зависит от параметра style в __init__. – Evpok 21 May 2013 в 01:33

Если вы просто хотите пропустить форматирование определенных уровней, вы можете сделать что-то более простое, чем другие ответы, такие как:

class FormatterNotFormattingInfo(logging.Formatter):
    def __init__(self, fmt = '%(levelname)s:%(message)s'):
        logging.Formatter.__init__(self, fmt)

    def format(self, record):
        if record.levelno == logging.INFO:
            return record.getMessage()
        return logging.Formatter.format(self, record)

Это также имеет преимущество работы до и после выпуска 3.2 не используя внутренние переменные, такие как self._fmt и self._style.

3
ответ дан JDiMatteo 18 August 2018 в 17:27
поделиться

Вместо того, чтобы полагаться на стили или внутренние поля, вы также можете создать Formatter, который делегирует другие форматы в зависимости от record.levelno (или других критериев). Это немного более чистое решение по моему скромному мнению. Код ниже должен работать для любой версии python> = 2.7:

Простой способ будет выглядеть примерно так:

class MyFormatter(logging.Formatter):

    default_fmt = logging.Formatter('%(levelname)s in %(name)s: %(message)s')
    info_fmt = logging.Formatter('%(message)s')

    def format(self, record):
        if record.levelno == logging.INFO:
            return self.info_fmt.format(record)
        else:
            return self.default_fmt.format(record)

Но вы могли бы сделать его более общим:

class VarFormatter(logging.Formatter):

    default_formatter = logging.Formatter('%(levelname)s in %(name)s: %(message)s')

    def __init__(self, formats):
        """ formats is a dict { loglevel : logformat } """
        self.formatters = {}
        for loglevel in formats:
            self.formatters[loglevel] = logging.Formatter(formats[loglevel])

    def format(self, record):
        formatter = self.formatters.get(record.levelno, self.default_formatter)
        return formatter.format(record)

В качестве входного сигнала я использовал здесь dict, но, очевидно, вы также можете использовать кортежи, ** kwargs, независимо от того, что плавает ваша лодка. Тогда это будет использоваться как:

formatter = VarFormatter({logging.INFO: '[%(message)s]', 
                          logging.WARNING: 'warning: %(message)s'})
<... attach formatter to logger ...>
6
ответ дан Joris 18 August 2018 в 17:27
поделиться

Вышеупомянутое решение работает с выпуском 3.3.3. Однако с 3.3.4 вы получаете следующую ошибку.

FORMATS = { logging.DEBUG : logging._STYLES['{']("{module} DEBUG: {lineno}: {message}"),

TypeError: объект «tuple» не может быть вызван

После некоторого поиска в классе ведения журнала Lib \ logging__init __. Py Я обнаружил, что структура данных изменилась с 3.3.3 до 3.3.4, что вызывает проблему

3.3.3

_STYLES = {
    '%': PercentStyle,
    '{': StrFormatStyle,
    '$': StringTemplateStyle
}

3.3.4

_STYLES = {
   '%': (PercentStyle, BASIC_FORMAT),
   '{': (StrFormatStyle, '{levelname}:{name}:{message} AA'),
    '$': (StringTemplateStyle, '${levelname}:${name}:${message} BB'),
}

Таким образом, обновленное решение

class SpecialFormatter(logging.Formatter):
     FORMATS = {logging.DEBUG : logging._STYLES['{'][0]("{module} DEBUG: {lineno}: {message}"),
       logging.ERROR : logging._STYLES['{'][0]("{module} ERROR: {message}"),
       logging.INFO : logging._STYLES['{'][0]("{module}: {message}"),
       'DEFAULT' : logging._STYLES['{'][0]("{module}: {message}")}

 def format(self, record):
    # Ugly. Should be better
    self._style = self.FORMATS.get(record.levelno, self.FORMATS['DEFAULT'])
    return logging.Formatter.format(self, record)
4
ответ дан user1837990 18 August 2018 в 17:27
поделиться
51
ответ дан Community 7 September 2018 в 02:01
поделиться
51
ответ дан Community 30 October 2018 в 06:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: