python日志字符串格式

时间:2011-07-14 11:10:36

标签: python logging formatting string-formatting

我使用python的日志formatter来格式化log records,我的fmt值为

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

我想要的是“[file.py:20]”被拉伸到10个字符宽(例如)。如果它是一个很容易的值,但有没有办法将整个结构拉伸到指定的长度? 我想要这样的东西:

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

我想知道是否可以使用字符串格式化,或者我是否可以欺骗python的格式化程序以获得我想要的东西..

3 个答案:

答案 0 :(得分:12)

作为示例,此Formatter通过截断文件名或使用空格右边填充(在行号后面)来确保固定宽度"[%(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)

答案 1 :(得分:9)

选项1

从这里开始:http://docs.python.org/library/logging.html#formatter-objects

您将创建自己的Formatter自定义子类,提供自己独有的format方法。

然后,您必须确保在每个setFormatter()中致电Handlers,以便他们使用您的新格式化程序。

选项2

使用附加属性创建自己的LogRecord子类。

子类Logger并覆盖makeRecord以创建LogRecord的新子类。

提供使用此新属性值的自定义格式。

答案 2 :(得分:2)

以@ 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