форматирование строки журнала Python - PullRequest
10 голосов
/ 14 июля 2011

Я использую журнал питона форматер для форматирования записей журнала , и у меня есть значение fmt

fmt = "[%(filename)s:%(lineno)s] %(message)s"

То, что я хотел бы, это чтобы «[file.py:20]» был растянут до 10 символов в ширину (например). Если бы это было одно значение, которое было бы легко, но есть ли способ растянуть всю эту структуру до указанной длины? Я хочу что-то вроде:

tmp = "[%(filename)s:%(lineno)s]"
fmt = "%(tmp)10s %(message)s"

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

Ответы [ 3 ]

12 голосов
/ 14 июля 2011

В качестве примера этот форматтер обеспечивает фиксированную ширину "[%(filename)s:%(lineno)s]" либо путем усечения имени файла, либо путем дополнения справа (после номера строки) пробелами.

class MyFormatter(logging.Formatter):
    width = 10

    def format(self, record):
        max_filename_width = self.width - 3 - len(str(record.lineno))
        filename = record.filename
        if len(record.filename) > max_filename_width:
            filename = record.filename[:max_filename_width]
        a = "%s:%s" % (filename, record.lineno)
        return "[%s] %s" % (a.ljust(self.width), record.msg)

if __name__ == '__main__':
    logger = logging.getLogger('simple_example')
    logger.setLevel(logging.DEBUG)
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    formatter = MyFormatter()
    ch.setFormatter(formatter)
    logger.addHandler(ch)

    logger.debug('No one expects the spammish repetition')

РЕДАКТИРОВАТЬ:

Если вы хотите обеспечить минимальную ширину из 10 символов, отбросьте название файла.

def format(self, record):
    a = "%s:%s" % (record.filename, record.lineno)
    return "[%s] %s" % (a.ljust(self.width), record.msg)
9 голосов
/ 14 июля 2011

Вариант 1

Начните здесь: http://docs.python.org/library/logging.html#formatter-objects

Вы создадите свой собственный настроенный подкласс Formatter, который предоставляет собственный уникальный метод format.

Тогда вы должны обязательно позвонить setFormatter() в каждый из ваших Handlers, чтобы они использовали ваш новый форматер.

Вариант 2

Создайте свой собственный подкласс LogRecord с дополнительным свойством.

Подкласс Logger и переопределите makeRecord, чтобы создать новый подкласс LogRecord.

Укажите настраиваемый формат, который использует это новое значение свойства.

2 голосов
/ 28 марта 2014

Используя ответ @ rob-cowie в качестве основы, я нашел следующее полезное:

class MyFormatter(logging.Formatter):
    width = 24
    datefmt='%Y-%m-%d %H:%M:%S'

    def format(self, record):
        cpath = '%s:%s:%s' % (record.module, record.funcName, record.lineno)
        cpath = cpath[-self.width:].ljust(self.width)
        record.message = record.getMessage()
        s = "%-7s %s %s : %s" % (record.levelname, self.formatTime(record, self.datefmt), cpath, record.getMessage())
        if record.exc_info:
            # Cache the traceback text to avoid converting it multiple times
            # (it's constant anyway)
            if not record.exc_text:
                record.exc_text = self.formatException(record.exc_info)
        if record.exc_text:
            if s[-1:] != "\n":
                s = s + "\n"
            s = s + record.exc_text
        #if record.stack_info:
        #    if s[-1:] != "\n":
        #        s = s + "\n"
        #    s = s + self.formatStack(record.stack_info)
        return s

logFormatter = MyFormatter()
logger = logging.getLogger("example")
logger.setFormatter(logFormatter)

, которое дает вывод типа:

WARNING 2014-03-28 16:05:09 module:function:31       : Message
WARNING 2014-03-28 16:05:09 dule:longerfunctions:140 : Message
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...